in src/smartHandler.ts [244:293]
async isBundleRequestAuthorized(request: AuthorizationBundleRequest): Promise<void> {
const { scopes, fhirUserObject, patientLaunchContext } = request.userIdentity;
const usableScopes: string[] = scopes.filter(
(scope: string) =>
(patientLaunchContext && scope.startsWith('patient/')) ||
(fhirUserObject && scope.startsWith('user/')) ||
scope.startsWith('system/'),
);
// Are the scopes the request have good enough for every entry in the bundle?
request.requests.forEach((req: BatchReadWriteRequest) => {
if (
!usableScopes.some((scope: string) =>
isScopeSufficient(
scope,
this.config.scopeRule,
req.operation,
this.isUserScopeAllowedForSystemExport,
req.resourceType,
),
)
) {
logger.error('User supplied scopes are insufficient', {
usableScopes,
operation: req.operation,
resourceType: req.resourceType,
});
throw new UnauthorizedError('An entry within the Bundle is not authorized');
}
});
// Ensure the requestor has access to write this request
const authWritePromises: Promise<void>[] = request.requests.map((req) => {
if (['create', 'update', 'patch', 'delete'].includes(req.operation)) {
return this.isWriteRequestAuthorized(<WriteRequestAuthorizedRequest>{
userIdentity: { ...request.userIdentity, usableScopes },
operation: req.operation,
resourceBody: req.resource,
fhirServiceBaseUrl: request.fhirServiceBaseUrl,
});
}
return Promise.resolve();
});
try {
await Promise.all(authWritePromises);
} catch (e) {
throw new UnauthorizedError('An entry within the Bundle is not authorized');
}
}