{"record":{"id":"c19120cd0bab3150","repo":"RocketChat/Rocket.Chat","slug":"not-authorized-c19120","errorCode":"not-authorized","errorMessage":"Not Authorized","messagePattern":"Not Authorized","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/imports/personal-access-tokens/server/api/methods/generateToken.ts","lineNumber":26,"sourceCode":"import { twoFactorRequired } from '../../../../../server/lib/2fa/twoFactorRequired';\ndeclare module '@rocket.chat/ddp-client' {\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tinterface ServerMethods {\n\t\t'personalAccessTokens:generateToken'(params: { tokenName: string; bypassTwoFactor: boolean }): Promise<string>;\n\t}\n}\n\nexport const generatePersonalAccessTokenOfUser = async ({\n\tbypassTwoFactor,\n\ttokenName,\n\tuserId,\n}: {\n\ttokenName: string;\n\tuserId: string;\n\tbypassTwoFactor: boolean;\n}): Promise<string> => {\n\tif (!(await hasPermissionAsync(userId, 'create-personal-access-tokens'))) {\n\t\tthrow new Meteor.Error('not-authorized', 'Not Authorized', {\n\t\t\tmethod: 'personalAccessTokens:generateToken',\n\t\t});\n\t}\n\n\tconst token = Random.secret();\n\tconst tokenExist = await Users.findPersonalAccessTokenByTokenNameAndUserId({\n\t\tuserId,\n\t\ttokenName,\n\t});\n\tif (tokenExist) {\n\t\tthrow new Meteor.Error('error-token-already-exists', 'A token with this name already exists', {\n\t\t\tmethod: 'personalAccessTokens:generateToken',\n\t\t});\n\t}\n\n\tawait Users.addPersonalAccessTokenToUser({\n\t\tuserId,\n\t\tloginTokenObject: {","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/imports/personal-access-tokens/server/api/methods/generateToken.ts#L8-L44","documentation":"Thrown by generatePersonalAccessTokenOfUser when the target user lacks the 'create-personal-access-tokens' permission. This is the programmatic/internal API guard (the function is called with an explicit userId, e.g. by an admin or another server-side caller) distinct from the login check. Without the permission the user cannot mint personal access tokens.","triggerScenarios":"Calling generatePersonalAccessTokenOfUser({ userId, tokenName, bypassTwoFactor }) for a user whose roles do not include 'create-personal-access-tokens'; calling on behalf of a user whose permission was revoked.","commonSituations":"Admin removed the permission after a security review; a custom role missing the permission; integration calling the internal API for a user that was demoted; new install where the default role policies were changed.","solutions":["Grant the 'create-personal-access-tokens' permission to the user's role in the administration UI.","Confirm you are passing the correct userId (not the caller's id) to the function.","If the caller is an admin acting on behalf of a user, ensure that user role has the permission.","Catch the error and return a 403/permission-denied response to the client."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"async function canCreateTokens(userId: string): Promise<boolean> {\n  return hasPermissionAsync(userId, 'create-personal-access-tokens');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await generatePersonalAccessTokenOfUser({ userId, tokenName, bypassTwoFactor });\n} catch (e) {\n  if (e.error === 'not-authorized') {\n    // return 403 and instruct admin to grant the permission\n  } else throw e;\n}","preventionTips":["Verify the user's role includes 'create-personal-access-tokens' before offering the token UI.","Audit permission grants after role changes.","Return clear 403 messages to the client when permission is missing."],"tags":["personal-access-tokens","authorization","permissions"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}