{"record":{"id":"b3ff32863f3e03fd","repo":"RocketChat/Rocket.Chat","slug":"error-not-allowed-b3ff32","errorCode":"error-not-allowed","errorMessage":"Not allowed","messagePattern":"Not allowed","errorType":"http","errorClass":"Meteor.Error","httpStatus":403,"severity":"error","filePath":"apps/meteor/server/lib/auth/oauth2-server/addOAuthApp.ts","lineNumber":23,"sourceCode":"\nimport { parseUriList } from './parseUriList';\nimport type { OauthAppsAddParams } from '../../../api/v1/oauthapps';\nimport { hasPermissionAsync } from '../../authorization/hasPermission';\n\nexport async function addOAuthApp(applicationParams: OauthAppsAddParams, uid: IUser['_id'] | undefined): Promise<IOAuthApps> {\n\tif (!uid) {\n\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'addOAuthApp' });\n\t}\n\n\tconst user = await Users.findOneById(uid, { projection: { username: 1 } });\n\n\tif (!user?.username) {\n\t\t// TODO: username is required, but not always present\n\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'addOAuthApp' });\n\t}\n\n\tif (!(await hasPermissionAsync(uid, 'manage-oauth-apps'))) {\n\t\tthrow new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'addOAuthApp' });\n\t}\n\n\tif (!applicationParams.name || typeof applicationParams.name.valueOf() !== 'string' || applicationParams.name.trim() === '') {\n\t\tthrow new Meteor.Error('error-invalid-name', 'Invalid name', { method: 'addOAuthApp' });\n\t}\n\n\tif (\n\t\t!applicationParams.redirectUri ||\n\t\ttypeof applicationParams.redirectUri.valueOf() !== 'string' ||\n\t\tapplicationParams.redirectUri.trim() === ''\n\t) {\n\t\tthrow new Meteor.Error('error-invalid-redirectUri', 'Invalid redirectUri', {\n\t\t\tmethod: 'addOAuthApp',\n\t\t});\n\t}\n\n\tif (typeof applicationParams.active !== 'boolean') {\n\t\tthrow new Meteor.Error('error-invalid-arguments', 'Invalid arguments', {","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/auth/oauth2-server/addOAuthApp.ts#L5-L41","documentation":"addOAuthApp requires the calling user to hold the manage-oauth-apps permission; without it the operation is rejected before any validation happens. The REST layer already enforces permissionsRequired: ['manage-oauth-apps'] (HTTP 403), so this Meteor.Error surfaces from direct method/internal calls - but both paths mean the same thing: the caller's role cannot manage OAuth apps.","triggerScenarios":"A non-admin user invokes the oauth-apps.create REST endpoint (403 from the route) or the method/function directly without the permission; a role had the permission revoked between UI load and submit.","commonSituations":"Custom admin dashboards calling the endpoint with a regular user's token; permission cleanup that accidentally removed manage-oauth-apps from an ops role; newly created roles never granted OAuth app rights.","solutions":["Grant manage-oauth-apps to the caller's role in Admin -> Permissions (OAuth Apps section) or promote the user to admin","Perform the operation logged in as a user who already holds the permission","Check the role assignment with hasPermissionAsync(uid, 'manage-oauth-apps') before retrying"],"exampleFix":"// before: request with a regular user's token\nPOST /api/v1/oauth-apps.create  -> 403 / error-not-allowed\n\n// after: same request with a token of a user whose role has manage-oauth-apps","handlingStrategy":"validation","validationCode":"// check permission before performing the operation\nimport { hasPermissionAsync } from '../../lib/authorization/hasPermission';\n\nif (!(await hasPermissionAsync(uid, 'manage-oauth-apps'))) {\n  throw new Meteor.Error('error-not-allowed', 'You need the manage-oauth-apps permission');\n}\nconst app = await addOAuthApp(params, uid);","typeGuard":null,"tryCatchPattern":"try {\n  await addOAuthApp(params, uid);\n} catch (error) {\n  if (error instanceof Meteor.Error && error.error === 'error-not-allowed') {\n    showError('You do not have permission to manage OAuth apps. Ask an admin.');\n  } else {\n    throw error;\n  }\n}","preventionTips":["Grant manage-oauth-apps only to roles that genuinely manage integrations","Check hasPermissionAsync(uid, 'manage-oauth-apps') in custom UIs before showing the create form","Audit role permissions after permission reorganizations"],"tags":["oauth-apps","permissions","authorization","rest-api"],"backgroundTag":"insufficient-permissions","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}