@culturefy/shared 1.0.62 → 1.0.64
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/enums/secretKeys.enum.js +0 -1
- package/build/cjs/enums/secretKeys.enum.js.map +1 -1
- package/build/cjs/interfaces/user.js.map +1 -1
- package/build/cjs/middlewares/verify-middleware.js +83 -18
- package/build/cjs/middlewares/verify-middleware.js.map +1 -1
- package/build/cjs/repositories/multi-tenant.repository.js +24 -11
- package/build/cjs/repositories/multi-tenant.repository.js.map +1 -1
- package/build/cjs/repositories/tenant-base.repository.js +7 -1
- package/build/cjs/repositories/tenant-base.repository.js.map +1 -1
- package/build/cjs/utils/initializers.js +11 -5
- package/build/cjs/utils/initializers.js.map +1 -1
- package/build/esm/enums/secretKeys.enum.js +0 -1
- package/build/esm/enums/secretKeys.enum.js.map +1 -1
- package/build/esm/interfaces/user.js.map +1 -1
- package/build/esm/middlewares/verify-middleware.js +85 -20
- package/build/esm/middlewares/verify-middleware.js.map +1 -1
- package/build/esm/repositories/multi-tenant.repository.js +24 -11
- package/build/esm/repositories/multi-tenant.repository.js.map +1 -1
- package/build/esm/repositories/tenant-base.repository.js +7 -1
- package/build/esm/repositories/tenant-base.repository.js.map +1 -1
- package/build/esm/utils/initializers.js +11 -5
- package/build/esm/utils/initializers.js.map +1 -1
- package/build/src/enums/secretKeys.enum.d.ts +0 -1
- package/build/src/enums/secretKeys.enum.js +0 -1
- package/build/src/enums/secretKeys.enum.js.map +1 -1
- package/build/src/middlewares/verify-middleware.js +90 -36
- package/build/src/middlewares/verify-middleware.js.map +1 -1
- package/build/src/repositories/multi-tenant.repository.d.ts +1 -0
- package/build/src/repositories/multi-tenant.repository.js +24 -11
- package/build/src/repositories/multi-tenant.repository.js.map +1 -1
- package/build/src/repositories/tenant-base.repository.d.ts +1 -0
- package/build/src/repositories/tenant-base.repository.js +18 -0
- package/build/src/repositories/tenant-base.repository.js.map +1 -1
- package/build/src/utils/initializers.d.ts +1 -0
- package/build/src/utils/initializers.js +11 -5
- package/build/src/utils/initializers.js.map +1 -1
- package/package.json +1 -1
|
@@ -17,7 +17,6 @@ let AzureSecretKeysEnum = exports.AzureSecretKeysEnum = /*#__PURE__*/function (A
|
|
|
17
17
|
// in-use,
|
|
18
18
|
AzureSecretKeysEnum["DB_CONNECTING_STRING_AUTH"] = "DB-CONNECTION-STRING-AUTH";
|
|
19
19
|
AzureSecretKeysEnum["DB_CONNECTING_STRING_USER"] = "DB-CONNECTION-STRING-USER";
|
|
20
|
-
AzureSecretKeysEnum["DB_CONNECTING_STRING_TENANT_BRIDGE"] = "DB-Connecting-String-Tenant-Bridge";
|
|
21
20
|
AzureSecretKeysEnum["DB_CONNECTING_STRING_PAYMENT"] = "DB-CONNECTION-STRING-PAYMENT";
|
|
22
21
|
AzureSecretKeysEnum["DB_CONNECTING_STRING_CORE"] = "DB-CONNECTION-STRING-CORE";
|
|
23
22
|
AzureSecretKeysEnum["DB_CONNECTING_STRING_BILLING"] = "DB-CONNECTION-STRING-BILLING";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secretKeys.enum.js","names":["AzureSecretKeysEnum","exports"],"sources":["../../../src/enums/secretKeys.enum.ts"],"sourcesContent":["// Enum for secret keys\nexport enum AzureSecretKeysEnum {\n KEYCLOAK_ADMIN_CLIENT_SECRET = \"KEYCLOAK-ADMIN-CLIENT-SECRET\",\n KEYCLOAK_ADMIN_CLIENT_ID = \"KEYCLOAK-ADMIN-CLIENT-ID\",\n KEYCLOAK_BASE_URL = \"KEYCLOAK-BASE-URL\",\n STRIPE_PAYMENT_WEBHOOK_SECRET_KEY = \"Stripe-payment-webhook-secret-key\", // in-use\n STRIPE_PRODUCT_WEBHOOK_SECRET = \"Stripe-product-webhook-secret-key\", // in-use\n STRIPE_PRICE_WEBHOOK_SECRET = \"Stripe-price-webhook-secret-key\", // in-use\n EMAIL_SERVICE_URL = \"Email-Service-Url\", // in-use,\n DB_CONNECTING_STRING_AUTH = \"DB-CONNECTION-STRING-AUTH\",\n DB_CONNECTING_STRING_USER = \"DB-CONNECTION-STRING-USER\",\n
|
|
1
|
+
{"version":3,"file":"secretKeys.enum.js","names":["AzureSecretKeysEnum","exports"],"sources":["../../../src/enums/secretKeys.enum.ts"],"sourcesContent":["// Enum for secret keys\nexport enum AzureSecretKeysEnum {\n KEYCLOAK_ADMIN_CLIENT_SECRET = \"KEYCLOAK-ADMIN-CLIENT-SECRET\",\n KEYCLOAK_ADMIN_CLIENT_ID = \"KEYCLOAK-ADMIN-CLIENT-ID\",\n KEYCLOAK_BASE_URL = \"KEYCLOAK-BASE-URL\",\n STRIPE_PAYMENT_WEBHOOK_SECRET_KEY = \"Stripe-payment-webhook-secret-key\", // in-use\n STRIPE_PRODUCT_WEBHOOK_SECRET = \"Stripe-product-webhook-secret-key\", // in-use\n STRIPE_PRICE_WEBHOOK_SECRET = \"Stripe-price-webhook-secret-key\", // in-use\n EMAIL_SERVICE_URL = \"Email-Service-Url\", // in-use,\n DB_CONNECTING_STRING_AUTH = \"DB-CONNECTION-STRING-AUTH\",\n DB_CONNECTING_STRING_USER = \"DB-CONNECTION-STRING-USER\",\n DB_CONNECTING_STRING_PAYMENT = \"DB-CONNECTION-STRING-PAYMENT\",\n DB_CONNECTING_STRING_CORE = \"DB-CONNECTION-STRING-CORE\",\n DB_CONNECTING_STRING_BILLING = \"DB-CONNECTION-STRING-BILLING\",\n DB_CONNECTING_STRING_STAGING = \"DB-CONNECTION-STRING-STAGING\",\n DB_CONNECTING_STRING_BNT_DEV = \"DB-CONNECTION-STRING-BNT-DEV\",\n DB_CONNECTION_STRING_TENANT_BRIDGE = \"DB-CONNECTION-STRING-TENANT-BRIDGE\",\n SERVICE_BUS_CONNECTION_STRING = \"servicebus-connection-string\",\n STRIPE_CUSTOMER_SYNC_WEBHOOK_SECRET = \"stripe-customer-sync-webhook-secret-key\",\n STRIPE_INVOICE_SYNC_WEBHOOK_SECRET = \"stripe-invoice-sync-webhook-secret-key\",\n STRIPE_PRODUCT_SYNC_WEBHOOK_SECRET = \"stripe-product-sync-webhook-secret-key\",\n STRIPE_PRICE_SYNC_WEBHOOK_SECRET = \"stripe-price-sync-webhook-secret-key\",\n STRIPE_SECRET_KEY = \"Stripe-secret-key\",\n STRIPE_WEBHOOK_CUSTOMER_CREATED_SECRET_KEY = \"Stripe-Webhook-Customer-Created-Secret-Key\",\n STRIPE_SUBSCRIPTION_SYNC_WEBHOOK_SECRET = \"stripe-subscription-sync-webhook-secret-key\",\n FIREBASE_SERVICE_ACCOUNTS_VARIABLE = \"firebase_service_accounts_variable\",\n HMS_ACCESS_KEY=\"MEETING-HMS-ACCESS-KEY-APP-SECRET\",\n MEETING_ROOM_APP_SECRET=\"MEETING-ROOM-APP-SECRET\",\n BASE_DB_CLUSTER_CONNECTING_STRING_CHAT = \"BASE-DB-CLUSTER-CONNECTING-STRING-CHAT\",\n AUTH_SERVICE_AUTHENTICATION_URL = \"AUTH-SERVICE-AUTHENTICATION-URL\",\n GCP_PROJECT_ID=\"gcp-project-id\",\n PUBSUB_SERVICE_ACCOUNT_KEYS=\"pubsub-service-account-keys\",\n VAPI_TOKEN = \"vapi-token\",\n GITHUB_TOKEN = \"GITHUB-TOKEN\",\n GITHUB_WORKFLOW_URL = \"GITHUB-WORKFLOW-URL\",\n DB_CONNECTION_STRING_ENCRYPTION_KEY = \"DB-CONNECTION-STRING-ENCRYPTION-KEY\",\n}\n\n// AUTH-SERVICE-AUTHENTICATION-URL\n// https://culturefy-auth-staging.azurewebsites.net/api/verify\n\n// REFRESH-SESSION-URL"],"mappings":";;;;AAAA;AAAA,IACYA,mBAAmB,GAAAC,OAAA,CAAAD,mBAAA,0BAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAI4C;EAJ/DA,mBAAmB;EAKwC;EAL3DA,mBAAmB;EAMoC;EANvDA,mBAAmB;EAOY;EAP/BA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAA,OAAnBA,mBAAmB;AAAA,OAqC/B;AACA;AAEA","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.js","names":[],"sources":["../../../src/interfaces/user.ts"],"sourcesContent":["export interface ICreateUser {\n userId: string;\n email: string;\n businessId: string;\n}"],"mappings":"","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"user.js","names":[],"sources":["../../../src/interfaces/user.ts"],"sourcesContent":["export interface ICreateUser {\n userId: string;\n email: string;\n businessId: string;\n}\n"],"mappings":"","ignoreList":[]}
|
|
@@ -20,6 +20,7 @@ function pickCookieDomain(appConfig, origin, requestUrl) {
|
|
|
20
20
|
var _appConfig$cookie$dom;
|
|
21
21
|
return (_appConfig$cookie$dom = appConfig.cookie.domain.local) != null ? _appConfig$cookie$dom : undefined;
|
|
22
22
|
}
|
|
23
|
+
// culturefy.app domains
|
|
23
24
|
if (host.endsWith(".dev.culturefy.app") || host === "dev.culturefy.app") {
|
|
24
25
|
return appConfig.cookie.domain.dev;
|
|
25
26
|
}
|
|
@@ -29,6 +30,16 @@ function pickCookieDomain(appConfig, origin, requestUrl) {
|
|
|
29
30
|
if (host.endsWith(".culturefy.app")) {
|
|
30
31
|
return appConfig.cookie.domain.prod;
|
|
31
32
|
}
|
|
33
|
+
// consultex.app domains
|
|
34
|
+
if (host.endsWith(".dev.consultex.app") || host === "dev.consultex.app") {
|
|
35
|
+
return appConfig.cookie.domain.dev;
|
|
36
|
+
}
|
|
37
|
+
if (host.endsWith(".staging.consultex.app") || host === "staging.consultex.app") {
|
|
38
|
+
return appConfig.cookie.domain.staging;
|
|
39
|
+
}
|
|
40
|
+
if (host.endsWith(".consultex.app")) {
|
|
41
|
+
return appConfig.cookie.domain.prod;
|
|
42
|
+
}
|
|
32
43
|
} catch {
|
|
33
44
|
return undefined;
|
|
34
45
|
}
|
|
@@ -44,8 +55,24 @@ const parseCookieHeader = header => {
|
|
|
44
55
|
}
|
|
45
56
|
return out;
|
|
46
57
|
};
|
|
58
|
+
function isLocalRequest(origin, requestUrl) {
|
|
59
|
+
const hostCandidate = origin != null ? origin : requestUrl;
|
|
60
|
+
if (!hostCandidate) return false;
|
|
61
|
+
try {
|
|
62
|
+
const host = new URL(hostCandidate).hostname;
|
|
63
|
+
return host === "localhost" || host.startsWith("127.0.0.1");
|
|
64
|
+
} catch {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function getSessionMappingCookieName(appId, origin, requestUrl) {
|
|
69
|
+
if (isLocalRequest(origin, requestUrl)) {
|
|
70
|
+
return `session-v1.${appId}.mapping`;
|
|
71
|
+
}
|
|
72
|
+
return `__Secure-session-v1.${appId}.mapping`;
|
|
73
|
+
}
|
|
47
74
|
const verifyMw = async (req, ctx, next) => {
|
|
48
|
-
var _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$
|
|
75
|
+
var _APP_MAP$appId, _req$headers$get, _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$to, _p$resource_access, _p$realm_access;
|
|
49
76
|
const appId = req.headers.get("app-id");
|
|
50
77
|
if (!appId || !(_constants.APP_MAP != null && (_APP_MAP$appId = _constants.APP_MAP[appId]) != null && _APP_MAP$appId.clientId)) {
|
|
51
78
|
return {
|
|
@@ -62,11 +89,12 @@ const verifyMw = async (req, ctx, next) => {
|
|
|
62
89
|
})
|
|
63
90
|
};
|
|
64
91
|
}
|
|
65
|
-
const
|
|
92
|
+
const clientId = _constants.APP_MAP[appId].clientId;
|
|
66
93
|
|
|
67
94
|
// cookies
|
|
68
95
|
const cookies = parseCookieHeader(req.headers.get("cookie"));
|
|
69
|
-
|
|
96
|
+
const requestOrigin = (_req$headers$get = req.headers.get("origin")) != null ? _req$headers$get : undefined;
|
|
97
|
+
let mapping = cookies[getSessionMappingCookieName(appId, requestOrigin, req.url)] || cookies[`__Secure-session-v1.${appId}.mapping`] || cookies[`session-v1.${appId}.mapping`] || req.headers.get("x-session-mapping") || req.headers.get("x-token-mapping");
|
|
70
98
|
if (!mapping) {
|
|
71
99
|
return {
|
|
72
100
|
status: 401,
|
|
@@ -155,7 +183,22 @@ const verifyMw = async (req, ctx, next) => {
|
|
|
155
183
|
};
|
|
156
184
|
}
|
|
157
185
|
const realm = tokenMapping.realmId;
|
|
158
|
-
const
|
|
186
|
+
const tokenClientId = tokenMapping.clientId;
|
|
187
|
+
if (!tokenClientId || tokenClientId !== clientId) {
|
|
188
|
+
return {
|
|
189
|
+
status: 403,
|
|
190
|
+
headers: {
|
|
191
|
+
"Content-Type": "application/json",
|
|
192
|
+
"Cache-Control": "no-store, no-cache, must-revalidate",
|
|
193
|
+
"Pragma": "no-cache",
|
|
194
|
+
"Vary": "Origin"
|
|
195
|
+
},
|
|
196
|
+
body: JSON.stringify({
|
|
197
|
+
status: "forbidden",
|
|
198
|
+
reason: "client_mismatch"
|
|
199
|
+
})
|
|
200
|
+
};
|
|
201
|
+
}
|
|
159
202
|
|
|
160
203
|
// decode/verify (lightweight; replace with your verifyJsonWebToken if you have it)
|
|
161
204
|
let p;
|
|
@@ -195,11 +238,11 @@ const verifyMw = async (req, ctx, next) => {
|
|
|
195
238
|
// Refresh only when expired
|
|
196
239
|
if (typeof p.exp === "number" && p.exp <= now) {
|
|
197
240
|
// Delegate to refresh helper; it will handle setting cookies/state or returning an error
|
|
198
|
-
return await getNewRefreshToken(req, ctx, appId, realm,
|
|
241
|
+
return await getNewRefreshToken(req, ctx, appId, realm, tokenClientId, rt, mapping, p, next);
|
|
199
242
|
}
|
|
200
243
|
|
|
201
244
|
// audience checks
|
|
202
|
-
const audOk = Array.isArray(p.aud) && p.aud.includes(
|
|
245
|
+
const audOk = Array.isArray(p.aud) && p.aud.includes(tokenClientId) || typeof p.aud === "string" && (p.aud === tokenClientId || p.aud === "account") || p.azp === tokenClientId;
|
|
203
246
|
if (!audOk) {
|
|
204
247
|
return {
|
|
205
248
|
status: 403,
|
|
@@ -227,7 +270,7 @@ const verifyMw = async (req, ctx, next) => {
|
|
|
227
270
|
tenantId,
|
|
228
271
|
email: (_ref5 = (_p$email = p.email) != null ? _p$email : p.preferred_username) != null ? _ref5 : null,
|
|
229
272
|
name: (_p$name = p.name) != null ? _p$name : undefined,
|
|
230
|
-
roles: (_ref6 = (_p$resource_access$
|
|
273
|
+
roles: (_ref6 = (_p$resource_access$to = (_p$resource_access = p.resource_access) == null || (_p$resource_access = _p$resource_access[tokenClientId]) == null ? void 0 : _p$resource_access.roles) != null ? _p$resource_access$to : (_p$realm_access = p.realm_access) == null ? void 0 : _p$realm_access.roles) != null ? _ref6 : [],
|
|
231
274
|
exp: p.exp
|
|
232
275
|
};
|
|
233
276
|
return next();
|
|
@@ -250,15 +293,31 @@ async function getNewRefreshToken(req, ctx, appId, realmId, clientId, rt, mappin
|
|
|
250
293
|
})
|
|
251
294
|
};
|
|
252
295
|
}
|
|
253
|
-
ctx.info("
|
|
296
|
+
ctx.info("Refreshing session token", {
|
|
254
297
|
realmId,
|
|
255
|
-
clientId
|
|
256
|
-
rt
|
|
298
|
+
clientId
|
|
257
299
|
});
|
|
258
300
|
|
|
259
301
|
// Call auth service to refresh
|
|
260
302
|
try {
|
|
261
|
-
var _req$headers$
|
|
303
|
+
var _req$headers$get2, _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;
|
|
304
|
+
if (!apiURL) {
|
|
305
|
+
ctx.error == null || ctx.error("Refresh session URL is not configured");
|
|
306
|
+
return {
|
|
307
|
+
status: 401,
|
|
308
|
+
headers: {
|
|
309
|
+
"Content-Type": "application/json",
|
|
310
|
+
"Cache-Control": "no-store, no-cache, must-revalidate",
|
|
311
|
+
"Pragma": "no-cache",
|
|
312
|
+
"Vary": "Origin"
|
|
313
|
+
},
|
|
314
|
+
body: JSON.stringify({
|
|
315
|
+
status: "unauthenticated",
|
|
316
|
+
reason: "refresh_not_configured"
|
|
317
|
+
})
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
const requestOrigin = (_req$headers$get2 = req.headers.get("origin")) != null ? _req$headers$get2 : undefined;
|
|
262
321
|
const resp = await fetch(apiURL, {
|
|
263
322
|
method: "POST",
|
|
264
323
|
headers: {
|
|
@@ -271,8 +330,7 @@ async function getNewRefreshToken(req, ctx, appId, realmId, clientId, rt, mappin
|
|
|
271
330
|
})
|
|
272
331
|
});
|
|
273
332
|
if (!resp.ok) {
|
|
274
|
-
|
|
275
|
-
ctx.warn == null || ctx.warn(`refresh call failed: ${resp.status} ${text}`);
|
|
333
|
+
ctx.warn == null || ctx.warn(`refresh call failed with status ${resp.status}`);
|
|
276
334
|
return {
|
|
277
335
|
status: 401,
|
|
278
336
|
headers: {
|
|
@@ -338,12 +396,15 @@ async function getNewRefreshToken(req, ctx, appId, realmId, clientId, rt, mappin
|
|
|
338
396
|
|
|
339
397
|
const mappingCookieValue = Buffer.from(mapping).toString("base64");
|
|
340
398
|
const appConfig = _constants.APP_MAP[appId];
|
|
341
|
-
|
|
342
|
-
|
|
399
|
+
|
|
400
|
+
// 5
|
|
401
|
+
const mappedDomain = pickCookieDomain(appConfig, requestOrigin, req.url);
|
|
402
|
+
const localRequest = isLocalRequest(requestOrigin, req.url);
|
|
403
|
+
(0, _cookies.setCookieKV)(ctx, getSessionMappingCookieName(appId, requestOrigin, req.url), mappingCookieValue, {
|
|
343
404
|
// mapping must be readable by FE in your flow; keep httpOnly default if you prefer server-only
|
|
344
405
|
httpOnly: false,
|
|
345
|
-
secure:
|
|
346
|
-
sameSite: "None",
|
|
406
|
+
secure: !localRequest,
|
|
407
|
+
sameSite: localRequest ? "Lax" : "None",
|
|
347
408
|
maxAge: mappingMaxAge,
|
|
348
409
|
domain: mappedDomain
|
|
349
410
|
});
|
|
@@ -402,7 +463,11 @@ async function getNewRefreshToken(req, ctx, appId, realmId, clientId, rt, mappin
|
|
|
402
463
|
// Continue pipeline after refresh
|
|
403
464
|
return next();
|
|
404
465
|
} catch (e) {
|
|
405
|
-
ctx.error == null || ctx.error("refresh exception",
|
|
466
|
+
ctx.error == null || ctx.error("refresh exception", {
|
|
467
|
+
message: e == null ? void 0 : e.message,
|
|
468
|
+
name: e == null ? void 0 : e.name,
|
|
469
|
+
code: e == null ? void 0 : e.code
|
|
470
|
+
});
|
|
406
471
|
return {
|
|
407
472
|
status: 401,
|
|
408
473
|
headers: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify-middleware.js","names":["_constants","require","_jwtDecode","_enums","_cookies","_utils","_tokenMapping","apiURL","process","env","REFRESH_SESSION_URL","verifyMappingCache","createCache","pickCookieDomain","appConfig","origin","requestUrl","undefined","hostCandidate","host","URL","hostname","startsWith","_appConfig$cookie$dom","cookie","domain","local","endsWith","dev","staging","prod","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","APP_MAP","clientId","status","body","JSON","stringify","reason","expectedClientId","cookies","mapping","base64Decode","dbUrl","getAzureVaultSecretByKey","AZURE_KEY_VAULT_NAME","AzureSecretKeysEnum","DB_CONNECTING_STRING_USER","tokenMappingService","TokenMappingService","tokenMappingRaw","getOrSet","fetched","getTokenMappingById","tokenMapping","parse","at","accessToken","rt","refreshToken","realm","realmId","p","jwtDecode","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","roles","resource_access","realm_access","exports","info","_req$headers$get","_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","delete","mappingMaxAge","refresh_expires_in","mappingCookieValue","Buffer","from","mappedDomain","url","setCookieKV","httpOnly","secure","sameSite","maxAge","p2","audOk2","tenantId2","e","error","value","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\nfunction pickCookieDomain(appConfig: (typeof APP_MAP)[IAppId] | undefined, origin?: string, requestUrl?: string): string | undefined {\n if (!appConfig) return undefined;\n const hostCandidate = origin ?? requestUrl;\n if (!hostCandidate) return undefined;\n try {\n const host = new URL(hostCandidate).hostname;\n if (host === \"localhost\" || host.startsWith(\"127.0.0.1\")) {\n return appConfig.cookie.domain.local ?? undefined;\n }\n if (host.endsWith(\".dev.culturefy.app\") || host === \"dev.culturefy.app\") {\n return appConfig.cookie.domain.dev;\n }\n if (host.endsWith(\".staging.culturefy.app\") || host === \"staging.culturefy.app\") {\n return appConfig.cookie.domain.staging;\n }\n if (host.endsWith(\".culturefy.app\")) {\n return appConfig.cookie.domain.prod;\n }\n } catch {\n return undefined;\n }\n return undefined;\n}\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 // Invalidate cache to ensure next request gets fresh tokens\n await verifyMappingCache.delete(ctx, mapping);\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 const mappingCookieValue = Buffer.from(mapping).toString(\"base64\");\n const appConfig = APP_MAP[appId];\n const mappedDomain = pickCookieDomain(appConfig, req.headers.get(\"origin\") ?? undefined, req.url);\n \n setCookieKV(ctx, `__Secure-session-v1.${appId}.mapping`, mappingCookieValue, {\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 domain: mappedDomain\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":[]}
|
|
1
|
+
{"version":3,"file":"verify-middleware.js","names":["_constants","require","_jwtDecode","_enums","_cookies","_utils","_tokenMapping","apiURL","process","env","REFRESH_SESSION_URL","verifyMappingCache","createCache","pickCookieDomain","appConfig","origin","requestUrl","undefined","hostCandidate","host","URL","hostname","startsWith","_appConfig$cookie$dom","cookie","domain","local","endsWith","dev","staging","prod","parseCookieHeader","header","out","part","split","k","rest","trim","decodeURIComponent","join","isLocalRequest","getSessionMappingCookieName","appId","verifyMw","req","ctx","next","_APP_MAP$appId","_req$headers$get","_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$to","_p$resource_access","_p$realm_access","headers","get","APP_MAP","clientId","status","body","JSON","stringify","reason","cookies","requestOrigin","mapping","url","base64Decode","dbUrl","getAzureVaultSecretByKey","AZURE_KEY_VAULT_NAME","AzureSecretKeysEnum","DB_CONNECTING_STRING_USER","tokenMappingService","TokenMappingService","tokenMappingRaw","getOrSet","fetched","getTokenMappingById","tokenMapping","parse","at","accessToken","rt","refreshToken","realm","realmId","tokenClientId","p","jwtDecode","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","roles","resource_access","realm_access","exports","info","_req$headers$get2","_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","error","resp","fetch","method","refresh_token","ok","warn","payload","json","data","newAT","access_token","newRT","updatedMapping","updateTokenMapping","expiresAt","expires_in","delete","mappingMaxAge","refresh_expires_in","mappingCookieValue","Buffer","from","mappedDomain","localRequest","setCookieKV","httpOnly","secure","sameSite","maxAge","p2","audOk2","tenantId2","e","message","code","value","console","log"],"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\nfunction pickCookieDomain(appConfig: (typeof APP_MAP)[IAppId] | undefined, origin?: string, requestUrl?: string): string | undefined {\n if (!appConfig) return undefined;\n const hostCandidate = origin ?? requestUrl;\n if (!hostCandidate) return undefined;\n try {\n const host = new URL(hostCandidate).hostname;\n if (host === \"localhost\" || host.startsWith(\"127.0.0.1\")) {\n return appConfig.cookie.domain.local ?? undefined;\n }\n // culturefy.app domains\n if (host.endsWith(\".dev.culturefy.app\") || host === \"dev.culturefy.app\") {\n return appConfig.cookie.domain.dev;\n }\n if (host.endsWith(\".staging.culturefy.app\") || host === \"staging.culturefy.app\") {\n return appConfig.cookie.domain.staging;\n }\n if (host.endsWith(\".culturefy.app\")) {\n return appConfig.cookie.domain.prod;\n }\n // consultex.app domains\n if (host.endsWith(\".dev.consultex.app\") || host === \"dev.consultex.app\") {\n return appConfig.cookie.domain.dev;\n }\n if (host.endsWith(\".staging.consultex.app\") || host === \"staging.consultex.app\") {\n return appConfig.cookie.domain.staging;\n }\n if (host.endsWith(\".consultex.app\")) {\n return appConfig.cookie.domain.prod;\n }\n } catch {\n return undefined;\n }\n return undefined;\n}\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\nfunction isLocalRequest(origin?: string, requestUrl?: string): boolean {\n const hostCandidate = origin ?? requestUrl;\n if (!hostCandidate) return false;\n try {\n const host = new URL(hostCandidate).hostname;\n return host === \"localhost\" || host.startsWith(\"127.0.0.1\");\n } catch {\n return false;\n }\n}\n\nfunction getSessionMappingCookieName(appId: IAppId, origin?: string, requestUrl?: string): string {\n if (isLocalRequest(origin, requestUrl)) {\n return `session-v1.${appId}.mapping`;\n }\n return `__Secure-session-v1.${appId}.mapping`;\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 clientId = APP_MAP[appId].clientId;\n\n // cookies\n const cookies = parseCookieHeader(req.headers.get(\"cookie\"));\n const requestOrigin = req.headers.get(\"origin\") ?? undefined;\n\n let mapping: string | null =\n cookies[getSessionMappingCookieName(appId, requestOrigin, req.url)] ||\n cookies[`__Secure-session-v1.${appId}.mapping`] ||\n cookies[`session-v1.${appId}.mapping`] ||\n req.headers.get(\"x-session-mapping\") ||\n req.headers.get(\"x-token-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 tokenClientId = tokenMapping.clientId;\n\n if (!tokenClientId || tokenClientId !== clientId) {\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: \"client_mismatch\" })\n };\n }\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, tokenClientId, rt, mapping, p, next);\n }\n\n // audience checks\n const audOk =\n (Array.isArray(p.aud) && p.aud.includes(tokenClientId)) ||\n (typeof p.aud === \"string\" && (p.aud === tokenClientId || p.aud === \"account\")) ||\n p.azp === tokenClientId;\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?.[tokenClientId]?.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 session token\", {\n realmId,\n clientId,\n });\n\n // Call auth service to refresh\n try {\n if (!apiURL) {\n ctx.error?.(\"Refresh session URL is not configured\");\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_not_configured\" })\n };\n }\n const requestOrigin = req.headers.get(\"origin\") ?? undefined;\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 ctx.warn?.(`refresh call failed with status ${resp.status}`);\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,\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 // Invalidate cache to ensure next request gets fresh tokens\n await verifyMappingCache.delete(ctx, mapping);\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 const mappingCookieValue = Buffer.from(mapping).toString(\"base64\");\n const appConfig = APP_MAP[appId];\n\n // 5\n const mappedDomain = pickCookieDomain(appConfig, requestOrigin, req.url);\n const localRequest = isLocalRequest(requestOrigin, req.url);\n\n setCookieKV(ctx, getSessionMappingCookieName(appId, requestOrigin, req.url), mappingCookieValue, {\n // mapping must be readable by FE in your flow; keep httpOnly default if you prefer server-only\n httpOnly: false,\n secure: !localRequest,\n sameSite: localRequest ? \"Lax\" : \"None\",\n maxAge: mappingMaxAge,\n domain: mappedDomain\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: any) {\n ctx.error?.(\"refresh exception\", {\n message: e?.message,\n name: e?.name,\n code: e?.code,\n });\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}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -57,11 +57,22 @@ let MultiTenantRepository = exports.MultiTenantRepository = (_dec = (0, _cache.C
|
|
|
57
57
|
this.serviceDBType = serviceDBType != null ? serviceDBType : "main";
|
|
58
58
|
this.tenantBridgeConfig = {
|
|
59
59
|
tenantBridgeEnvKey: "TENANT_BRIDGE_DB_URI",
|
|
60
|
-
tenantBridgeSecretKey: _enums.AzureSecretKeysEnum.
|
|
60
|
+
tenantBridgeSecretKey: _enums.AzureSecretKeysEnum.DB_CONNECTION_STRING_TENANT_BRIDGE,
|
|
61
61
|
...config
|
|
62
62
|
};
|
|
63
63
|
this.connectionPromise = this.ensureClientConnection();
|
|
64
64
|
}
|
|
65
|
+
getConnectionLogLabel(connectionString) {
|
|
66
|
+
const match = connectionString.match(/\/([^/?]+)(\?|$)/);
|
|
67
|
+
const dbName = (match == null ? void 0 : match[1]) || "unknown";
|
|
68
|
+
if (dbName.toLowerCase().includes("tenantbridge")) {
|
|
69
|
+
return "TenantBridge-DB";
|
|
70
|
+
}
|
|
71
|
+
if (dbName.toLowerCase().includes("user")) {
|
|
72
|
+
return "Auth-DB";
|
|
73
|
+
}
|
|
74
|
+
return `${dbName}-DB`;
|
|
75
|
+
}
|
|
65
76
|
getEncryptionIv() {
|
|
66
77
|
const iv = process.env.DB_CONNECTION_STRING_ENCRYPTION_IV;
|
|
67
78
|
if (!iv) {
|
|
@@ -89,7 +100,8 @@ let MultiTenantRepository = exports.MultiTenantRepository = (_dec = (0, _cache.C
|
|
|
89
100
|
if (existing && existing.connection.readyState === 1) {
|
|
90
101
|
return existing;
|
|
91
102
|
}
|
|
92
|
-
this.
|
|
103
|
+
const dbLabel = this.getConnectionLogLabel(connectionString);
|
|
104
|
+
this.context.info(`Initializing database connection (${dbLabel})...`);
|
|
93
105
|
const instance = new _mongoose.default.Mongoose();
|
|
94
106
|
try {
|
|
95
107
|
await instance.connect(connectionString, {
|
|
@@ -97,11 +109,11 @@ let MultiTenantRepository = exports.MultiTenantRepository = (_dec = (0, _cache.C
|
|
|
97
109
|
connectTimeoutMS: 10000,
|
|
98
110
|
socketTimeoutMS: 45000
|
|
99
111
|
});
|
|
100
|
-
this.context.info(`✅ MongoDB connected successfully ${
|
|
112
|
+
this.context.info(`✅ MongoDB connected successfully (${dbLabel})`);
|
|
101
113
|
MultiTenantRepository.connections.set(connectionString, instance);
|
|
102
114
|
return instance;
|
|
103
115
|
} catch (err) {
|
|
104
|
-
this.context.error(`❌ MongoDB connection error for ${
|
|
116
|
+
this.context.error(`❌ MongoDB connection error for (${dbLabel})`, {
|
|
105
117
|
message: err.message,
|
|
106
118
|
name: err.name,
|
|
107
119
|
code: err.code,
|
|
@@ -123,7 +135,7 @@ let MultiTenantRepository = exports.MultiTenantRepository = (_dec = (0, _cache.C
|
|
|
123
135
|
return localUri;
|
|
124
136
|
}
|
|
125
137
|
const vault = process.env.AZURE_KEY_VAULT_NAME || "";
|
|
126
|
-
const secretKey = this.tenantBridgeConfig.tenantBridgeSecretKey || _enums.AzureSecretKeysEnum.
|
|
138
|
+
const secretKey = this.tenantBridgeConfig.tenantBridgeSecretKey || _enums.AzureSecretKeysEnum.DB_CONNECTION_STRING_TENANT_BRIDGE;
|
|
127
139
|
const dbUrl = await (0, _secrets.getAzureVaultSecretByKey)(this.context, vault, secretKey);
|
|
128
140
|
if (!dbUrl) {
|
|
129
141
|
throw new Error("TenantBridge database connection string not found");
|
|
@@ -180,6 +192,9 @@ let MultiTenantRepository = exports.MultiTenantRepository = (_dec = (0, _cache.C
|
|
|
180
192
|
throw new Error(`DB connection string encryption key must be 16 bytes for aes-128-cbc (got ${utf8Key.length})`);
|
|
181
193
|
}
|
|
182
194
|
async getClientDbConnectionString(businessId, appId, serviceDBType) {
|
|
195
|
+
if (!appId) {
|
|
196
|
+
throw new Error("appId is required to resolve tenant client database");
|
|
197
|
+
}
|
|
183
198
|
const resolvedServiceDbType = serviceDBType != null ? serviceDBType : "main";
|
|
184
199
|
const tenantBridgeUrl = await this.getTenantBridgeSrvDbConnectionString();
|
|
185
200
|
const connection = await this.getOrCreateCachedConnection(tenantBridgeUrl);
|
|
@@ -187,16 +202,14 @@ let MultiTenantRepository = exports.MultiTenantRepository = (_dec = (0, _cache.C
|
|
|
187
202
|
const filter = {
|
|
188
203
|
businessId: this.toObjectId(businessId, "businessId")
|
|
189
204
|
};
|
|
190
|
-
|
|
191
|
-
filter.appId = appId;
|
|
192
|
-
}
|
|
205
|
+
filter.appId = appId;
|
|
193
206
|
filter.serviceDBType = resolvedServiceDbType;
|
|
194
207
|
const configMapping = await ConfigMapping.findOne(filter).lean().exec();
|
|
195
208
|
if (!(configMapping != null && configMapping.connectionString)) {
|
|
196
209
|
throw new Error("Config mapping not found for this business");
|
|
197
210
|
}
|
|
198
211
|
const decryptedConnectionString = await this.decryptConnectionString(configMapping.connectionString);
|
|
199
|
-
this.context.info(
|
|
212
|
+
this.context.info("Resolved tenant database mapping from TenantBridge");
|
|
200
213
|
return decryptedConnectionString;
|
|
201
214
|
}
|
|
202
215
|
getConnection() {
|
|
@@ -223,9 +236,9 @@ let MultiTenantRepository = exports.MultiTenantRepository = (_dec = (0, _cache.C
|
|
|
223
236
|
if (!existing) return;
|
|
224
237
|
try {
|
|
225
238
|
await existing.disconnect();
|
|
226
|
-
this.context.info(`✅ Disconnected from database
|
|
239
|
+
this.context.info(`✅ Disconnected from database (${this.getConnectionLogLabel(connectionString)})`);
|
|
227
240
|
} catch (error) {
|
|
228
|
-
this.context.error(`❌ Error disconnecting from database
|
|
241
|
+
this.context.error(`❌ Error disconnecting from database (${this.getConnectionLogLabel(connectionString)})`, error);
|
|
229
242
|
} finally {
|
|
230
243
|
MultiTenantRepository.connections.delete(connectionString);
|
|
231
244
|
}
|