@culturefy/shared 1.0.56 → 1.0.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/index.js +6 -0
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/middlewares/verify-middleware.js +7 -6
- package/build/cjs/middlewares/verify-middleware.js.map +1 -1
- package/build/cjs/models/config-mapping.model.js +41 -0
- package/build/cjs/models/config-mapping.model.js.map +1 -0
- package/build/cjs/repositories/index.js +16 -0
- package/build/cjs/repositories/index.js.map +1 -0
- package/build/cjs/repositories/multi-tenant.repository.js +266 -0
- package/build/cjs/repositories/multi-tenant.repository.js.map +1 -0
- package/build/cjs/repositories/tenant-base.repository.js +52 -0
- package/build/cjs/repositories/tenant-base.repository.js.map +1 -0
- package/build/esm/index.js +1 -0
- package/build/esm/index.js.map +1 -1
- package/build/esm/middlewares/verify-middleware.js +7 -6
- package/build/esm/middlewares/verify-middleware.js.map +1 -1
- package/build/esm/models/config-mapping.model.js +36 -0
- package/build/esm/models/config-mapping.model.js.map +1 -0
- package/build/esm/repositories/index.js +3 -0
- package/build/esm/repositories/index.js.map +1 -0
- package/build/esm/repositories/multi-tenant.repository.js +259 -0
- package/build/esm/repositories/multi-tenant.repository.js.map +1 -0
- package/build/esm/repositories/tenant-base.repository.js +48 -0
- package/build/esm/repositories/tenant-base.repository.js.map +1 -0
- package/build/src/index.d.ts +1 -0
- package/build/src/index.js +1 -0
- package/build/src/index.js.map +1 -1
- package/build/src/middlewares/verify-middleware.js +12 -11
- package/build/src/middlewares/verify-middleware.js.map +1 -1
- package/build/src/models/config-mapping.model.d.ts +20 -0
- package/build/src/models/config-mapping.model.js +41 -0
- package/build/src/models/config-mapping.model.js.map +1 -0
- package/build/src/repositories/index.d.ts +2 -0
- package/build/src/repositories/index.js +6 -0
- package/build/src/repositories/index.js.map +1 -0
- package/build/src/repositories/multi-tenant.repository.d.ts +44 -0
- package/build/src/repositories/multi-tenant.repository.js +295 -0
- package/build/src/repositories/multi-tenant.repository.js.map +1 -0
- package/build/src/repositories/tenant-base.repository.d.ts +17 -0
- package/build/src/repositories/tenant-base.repository.js +141 -0
- package/build/src/repositories/tenant-base.repository.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.TenantBaseRepository = void 0;
|
|
5
|
+
var _multiTenant = require("./multi-tenant.repository");
|
|
6
|
+
var _class;
|
|
7
|
+
function _applyDecoratedDescriptor(i, e, r, n, l) { var a = {}; return Object.keys(n).forEach(function (i) { a[i] = n[i]; }), a.enumerable = !!a.enumerable, a.configurable = !!a.configurable, ("value" in a || a.initializer) && (a.writable = !0), a = r.slice().reverse().reduce(function (r, n) { return n(i, e, r) || r; }, a), l && void 0 !== a.initializer && (a.value = a.initializer ? a.initializer.call(l) : void 0, a.initializer = void 0), void 0 === a.initializer ? (Object.defineProperty(i, e, a), null) : a; }
|
|
8
|
+
let TenantBaseRepository = exports.TenantBaseRepository = (_class = class TenantBaseRepository extends _multiTenant.TenantModelRepository {
|
|
9
|
+
constructor(...args) {
|
|
10
|
+
super(...args);
|
|
11
|
+
this.modelDef = void 0;
|
|
12
|
+
}
|
|
13
|
+
async aggregate(pipeline) {
|
|
14
|
+
return this.dbModel.aggregate(pipeline).exec();
|
|
15
|
+
}
|
|
16
|
+
async create(body) {
|
|
17
|
+
return this.dbModel.create(body);
|
|
18
|
+
}
|
|
19
|
+
async createMany(body) {
|
|
20
|
+
return this.dbModel.insertMany(body);
|
|
21
|
+
}
|
|
22
|
+
async count(query = {}) {
|
|
23
|
+
return this.dbModel.countDocuments(query).exec();
|
|
24
|
+
}
|
|
25
|
+
async findById(id, projection = {}, options = {}) {
|
|
26
|
+
return this.dbModel.findById(id, projection, options).exec();
|
|
27
|
+
}
|
|
28
|
+
async findOne(query, projection = {}, options = {}) {
|
|
29
|
+
return this.dbModel.findOne(query, projection, options).exec();
|
|
30
|
+
}
|
|
31
|
+
async find(query = {}, projection = {}, options = {}) {
|
|
32
|
+
return this.dbModel.find(query, projection, options).exec();
|
|
33
|
+
}
|
|
34
|
+
async updateById(id, body, options = {
|
|
35
|
+
new: true
|
|
36
|
+
}) {
|
|
37
|
+
return this.dbModel.findByIdAndUpdate(id, body, options).exec();
|
|
38
|
+
}
|
|
39
|
+
async updateOne(query, body, options = {}) {
|
|
40
|
+
return this.dbModel.updateOne(query, body, options).exec();
|
|
41
|
+
}
|
|
42
|
+
async updateMany(query, body, options = {}) {
|
|
43
|
+
return this.dbModel.updateMany(query, body, options).exec();
|
|
44
|
+
}
|
|
45
|
+
async deleteById(id) {
|
|
46
|
+
return this.dbModel.findByIdAndDelete(id).exec();
|
|
47
|
+
}
|
|
48
|
+
async deleteMany(query = {}) {
|
|
49
|
+
return this.dbModel.deleteMany(query).exec();
|
|
50
|
+
}
|
|
51
|
+
}, _applyDecoratedDescriptor(_class.prototype, "aggregate", [_multiTenant.WithTenantDb], Object.getOwnPropertyDescriptor(_class.prototype, "aggregate"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "create", [_multiTenant.WithTenantDb], Object.getOwnPropertyDescriptor(_class.prototype, "create"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "createMany", [_multiTenant.WithTenantDb], Object.getOwnPropertyDescriptor(_class.prototype, "createMany"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "count", [_multiTenant.WithTenantDb], Object.getOwnPropertyDescriptor(_class.prototype, "count"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "findById", [_multiTenant.WithTenantDb], Object.getOwnPropertyDescriptor(_class.prototype, "findById"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "findOne", [_multiTenant.WithTenantDb], Object.getOwnPropertyDescriptor(_class.prototype, "findOne"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "find", [_multiTenant.WithTenantDb], Object.getOwnPropertyDescriptor(_class.prototype, "find"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "updateById", [_multiTenant.WithTenantDb], Object.getOwnPropertyDescriptor(_class.prototype, "updateById"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "updateOne", [_multiTenant.WithTenantDb], Object.getOwnPropertyDescriptor(_class.prototype, "updateOne"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "updateMany", [_multiTenant.WithTenantDb], Object.getOwnPropertyDescriptor(_class.prototype, "updateMany"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "deleteById", [_multiTenant.WithTenantDb], Object.getOwnPropertyDescriptor(_class.prototype, "deleteById"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "deleteMany", [_multiTenant.WithTenantDb], Object.getOwnPropertyDescriptor(_class.prototype, "deleteMany"), _class.prototype), _class);
|
|
52
|
+
//# sourceMappingURL=tenant-base.repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-base.repository.js","names":["_multiTenant","require","_class","_applyDecoratedDescriptor","i","e","r","n","l","a","Object","keys","forEach","enumerable","configurable","initializer","writable","slice","reverse","reduce","value","call","defineProperty","TenantBaseRepository","exports","TenantModelRepository","constructor","args","modelDef","aggregate","pipeline","dbModel","exec","create","body","createMany","insertMany","count","query","countDocuments","findById","id","projection","options","findOne","find","updateById","new","findByIdAndUpdate","updateOne","updateMany","deleteById","findByIdAndDelete","deleteMany","prototype","WithTenantDb","getOwnPropertyDescriptor"],"sources":["../../../src/repositories/tenant-base.repository.ts"],"sourcesContent":["import {\n FilterQuery,\n Model,\n PipelineStage,\n ProjectionType,\n QueryOptions,\n UpdateQuery,\n} from \"mongoose\";\nimport { TenantModelRepository, WithTenantDb } from \"./multi-tenant.repository\";\n\nexport abstract class TenantBaseRepository<T> extends TenantModelRepository<T> {\n protected abstract readonly modelDef: Model<T>;\n\n @WithTenantDb\n async aggregate(\n pipeline: PipelineStage[],\n ): Promise<any[]> {\n return this.dbModel.aggregate(pipeline).exec();\n }\n\n @WithTenantDb\n async create(body: T): Promise<T> {\n return this.dbModel.create(body);\n }\n\n @WithTenantDb\n async createMany(body: T[]): Promise<T[]> {\n return this.dbModel.insertMany(body);\n }\n\n @WithTenantDb\n async count(query: FilterQuery<T> = {}): Promise<number> {\n return this.dbModel.countDocuments(query).exec();\n }\n\n @WithTenantDb\n async findById(\n id: string,\n projection: ProjectionType<T> = {},\n options: QueryOptions<T> = {},\n ): Promise<T | null> {\n return this.dbModel.findById(id, projection, options).exec();\n }\n\n @WithTenantDb\n async findOne(\n query: FilterQuery<T>,\n projection: ProjectionType<T> = {},\n options: QueryOptions<T> = {},\n ): Promise<T | null> {\n return this.dbModel.findOne(query, projection, options).exec();\n }\n\n @WithTenantDb\n async find(\n query: FilterQuery<T> = {},\n projection: ProjectionType<T> = {},\n options: QueryOptions<T> = {},\n ): Promise<T[]> {\n return this.dbModel.find(query, projection, options).exec();\n }\n\n @WithTenantDb\n async updateById(\n id: string,\n body: UpdateQuery<T>,\n options: any = { new: true },\n ): Promise<T | null> {\n return this.dbModel.findByIdAndUpdate(id, body, options).exec() as Promise<\n T | null\n >;\n }\n\n @WithTenantDb\n async updateOne(\n query: FilterQuery<T>,\n body: UpdateQuery<T>,\n options: any = {},\n ): Promise<any> {\n return this.dbModel.updateOne(query, body, options).exec();\n }\n\n @WithTenantDb\n async updateMany(\n query: FilterQuery<T>,\n body: UpdateQuery<T>,\n options: any = {},\n ): Promise<any> {\n return this.dbModel.updateMany(query, body, options).exec();\n }\n\n @WithTenantDb\n async deleteById(id: string): Promise<T | null> {\n return this.dbModel.findByIdAndDelete(id).exec();\n }\n\n @WithTenantDb\n async deleteMany(query: FilterQuery<T> = {}): Promise<any> {\n return this.dbModel.deleteMany(query).exec();\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
package/build/esm/index.js
CHANGED
package/build/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/index.ts"],"sourcesContent":["export * from './types';\nexport * from './enums';\nexport * from './utils';\nexport * from './utils/cache';\nexport * from './middlewares';\nexport * from './constants';\n"],"mappings":"AAAA,cAAc,SAAS;AACvB,cAAc,SAAS;AACvB,cAAc,SAAS;AACvB,cAAc,eAAe;AAC7B,cAAc,eAAe;AAC7B,cAAc,aAAa","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/index.ts"],"sourcesContent":["export * from './types';\nexport * from './enums';\nexport * from './utils';\nexport * from './utils/cache';\nexport * from './middlewares';\nexport * from './constants';\nexport * from './repositories';\n"],"mappings":"AAAA,cAAc,SAAS;AACvB,cAAc,SAAS;AACvB,cAAc,SAAS;AACvB,cAAc,eAAe;AAC7B,cAAc,eAAe;AAC7B,cAAc,aAAa;AAC3B,cAAc,gBAAgB","ignoreList":[]}
|
|
@@ -229,7 +229,7 @@ async function getNewRefreshToken(req, ctx, appId, realmId, clientId, rt, mappin
|
|
|
229
229
|
|
|
230
230
|
// Call auth service to refresh
|
|
231
231
|
try {
|
|
232
|
-
var _ref7, _ref7$state, _p2$sub,
|
|
232
|
+
var _ref7, _ref7$state, _ref8, _updatedMapping$userI, _updatedMapping$userI2, _ref9, _p2$sub, _ref0, _p2$cfy_bid, _ref1, _p2$email, _p2$name, _ref10, _p2$resource_access$c, _p2$resource_access, _p2$realm_access;
|
|
233
233
|
const resp = await fetch(apiURL, {
|
|
234
234
|
method: "POST",
|
|
235
235
|
headers: {
|
|
@@ -294,7 +294,7 @@ async function getNewRefreshToken(req, ctx, appId, realmId, clientId, rt, mappin
|
|
|
294
294
|
};
|
|
295
295
|
}
|
|
296
296
|
const tokenMappingService = new TokenMappingService(ctx, dbUrl);
|
|
297
|
-
await tokenMappingService.updateTokenMapping(mapping, {
|
|
297
|
+
const updatedMapping = await tokenMappingService.updateTokenMapping(mapping, {
|
|
298
298
|
accessToken: newAT,
|
|
299
299
|
refreshToken: newRT,
|
|
300
300
|
// expires_in is a duration (seconds); store absolute expiry for later checks
|
|
@@ -353,12 +353,13 @@ async function getNewRefreshToken(req, ctx, appId, realmId, clientId, rt, mappin
|
|
|
353
353
|
const tenantId2 = realmId.toString();
|
|
354
354
|
ctx.state.auth = {
|
|
355
355
|
appId,
|
|
356
|
-
userId: (
|
|
357
|
-
|
|
356
|
+
userId: (_ref8 = (_updatedMapping$userI = updatedMapping == null || (_updatedMapping$userI2 = updatedMapping.userId) == null || _updatedMapping$userI2.toString == null ? void 0 : _updatedMapping$userI2.toString()) != null ? _updatedMapping$userI : p2.sub) != null ? _ref8 : null,
|
|
357
|
+
keycloakUserId: (_ref9 = (_p2$sub = p2.sub) != null ? _p2$sub : updatedMapping == null ? void 0 : updatedMapping.keycloakUserId) != null ? _ref9 : null,
|
|
358
|
+
businessId: (_ref0 = (_p2$cfy_bid = p2.cfy_bid) != null ? _p2$cfy_bid : tenantId2) != null ? _ref0 : null,
|
|
358
359
|
tenantId: tenantId2,
|
|
359
|
-
email: (
|
|
360
|
+
email: (_ref1 = (_p2$email = p2.email) != null ? _p2$email : p2.preferred_username) != null ? _ref1 : null,
|
|
360
361
|
name: (_p2$name = p2.name) != null ? _p2$name : undefined,
|
|
361
|
-
roles: (
|
|
362
|
+
roles: (_ref10 = (_p2$resource_access$c = (_p2$resource_access = p2.resource_access) == null || (_p2$resource_access = _p2$resource_access[clientId]) == null ? void 0 : _p2$resource_access.roles) != null ? _p2$resource_access$c : (_p2$realm_access = p2.realm_access) == null ? void 0 : _p2$realm_access.roles) != null ? _ref10 : [],
|
|
362
363
|
exp: p2.exp
|
|
363
364
|
};
|
|
364
365
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify-middleware.js","names":["APP_MAP","jwtDecode","AzureSecretKeysEnum","setCookieKV","createCache","getAzureVaultSecretByKey","TokenMappingService","apiURL","process","env","REFRESH_SESSION_URL","verifyMappingCache","parseCookieHeader","header","out","part","split","k","rest","trim","decodeURIComponent","join","verifyMw","req","ctx","next","_APP_MAP$appId","_p","_ref","_ref$state","_ref2","_tokenMapping$userId$","_tokenMapping$userId","_ref3","_p$sub","_ref4","_p$cfy_bid","_ref5","_p$email","_p$name","_ref6","_p$resource_access$cl","_p$resource_access","_p$realm_access","appId","headers","get","clientId","status","body","JSON","stringify","reason","expectedClientId","cookies","mapping","base64Decode","dbUrl","AZURE_KEY_VAULT_NAME","DB_CONNECTING_STRING_USER","tokenMappingService","tokenMappingRaw","getOrSet","fetched","getTokenMappingById","tokenMapping","parse","at","accessToken","rt","refreshToken","realm","realmId","p","_unused","sid","now","Math","floor","Date","exp","getNewRefreshToken","audOk","Array","isArray","aud","includes","azp","state","tenantId","toString","auth","userId","sub","keycloakUserId","businessId","cfy_bid","email","preferred_username","name","undefined","roles","resource_access","realm_access","info","_ref7","_ref7$state","_p2$sub","_ref8","_p2$cfy_bid","_ref9","_p2$email","_p2$name","_ref0","_p2$resource_access$c","_p2$resource_access","_p2$realm_access","resp","fetch","method","refresh_token","ok","text","warn","payload","json","data","newAT","access_token","newRT","updateTokenMapping","expiresAt","expires_in","mappingMaxAge","refresh_expires_in","httpOnly","secure","sameSite","maxAge","p2","_unused2","audOk2","tenantId2","e","error","value","Buffer","from","console","log","message"],"sources":["../../../src/middlewares/verify-middleware.ts"],"sourcesContent":["import { IAppId } from \"../types/app\";\nimport { APP_MAP } from \"../constants\";\nimport { jwtDecode } from \"jwt-decode\";\nimport { HttpRequest } from \"@azure/functions\";\nimport { AzureSecretKeysEnum } from \"../enums\";\nimport { setCookieKV } from \"../utils/cookies\";\nimport { IMiddleware } from \"../types/middleware\";\nimport { HttpResponseInit } from \"@azure/functions\";\nimport { createCache, getAzureVaultSecretByKey } from \"../utils\";\nimport { InvocationContext } from \"@azure/functions\";\nimport { TokenMappingService } from \"../service/tokenMapping.service\";\n\nconst apiURL = process.env.REFRESH_SESSION_URL || '';\nconst verifyMappingCache = createCache(\"verify-mw\", 60);\n\nconst parseCookieHeader = (header: string | null | undefined) => {\n const out: Record<string, string> = {};\n if (!header) return out;\n for (const part of header.split(\";\")) {\n const [k, ...rest] = part.trim().split(\"=\");\n if (!k) continue;\n out[k] = decodeURIComponent(rest.join(\"=\") || \"\");\n }\n return out;\n};\n\nexport const verifyMw: IMiddleware = async (\n req: HttpRequest,\n ctx: InvocationContext,\n next: () => Promise<HttpResponseInit>\n): Promise<HttpResponseInit> => {\n const appId = req.headers.get(\"app-id\") as IAppId | undefined;\n\n if (!appId || !APP_MAP?.[appId]?.clientId) {\n return {\n status: 400,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"bad_request\", reason: \"invalid_app\" })\n };\n }\n\n const expectedClientId = APP_MAP[appId].clientId;\n\n // cookies\n const cookies = parseCookieHeader(req.headers.get(\"cookie\"));\n\n let mapping: string | null = cookies[`__Secure-session-v1.${appId}.mapping`];\n\n if (!mapping) {\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"no_token_mapping\" })\n };\n }\n\n mapping = base64Decode(mapping);\n\n if (!mapping) {\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"invalid_token_mapping\" })\n };\n }\n\n // Get database connection string\n const dbUrl = await getAzureVaultSecretByKey(\n ctx,\n process.env.AZURE_KEY_VAULT_NAME || \"\",\n AzureSecretKeysEnum.DB_CONNECTING_STRING_USER\n );\n\n if (!dbUrl) {\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"database_connection_string_not_found\" })\n };\n }\n\n const tokenMappingService = new TokenMappingService(ctx, dbUrl);\n\n const tokenMappingRaw = await verifyMappingCache.getOrSet(\n ctx,\n [mapping],\n async () => {\n const fetched = await tokenMappingService.getTokenMappingById(mapping);\n return fetched ? JSON.stringify(fetched) : \"\";\n },\n );\n const tokenMapping = tokenMappingRaw ? JSON.parse(tokenMappingRaw) : null;\n\n if (!tokenMapping) {\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"token_mapping_not_found\" })\n };\n }\n\n let at = tokenMapping.accessToken;\n let rt = tokenMapping.refreshToken;\n\n if (!at && !rt) {\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"no_tokens\" })\n };\n }\n\n const realm = tokenMapping.realmId;\n const clientId = tokenMapping.clientId;\n\n // decode/verify (lightweight; replace with your verifyJsonWebToken if you have it)\n let p: any;\n try {\n p = jwtDecode(at);\n } catch {\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"invalid_token\" })\n };\n }\n\n if (!p?.sid) {\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"user_not_found\" })\n };\n }\n\n const now = Math.floor(Date.now() / 1000);\n // Refresh only when expired\n if (typeof p.exp === \"number\" && p.exp <= now) {\n // Delegate to refresh helper; it will handle setting cookies/state or returning an error\n return await getNewRefreshToken(req, ctx, appId, realm, clientId, rt, mapping, p, next);\n }\n\n // audience checks\n const audOk =\n (Array.isArray(p.aud) && p.aud.includes(clientId)) ||\n (typeof p.aud === \"string\" && (p.aud === clientId || p.aud === \"account\")) ||\n p.azp === clientId;\n\n if (!audOk) {\n return {\n status: 403,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"forbidden\", reason: \"audience_mismatch\" })\n };\n }\n\n\n // pass data downstream\n (ctx as any).state ??= {};\n const tenantId = realm.toString();\n\n (ctx as any).state.auth = {\n appId,\n userId: tokenMapping.userId?.toString?.() ?? p.sub ?? null,\n keycloakUserId: p.sub ?? tokenMapping.keycloakUserId ?? null,\n businessId: p.cfy_bid ?? tenantId ?? null,\n tenantId,\n email: p.email ?? p.preferred_username ?? null,\n name: p.name ?? undefined,\n roles: p.resource_access?.[clientId]?.roles ?? p.realm_access?.roles ?? [],\n exp: p.exp,\n };\n\n return next();\n};\n\n\n\nasync function getNewRefreshToken(\n req: HttpRequest,\n ctx: InvocationContext,\n appId: IAppId,\n realmId: string,\n clientId: string,\n rt: string | undefined,\n mapping: string,\n p: any,\n next: () => Promise<HttpResponseInit>\n): Promise<HttpResponseInit> {\n // Attempt server-side refresh using RT\n if (!rt) {\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"expired_no_rt\" })\n };\n }\n\n ctx.info(\"refreshing token payload ----------------------\", {\n realmId,\n clientId,\n rt\n });\n\n // Call auth service to refresh\n try {\n const resp = await fetch(apiURL, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n realmId,\n clientId: clientId,\n refresh_token: rt\n })\n });\n\n if (!resp.ok) {\n const text = await resp.text();\n ctx.warn?.(`refresh call failed: ${resp.status} ${text}`);\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"refresh_failed\" })\n };\n }\n\n const payload = await resp.json();\n const data = payload?.data || {};\n\n const newAT = data.access_token as string | undefined;\n const newRT = data.refresh_token as string | undefined;\n\n if (!newAT || !newRT) {\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"invalid_refresh_response\" })\n };\n }\n\n const dbUrl = await getAzureVaultSecretByKey(\n ctx,\n process.env.AZURE_KEY_VAULT_NAME || \"\",\n AzureSecretKeysEnum.DB_CONNECTING_STRING_USER\n );\n\n if (!dbUrl) {\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"database_connection_string_not_found\" })\n };\n }\n\n const tokenMappingService = new TokenMappingService(ctx, dbUrl);\n\n await tokenMappingService.updateTokenMapping(mapping, {\n accessToken: newAT as string,\n refreshToken: newRT as string,\n // expires_in is a duration (seconds); store absolute expiry for later checks\n expiresAt: typeof data.expires_in === \"number\" ? new Date(Date.now() + data.expires_in * 1000) : undefined\n });\n\n // Set refreshed mapping cookie for client session (AT/RT stay server-side in token mapping)\n const mappingMaxAge =\n typeof data.refresh_expires_in === \"number\"\n ? data.refresh_expires_in\n : typeof data.expires_in === \"number\"\n ? data.expires_in\n : 60 * 60 * 24; // fallback 24h\n\n setCookieKV(ctx, `__Secure-session-v1.${appId}.mapping`, mapping, {\n // mapping must be readable by FE in your flow; keep httpOnly default if you prefer server-only\n httpOnly: false,\n secure: true,\n sameSite: \"None\",\n maxAge: mappingMaxAge\n });\n\n // Decode new AT and proceed\n let p2: any;\n try { p2 = jwtDecode(newAT); } catch {\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"invalid_new_token\" })\n };\n }\n\n const audOk2 =\n (Array.isArray(p2.aud) && p2.aud.includes(clientId)) ||\n (typeof p2.aud === \"string\" && (p2.aud === clientId || p2.aud === \"account\")) ||\n p2.azp === clientId;\n if (!audOk2) {\n return {\n status: 403,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"forbidden\", reason: \"audience_mismatch\" })\n };\n }\n\n // Update downstream auth state with refreshed token\n (ctx as any).state ??= {};\n const tenantId2 = realmId.toString();\n (ctx as any).state.auth = {\n appId,\n userId: p2.sub ?? null,\n businessId: p2.cfy_bid ?? tenantId2 ?? null,\n tenantId: tenantId2,\n email: p2.email ?? p2.preferred_username ?? null,\n name: p2.name ?? undefined,\n roles: p2.resource_access?.[clientId]?.roles ?? p2.realm_access?.roles ?? [],\n exp: p2.exp,\n };\n\n // Continue pipeline after refresh\n return next();\n } catch (e) {\n ctx.error?.(\"refresh exception\", e as any);\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"refresh_exception\" })\n };\n }\n}\n\nfunction base64Decode(value: string): string | null {\n try {\n return Buffer.from(value, 'base64').toString();\n } catch (error: any) {\n console.log(\"Error decoding base64: \" + error.message);\n return null;\n }\n}"],"mappings":"AACA,SAASA,OAAO,QAAQ,cAAc;AACtC,SAASC,SAAS,QAAQ,YAAY;AAEtC,SAASC,mBAAmB,QAAQ,UAAU;AAC9C,SAASC,WAAW,QAAQ,kBAAkB;AAG9C,SAASC,WAAW,EAAEC,wBAAwB,QAAQ,UAAU;AAEhE,SAASC,mBAAmB,QAAQ,iCAAiC;AAErE,MAAMC,MAAM,GAAGC,OAAO,CAACC,GAAG,CAACC,mBAAmB,IAAI,EAAE;AACpD,MAAMC,kBAAkB,GAAGP,WAAW,CAAC,WAAW,EAAE,EAAE,CAAC;AAEvD,MAAMQ,iBAAiB,GAAIC,MAAiC,IAAK;EAC/D,MAAMC,GAA2B,GAAG,CAAC,CAAC;EACtC,IAAI,CAACD,MAAM,EAAE,OAAOC,GAAG;EACvB,KAAK,MAAMC,IAAI,IAAIF,MAAM,CAACG,KAAK,CAAC,GAAG,CAAC,EAAE;IACpC,MAAM,CAACC,CAAC,EAAE,GAAGC,IAAI,CAAC,GAAGH,IAAI,CAACI,IAAI,CAAC,CAAC,CAACH,KAAK,CAAC,GAAG,CAAC;IAC3C,IAAI,CAACC,CAAC,EAAE;IACRH,GAAG,CAACG,CAAC,CAAC,GAAGG,kBAAkB,CAACF,IAAI,CAACG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;EACnD;EACA,OAAOP,GAAG;AACZ,CAAC;AAED,OAAO,MAAMQ,QAAqB,GAAG,MAAAA,CACnCC,GAAgB,EAChBC,GAAsB,EACtBC,IAAqC,KACP;EAAA,IAAAC,cAAA,EAAAC,EAAA,EAAAC,IAAA,EAAAC,UAAA,EAAAC,KAAA,EAAAC,qBAAA,EAAAC,oBAAA,EAAAC,KAAA,EAAAC,MAAA,EAAAC,KAAA,EAAAC,UAAA,EAAAC,KAAA,EAAAC,QAAA,EAAAC,OAAA,EAAAC,KAAA,EAAAC,qBAAA,EAAAC,kBAAA,EAAAC,eAAA;EAC9B,MAAMC,KAAK,GAAGrB,GAAG,CAACsB,OAAO,CAACC,GAAG,CAAC,QAAQ,CAAuB;EAE7D,IAAI,CAACF,KAAK,IAAI,EAAC5C,OAAO,aAAA0B,cAAA,GAAP1B,OAAO,CAAG4C,KAAK,CAAC,aAAhBlB,cAAA,CAAkBqB,QAAQ,GAAE;IACzC,OAAO;MACLC,MAAM,EAAE,GAAG;MACXH,OAAO,EAAE;QAAE,cAAc,EAAE,kBAAkB;QAAE,eAAe,EAAE,qCAAqC;QAAE,QAAQ,EAAE,UAAU;QAAE,MAAM,EAAE;MAAS,CAAC;MAC/II,IAAI,EAAEC,IAAI,CAACC,SAAS,CAAC;QAAEH,MAAM,EAAE,aAAa;QAAEI,MAAM,EAAE;MAAc,CAAC;IACvE,CAAC;EACH;EAEA,MAAMC,gBAAgB,GAAGrD,OAAO,CAAC4C,KAAK,CAAC,CAACG,QAAQ;;EAEhD;EACA,MAAMO,OAAO,GAAG1C,iBAAiB,CAACW,GAAG,CAACsB,OAAO,CAACC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAE5D,IAAIS,OAAsB,GAAGD,OAAO,CAAC,uBAAuBV,KAAK,UAAU,CAAC;EAE5E,IAAI,CAACW,OAAO,EAAE;IACZ,OAAO;MACLP,MAAM,EAAE,GAAG;MACXH,OAAO,EAAE;QAAE,cAAc,EAAE,kBAAkB;QAAE,eAAe,EAAE,qCAAqC;QAAE,QAAQ,EAAE,UAAU;QAAE,MAAM,EAAE;MAAS,CAAC;MAC/II,IAAI,EAAEC,IAAI,CAACC,SAAS,CAAC;QAAEH,MAAM,EAAE,iBAAiB;QAAEI,MAAM,EAAE;MAAmB,CAAC;IAChF,CAAC;EACH;EAEAG,OAAO,GAAGC,YAAY,CAACD,OAAO,CAAC;EAE/B,IAAI,CAACA,OAAO,EAAE;IACZ,OAAO;MACLP,MAAM,EAAE,GAAG;MACXH,OAAO,EAAE;QAAE,cAAc,EAAE,kBAAkB;QAAE,eAAe,EAAE,qCAAqC;QAAE,QAAQ,EAAE,UAAU;QAAE,MAAM,EAAE;MAAS,CAAC;MAC/II,IAAI,EAAEC,IAAI,CAACC,SAAS,CAAC;QAAEH,MAAM,EAAE,iBAAiB;QAAEI,MAAM,EAAE;MAAwB,CAAC;IACrF,CAAC;EACH;;EAEA;EACA,MAAMK,KAAK,GAAG,MAAMpD,wBAAwB,CAC1CmB,GAAG,EACHhB,OAAO,CAACC,GAAG,CAACiD,oBAAoB,IAAI,EAAE,EACtCxD,mBAAmB,CAACyD,yBACtB,CAAC;EAED,IAAI,CAACF,KAAK,EAAE;IACV,OAAO;MACLT,MAAM,EAAE,GAAG;MACXH,OAAO,EAAE;QAAE,cAAc,EAAE,kBAAkB;QAAE,eAAe,EAAE,qCAAqC;QAAE,QAAQ,EAAE,UAAU;QAAE,MAAM,EAAE;MAAS,CAAC;MAC/II,IAAI,EAAEC,IAAI,CAACC,SAAS,CAAC;QAAEH,MAAM,EAAE,iBAAiB;QAAEI,MAAM,EAAE;MAAuC,CAAC;IACpG,CAAC;EACH;EAEA,MAAMQ,mBAAmB,GAAG,IAAItD,mBAAmB,CAACkB,GAAG,EAAEiC,KAAK,CAAC;EAE/D,MAAMI,eAAe,GAAG,MAAMlD,kBAAkB,CAACmD,QAAQ,CACvDtC,GAAG,EACH,CAAC+B,OAAO,CAAC,EACT,YAAY;IACV,MAAMQ,OAAO,GAAG,MAAMH,mBAAmB,CAACI,mBAAmB,CAACT,OAAO,CAAC;IACtE,OAAOQ,OAAO,GAAGb,IAAI,CAACC,SAAS,CAACY,OAAO,CAAC,GAAG,EAAE;EAC/C,CACF,CAAC;EACD,MAAME,YAAY,GAAGJ,eAAe,GAAGX,IAAI,CAACgB,KAAK,CAACL,eAAe,CAAC,GAAG,IAAI;EAEzE,IAAI,CAACI,YAAY,EAAE;IACjB,OAAO;MACLjB,MAAM,EAAE,GAAG;MACXH,OAAO,EAAE;QAAE,cAAc,EAAE,kBAAkB;QAAE,eAAe,EAAE,qCAAqC;QAAE,QAAQ,EAAE,UAAU;QAAE,MAAM,EAAE;MAAS,CAAC;MAC/II,IAAI,EAAEC,IAAI,CAACC,SAAS,CAAC;QAAEH,MAAM,EAAE,iBAAiB;QAAEI,MAAM,EAAE;MAA0B,CAAC;IACvF,CAAC;EACH;EAEA,IAAIe,EAAE,GAAGF,YAAY,CAACG,WAAW;EACjC,IAAIC,EAAE,GAAGJ,YAAY,CAACK,YAAY;EAElC,IAAI,CAACH,EAAE,IAAI,CAACE,EAAE,EAAE;IACd,OAAO;MACLrB,MAAM,EAAE,GAAG;MACXH,OAAO,EAAE;QAAE,cAAc,EAAE,kBAAkB;QAAE,eAAe,EAAE,qCAAqC;QAAE,QAAQ,EAAE,UAAU;QAAE,MAAM,EAAE;MAAS,CAAC;MAC/II,IAAI,EAAEC,IAAI,CAACC,SAAS,CAAC;QAAEH,MAAM,EAAE,iBAAiB;QAAEI,MAAM,EAAE;MAAY,CAAC;IACzE,CAAC;EACH;EAEA,MAAMmB,KAAK,GAAGN,YAAY,CAACO,OAAO;EAClC,MAAMzB,QAAQ,GAAGkB,YAAY,CAAClB,QAAQ;;EAEtC;EACA,IAAI0B,CAAM;EACV,IAAI;IACFA,CAAC,GAAGxE,SAAS,CAACkE,EAAE,CAAC;EACnB,CAAC,CAAC,OAAAO,OAAA,EAAM;IACN,OAAO;MACL1B,MAAM,EAAE,GAAG;MACXH,OAAO,EAAE;QAAE,cAAc,EAAE,kBAAkB;QAAE,eAAe,EAAE,qCAAqC;QAAE,QAAQ,EAAE,UAAU;QAAE,MAAM,EAAE;MAAS,CAAC;MAC/II,IAAI,EAAEC,IAAI,CAACC,SAAS,CAAC;QAAEH,MAAM,EAAE,iBAAiB;QAAEI,MAAM,EAAE;MAAgB,CAAC;IAC7E,CAAC;EACH;EAEA,IAAI,GAAAzB,EAAA,GAAC8C,CAAC,aAAD9C,EAAA,CAAGgD,GAAG,GAAE;IACX,OAAO;MACL3B,MAAM,EAAE,GAAG;MACXH,OAAO,EAAE;QAAE,cAAc,EAAE,kBAAkB;QAAE,eAAe,EAAE,qCAAqC;QAAE,QAAQ,EAAE,UAAU;QAAE,MAAM,EAAE;MAAS,CAAC;MAC/II,IAAI,EAAEC,IAAI,CAACC,SAAS,CAAC;QAAEH,MAAM,EAAE,iBAAiB;QAAEI,MAAM,EAAE;MAAiB,CAAC;IAC9E,CAAC;EACH;EAEA,MAAMwB,GAAG,GAAGC,IAAI,CAACC,KAAK,CAACC,IAAI,CAACH,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC;EACzC;EACA,IAAI,OAAOH,CAAC,CAACO,GAAG,KAAK,QAAQ,IAAIP,CAAC,CAACO,GAAG,IAAIJ,GAAG,EAAE;IAC7C;IACA,OAAO,MAAMK,kBAAkB,CAAC1D,GAAG,EAAEC,GAAG,EAAEoB,KAAK,EAAE2B,KAAK,EAAExB,QAAQ,EAAEsB,EAAE,EAAEd,OAAO,EAAEkB,CAAC,EAAEhD,IAAI,CAAC;EACzF;;EAEA;EACA,MAAMyD,KAAK,GACRC,KAAK,CAACC,OAAO,CAACX,CAAC,CAACY,GAAG,CAAC,IAAIZ,CAAC,CAACY,GAAG,CAACC,QAAQ,CAACvC,QAAQ,CAAC,IAChD,OAAO0B,CAAC,CAACY,GAAG,KAAK,QAAQ,KAAKZ,CAAC,CAACY,GAAG,KAAKtC,QAAQ,IAAI0B,CAAC,CAACY,GAAG,KAAK,SAAS,CAAE,IAC1EZ,CAAC,CAACc,GAAG,KAAKxC,QAAQ;EAEpB,IAAI,CAACmC,KAAK,EAAE;IACV,OAAO;MACLlC,MAAM,EAAE,GAAG;MACXH,OAAO,EAAE;QAAE,cAAc,EAAE,kBAAkB;QAAE,eAAe,EAAE,qCAAqC;QAAE,QAAQ,EAAE,UAAU;QAAE,MAAM,EAAE;MAAS,CAAC;MAC/II,IAAI,EAAEC,IAAI,CAACC,SAAS,CAAC;QAAEH,MAAM,EAAE,WAAW;QAAEI,MAAM,EAAE;MAAoB,CAAC;IAC3E,CAAC;EACH;;EAGA;EACA,CAAAvB,UAAA,IAAAD,IAAA,GAACJ,GAAG,EAASgE,KAAK,YAAA3D,UAAA,GAAlBD,IAAA,CAAa4D,KAAK,GAAK,CAAC,CAAC;EACzB,MAAMC,QAAQ,GAAGlB,KAAK,CAACmB,QAAQ,CAAC,CAAC;EAEhClE,GAAG,CAASgE,KAAK,CAACG,IAAI,GAAG;IACxB/C,KAAK;IACLgD,MAAM,GAAA9D,KAAA,IAAAC,qBAAA,IAAAC,oBAAA,GAAEiC,YAAY,CAAC2B,MAAM,aAAnB5D,oBAAA,CAAqB0D,QAAQ,oBAA7B1D,oBAAA,CAAqB0D,QAAQ,CAAG,CAAC,YAAA3D,qBAAA,GAAI0C,CAAC,CAACoB,GAAG,YAAA/D,KAAA,GAAI,IAAI;IAC1DgE,cAAc,GAAA7D,KAAA,IAAAC,MAAA,GAAEuC,CAAC,CAACoB,GAAG,YAAA3D,MAAA,GAAI+B,YAAY,CAAC6B,cAAc,YAAA7D,KAAA,GAAI,IAAI;IAC5D8D,UAAU,GAAA5D,KAAA,IAAAC,UAAA,GAAEqC,CAAC,CAACuB,OAAO,YAAA5D,UAAA,GAAIqD,QAAQ,YAAAtD,KAAA,GAAI,IAAI;IACzCsD,QAAQ;IACRQ,KAAK,GAAA5D,KAAA,IAAAC,QAAA,GAAEmC,CAAC,CAACwB,KAAK,YAAA3D,QAAA,GAAImC,CAAC,CAACyB,kBAAkB,YAAA7D,KAAA,GAAI,IAAI;IAC9C8D,IAAI,GAAA5D,OAAA,GAAEkC,CAAC,CAAC0B,IAAI,YAAA5D,OAAA,GAAI6D,SAAS;IACzBC,KAAK,GAAA7D,KAAA,IAAAC,qBAAA,IAAAC,kBAAA,GAAE+B,CAAC,CAAC6B,eAAe,cAAA5D,kBAAA,GAAjBA,kBAAA,CAAoBK,QAAQ,CAAC,qBAA7BL,kBAAA,CAA+B2D,KAAK,YAAA5D,qBAAA,IAAAE,eAAA,GAAI8B,CAAC,CAAC8B,YAAY,qBAAd5D,eAAA,CAAgB0D,KAAK,YAAA7D,KAAA,GAAI,EAAE;IAC1EwC,GAAG,EAAEP,CAAC,CAACO;EACT,CAAC;EAED,OAAOvD,IAAI,CAAC,CAAC;AACf,CAAC;AAID,eAAewD,kBAAkBA,CAC/B1D,GAAgB,EAChBC,GAAsB,EACtBoB,KAAa,EACb4B,OAAe,EACfzB,QAAgB,EAChBsB,EAAsB,EACtBd,OAAe,EACfkB,CAAM,EACNhD,IAAqC,EACV;EAC3B;EACA,IAAI,CAAC4C,EAAE,EAAE;IACP,OAAO;MACLrB,MAAM,EAAE,GAAG;MACXH,OAAO,EAAE;QAAE,cAAc,EAAE,kBAAkB;QAAE,eAAe,EAAE,qCAAqC;QAAE,QAAQ,EAAE,UAAU;QAAE,MAAM,EAAE;MAAS,CAAC;MAC/II,IAAI,EAAEC,IAAI,CAACC,SAAS,CAAC;QAAEH,MAAM,EAAE,iBAAiB;QAAEI,MAAM,EAAE;MAAgB,CAAC;IAC7E,CAAC;EACH;EAEA5B,GAAG,CAACgF,IAAI,CAAC,iDAAiD,EAAE;IAC1DhC,OAAO;IACPzB,QAAQ;IACRsB;EACF,CAAC,CAAC;;EAEF;EACA,IAAI;IAAA,IAAAoC,KAAA,EAAAC,WAAA,EAAAC,OAAA,EAAAC,KAAA,EAAAC,WAAA,EAAAC,KAAA,EAAAC,SAAA,EAAAC,QAAA,EAAAC,KAAA,EAAAC,qBAAA,EAAAC,mBAAA,EAAAC,gBAAA;IACF,MAAMC,IAAI,GAAG,MAAMC,KAAK,CAAC/G,MAAM,EAAE;MAC/BgH,MAAM,EAAE,MAAM;MACd1E,OAAO,EAAE;QAAE,cAAc,EAAE;MAAmB,CAAC;MAC/CI,IAAI,EAAEC,IAAI,CAACC,SAAS,CAAC;QACnBqB,OAAO;QACPzB,QAAQ,EAAEA,QAAQ;QAClByE,aAAa,EAAEnD;MACjB,CAAC;IACH,CAAC,CAAC;IAEF,IAAI,CAACgD,IAAI,CAACI,EAAE,EAAE;MACZ,MAAMC,IAAI,GAAG,MAAML,IAAI,CAACK,IAAI,CAAC,CAAC;MAC9BlG,GAAG,CAACmG,IAAI,YAARnG,GAAG,CAACmG,IAAI,CAAG,wBAAwBN,IAAI,CAACrE,MAAM,IAAI0E,IAAI,EAAE,CAAC;MACzD,OAAO;QACL1E,MAAM,EAAE,GAAG;QACXH,OAAO,EAAE;UAAE,cAAc,EAAE,kBAAkB;UAAE,eAAe,EAAE,qCAAqC;UAAE,QAAQ,EAAE,UAAU;UAAE,MAAM,EAAE;QAAS,CAAC;QAC/II,IAAI,EAAEC,IAAI,CAACC,SAAS,CAAC;UAAEH,MAAM,EAAE,iBAAiB;UAAEI,MAAM,EAAE;QAAiB,CAAC;MAC9E,CAAC;IACH;IAEA,MAAMwE,OAAO,GAAG,MAAMP,IAAI,CAACQ,IAAI,CAAC,CAAC;IACjC,MAAMC,IAAI,GAAG,CAAAF,OAAO,oBAAPA,OAAO,CAAEE,IAAI,KAAI,CAAC,CAAC;IAEhC,MAAMC,KAAK,GAAGD,IAAI,CAACE,YAAkC;IACrD,MAAMC,KAAK,GAAGH,IAAI,CAACN,aAAmC;IAEtD,IAAI,CAACO,KAAK,IAAI,CAACE,KAAK,EAAE;MACpB,OAAO;QACLjF,MAAM,EAAE,GAAG;QACXH,OAAO,EAAE;UAAE,cAAc,EAAE,kBAAkB;UAAE,eAAe,EAAE,qCAAqC;UAAE,QAAQ,EAAE,UAAU;UAAE,MAAM,EAAE;QAAS,CAAC;QAC/II,IAAI,EAAEC,IAAI,CAACC,SAAS,CAAC;UAAEH,MAAM,EAAE,iBAAiB;UAAEI,MAAM,EAAE;QAA2B,CAAC;MACxF,CAAC;IACH;IAEA,MAAMK,KAAK,GAAG,MAAMpD,wBAAwB,CAC1CmB,GAAG,EACHhB,OAAO,CAACC,GAAG,CAACiD,oBAAoB,IAAI,EAAE,EACtCxD,mBAAmB,CAACyD,yBACtB,CAAC;IAED,IAAI,CAACF,KAAK,EAAE;MACV,OAAO;QACLT,MAAM,EAAE,GAAG;QACXH,OAAO,EAAE;UAAE,cAAc,EAAE,kBAAkB;UAAE,eAAe,EAAE,qCAAqC;UAAE,QAAQ,EAAE,UAAU;UAAE,MAAM,EAAE;QAAS,CAAC;QAC/II,IAAI,EAAEC,IAAI,CAACC,SAAS,CAAC;UAAEH,MAAM,EAAE,iBAAiB;UAAEI,MAAM,EAAE;QAAuC,CAAC;MACpG,CAAC;IACH;IAEA,MAAMQ,mBAAmB,GAAG,IAAItD,mBAAmB,CAACkB,GAAG,EAAEiC,KAAK,CAAC;IAE/D,MAAMG,mBAAmB,CAACsE,kBAAkB,CAAC3E,OAAO,EAAE;MACpDa,WAAW,EAAE2D,KAAe;MAC5BzD,YAAY,EAAE2D,KAAe;MAC7B;MACAE,SAAS,EAAE,OAAOL,IAAI,CAACM,UAAU,KAAK,QAAQ,GAAG,IAAIrD,IAAI,CAACA,IAAI,CAACH,GAAG,CAAC,CAAC,GAAGkD,IAAI,CAACM,UAAU,GAAG,IAAI,CAAC,GAAGhC;IACnG,CAAC,CAAC;;IAEF;IACA,MAAMiC,aAAa,GACjB,OAAOP,IAAI,CAACQ,kBAAkB,KAAK,QAAQ,GACvCR,IAAI,CAACQ,kBAAkB,GACvB,OAAOR,IAAI,CAACM,UAAU,KAAK,QAAQ,GACjCN,IAAI,CAACM,UAAU,GACf,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;;IAEtBjI,WAAW,CAACqB,GAAG,EAAE,uBAAuBoB,KAAK,UAAU,EAAEW,OAAO,EAAE;MAChE;MACAgF,QAAQ,EAAE,KAAK;MACfC,MAAM,EAAE,IAAI;MACZC,QAAQ,EAAE,MAAM;MAChBC,MAAM,EAAEL;IACV,CAAC,CAAC;;IAEF;IACA,IAAIM,EAAO;IACX,IAAI;MAAEA,EAAE,GAAG1I,SAAS,CAAC8H,KAAK,CAAC;IAAE,CAAC,CAAC,OAAAa,QAAA,EAAM;MACnC,OAAO;QACL5F,MAAM,EAAE,GAAG;QACXH,OAAO,EAAE;UAAE,cAAc,EAAE,kBAAkB;UAAE,eAAe,EAAE,qCAAqC;UAAE,QAAQ,EAAE,UAAU;UAAE,MAAM,EAAE;QAAS,CAAC;QAC/II,IAAI,EAAEC,IAAI,CAACC,SAAS,CAAC;UAAEH,MAAM,EAAE,iBAAiB;UAAEI,MAAM,EAAE;QAAoB,CAAC;MACjF,CAAC;IACH;IAEA,MAAMyF,MAAM,GACT1D,KAAK,CAACC,OAAO,CAACuD,EAAE,CAACtD,GAAG,CAAC,IAAIsD,EAAE,CAACtD,GAAG,CAACC,QAAQ,CAACvC,QAAQ,CAAC,IAClD,OAAO4F,EAAE,CAACtD,GAAG,KAAK,QAAQ,KAAKsD,EAAE,CAACtD,GAAG,KAAKtC,QAAQ,IAAI4F,EAAE,CAACtD,GAAG,KAAK,SAAS,CAAE,IAC7EsD,EAAE,CAACpD,GAAG,KAAKxC,QAAQ;IACrB,IAAI,CAAC8F,MAAM,EAAE;MACX,OAAO;QACL7F,MAAM,EAAE,GAAG;QACXH,OAAO,EAAE;UAAE,cAAc,EAAE,kBAAkB;UAAE,eAAe,EAAE,qCAAqC;UAAE,QAAQ,EAAE,UAAU;UAAE,MAAM,EAAE;QAAS,CAAC;QAC/II,IAAI,EAAEC,IAAI,CAACC,SAAS,CAAC;UAAEH,MAAM,EAAE,WAAW;UAAEI,MAAM,EAAE;QAAoB,CAAC;MAC3E,CAAC;IACH;;IAEA;IACA,CAAAsD,WAAA,IAAAD,KAAA,GAACjF,GAAG,EAASgE,KAAK,YAAAkB,WAAA,GAAlBD,KAAA,CAAajB,KAAK,GAAK,CAAC,CAAC;IACzB,MAAMsD,SAAS,GAAGtE,OAAO,CAACkB,QAAQ,CAAC,CAAC;IACnClE,GAAG,CAASgE,KAAK,CAACG,IAAI,GAAG;MACxB/C,KAAK;MACLgD,MAAM,GAAAe,OAAA,GAAEgC,EAAE,CAAC9C,GAAG,YAAAc,OAAA,GAAI,IAAI;MACtBZ,UAAU,GAAAa,KAAA,IAAAC,WAAA,GAAE8B,EAAE,CAAC3C,OAAO,YAAAa,WAAA,GAAIiC,SAAS,YAAAlC,KAAA,GAAI,IAAI;MAC3CnB,QAAQ,EAAEqD,SAAS;MACnB7C,KAAK,GAAAa,KAAA,IAAAC,SAAA,GAAE4B,EAAE,CAAC1C,KAAK,YAAAc,SAAA,GAAI4B,EAAE,CAACzC,kBAAkB,YAAAY,KAAA,GAAI,IAAI;MAChDX,IAAI,GAAAa,QAAA,GAAE2B,EAAE,CAACxC,IAAI,YAAAa,QAAA,GAAIZ,SAAS;MAC1BC,KAAK,GAAAY,KAAA,IAAAC,qBAAA,IAAAC,mBAAA,GAAEwB,EAAE,CAACrC,eAAe,cAAAa,mBAAA,GAAlBA,mBAAA,CAAqBpE,QAAQ,CAAC,qBAA9BoE,mBAAA,CAAgCd,KAAK,YAAAa,qBAAA,IAAAE,gBAAA,GAAIuB,EAAE,CAACpC,YAAY,qBAAfa,gBAAA,CAAiBf,KAAK,YAAAY,KAAA,GAAI,EAAE;MAC5EjC,GAAG,EAAE2D,EAAE,CAAC3D;IACV,CAAC;;IAED;IACA,OAAOvD,IAAI,CAAC,CAAC;EACf,CAAC,CAAC,OAAOsH,CAAC,EAAE;IACVvH,GAAG,CAACwH,KAAK,YAATxH,GAAG,CAACwH,KAAK,CAAG,mBAAmB,EAAED,CAAQ,CAAC;IAC1C,OAAO;MACL/F,MAAM,EAAE,GAAG;MACXH,OAAO,EAAE;QAAE,cAAc,EAAE,kBAAkB;QAAE,eAAe,EAAE,qCAAqC;QAAE,QAAQ,EAAE,UAAU;QAAE,MAAM,EAAE;MAAS,CAAC;MAC/II,IAAI,EAAEC,IAAI,CAACC,SAAS,CAAC;QAAEH,MAAM,EAAE,iBAAiB;QAAEI,MAAM,EAAE;MAAoB,CAAC;IACjF,CAAC;EACH;AACF;AAEA,SAASI,YAAYA,CAACyF,KAAa,EAAiB;EAClD,IAAI;IACF,OAAOC,MAAM,CAACC,IAAI,CAACF,KAAK,EAAE,QAAQ,CAAC,CAACvD,QAAQ,CAAC,CAAC;EAChD,CAAC,CAAC,OAAOsD,KAAU,EAAE;IACnBI,OAAO,CAACC,GAAG,CAAC,yBAAyB,GAAGL,KAAK,CAACM,OAAO,CAAC;IACtD,OAAO,IAAI;EACb;AACF","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"verify-middleware.js","names":["APP_MAP","jwtDecode","AzureSecretKeysEnum","setCookieKV","createCache","getAzureVaultSecretByKey","TokenMappingService","apiURL","process","env","REFRESH_SESSION_URL","verifyMappingCache","parseCookieHeader","header","out","part","split","k","rest","trim","decodeURIComponent","join","verifyMw","req","ctx","next","_APP_MAP$appId","_p","_ref","_ref$state","_ref2","_tokenMapping$userId$","_tokenMapping$userId","_ref3","_p$sub","_ref4","_p$cfy_bid","_ref5","_p$email","_p$name","_ref6","_p$resource_access$cl","_p$resource_access","_p$realm_access","appId","headers","get","clientId","status","body","JSON","stringify","reason","expectedClientId","cookies","mapping","base64Decode","dbUrl","AZURE_KEY_VAULT_NAME","DB_CONNECTING_STRING_USER","tokenMappingService","tokenMappingRaw","getOrSet","fetched","getTokenMappingById","tokenMapping","parse","at","accessToken","rt","refreshToken","realm","realmId","p","_unused","sid","now","Math","floor","Date","exp","getNewRefreshToken","audOk","Array","isArray","aud","includes","azp","state","tenantId","toString","auth","userId","sub","keycloakUserId","businessId","cfy_bid","email","preferred_username","name","undefined","roles","resource_access","realm_access","info","_ref7","_ref7$state","_ref8","_updatedMapping$userI","_updatedMapping$userI2","_ref9","_p2$sub","_ref0","_p2$cfy_bid","_ref1","_p2$email","_p2$name","_ref10","_p2$resource_access$c","_p2$resource_access","_p2$realm_access","resp","fetch","method","refresh_token","ok","text","warn","payload","json","data","newAT","access_token","newRT","updatedMapping","updateTokenMapping","expiresAt","expires_in","mappingMaxAge","refresh_expires_in","httpOnly","secure","sameSite","maxAge","p2","_unused2","audOk2","tenantId2","e","error","value","Buffer","from","console","log","message"],"sources":["../../../src/middlewares/verify-middleware.ts"],"sourcesContent":["import { IAppId } from \"../types/app\";\nimport { APP_MAP } from \"../constants\";\nimport { jwtDecode } from \"jwt-decode\";\nimport { HttpRequest } from \"@azure/functions\";\nimport { AzureSecretKeysEnum } from \"../enums\";\nimport { setCookieKV } from \"../utils/cookies\";\nimport { IMiddleware } from \"../types/middleware\";\nimport { HttpResponseInit } from \"@azure/functions\";\nimport { createCache, getAzureVaultSecretByKey } from \"../utils\";\nimport { InvocationContext } from \"@azure/functions\";\nimport { TokenMappingService } from \"../service/tokenMapping.service\";\n\nconst apiURL = process.env.REFRESH_SESSION_URL || '';\nconst verifyMappingCache = createCache(\"verify-mw\", 60);\n\nconst parseCookieHeader = (header: string | null | undefined) => {\n const out: Record<string, string> = {};\n if (!header) return out;\n for (const part of header.split(\";\")) {\n const [k, ...rest] = part.trim().split(\"=\");\n if (!k) continue;\n out[k] = decodeURIComponent(rest.join(\"=\") || \"\");\n }\n return out;\n};\n\nexport const verifyMw: IMiddleware = async (\n req: HttpRequest,\n ctx: InvocationContext,\n next: () => Promise<HttpResponseInit>\n): Promise<HttpResponseInit> => {\n const appId = req.headers.get(\"app-id\") as IAppId | undefined;\n\n if (!appId || !APP_MAP?.[appId]?.clientId) {\n return {\n status: 400,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"bad_request\", reason: \"invalid_app\" })\n };\n }\n\n const expectedClientId = APP_MAP[appId].clientId;\n\n // cookies\n const cookies = parseCookieHeader(req.headers.get(\"cookie\"));\n\n let mapping: string | null = cookies[`__Secure-session-v1.${appId}.mapping`];\n\n if (!mapping) {\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"no_token_mapping\" })\n };\n }\n\n mapping = base64Decode(mapping);\n\n if (!mapping) {\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"invalid_token_mapping\" })\n };\n }\n\n // Get database connection string\n const dbUrl = await getAzureVaultSecretByKey(\n ctx,\n process.env.AZURE_KEY_VAULT_NAME || \"\",\n AzureSecretKeysEnum.DB_CONNECTING_STRING_USER\n );\n\n if (!dbUrl) {\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"database_connection_string_not_found\" })\n };\n }\n\n const tokenMappingService = new TokenMappingService(ctx, dbUrl);\n\n const tokenMappingRaw = await verifyMappingCache.getOrSet(\n ctx,\n [mapping],\n async () => {\n const fetched = await tokenMappingService.getTokenMappingById(mapping);\n return fetched ? JSON.stringify(fetched) : \"\";\n },\n );\n const tokenMapping = tokenMappingRaw ? JSON.parse(tokenMappingRaw) : null;\n\n if (!tokenMapping) {\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"token_mapping_not_found\" })\n };\n }\n\n let at = tokenMapping.accessToken;\n let rt = tokenMapping.refreshToken;\n\n if (!at && !rt) {\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"no_tokens\" })\n };\n }\n\n const realm = tokenMapping.realmId;\n const clientId = tokenMapping.clientId;\n\n // decode/verify (lightweight; replace with your verifyJsonWebToken if you have it)\n let p: any;\n try {\n p = jwtDecode(at);\n } catch {\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"invalid_token\" })\n };\n }\n\n if (!p?.sid) {\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"user_not_found\" })\n };\n }\n\n const now = Math.floor(Date.now() / 1000);\n // Refresh only when expired\n if (typeof p.exp === \"number\" && p.exp <= now) {\n // Delegate to refresh helper; it will handle setting cookies/state or returning an error\n return await getNewRefreshToken(req, ctx, appId, realm, clientId, rt, mapping, p, next);\n }\n\n // audience checks\n const audOk =\n (Array.isArray(p.aud) && p.aud.includes(clientId)) ||\n (typeof p.aud === \"string\" && (p.aud === clientId || p.aud === \"account\")) ||\n p.azp === clientId;\n\n if (!audOk) {\n return {\n status: 403,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"forbidden\", reason: \"audience_mismatch\" })\n };\n }\n\n\n // pass data downstream\n (ctx as any).state ??= {};\n const tenantId = realm.toString();\n\n (ctx as any).state.auth = {\n appId,\n userId: tokenMapping.userId?.toString?.() ?? p.sub ?? null,\n keycloakUserId: p.sub ?? tokenMapping.keycloakUserId ?? null,\n businessId: p.cfy_bid ?? tenantId ?? null,\n tenantId,\n email: p.email ?? p.preferred_username ?? null,\n name: p.name ?? undefined,\n roles: p.resource_access?.[clientId]?.roles ?? p.realm_access?.roles ?? [],\n exp: p.exp,\n };\n\n return next();\n};\n\n\n\nasync function getNewRefreshToken(\n req: HttpRequest,\n ctx: InvocationContext,\n appId: IAppId,\n realmId: string,\n clientId: string,\n rt: string | undefined,\n mapping: string,\n p: any,\n next: () => Promise<HttpResponseInit>\n): Promise<HttpResponseInit> {\n // Attempt server-side refresh using RT\n if (!rt) {\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"expired_no_rt\" })\n };\n }\n\n ctx.info(\"refreshing token payload ----------------------\", {\n realmId,\n clientId,\n rt\n });\n\n // Call auth service to refresh\n try {\n const resp = await fetch(apiURL, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n realmId,\n clientId: clientId,\n refresh_token: rt\n })\n });\n\n if (!resp.ok) {\n const text = await resp.text();\n ctx.warn?.(`refresh call failed: ${resp.status} ${text}`);\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"refresh_failed\" })\n };\n }\n\n const payload = await resp.json();\n const data = payload?.data || {};\n\n const newAT = data.access_token as string | undefined;\n const newRT = data.refresh_token as string | undefined;\n\n if (!newAT || !newRT) {\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"invalid_refresh_response\" })\n };\n }\n\n const dbUrl = await getAzureVaultSecretByKey(\n ctx,\n process.env.AZURE_KEY_VAULT_NAME || \"\",\n AzureSecretKeysEnum.DB_CONNECTING_STRING_USER\n );\n\n if (!dbUrl) {\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"database_connection_string_not_found\" })\n };\n }\n\n const tokenMappingService = new TokenMappingService(ctx, dbUrl);\n\n const updatedMapping = await tokenMappingService.updateTokenMapping(mapping, {\n accessToken: newAT as string,\n refreshToken: newRT as string,\n // expires_in is a duration (seconds); store absolute expiry for later checks\n expiresAt: typeof data.expires_in === \"number\" ? new Date(Date.now() + data.expires_in * 1000) : undefined\n });\n\n // Set refreshed mapping cookie for client session (AT/RT stay server-side in token mapping)\n const mappingMaxAge =\n typeof data.refresh_expires_in === \"number\"\n ? data.refresh_expires_in\n : typeof data.expires_in === \"number\"\n ? data.expires_in\n : 60 * 60 * 24; // fallback 24h\n\n setCookieKV(ctx, `__Secure-session-v1.${appId}.mapping`, mapping, {\n // mapping must be readable by FE in your flow; keep httpOnly default if you prefer server-only\n httpOnly: false,\n secure: true,\n sameSite: \"None\",\n maxAge: mappingMaxAge\n });\n\n // Decode new AT and proceed\n let p2: any;\n try { p2 = jwtDecode(newAT); } catch {\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"invalid_new_token\" })\n };\n }\n\n const audOk2 =\n (Array.isArray(p2.aud) && p2.aud.includes(clientId)) ||\n (typeof p2.aud === \"string\" && (p2.aud === clientId || p2.aud === \"account\")) ||\n p2.azp === clientId;\n if (!audOk2) {\n return {\n status: 403,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"forbidden\", reason: \"audience_mismatch\" })\n };\n }\n\n // Update downstream auth state with refreshed token\n (ctx as any).state ??= {};\n const tenantId2 = realmId.toString();\n (ctx as any).state.auth = {\n appId,\n userId: updatedMapping?.userId?.toString?.() ?? p2.sub ?? null,\n keycloakUserId: p2.sub ?? updatedMapping?.keycloakUserId ?? null,\n businessId: p2.cfy_bid ?? tenantId2 ?? null,\n tenantId: tenantId2,\n email: p2.email ?? p2.preferred_username ?? null,\n name: p2.name ?? undefined,\n roles: p2.resource_access?.[clientId]?.roles ?? p2.realm_access?.roles ?? [],\n exp: p2.exp,\n };\n\n // Continue pipeline after refresh\n return next();\n } catch (e) {\n ctx.error?.(\"refresh exception\", e as any);\n return {\n status: 401,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store, no-cache, must-revalidate\", \"Pragma\": \"no-cache\", \"Vary\": \"Origin\" },\n body: JSON.stringify({ status: \"unauthenticated\", reason: \"refresh_exception\" })\n };\n }\n}\n\nfunction base64Decode(value: string): string | null {\n try {\n return Buffer.from(value, 'base64').toString();\n } catch (error: any) {\n console.log(\"Error decoding base64: \" + error.message);\n return null;\n }\n}"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import mongoose, { model, Schema } from 'mongoose';
|
|
2
|
+
export const CONFIG_MAPPING_DOCUMENT_NAME = 'ConfigMapping';
|
|
3
|
+
export const CONFIG_MAPPING_COLLECTION_NAME = 'configMappings';
|
|
4
|
+
const schema = new Schema({
|
|
5
|
+
_id: {
|
|
6
|
+
type: Schema.Types.ObjectId,
|
|
7
|
+
required: true,
|
|
8
|
+
unique: true,
|
|
9
|
+
auto: true
|
|
10
|
+
},
|
|
11
|
+
businessId: {
|
|
12
|
+
type: Schema.Types.ObjectId,
|
|
13
|
+
required: true
|
|
14
|
+
},
|
|
15
|
+
connectionString: {
|
|
16
|
+
type: String,
|
|
17
|
+
required: true
|
|
18
|
+
},
|
|
19
|
+
domain: {
|
|
20
|
+
type: String,
|
|
21
|
+
required: false
|
|
22
|
+
},
|
|
23
|
+
appId: {
|
|
24
|
+
type: String,
|
|
25
|
+
required: false
|
|
26
|
+
},
|
|
27
|
+
serviceDBType: {
|
|
28
|
+
type: String,
|
|
29
|
+
required: false
|
|
30
|
+
}
|
|
31
|
+
}, {
|
|
32
|
+
timestamps: true,
|
|
33
|
+
collection: CONFIG_MAPPING_COLLECTION_NAME
|
|
34
|
+
});
|
|
35
|
+
export const ConfigMappingModel = mongoose.models.ConfigMapping || model(CONFIG_MAPPING_DOCUMENT_NAME, schema);
|
|
36
|
+
//# sourceMappingURL=config-mapping.model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-mapping.model.js","names":["mongoose","model","Schema","CONFIG_MAPPING_DOCUMENT_NAME","CONFIG_MAPPING_COLLECTION_NAME","schema","_id","type","Types","ObjectId","required","unique","auto","businessId","connectionString","String","domain","appId","serviceDBType","timestamps","collection","ConfigMappingModel","models","ConfigMapping"],"sources":["../../../src/models/config-mapping.model.ts"],"sourcesContent":["import mongoose, { model, Schema } from 'mongoose';\n\nexport const CONFIG_MAPPING_DOCUMENT_NAME = 'ConfigMapping';\nexport const CONFIG_MAPPING_COLLECTION_NAME = 'configMappings';\n\nexport type ServiceDbType = 'main' | 'chatDB';\n\nexport interface IConfigMapping {\n _id?: Schema.Types.ObjectId;\n businessId: Schema.Types.ObjectId;\n connectionString: string;\n domain?: string;\n appId?: string;\n serviceDBType?: ServiceDbType;\n}\n\nexport interface ICreateConfigMapping {\n businessId: string;\n connectionString: string;\n domain?: string;\n appId?: string;\n serviceDBType?: ServiceDbType;\n}\n\nconst schema = new Schema<IConfigMapping>(\n {\n _id: {\n type: Schema.Types.ObjectId,\n required: true,\n unique: true,\n auto: true,\n },\n businessId: {\n type: Schema.Types.ObjectId,\n required: true,\n },\n connectionString: {\n type: String,\n required: true,\n },\n domain: {\n type: String,\n required: false,\n },\n appId: {\n type: String,\n required: false,\n },\n serviceDBType: {\n type: String,\n required: false,\n },\n },\n {\n timestamps: true,\n collection: CONFIG_MAPPING_COLLECTION_NAME,\n },\n);\n\nexport const ConfigMappingModel =\n mongoose.models.ConfigMapping ||\n model<IConfigMapping>(CONFIG_MAPPING_DOCUMENT_NAME, schema);\n"],"mappings":"AAAA,OAAOA,QAAQ,IAAIC,KAAK,EAAEC,MAAM,QAAQ,UAAU;AAElD,OAAO,MAAMC,4BAA4B,GAAG,eAAe;AAC3D,OAAO,MAAMC,8BAA8B,GAAG,gBAAgB;AAqB9D,MAAMC,MAAM,GAAG,IAAIH,MAAM,CACvB;EACEI,GAAG,EAAE;IACHC,IAAI,EAAEL,MAAM,CAACM,KAAK,CAACC,QAAQ;IAC3BC,QAAQ,EAAE,IAAI;IACdC,MAAM,EAAE,IAAI;IACZC,IAAI,EAAE;EACR,CAAC;EACDC,UAAU,EAAE;IACVN,IAAI,EAAEL,MAAM,CAACM,KAAK,CAACC,QAAQ;IAC3BC,QAAQ,EAAE;EACZ,CAAC;EACDI,gBAAgB,EAAE;IAChBP,IAAI,EAAEQ,MAAM;IACZL,QAAQ,EAAE;EACZ,CAAC;EACDM,MAAM,EAAE;IACNT,IAAI,EAAEQ,MAAM;IACZL,QAAQ,EAAE;EACZ,CAAC;EACDO,KAAK,EAAE;IACLV,IAAI,EAAEQ,MAAM;IACZL,QAAQ,EAAE;EACZ,CAAC;EACDQ,aAAa,EAAE;IACbX,IAAI,EAAEQ,MAAM;IACZL,QAAQ,EAAE;EACZ;AACF,CAAC,EACD;EACES,UAAU,EAAE,IAAI;EAChBC,UAAU,EAAEhB;AACd,CACF,CAAC;AAED,OAAO,MAAMiB,kBAAkB,GAC7BrB,QAAQ,CAACsB,MAAM,CAACC,aAAa,IAC7BtB,KAAK,CAAiBE,4BAA4B,EAAEE,MAAM,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/repositories/index.ts"],"sourcesContent":["export * from \"./multi-tenant.repository\";\nexport * from \"./tenant-base.repository\";\n"],"mappings":"AAAA,cAAc,2BAA2B;AACzC,cAAc,0BAA0B","ignoreList":[]}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
var _dec, _dec2, _dec3, _class, _MultiTenantRepository;
|
|
2
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
3
|
+
function _applyDecoratedDescriptor(i, e, r, n, l) { var a = {}; return Object.keys(n).forEach(function (i) { a[i] = n[i]; }), a.enumerable = !!a.enumerable, a.configurable = !!a.configurable, ("value" in a || a.initializer) && (a.writable = !0), a = r.slice().reverse().reduce(function (r, n) { return n(i, e, r) || r; }, a), l && void 0 !== a.initializer && (a.value = a.initializer ? a.initializer.call(l) : void 0, a.initializer = void 0), void 0 === a.initializer ? (Object.defineProperty(i, e, a), null) : a; }
|
|
4
|
+
import mongoose, { Types } from "mongoose";
|
|
5
|
+
import * as crypto from "crypto";
|
|
6
|
+
import { DefaultAzureCredential } from "@azure/identity";
|
|
7
|
+
import { SecretClient } from "@azure/keyvault-secrets";
|
|
8
|
+
import { AzureSecretKeysEnum } from "../enums";
|
|
9
|
+
import { Cacheable, createCache } from "../utils/cache";
|
|
10
|
+
import { getAzureVaultSecretByKey } from "../utils/secrets";
|
|
11
|
+
import { CONFIG_MAPPING_COLLECTION_NAME, CONFIG_MAPPING_DOCUMENT_NAME, ConfigMappingModel } from "../models/config-mapping.model";
|
|
12
|
+
const tenantDbCache = createCache("tenant-db", 600);
|
|
13
|
+
const tenantBridgeCache = createCache("tenant-bridge-db-connection-string", 1800);
|
|
14
|
+
const encryptionKeyCache = createCache("db-enc-key", 1800);
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Decorator that ensures tenant DB is connected before the method runs.
|
|
18
|
+
*/
|
|
19
|
+
export function WithTenantDb(_target, _propertyKey, descriptor) {
|
|
20
|
+
if (!descriptor.value) return;
|
|
21
|
+
const originalMethod = descriptor.value;
|
|
22
|
+
descriptor.value = async function (...args) {
|
|
23
|
+
await this.ensureClientConnection();
|
|
24
|
+
return originalMethod.apply(this, args);
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export let MultiTenantRepository = (_dec = Cacheable({
|
|
28
|
+
cache: tenantBridgeCache,
|
|
29
|
+
key: () => ["tenant-bridge"],
|
|
30
|
+
getContext: instance => instance.context
|
|
31
|
+
}), _dec2 = Cacheable({
|
|
32
|
+
cache: encryptionKeyCache,
|
|
33
|
+
key: () => ["key"],
|
|
34
|
+
getContext: instance => instance.context
|
|
35
|
+
}), _dec3 = Cacheable({
|
|
36
|
+
cache: tenantDbCache,
|
|
37
|
+
key: (businessId, appId, serviceDbType) => [businessId, appId, serviceDbType],
|
|
38
|
+
getContext: instance => instance.context
|
|
39
|
+
}), _class = (_MultiTenantRepository = class MultiTenantRepository {
|
|
40
|
+
constructor(context, businessId, appId, config, serviceDBType) {
|
|
41
|
+
this.context = void 0;
|
|
42
|
+
this.tenantBridgeConfig = void 0;
|
|
43
|
+
this.businessId = void 0;
|
|
44
|
+
this.appId = void 0;
|
|
45
|
+
this.serviceDBType = void 0;
|
|
46
|
+
this.dbConnectionEncryptionKey = void 0;
|
|
47
|
+
this.clientConnectionString = void 0;
|
|
48
|
+
this.connectionPromise = void 0;
|
|
49
|
+
this.context = context;
|
|
50
|
+
this.businessId = businessId;
|
|
51
|
+
this.appId = appId;
|
|
52
|
+
this.serviceDBType = serviceDBType != null ? serviceDBType : "main";
|
|
53
|
+
this.tenantBridgeConfig = _extends({
|
|
54
|
+
tenantBridgeEnvKey: "TENANT_BRIDGE_DB_URI",
|
|
55
|
+
tenantBridgeSecretKey: AzureSecretKeysEnum.DB_CONNECTING_STRING_TENANT_BRIDGE
|
|
56
|
+
}, config);
|
|
57
|
+
this.connectionPromise = this.ensureClientConnection();
|
|
58
|
+
}
|
|
59
|
+
getEncryptionIv() {
|
|
60
|
+
const iv = process.env.DB_CONNECTION_STRING_ENCRYPTION_IV;
|
|
61
|
+
if (!iv) {
|
|
62
|
+
return Buffer.alloc(16, 0);
|
|
63
|
+
}
|
|
64
|
+
return this.normalizeFixedSize(iv, "IV");
|
|
65
|
+
}
|
|
66
|
+
normalizeFixedSize(value, label) {
|
|
67
|
+
const utf8Value = Buffer.from(value, "utf8");
|
|
68
|
+
if (utf8Value.length === 16) {
|
|
69
|
+
return utf8Value;
|
|
70
|
+
}
|
|
71
|
+
const base64Value = Buffer.from(value, "base64");
|
|
72
|
+
if (base64Value.length === 16) {
|
|
73
|
+
return base64Value;
|
|
74
|
+
}
|
|
75
|
+
const hexValue = Buffer.from(value, "hex");
|
|
76
|
+
if (hexValue.length === 16) {
|
|
77
|
+
return hexValue;
|
|
78
|
+
}
|
|
79
|
+
throw new Error(`${label} must be 16 bytes for aes-128-cbc (got ${utf8Value.length})`);
|
|
80
|
+
}
|
|
81
|
+
async getOrCreateCachedConnection(connectionString) {
|
|
82
|
+
const existing = MultiTenantRepository.connections.get(connectionString);
|
|
83
|
+
if (existing && existing.connection.readyState === 1) {
|
|
84
|
+
return existing;
|
|
85
|
+
}
|
|
86
|
+
this.context.info(`Initializing database connection... ${connectionString}`);
|
|
87
|
+
const instance = new mongoose.Mongoose();
|
|
88
|
+
try {
|
|
89
|
+
await instance.connect(connectionString, {
|
|
90
|
+
serverSelectionTimeoutMS: 10000,
|
|
91
|
+
connectTimeoutMS: 10000,
|
|
92
|
+
socketTimeoutMS: 45000
|
|
93
|
+
});
|
|
94
|
+
this.context.info(`✅ MongoDB connected successfully ${connectionString}`);
|
|
95
|
+
MultiTenantRepository.connections.set(connectionString, instance);
|
|
96
|
+
return instance;
|
|
97
|
+
} catch (err) {
|
|
98
|
+
this.context.error(`❌ MongoDB connection error for ${connectionString}`, {
|
|
99
|
+
message: err.message,
|
|
100
|
+
name: err.name,
|
|
101
|
+
code: err.code,
|
|
102
|
+
stack: err.stack
|
|
103
|
+
});
|
|
104
|
+
throw new Error(`Failed to connect to MongoDB: ${err.message}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
toObjectId(id, fieldName) {
|
|
108
|
+
if (!Types.ObjectId.isValid(id)) {
|
|
109
|
+
throw new Error(`Invalid ${fieldName}`);
|
|
110
|
+
}
|
|
111
|
+
return new Types.ObjectId(id);
|
|
112
|
+
}
|
|
113
|
+
async getTenantBridgeSrvDbConnectionString() {
|
|
114
|
+
const envKey = this.tenantBridgeConfig.tenantBridgeEnvKey;
|
|
115
|
+
const localUri = envKey ? process.env[envKey] : undefined;
|
|
116
|
+
if (localUri) {
|
|
117
|
+
return localUri;
|
|
118
|
+
}
|
|
119
|
+
const vault = process.env.AZURE_KEY_VAULT_NAME || "";
|
|
120
|
+
const secretKey = this.tenantBridgeConfig.tenantBridgeSecretKey || AzureSecretKeysEnum.DB_CONNECTING_STRING_TENANT_BRIDGE;
|
|
121
|
+
const dbUrl = await getAzureVaultSecretByKey(this.context, vault, secretKey);
|
|
122
|
+
if (!dbUrl) {
|
|
123
|
+
throw new Error("TenantBridge database connection string not found");
|
|
124
|
+
}
|
|
125
|
+
return dbUrl;
|
|
126
|
+
}
|
|
127
|
+
async getDbConnectionEncryptionKey() {
|
|
128
|
+
var _secret$value;
|
|
129
|
+
if (this.dbConnectionEncryptionKey) {
|
|
130
|
+
return this.dbConnectionEncryptionKey;
|
|
131
|
+
}
|
|
132
|
+
const envKey = process.env.DB_CONNECTION_STRING_ENCRYPTION_KEY;
|
|
133
|
+
if (envKey) {
|
|
134
|
+
this.dbConnectionEncryptionKey = envKey;
|
|
135
|
+
return envKey;
|
|
136
|
+
}
|
|
137
|
+
const vault = process.env.AZURE_KEY_VAULT_NAME || "";
|
|
138
|
+
if (!vault) {
|
|
139
|
+
throw new Error("AZURE_KEY_VAULT_NAME is required to fetch encryption key");
|
|
140
|
+
}
|
|
141
|
+
const vaultUrl = `https://${vault}.vault.azure.net`;
|
|
142
|
+
const credential = new DefaultAzureCredential();
|
|
143
|
+
const client = new SecretClient(vaultUrl, credential);
|
|
144
|
+
const secret = await client.getSecret("DB-CONNECTION-STRING-ENCRYPTION-KEY");
|
|
145
|
+
const key = (_secret$value = secret.value) != null ? _secret$value : "";
|
|
146
|
+
if (!key) {
|
|
147
|
+
throw new Error("DB connection string encryption key not found");
|
|
148
|
+
}
|
|
149
|
+
this.dbConnectionEncryptionKey = key;
|
|
150
|
+
return key;
|
|
151
|
+
}
|
|
152
|
+
async decryptConnectionString(encryptedValue) {
|
|
153
|
+
const key = await this.getDbConnectionEncryptionKey();
|
|
154
|
+
const keyBuffer = this.normalizeEncryptionKey(key);
|
|
155
|
+
const ivBuffer = this.getEncryptionIv();
|
|
156
|
+
const decipher = crypto.createDecipheriv("aes-128-cbc", keyBuffer, ivBuffer);
|
|
157
|
+
let decrypted = decipher.update(encryptedValue, "base64", "utf8");
|
|
158
|
+
decrypted += decipher.final("utf8");
|
|
159
|
+
return decrypted;
|
|
160
|
+
}
|
|
161
|
+
normalizeEncryptionKey(key) {
|
|
162
|
+
const utf8Key = Buffer.from(key, "utf8");
|
|
163
|
+
if (utf8Key.length === 16) {
|
|
164
|
+
return utf8Key;
|
|
165
|
+
}
|
|
166
|
+
const base64Key = Buffer.from(key, "base64");
|
|
167
|
+
if (base64Key.length === 16) {
|
|
168
|
+
return base64Key;
|
|
169
|
+
}
|
|
170
|
+
const hexKey = Buffer.from(key, "hex");
|
|
171
|
+
if (hexKey.length === 16) {
|
|
172
|
+
return hexKey;
|
|
173
|
+
}
|
|
174
|
+
throw new Error(`DB connection string encryption key must be 16 bytes for aes-128-cbc (got ${utf8Key.length})`);
|
|
175
|
+
}
|
|
176
|
+
async getClientDbConnectionString(businessId, appId, serviceDBType) {
|
|
177
|
+
const resolvedServiceDbType = serviceDBType != null ? serviceDBType : "main";
|
|
178
|
+
const tenantBridgeUrl = await this.getTenantBridgeSrvDbConnectionString();
|
|
179
|
+
const connection = await this.getOrCreateCachedConnection(tenantBridgeUrl);
|
|
180
|
+
const ConfigMapping = this.getModel(connection, CONFIG_MAPPING_DOCUMENT_NAME, ConfigMappingModel.schema, CONFIG_MAPPING_COLLECTION_NAME);
|
|
181
|
+
const filter = {
|
|
182
|
+
businessId: this.toObjectId(businessId, "businessId")
|
|
183
|
+
};
|
|
184
|
+
if (appId) {
|
|
185
|
+
filter.appId = appId;
|
|
186
|
+
}
|
|
187
|
+
filter.serviceDBType = resolvedServiceDbType;
|
|
188
|
+
const configMapping = await ConfigMapping.findOne(filter).lean().exec();
|
|
189
|
+
if (!(configMapping != null && configMapping.connectionString)) {
|
|
190
|
+
throw new Error("Config mapping not found for this business");
|
|
191
|
+
}
|
|
192
|
+
const decryptedConnectionString = await this.decryptConnectionString(configMapping.connectionString);
|
|
193
|
+
this.context.info(`Resolved tenant DB connection string from bridge: ${decryptedConnectionString}`);
|
|
194
|
+
return decryptedConnectionString;
|
|
195
|
+
}
|
|
196
|
+
getConnection() {
|
|
197
|
+
if (!this.clientConnectionString) return undefined;
|
|
198
|
+
return MultiTenantRepository.connections.get(this.clientConnectionString);
|
|
199
|
+
}
|
|
200
|
+
async ensureClientConnection() {
|
|
201
|
+
if (this.connectionPromise) {
|
|
202
|
+
return this.connectionPromise;
|
|
203
|
+
}
|
|
204
|
+
if (this.clientConnectionString) {
|
|
205
|
+
const existing = this.getConnection();
|
|
206
|
+
if (existing && existing.connection.readyState === 1) {
|
|
207
|
+
return existing;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
const clientDbUrl = await this.getClientDbConnectionString(this.businessId, this.appId, this.serviceDBType);
|
|
211
|
+
this.clientConnectionString = clientDbUrl;
|
|
212
|
+
this.connectionPromise = this.getOrCreateCachedConnection(clientDbUrl);
|
|
213
|
+
return this.connectionPromise;
|
|
214
|
+
}
|
|
215
|
+
async disconnectByConnectionString(connectionString) {
|
|
216
|
+
const existing = MultiTenantRepository.connections.get(connectionString);
|
|
217
|
+
if (!existing) return;
|
|
218
|
+
try {
|
|
219
|
+
await existing.disconnect();
|
|
220
|
+
this.context.info(`✅ Disconnected from database: ${connectionString}`);
|
|
221
|
+
} catch (error) {
|
|
222
|
+
this.context.error(`❌ Error disconnecting from database: ${connectionString}`, error);
|
|
223
|
+
} finally {
|
|
224
|
+
MultiTenantRepository.connections.delete(connectionString);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
async disconnectClient() {
|
|
228
|
+
const clientDbUrl = await this.getClientDbConnectionString(this.businessId, this.appId);
|
|
229
|
+
await this.disconnectByConnectionString(clientDbUrl);
|
|
230
|
+
this.clientConnectionString = undefined;
|
|
231
|
+
this.connectionPromise = undefined;
|
|
232
|
+
}
|
|
233
|
+
getTenantModel(modelName, schema, collectionName) {
|
|
234
|
+
const connection = this.getConnection();
|
|
235
|
+
if (!connection) {
|
|
236
|
+
throw new Error("database connection not established");
|
|
237
|
+
}
|
|
238
|
+
return this.getModel(connection, modelName, schema, collectionName);
|
|
239
|
+
}
|
|
240
|
+
model(model, collectionName) {
|
|
241
|
+
return this.getTenantModel(model.modelName, model.schema, collectionName);
|
|
242
|
+
}
|
|
243
|
+
getModel(connection, modelName, schema, collectionName) {
|
|
244
|
+
if (connection.models[modelName]) {
|
|
245
|
+
return connection.models[modelName];
|
|
246
|
+
}
|
|
247
|
+
return connection.model(modelName, schema, collectionName);
|
|
248
|
+
}
|
|
249
|
+
}, _MultiTenantRepository.connections = new Map(), _MultiTenantRepository), _applyDecoratedDescriptor(_class.prototype, "getTenantBridgeSrvDbConnectionString", [_dec], Object.getOwnPropertyDescriptor(_class.prototype, "getTenantBridgeSrvDbConnectionString"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "getDbConnectionEncryptionKey", [_dec2], Object.getOwnPropertyDescriptor(_class.prototype, "getDbConnectionEncryptionKey"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "getClientDbConnectionString", [_dec3], Object.getOwnPropertyDescriptor(_class.prototype, "getClientDbConnectionString"), _class.prototype), _class);
|
|
250
|
+
export class TenantModelRepository extends MultiTenantRepository {
|
|
251
|
+
constructor(...args) {
|
|
252
|
+
super(...args);
|
|
253
|
+
this.modelDef = void 0;
|
|
254
|
+
}
|
|
255
|
+
get dbModel() {
|
|
256
|
+
return this.model(this.modelDef);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=multi-tenant.repository.js.map
|