{"record":{"id":"6ae0fc3963757ed0","repo":"RocketChat/Rocket.Chat","slug":"error-not-authorized-6ae0fc","errorCode":"error-not-authorized","errorMessage":"Not authorized","messagePattern":"Not authorized","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/meteor-methods/rooms/getRoomJoinCode.ts","lineNumber":27,"sourceCode":"declare module '@rocket.chat/ddp-client' {\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tinterface ServerMethods {\n\t\tgetRoomJoinCode(rid: string): string | false;\n\t}\n}\n/* @deprecated */\nMeteor.methods<ServerMethods>({\n\tasync getRoomJoinCode(rid) {\n\t\tcheck(rid, String);\n\n\t\tconst userId = Meteor.userId();\n\n\t\tif (!userId) {\n\t\t\tthrow new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'getJoinCode' });\n\t\t}\n\n\t\tif (!(await hasPermissionAsync(userId, 'view-join-code'))) {\n\t\t\tthrow new Meteor.Error('error-not-authorized', 'Not authorized', { method: 'getJoinCode' });\n\t\t}\n\n\t\tconst room = await Rooms.findById(rid);\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\treturn Boolean(room) && (isRoomWithJoinCode(room!) ? room.joinCode : false);\n\t},\n});\n","sourceCodeStart":9,"sourceCodeEnd":36,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/meteor-methods/rooms/getRoomJoinCode.ts#L9-L36","documentation":"The user is authenticated, but hasPermissionAsync(userId, 'view-join-code') returned false, so getRoomJoinCode refuses with 'error-not-authorized'. The view-join-code permission is admin-oriented by default; ordinary members and even room owners typically do not hold it.","triggerScenarios":"A non-admin user calls Meteor.call('getRoomJoinCode', rid); a custom role was created without the view-join-code permission; the permission was revoked from a role after code that depended on it shipped.","commonSituations":"Apps or UI features surfacing join codes to regular users; permission matrix edits in Administration -> Permissions that dropped view-join-code; enterprise roles provisioned without the admin default set.","solutions":["Grant view-join-code to the user's role in Administration -> Permissions","Assign the user a role (e.g. admin) that already holds view-join-code","Have an admin fetch the join code and share it through a controlled channel instead","If the feature is not needed, remove the call - join codes are sensitive room credentials"],"exampleFix":"// before - any member UI tries to read the join code\nconst code = await Meteor.callAsync('getRoomJoinCode', rid);\n\n// after - only render the affordance for users with the permission\nconst canView = await Meteor.callAsync('getUserPermission', 'view-join-code'); // or track roles client-side\nif (!canView) return null;\nconst code = await Meteor.callAsync('getRoomJoinCode', rid);","handlingStrategy":"try-catch","validationCode":"// hide the affordance unless the user's roles plausibly hold the permission\nconst roles = Meteor.user()?.roles ?? [];\nconst canProbablyView = roles.includes('admin'); // conservative client-side check\nif (!canProbablyView) return null;\nconst code = await Meteor.callAsync('getRoomJoinCode', rid);","typeGuard":"const isJoinCode = (v: string | false): v is string => typeof v === 'string';","tryCatchPattern":"try {\n  const code = await Meteor.callAsync('getRoomJoinCode', rid);\n} catch (e) {\n  if (e instanceof Meteor.Error && e.error === 'error-not-authorized') {\n    // permission denied - degrade gracefully instead of surfacing an error\n    showJoinCodeUnavailable();\n  }\n}","preventionTips":["Check the permission matrix (Administration -> Permissions -> view-join-code) before shipping join-code features","Gate join-code UI on role membership, not on room ownership","Avoid caching join codes - permissions can be revoked at any time"],"tags":["meteor","ddp","authorization","permissions","join-code","rooms"],"backgroundTag":"permission-denied","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}