RocketChat/Rocket.Chat · error · Meteor.Error
not-authorized
not-authorized
Error message
Not Authorized
What it means
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.
Source
Thrown at apps/meteor/imports/personal-access-tokens/server/api/methods/regenerateToken.ts:19
import { Meteor } from 'meteor/meteor';
import type { ServerMethods } from '@rocket.chat/ddp-client';
import { Users } from '@rocket.chat/models';
import { isPersonalAccessToken } from '@rocket.chat/core-typings';
import { hasPermissionAsync } from '../../../../../server/lib/authorization/hasPermission';
import { twoFactorRequired } from '../../../../../server/lib/2fa/twoFactorRequired';
import { removePersonalAccessTokenOfUser } from './removeToken';
import { generatePersonalAccessTokenOfUser } from './generateToken';
declare module '@rocket.chat/ddp-client' {
// eslint-disable-next-line @typescript-eslint/naming-convention
interface ServerMethods {
'personalAccessTokens:regenerateToken'(params: { tokenName: string }): Promise<string>;
}
}
export const regeneratePersonalAccessTokenOfUser = async (tokenName: string, userId: string): Promise<string> => {
if (!(await hasPermissionAsync(userId, 'create-personal-access-tokens'))) {
throw new Meteor.Error('not-authorized', 'Not Authorized', {
method: 'personalAccessTokens:regenerateToken',
});
}
const tokenExist = await Users.findPersonalAccessTokenByTokenNameAndUserId({
userId,
tokenName,
});
if (!tokenExist) {
throw new Meteor.Error('error-token-does-not-exists', 'Token does not exist', {
method: 'personalAccessTokens:regenerateToken',
});
}
await removePersonalAccessTokenOfUser(tokenName, userId);
const tokenObject = tokenExist.services?.resume?.loginTokens?.find((token) => isPersonalAccessToken(token) && token.name === tokenName);
View on GitHub (pinned to f9d3ec372b)
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.
Defensive patterns
Strategy: validation
Validate before calling
async function canCreateTokens(userId: string): Promise<boolean> {
return hasPermissionAsync(userId, 'create-personal-access-tokens');
} Try / catch
try {
await regeneratePersonalAccessTokenOfUser(tokenName, userId);
} catch (e) {
if (e.error === 'not-authorized') {
// return 403 and prompt admin to grant the permission
} else throw e;
} Prevention
- 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.
When it happens
Trigger: Calling regeneratePersonalAccessTokenOfUser(tokenName, userId) for a user whose role was changed and no longer has 'create-personal-access-tokens'; permission revoked mid-session.
Common situations: Permission revoked after a security audit; user role changed (e.g. admin -> member); integration calling the internal API for a demoted user.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/565d888f3b9dea1b.
Report an issue: GitHub.