@mbc-cqrs-serverless/core
Version:
CQRS and event base core
52 lines • 2.01 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.UserContext = void 0;
exports.getUserContext = getUserContext;
const constants_1 = require("../constants");
const invoke_1 = require("./invoke");
class UserContext {
constructor(partial) {
Object.assign(this, partial);
}
}
exports.UserContext = UserContext;
/**
* Extract user context from JWT claims and request headers.
*
* Tenant code determination:
* 1. If `custom:tenant` exists in JWT claims, use it (user bound to specific tenant)
* 2. Otherwise, use `x-tenant-code` header (for cross-tenant operations)
*
* Note: Security validation for header-based tenant override is handled by RolesGuard,
* not by this function. This allows for flexible security policies at the application level.
*/
function getUserContext(ctx) {
if ('getHandler' in ctx) {
ctx = (0, invoke_1.extractInvokeContext)(ctx);
}
const claims = (0, invoke_1.getAuthorizerClaims)(ctx);
const userId = claims.sub;
// Parse roles
const roles = JSON.parse(claims['custom:roles'] || '[]').map((role) => ({ ...role, tenant: (role.tenant || '').toLowerCase() }));
// Determine tenant code
// 1. Cognito custom:tenant attribute takes priority
// 2. Otherwise, use header value (security check delegated to RolesGuard)
// Note: tenantCode is normalized to lowercase for case-insensitive matching with role.tenant
const tenantCode = (claims['custom:tenant'] || (ctx?.event?.headers || {})[constants_1.HEADER_TENANT_CODE])?.toLowerCase();
// Find tenantRole (case-insensitive matching - both tenantCode and role.tenant are lowercase)
let tenantRole = '';
for (const { tenant, role } of roles) {
if (tenant === '' || tenant === tenantCode) {
tenantRole = role;
if (tenant !== '') {
break;
}
}
}
return {
userId,
tenantRole,
tenantCode,
};
}
//# sourceMappingURL=user.js.map