{"record":{"id":"703b623262734206","repo":"immich-app/immich","slug":"elevated-permission-is-required","errorCode":null,"errorMessage":"Elevated permission is required","messagePattern":"Elevated permission is required","errorType":"exception","errorClass":"UnauthorizedException","httpStatus":401,"severity":"error","filePath":"server/src/utils/access.ts","lineNumber":339,"sourceCode":"    case Permission.StackDelete: {\n      return access.stack.checkOwnerAccess(auth.user.id, ids);\n    }\n\n    case Permission.WorkflowRead:\n    case Permission.WorkflowUpdate:\n    case Permission.WorkflowDelete: {\n      return access.workflow.checkOwnerAccess(auth.user.id, ids);\n    }\n\n    default: {\n      return new Set<string>();\n    }\n  }\n};\n\nexport const requireElevatedPermission = (auth: AuthDto) => {\n  if (!auth.session?.hasElevatedPermission) {\n    throw new UnauthorizedException('Elevated permission is required');\n  }\n};\n","sourceCodeStart":321,"sourceCodeEnd":342,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/server/src/utils/access.ts#L321-L342","documentation":"An UnauthorizedException (HTTP 401) thrown by requireElevatedPermission when the session on the auth context does not have hasElevatedPermission set. Elevated permission is granted after a recent PIN/password re-authentication and is required for sensitive operations; a session that has not been elevated (or whose elevation expired) is rejected.","triggerScenarios":"Calling a route guarded by requireElevatedPermission without first completing the PIN/password step-up flow, or after the elevated state has timed out on the session.","commonSituations":"User logged in normally but the operation requires step-up auth; elevated permission expired mid-session; PIN not configured; integration tests that authenticate but skip the elevation step.","solutions":["Drive the PIN/password step-up flow to set hasElevatedPermission on the session before retrying the operation.","Re-run the elevation flow if the elevated state has expired.","Ensure a PIN is configured for the user if the flow requires it.","In tests, perform the elevation request after login before calling elevated endpoints."],"exampleFix":"// before\nawait api.deleteSensitiveThing(id); // 401 'Elevated permission is required'\n\n// after\nawait api.unlockWithPin(userPin); // sets hasElevatedPermission on session\nawait api.deleteSensitiveThing(id);","handlingStrategy":"validation","validationCode":"function hasElevated(auth) {\n  return Boolean(auth?.session?.hasElevatedPermission);\n}\nif (!hasElevated(auth)) {\n  await api.unlockWithPin(pin); // step-up\n}\nif (!hasElevated(auth)) {\n  return unauthorized('Elevated permission required');\n}","typeGuard":"const isElevatedPermissionError = (e: unknown): boolean =>\n  typeof e === 'object' && e !== null && (e as any).status === 401 && (e as any).message === 'Elevated permission is required';","tryCatchPattern":"try {\n  await api.doSensitiveOp(id);\n} catch (e) {\n  if (isElevatedPermissionError(e)) {\n    await promptPinAndUnlock();\n    return api.doSensitiveOp(id); // retry once after step-up\n  }\n  throw e;\n}","preventionTips":["Run the PIN/password step-up flow before any elevated endpoint.","Track the elevated state in the client and re-elevate after timeout.","In tests, perform elevation right after login for elevated endpoints."],"tags":["authorization","authentication","step-up","session","nestjs"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}