import { Authorizer } from '@authorizerdev/authorizer-js'; import { Server } from '@hocuspocus/server' const port = process.env.PORT || 4000 const authorizer = new Authorizer({ clientID: process.env.AUTHORIZER_CLIENT_ID || '', authorizerURL: process.env.AUTHORIZER_URL || 'https://auth.discours.io', redirectURL: process.env.REDIRECT_URL || 'https://testing.discours.io', }); // console.info(authorizer) const server = Server.configure({ port, onConnect({ connection }) { connection.requiresAuthentication = true; }, onAuthenticate(data) { return new Promise((resolve, reject) => { const headers = data.requestHeaders if (!headers) { console.error('Request headers not found'); return Promise.reject('required header is not present') } const shout_id = parseInt(data.documentName.replace('shout-', ''), 10) console.debug(`shout_id extracted: ${shout_id}`); const token = data.token || headers['authorization'] || '' const params = { token_type: 'access_token', token }; if (!token) { console.error('Authorization token not found'); return Promise.reject('token is not found') } authorizer.validateJWTToken(params) .then(response => { if (!response?.data?.is_valid) { console.error('Invalid authorization token'); return Promise.reject('token is invalid') } const { sub: user_id, allowed_roles: roles } = response.data.claims console.debug(`user_id: ${user_id} roles: ${roles}`) if (roles.includes('editor')) { return Promise.resolve({ id: user_id, roles: Array.isArray(roles) ? roles : roles.split(',') }) } authorizer.getProfile(params).then((r) => { console.debug(r) const { profile: author } = r.data.app_data const author_id = author.get('id') if(author_id) { const query = ` query { get_shout(shout_id: $shout_id) { id slug authors } } `; fetch('https://core.discours.io/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query, variables: { shout_id } }), }) .then(res => res.json()) .then(data => { console.debug(data) const { authors } = data.get_shout; if (authors.includes(author_id)) { return { id: user_id, author: author_id, roles: Array.isArray(roles) ? roles : roles.split(','), }; } return Promise.reject('not in authors list') }) .catch(e => { console.error('Error fetching shout data:', e.message); console.error(e.stack); return Promise.reject('error fetching shout data') }); } }) }) .catch(e => { console.error('Error validating authorization token:', e.message); console.error(e.stack); return Promise.reject('token is invalid') }); }) } }); server.listen().then(r => console.info('started'));