UNPKG

integreat

Version:
115 lines 4.55 kB
import pProgress from 'p-progress'; import { setErrorOnAction, setActionIds } from '../../utils/action.js'; import { createErrorResponse, setOrigin } from '../../utils/response.js'; import { isObject } from '../../utils/is.js'; import { completeIdent } from '../../utils/completeIdent.js'; const identityFromIntegreat = Symbol('identityFromIntegreat'); const setServiceIdAsSourceServiceOnAction = (action, serviceId) => ({ ...action, payload: { ...action.payload, sourceService: serviceId, }, }); const isIdent = (ident) => isObject(ident) && (typeof ident.id === 'string' || typeof ident.withToken === 'string' || (Array.isArray(ident.withToken) && typeof ident.withToken[0] === 'string')); const isKnownIdent = (ident) => ident[identityFromIntegreat] === true; function markIdentAsKnown(response) { const ident = response.access?.ident; if (isIdent(ident)) { return { ...response, access: { ...response.access, ident: { ...ident, [identityFromIntegreat]: true }, }, }; } else { return response; } } const removeKnownIdentMarker = ({ [identityFromIntegreat]: _, ...identWithoutMarker }) => identWithoutMarker; async function authorizeIncoming(action, serviceId) { if (typeof action.response?.status === 'string') { return action; } const ident = action.meta?.ident; if (!isIdent(ident)) { return setErrorOnAction(action, 'Authentication was refused. No ident', `auth:service:${serviceId}`, 'noaccess'); } else { return { ...action, meta: { ...action.meta, ident: isKnownIdent(ident) ? removeKnownIdentMarker(ident) : undefined, auth: undefined, }, }; } } const dispatchWithProgress = (dispatch, setProgress, serviceId) => async function (action) { const p = dispatch(action); p.onProgress(setProgress); const response = await p; return setOrigin(response, `service:${serviceId}`); }; async function runAuths(auths, authentication, action, dispatch) { let response = undefined; for (const auth of auths) { response = await auth.validate(authentication, action, dispatch); if (response.status !== 'noaccess' && response.access?.ident) { return response; } } return response || { status: 'noaccess', error: 'No authentication was run' }; } async function getAuthsFromAction(service, action) { if (!action) { return undefined; } const endpoint = await service.endpointFromAction(action, true); return endpoint?.incomingAuth; } async function runAuthsAndCompleteIdent(dispatch, authentication, shouldCompleteIdent, auths, action) { const response = await runAuths(auths, authentication, action || null, dispatch); if (shouldCompleteIdent) { return await completeIdent(response.access?.ident, dispatch); } else { return response; } } export const authenticateCallback = (service, dispatch, shouldCompleteIdent, incomingAuth) => async function authenticateFromListen(authentication, action) { const auths = (await getAuthsFromAction(service, action)) || incomingAuth; if (auths) { const response = await runAuthsAndCompleteIdent(dispatch, authentication, shouldCompleteIdent, auths, action); return setOrigin(markIdentAsKnown(response), `auth:service:${service.id}`, true); } else { return createErrorResponse(`Could not authenticate. Service '${service.id}' has no incoming authenticator`, `auth:service:${service.id}`, 'noaction'); } }; export function dispatchIncoming(dispatch, middleware, serviceId) { return (action) => pProgress(async (setProgress) => { if (action) { const authorizedAction = await authorizeIncoming(setServiceIdAsSourceServiceOnAction(setActionIds(action), serviceId), serviceId); const response = await middleware(dispatchWithProgress(dispatch, setProgress, serviceId))(authorizedAction); return (setOrigin(response, `middleware:service:${serviceId}`) || { status: 'error', origin: `service:${serviceId}`, }); } else { return { status: 'noaction', error: 'No action was dispatched', origin: `service:${serviceId}`, }; } }); } //# sourceMappingURL=incoming.js.map