{"record":{"id":"565d888f3b9dea1b","repo":"RocketChat/Rocket.Chat","slug":"not-authorized-565d88","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/regenerateToken.ts","lineNumber":19,"sourceCode":"import { Meteor } from 'meteor/meteor';\nimport type { ServerMethods } from '@rocket.chat/ddp-client';\nimport { Users } from '@rocket.chat/models';\nimport { isPersonalAccessToken } from '@rocket.chat/core-typings';\n\nimport { hasPermissionAsync } from '../../../../../server/lib/authorization/hasPermission';\nimport { twoFactorRequired } from '../../../../../server/lib/2fa/twoFactorRequired';\nimport { removePersonalAccessTokenOfUser } from './removeToken';\nimport { generatePersonalAccessTokenOfUser } from './generateToken';\ndeclare module '@rocket.chat/ddp-client' {\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tinterface ServerMethods {\n\t\t'personalAccessTokens:regenerateToken'(params: { tokenName: string }): Promise<string>;\n\t}\n}\n\nexport const regeneratePersonalAccessTokenOfUser = async (tokenName: string, userId: string): 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:regenerateToken',\n\t\t});\n\t}\n\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-does-not-exists', 'Token does not exist', {\n\t\t\tmethod: 'personalAccessTokens:regenerateToken',\n\t\t});\n\t}\n\n\tawait removePersonalAccessTokenOfUser(tokenName, userId);\n\n\tconst tokenObject = tokenExist.services?.resume?.loginTokens?.find((token) => isPersonalAccessToken(token) && token.name === tokenName);\n","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/imports/personal-access-tokens/server/api/methods/regenerateToken.ts#L1-L37","documentation":"Thrown by regeneratePersonalAccessTokenOfUser when the target user lacks the 'create-personal-access-tokens' permission. Regeneration is treated as a creation operation for authorization purposes, so the same permission gate applies. This is the internal-API guard (explicit userId), distinct from the login check at the method entry.","triggerScenarios":"Calling regeneratePersonalAccessTokenOfUser(tokenName, userId) for a user whose role was changed and no longer has 'create-personal-access-tokens'; permission revoked mid-session.","commonSituations":"Permission revoked after a security audit; user role changed (e.g. admin -> member); integration calling the internal API for a demoted user.","solutions":["Grant the 'create-personal-access-tokens' permission to the user's role.","Verify you are passing the correct userId.","Return a 403 to the client and prompt an admin to update permissions.","Audit role changes to catch unexpected permission loss."],"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 regeneratePersonalAccessTokenOfUser(tokenName, userId);\n} catch (e) {\n  if (e.error === 'not-authorized') {\n    // return 403 and prompt admin to grant the permission\n  } else throw e;\n}","preventionTips":["Check 'create-personal-access-tokens' permission before showing a regenerate action.","Audit role downgrades that strip token permissions.","Return clear 403 messages 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"}