UNPKG

integreat

Version:
96 lines 4.67 kB
import { validateRoleOrIdent } from './authAction.js'; import getField from '../../utils/getField.js'; import { arrayIncludes } from '../../utils/array.js'; import { isTypedData, isNullOrUndefined, isRootIdent } from '../../utils/is.js'; const isStringOrArray = (value) => typeof value === 'string' || Array.isArray(value); function getValueAndCompare(item, fieldPath, compareValue) { const values = getField(item, fieldPath); return isStringOrArray(values) && arrayIncludes(compareValue, values); } const isIdentFromFieldOrIdentOk = (item, field, present) => field && getValueAndCompare(item, field, present); const isItemAuthorized = (item, access, ident) => (!access.identFromField && !access.roleFromField) || validateRoleOrIdent(access.role, ident?.roles) || validateRoleOrIdent(access.ident, ident?.id) || isIdentFromFieldOrIdentOk(item, access.identFromField, ident?.id) || isIdentFromFieldOrIdentOk(item, access.roleFromField, ident?.roles); const authorizeItem = (schemas, actionType, allowRaw, ident) => (item) => { if (!isTypedData(item)) { return allowRaw ? undefined : 'RAW_DATA'; } const schema = schemas.get(item.$type); if (!schema) { return 'NO_SCHEMA'; } const access = schema.accessForAction(actionType); if (isItemAuthorized(item, access, ident)) { return undefined; } else { return access.identFromField ? 'WRONG_IDENT' : 'MISSING_ROLE'; } }; const generateWarning = (removedCount, isToService) => removedCount > 0 ? `${removedCount} item${removedCount === 1 ? ' was' : 's were'} removed from ${isToService ? 'request' : 'response'} data due to lack of access` : undefined; const generateErrorAndReason = (reason, data, isToService, service) => reason === 'RAW_DATA' ? `Authentication was refused for raw ${isToService ? 'request' : 'response'} data${service ? ` ${isToService ? 'to' : 'from'} service '${service}'` : ''}` : `Authentication was refused for type '${data.$type}'${service ? ` on service '${service}'` : ''}`; function authorizeDataArrayAndWrapInResponse(data, authItemFn, isToService) { const authed = data.filter((data) => authItemFn(data) === undefined); const warning = generateWarning(data.length - authed.length, isToService); return { data: authed, warning }; } function authorizeDataItemAndWrapInResponse(data, authItemFn, isToService, service) { if (!isNullOrUndefined(data)) { const reason = authItemFn(data); if (typeof reason === 'string') { const error = generateErrorAndReason(reason, data, isToService, service); return { data: undefined, status: 'noaccess', error, reason, origin: 'auth:data', }; } } return { data }; } const authorizeDataAndWrapInResponse = (data, authItemFn, isToService, service) => Array.isArray(data) ? authorizeDataArrayAndWrapInResponse(data, authItemFn, isToService) : authorizeDataItemAndWrapInResponse(data, authItemFn, isToService, service); const isError = (status) => typeof status === 'string' && status !== 'ok'; const authorizeDataBase = (schemas, isToService) => function authorizeData(action, allowRaw = false) { if (isRootIdent(action.meta?.ident)) { return action; } const { type: actionType, payload: { targetService }, meta: { ident } = {}, } = action; const { data, status: authedStatus, error, reason, warning, } = authorizeDataAndWrapInResponse(isToService ? action.payload.data : action.response?.data, authorizeItem(schemas, actionType, allowRaw, ident), isToService, targetService); const status = isError(action.response?.status) || !authedStatus ? action.response?.status : authedStatus; const response = status !== undefined || warning ? { ...action.response, ...(!isToService && { data }), ...(!action.response?.error && error && { error }), ...(!action.response?.error && reason && { reason }), ...(warning && { warning }), ...(isError(status) ? { origin: action.response?.origin || 'auth:data' } : {}), status, } : undefined; return { ...action, payload: { ...action.payload, ...(isToService && { data }), }, ...(response && { response }), }; }; export const fromService = (schemas) => authorizeDataBase(schemas, false); export const toService = (schemas) => authorizeDataBase(schemas, true); //# sourceMappingURL=authData.js.map