UNPKG

@directus/api

Version:

Directus is a real-time API and App dashboard for managing SQL database content

69 lines (68 loc) 2.95 kB
import { isEqual } from 'lodash-es'; import { DEFAULT_AUTH_PROVIDER } from '../constants.js'; import getDatabase from '../database/index.js'; import emitter from '../emitter.js'; import { createDefaultAccountability } from '../permissions/utils/create-default-accountability.js'; import { AuthenticationService } from '../services/index.js'; import { getAccountabilityForToken } from '../utils/get-accountability-for-token.js'; import { getSchema } from '../utils/get-schema.js'; import { WebSocketError } from './errors.js'; import { getExpiresAtForToken } from './utils/get-expires-at-for-token.js'; export async function authenticateConnection(message, accountabilityOverrides) { let access_token, refresh_token; try { if ('email' in message && 'password' in message) { const authenticationService = new AuthenticationService({ schema: await getSchema() }); const { accessToken, refreshToken } = await authenticationService.login(DEFAULT_AUTH_PROVIDER, message); access_token = accessToken; refresh_token = refreshToken; } if ('refresh_token' in message) { const authenticationService = new AuthenticationService({ schema: await getSchema() }); const { accessToken, refreshToken } = await authenticationService.refresh(message.refresh_token); access_token = accessToken; refresh_token = refreshToken; } if ('access_token' in message) { access_token = message.access_token; } if (!access_token) throw new Error(); const defaultAccountability = createDefaultAccountability(accountabilityOverrides); const authenticationState = { accountability: defaultAccountability, expires_at: getExpiresAtForToken(access_token), refresh_token, }; const customAccountability = await emitter.emitFilter('websocket.authenticate', defaultAccountability, { message, }, { database: getDatabase(), schema: null, accountability: null, }); if (customAccountability && isEqual(customAccountability, defaultAccountability) === false) { authenticationState.accountability = customAccountability; } else { authenticationState.accountability = await getAccountabilityForToken(access_token, defaultAccountability); } return authenticationState; } catch { throw new WebSocketError('auth', 'AUTH_FAILED', 'Authentication failed.', message['uid']); } } export function authenticationSuccess(uid, refresh_token) { const message = { type: 'auth', status: 'ok', }; if (uid !== undefined) { message.uid = uid; } if (refresh_token !== undefined) { message['refresh_token'] = refresh_token; } return JSON.stringify(message); }