Repository navigation
Using super admin to create resource for other tenants and orgs #1639
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4ddcd7c
7aa95f5
8ea453e
e97582c
d92ca53
26ce350
4177e8a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| 'use strict' | ||
|
|
||
| /** @type {import('sequelize-cli').Migration} */ | ||
| module.exports = { | ||
| up: async (queryInterface) => { | ||
| const transaction = await queryInterface.sequelize.transaction() | ||
|
|
||
| try { | ||
| // Step 1: Get all tenants from organization_extension restricted to the default org | ||
| const defaultOrgCode = process.env.DEFAULT_ORGANISATION_CODE | ||
| if (!defaultOrgCode) { | ||
| throw new Error('DEFAULT_ORGANISATION_CODE env variable is not set') | ||
| } | ||
|
|
||
| const [defaultOrgPerTenants] = await queryInterface.sequelize.query( | ||
| `SELECT DISTINCT oe.tenant_code, oe.organization_id, oe.organization_code | ||
| FROM organization_extension oe | ||
| INNER JOIN tenants t ON t.code = oe.tenant_code AND t.deleted_at IS NULL | ||
| WHERE oe.deleted_at IS NULL | ||
| AND oe.organization_code = :defaultOrgCode | ||
| ORDER BY oe.tenant_code, oe.organization_id`, | ||
| { transaction, replacements: { defaultOrgCode } } | ||
| ) | ||
|
|
||
| if (defaultOrgPerTenants.length === 0) { | ||
| console.log( | ||
| 'No active tenant-org combinations found in organization_extension. Skipping role_extensions insert.' | ||
| ) | ||
| } else { | ||
| // Step 2: Insert tenant_admin into role_extensions for each tenant+org combination | ||
| const roleExtensionInserts = defaultOrgPerTenants.map((row) => ({ | ||
| title: 'tenant_admin', | ||
| label: 'Tenant Admin', | ||
| status: 'ACTIVE', | ||
| scope: 'ALL', | ||
| organization_id: row.organization_id, | ||
| organization_code: row.organization_code, | ||
| tenant_code: row.tenant_code, | ||
| created_at: new Date(), | ||
| updated_at: new Date(), | ||
| deleted_at: null, | ||
| })) | ||
|
|
||
| await queryInterface.bulkInsert('role_extensions', roleExtensionInserts, { | ||
| transaction, | ||
| ignoreDuplicates: true, | ||
| }) | ||
|
|
||
| console.log(`Inserted tenant_admin role for ${defaultOrgPerTenants.length} active tenants`) | ||
| } | ||
|
|
||
| // Step 3: Copy all admin permissions except the admin module | ||
| const [adminPermissions] = await queryInterface.sequelize.query( | ||
| `SELECT DISTINCT | ||
| permission_id, | ||
| module, | ||
| request_type, | ||
| api_path, | ||
| created_by | ||
| FROM role_permission_mapping | ||
| WHERE role_title = 'admin' | ||
| AND module != 'admin' | ||
| ORDER BY permission_id`, | ||
| { transaction } | ||
| ) | ||
|
|
||
| console.log(`Found ${adminPermissions.length} permissions to copy for tenant_admin`) | ||
|
|
||
| if (adminPermissions.length > 0) { | ||
| const permissionInserts = adminPermissions.map((perm) => ({ | ||
| role_title: 'tenant_admin', | ||
| permission_id: perm.permission_id, | ||
| module: perm.module, | ||
| request_type: perm.request_type, | ||
| api_path: perm.api_path, | ||
| created_at: new Date(), | ||
| updated_at: new Date(), | ||
| created_by: perm.created_by, | ||
| })) | ||
|
|
||
| await queryInterface.bulkInsert('role_permission_mapping', permissionInserts, { | ||
| transaction, | ||
| ignoreDuplicates: true, | ||
| }) | ||
|
|
||
| console.log(`Inserted ${permissionInserts.length} permissions for tenant_admin`) | ||
| } | ||
|
|
||
| await transaction.commit() | ||
| console.log('Migration completed successfully') | ||
| } catch (error) { | ||
| await transaction.rollback() | ||
| console.error('Migration failed, rolled back:', error) | ||
| throw error | ||
| } | ||
| }, | ||
|
|
||
| down: async (queryInterface) => { | ||
| const transaction = await queryInterface.sequelize.transaction() | ||
|
|
||
| try { | ||
| await queryInterface.sequelize.query( | ||
| `DELETE FROM role_permission_mapping WHERE role_title = 'tenant_admin'`, | ||
| { transaction } | ||
| ) | ||
|
|
||
| await queryInterface.sequelize.query(`DELETE FROM role_extensions WHERE title = 'tenant_admin'`, { | ||
| transaction, | ||
| }) | ||
|
|
||
| await transaction.commit() | ||
| console.log('Rollback completed successfully') | ||
| } catch (error) { | ||
| await transaction.rollback() | ||
| console.error('Rollback failed:', error) | ||
| throw error | ||
| } | ||
| }, | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -11,6 +11,7 @@ const MenteeExtensionQueries = require('@database/queries/userExtension') | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const utils = require('@generics/utils') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const path = require('path') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const cacheHelper = require('@generics/cacheHelper') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const OrganizationExtensionQueries = require('@database/queries/organisationExtension') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| module.exports = async function (req, res, next) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -152,6 +153,93 @@ module.exports = async function (req, res, next) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| req.decodedToken.token = authHeader | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Check for admin and tenant admin roles — allow overriding tenant/org via headers | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const roles = req.decodedToken.roles || [] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const isAdmin = roles.some((role) => role.title === common.ADMIN_ROLE) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const isTenantAdmin = roles.some((role) => role.title === common.TENANT_ADMIN_ROLE) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (isAdmin || isTenantAdmin) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const orgCodeHeaderName = common.ORG_CODE_HEADER | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const tenantCodeHeaderName = common.TENANT_CODE_HEADER | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const orgCode = (req.headers[orgCodeHeaderName] || '').trim() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const tenantCode = (req.headers[tenantCodeHeaderName] || '').trim() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const hasAnyOverrideHeader = orgCode || tenantCode | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (hasAnyOverrideHeader) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (isTenantAdmin && !isAdmin) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const effectiveTenantCode = req.decodedToken.tenant_code | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!orgCode) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| throw responses.failureResponse({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| message: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| key: 'ORG_CODE_REQUIRED_FOR_TENANT_ADMIN', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| interpolation: { orgCodeHeader: orgCodeHeaderName }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| statusCode: httpStatusCode.bad_request, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| responseCode: 'CLIENT_ERROR', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const overrideOrg = await OrganizationExtensionQueries.findOne( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { organization_code: orgCode }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| effectiveTenantCode | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!overrideOrg) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| throw responses.failureResponse({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| message: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| key: 'INVALID_ORG_CODE_FOR_TENANT', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| interpolation: { orgCodeHeader: orgCodeHeaderName }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| statusCode: httpStatusCode.bad_request, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| responseCode: 'CLIENT_ERROR', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| req.decodedToken.organization_id = overrideOrg.organization_id | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| req.decodedToken.organization_code = orgCode | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+171
to
+201
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Privilege escalation: tenant_admin can resolve orgs across tenants when token lacks
if (tenantCode) {
filter.tenant_code = tenantCode
}If a 🔒 Suggested guard before the lookup if (isTenantAdmin && !isAdmin) {
const effectiveTenantCode = req.decodedToken.tenant_code
+ if (!effectiveTenantCode) {
+ throw createUnauthorizedResponse()
+ }
if (!orgCode) {
throw responses.failureResponse({
message: {
key: 'ORG_CODE_REQUIRED_FOR_TENANT_ADMIN',
interpolation: { orgCodeHeader: orgCodeHeaderName },
},
statusCode: httpStatusCode.bad_request,
responseCode: 'CLIENT_ERROR',
})
}
const overrideOrg = await OrganizationExtensionQueries.findOne(
{ organization_code: orgCode },
effectiveTenantCode
)🤖 Prompt for AI Agents
When Either reject the request with a clear 400 when a tenant_admin sends 🔒 Suggested explicit rejection if (isTenantAdmin && !isAdmin) {
+ if (tenantCode) {
+ throw responses.failureResponse({
+ message: 'INVALID_ORG_CODE_FOR_TENANT',
+ statusCode: httpStatusCode.bad_request,
+ responseCode: 'CLIENT_ERROR',
+ })
+ }
const effectiveTenantCode = req.decodedToken.tenant_code📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else if (isAdmin) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!orgCode || !tenantCode) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| throw responses.failureResponse({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| message: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| key: 'ADD_ORG_OR_TENANT_HEADER', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| interpolation: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| orgCodeHeader: orgCodeHeaderName, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tenantCodeHeader: tenantCodeHeaderName, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| statusCode: httpStatusCode.bad_request, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| responseCode: 'CLIENT_ERROR', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const overrideOrg = await OrganizationExtensionQueries.findOne( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { organization_code: orgCode }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tenantCode | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!overrideOrg) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| throw responses.failureResponse({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| message: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| key: 'INVALID_ORG_OR_TENANT_CODE', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| interpolation: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| orgCodeHeader: orgCodeHeaderName, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tenantCodeHeader: tenantCodeHeaderName, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| statusCode: httpStatusCode.bad_request, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| responseCode: 'CLIENT_ERROR', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| req.decodedToken.tenant_code = tenantCode | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| req.decodedToken.organization_id = overrideOrg.organization_id | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| req.decodedToken.organization_code = orgCode | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+200
to
+238
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Type inconsistency on A few lines above (146-149), The existing admin-token branch at line 251 ( 🛠 Proposed fix req.decodedToken.organization_id = overrideOrg.organization_id
req.decodedToken.organization_code = orgCode
- } else if (isAdmin) {
+ } else if (isAdmin) {
@@
req.decodedToken.tenant_code = tenantCode
req.decodedToken.organization_id = overrideOrg.organization_id
req.decodedToken.organization_code = orgCodeReplace both assignments to use string coercion: - req.decodedToken.organization_id = overrideOrg.organization_id
+ req.decodedToken.organization_id = overrideOrg.organization_id?.toString()🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (adminHeader) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (adminHeader != process.env.ADMIN_ACCESS_TOKEN) throw createUnauthorizedResponse() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const organizationId = req.get(process.env.ORG_ID_HEADER_NAME) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -433,6 +521,7 @@ const validRoles = new Set([ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| common.ORG_ADMIN_ROLE, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| common.ADMIN_ROLE, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| common.SESSION_MANAGER_ROLE, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| common.TENANT_ADMIN_ROLE, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async function keycloakPublicKeyAuthentication(token) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor wording issue in
ADD_ORG_OR_TENANT_HEADER.Two small issues:
{{tenantCodeHeader}}is a tenant header, not an organization header.x-org-code, and x-tenant-code).✏️ Proposed wording fix
📝 Committable suggestion
🤖 Prompt for AI Agents