@culturefy/shared 1.0.76 → 1.0.77
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/middlewares/withPermissionsMw.js +73 -0
- package/build/cjs/middlewares/withPermissionsMw.js.map +1 -0
- package/build/cjs/service/tokenMapping.service.js +3 -3
- package/build/cjs/service/tokenMapping.service.js.map +1 -1
- package/build/cjs/service/user.service.js +2 -2
- package/build/cjs/service/user.service.js.map +1 -1
- package/build/cjs/utils/cache.js +4 -1
- package/build/cjs/utils/cache.js.map +1 -1
- package/build/cjs/utils/secrets.js +89 -19
- package/build/cjs/utils/secrets.js.map +1 -1
- package/build/esm/middlewares/withPermissionsMw.js +68 -0
- package/build/esm/middlewares/withPermissionsMw.js.map +1 -0
- package/build/esm/service/tokenMapping.service.js +1 -1
- package/build/esm/service/tokenMapping.service.js.map +1 -1
- package/build/esm/service/user.service.js +1 -1
- package/build/esm/service/user.service.js.map +1 -1
- package/build/esm/utils/cache.js +5 -2
- package/build/esm/utils/cache.js.map +1 -1
- package/build/esm/utils/secrets.js +88 -19
- package/build/esm/utils/secrets.js.map +1 -1
- package/build/src/schema/location.model.d.ts +1 -1
- package/build/src/service/tokenMapping.service.d.ts +1 -1
- package/build/src/service/tokenMapping.service.js +9 -9
- package/build/src/service/tokenMapping.service.js.map +1 -1
- package/build/src/service/user.service.d.ts +1 -1
- package/build/src/service/user.service.js +2 -2
- package/build/src/service/user.service.js.map +1 -1
- package/build/src/types/location.d.ts +1 -1
- package/build/src/utils/cache.js +5 -1
- package/build/src/utils/cache.js.map +1 -1
- package/build/src/utils/secrets.d.ts +12 -4
- package/build/src/utils/secrets.js +91 -18
- package/build/src/utils/secrets.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.withPermissionsMw = void 0;
|
|
5
|
+
const USER_WITH_PERMISSIONS_PATH = "/v1/user/user-with-permissions";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Fetches current user permissions (roleId.features) from shared-user GET user-with-permissions.
|
|
9
|
+
* Sets state.auth.features and optional state.auth.industry from user.business.
|
|
10
|
+
* Run after verifyMw. Same behaviour as former modules/shared_goals middleware.
|
|
11
|
+
*/
|
|
12
|
+
const withPermissionsMw = async (req, ctx, next) => {
|
|
13
|
+
var _req$headers$get, _req$headers$get2, _ref2, _req$headers$get3;
|
|
14
|
+
const baseUrl = (process.env.SHARED_USER_URL || "").replace(/\s+/g, "").replace(/\/$/, "");
|
|
15
|
+
if (!baseUrl) {
|
|
16
|
+
var _ref, _ref$state, _state, _state$auth;
|
|
17
|
+
ctx.warn == null || ctx.warn("withPermissionsMw: SHARED_USER_URL not set, skipping permissions fetch");
|
|
18
|
+
(_ref$state = (_ref = ctx).state) != null ? _ref$state : _ref.state = {};
|
|
19
|
+
(_state$auth = (_state = ctx.state).auth) != null ? _state$auth : _state.auth = {};
|
|
20
|
+
ctx.state.auth.features = [];
|
|
21
|
+
return next();
|
|
22
|
+
}
|
|
23
|
+
const url = `${baseUrl}${USER_WITH_PERMISSIONS_PATH}`;
|
|
24
|
+
const cookie = (_req$headers$get = req.headers.get("cookie")) != null ? _req$headers$get : "";
|
|
25
|
+
const appId = (_req$headers$get2 = req.headers.get("app-id")) != null ? _req$headers$get2 : "";
|
|
26
|
+
const sessionMapping = (_ref2 = (_req$headers$get3 = req.headers.get("x-session-mapping")) != null ? _req$headers$get3 : req.headers.get("x-token-mapping")) != null ? _ref2 : "";
|
|
27
|
+
const headers = {
|
|
28
|
+
"Content-Type": "application/json",
|
|
29
|
+
Accept: "application/json"
|
|
30
|
+
};
|
|
31
|
+
if (cookie) headers.Cookie = cookie;
|
|
32
|
+
if (appId) headers["app-id"] = appId;
|
|
33
|
+
if (sessionMapping) headers["x-session-mapping"] = sessionMapping;
|
|
34
|
+
try {
|
|
35
|
+
var _body$data, _user$roleId, _industry, _user$business, _ref4, _ref4$state, _state3, _state3$auth;
|
|
36
|
+
const res = await fetch(url, {
|
|
37
|
+
method: "GET",
|
|
38
|
+
headers
|
|
39
|
+
});
|
|
40
|
+
const body = await res.json().catch(() => ({}));
|
|
41
|
+
if (!res.ok) {
|
|
42
|
+
var _ref3, _ref3$state, _state2, _state2$auth;
|
|
43
|
+
ctx.warn == null || ctx.warn(`withPermissionsMw: user-with-permissions returned ${res.status}`, {
|
|
44
|
+
url,
|
|
45
|
+
status: res.status
|
|
46
|
+
});
|
|
47
|
+
(_ref3$state = (_ref3 = ctx).state) != null ? _ref3$state : _ref3.state = {};
|
|
48
|
+
(_state2$auth = (_state2 = ctx.state).auth) != null ? _state2$auth : _state2.auth = {};
|
|
49
|
+
ctx.state.auth.features = [];
|
|
50
|
+
return next();
|
|
51
|
+
}
|
|
52
|
+
const user = (_body$data = body == null ? void 0 : body.data) != null ? _body$data : body;
|
|
53
|
+
const features = Array.isArray(user == null || (_user$roleId = user.roleId) == null ? void 0 : _user$roleId.features) ? user.roleId.features : [];
|
|
54
|
+
const industry = (_industry = user == null || (_user$business = user.business) == null ? void 0 : _user$business.industry) != null ? _industry : null;
|
|
55
|
+
(_ref4$state = (_ref4 = ctx).state) != null ? _ref4$state : _ref4.state = {};
|
|
56
|
+
(_state3$auth = (_state3 = ctx.state).auth) != null ? _state3$auth : _state3.auth = {};
|
|
57
|
+
ctx.state.auth.features = features;
|
|
58
|
+
if (industry) ctx.state.auth.industry = industry;
|
|
59
|
+
} catch (err) {
|
|
60
|
+
var _ref5, _ref5$state, _state4, _state4$auth;
|
|
61
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
62
|
+
ctx.error == null || ctx.error("withPermissionsMw: fetch failed", {
|
|
63
|
+
message,
|
|
64
|
+
url
|
|
65
|
+
});
|
|
66
|
+
(_ref5$state = (_ref5 = ctx).state) != null ? _ref5$state : _ref5.state = {};
|
|
67
|
+
(_state4$auth = (_state4 = ctx.state).auth) != null ? _state4$auth : _state4.auth = {};
|
|
68
|
+
ctx.state.auth.features = [];
|
|
69
|
+
}
|
|
70
|
+
return next();
|
|
71
|
+
};
|
|
72
|
+
exports.withPermissionsMw = withPermissionsMw;
|
|
73
|
+
//# sourceMappingURL=withPermissionsMw.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"withPermissionsMw.js","names":["USER_WITH_PERMISSIONS_PATH","withPermissionsMw","req","ctx","next","_req$headers$get","_req$headers$get2","_ref2","_req$headers$get3","baseUrl","process","env","SHARED_USER_URL","replace","_ref","_ref$state","_state","_state$auth","warn","state","auth","features","url","cookie","headers","get","appId","sessionMapping","Accept","Cookie","_body$data","_user$roleId","_industry","_user$business","_ref4","_ref4$state","_state3","_state3$auth","res","fetch","method","body","json","catch","ok","_ref3","_ref3$state","_state2","_state2$auth","status","user","data","Array","isArray","roleId","industry","business","err","_ref5","_ref5$state","_state4","_state4$auth","message","Error","String","error","exports"],"sources":["../../../src/middlewares/withPermissionsMw.ts"],"sourcesContent":["import { HttpRequest, HttpResponseInit, InvocationContext } from \"@azure/functions\";\nimport { IMiddleware } from \"../types/middleware\";\n\nconst USER_WITH_PERMISSIONS_PATH = \"/v1/user/user-with-permissions\";\n\n/**\n * Fetches current user permissions (roleId.features) from shared-user GET user-with-permissions.\n * Sets state.auth.features and optional state.auth.industry from user.business.\n * Run after verifyMw. Same behaviour as former modules/shared_goals middleware.\n */\nexport const withPermissionsMw: IMiddleware = async (\n req: HttpRequest,\n ctx: InvocationContext,\n next: () => Promise<HttpResponseInit>,\n): Promise<HttpResponseInit> => {\n const baseUrl = (process.env.SHARED_USER_URL || \"\").replace(/\\s+/g, \"\").replace(/\\/$/, \"\");\n if (!baseUrl) {\n ctx.warn?.(\"withPermissionsMw: SHARED_USER_URL not set, skipping permissions fetch\");\n (ctx as any).state ??= {};\n (ctx as any).state.auth ??= {};\n (ctx as any).state.auth.features = [];\n return next();\n }\n\n const url = `${baseUrl}${USER_WITH_PERMISSIONS_PATH}`;\n const cookie = req.headers.get(\"cookie\") ?? \"\";\n const appId = req.headers.get(\"app-id\") ?? \"\";\n const sessionMapping = req.headers.get(\"x-session-mapping\") ?? req.headers.get(\"x-token-mapping\") ?? \"\";\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n };\n if (cookie) headers.Cookie = cookie;\n if (appId) headers[\"app-id\"] = appId;\n if (sessionMapping) headers[\"x-session-mapping\"] = sessionMapping;\n\n try {\n const res = await fetch(url, { method: \"GET\", headers });\n const body = await res.json().catch(() => ({}));\n\n if (!res.ok) {\n ctx.warn?.(`withPermissionsMw: user-with-permissions returned ${res.status}`, { url, status: res.status });\n (ctx as any).state ??= {};\n (ctx as any).state.auth ??= {};\n (ctx as any).state.auth.features = [];\n return next();\n }\n\n const user = body?.data ?? body;\n const features = Array.isArray(user?.roleId?.features) ? user.roleId.features : [];\n const industry = (user?.business as { industry?: string } | undefined)?.industry ?? null;\n (ctx as any).state ??= {};\n (ctx as any).state.auth ??= {};\n (ctx as any).state.auth.features = features;\n if (industry) (ctx as any).state.auth.industry = industry;\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n ctx.error?.(\"withPermissionsMw: fetch failed\", { message, url });\n (ctx as any).state ??= {};\n (ctx as any).state.auth ??= {};\n (ctx as any).state.auth.features = [];\n }\n\n return next();\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
4
|
exports.TokenMappingService = void 0;
|
|
5
5
|
var _mongoose = require("mongoose");
|
|
6
|
-
var _shared = require("@culturefy/shared");
|
|
7
6
|
var _tokenMapping = require("../models/tokenMapping.model");
|
|
7
|
+
var _utils = require("../utils");
|
|
8
8
|
var _class;
|
|
9
9
|
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; }
|
|
10
|
-
let TokenMappingService = exports.TokenMappingService = (_class = class TokenMappingService extends
|
|
10
|
+
let TokenMappingService = exports.TokenMappingService = (_class = class TokenMappingService extends _utils.Initializers {
|
|
11
11
|
constructor(context, dbUrl) {
|
|
12
12
|
super(context, dbUrl);
|
|
13
13
|
this.schema = _tokenMapping.TokenMappingModel.schema;
|
|
@@ -113,5 +113,5 @@ let TokenMappingService = exports.TokenMappingService = (_class = class TokenMap
|
|
|
113
113
|
}
|
|
114
114
|
await this.getModel().deleteMany(filter);
|
|
115
115
|
}
|
|
116
|
-
}, _applyDecoratedDescriptor(_class.prototype, "createTokenMapping", [
|
|
116
|
+
}, _applyDecoratedDescriptor(_class.prototype, "createTokenMapping", [_utils.WithDb], Object.getOwnPropertyDescriptor(_class.prototype, "createTokenMapping"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "getTokenMappingById", [_utils.WithDb], Object.getOwnPropertyDescriptor(_class.prototype, "getTokenMappingById"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "getTokenMappingByUserId", [_utils.WithDb], Object.getOwnPropertyDescriptor(_class.prototype, "getTokenMappingByUserId"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "getTokenMappingBy", [_utils.WithDb], Object.getOwnPropertyDescriptor(_class.prototype, "getTokenMappingBy"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "deleteTokenMapping", [_utils.WithDb], Object.getOwnPropertyDescriptor(_class.prototype, "deleteTokenMapping"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "updateTokenMapping", [_utils.WithDb], Object.getOwnPropertyDescriptor(_class.prototype, "updateTokenMapping"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "deleteTokenMappingBy", [_utils.WithDb], Object.getOwnPropertyDescriptor(_class.prototype, "deleteTokenMappingBy"), _class.prototype), _class);
|
|
117
117
|
//# sourceMappingURL=tokenMapping.service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokenMapping.service.js","names":["_mongoose","require","_shared","_tokenMapping","_class","_applyDecoratedDescriptor","i","e","r","n","l","a","Object","keys","forEach","enumerable","configurable","initializer","writable","slice","reverse","reduce","value","call","defineProperty","TokenMappingService","exports","Initializers","constructor","context","dbUrl","schema","TokenMappingModel","getModel","connection","getConnection","Error","model","modelName","createTokenMapping","tokenMappingData","create","keycloakUserId","appId","userId","Types","ObjectId","realmId","clientId","accessToken","refreshToken","expiresAt","getTokenMappingById","tokenMappingId","findById","getTokenMappingByUserId","findOne","getTokenMappingBy","object","filter","deleteTokenMapping","findByIdAndDelete","updateTokenMapping","findByIdAndUpdate","new","deleteTokenMappingBy","deleteMany","prototype","WithDb","getOwnPropertyDescriptor"],"sources":["../../../src/service/tokenMapping.service.ts"],"sourcesContent":["import { Types } from \"mongoose\";\nimport { InvocationContext } from \"@azure/functions\";\nimport { Initializers, WithDb } from \"@culturefy/shared\";\nimport { ITokenMapping, TokenMappingModel } from \"../models/tokenMapping.model\";\nimport { ICreateTokenMapping, IFilterTokenMapping } from \"../interfaces/tokenMapping\";\n\nexport class TokenMappingService extends Initializers {\n\n private readonly schema = TokenMappingModel.schema;\n constructor(context: InvocationContext, dbUrl: string) {\n super(context, dbUrl);\n }\n\n private getModel() {\n const connection = (this as any).getConnection();\n if (!connection) {\n throw new Error('Database connection not established');\n }\n return connection.model(TokenMappingModel.modelName, this.schema);\n }\n\n @WithDb\n async createTokenMapping(tokenMappingData: ICreateTokenMapping): Promise<ITokenMapping> {\n return await this.getModel().create({\n keycloakUserId: tokenMappingData.keycloakUserId,\n appId: tokenMappingData.appId,\n userId: new Types.ObjectId(tokenMappingData.userId as string),\n realmId: tokenMappingData.realmId,\n clientId: tokenMappingData.clientId,\n accessToken: tokenMappingData.accessToken,\n refreshToken: tokenMappingData.refreshToken,\n expiresAt: tokenMappingData.expiresAt,\n });\n }\n\n @WithDb\n async getTokenMappingById(tokenMappingId: string): Promise<ITokenMapping | null> {\n return await this.getModel().findById(tokenMappingId);\n }\n\n @WithDb\n async getTokenMappingByUserId(userId: string): Promise<ITokenMapping | null> {\n return await this.getModel().findOne({ userId: new Types.ObjectId(userId) });\n }\n\n @WithDb\n async getTokenMappingBy(object: Partial<IFilterTokenMapping>): Promise<ITokenMapping | null> {\n let filter: any = {};\n if('keycloakUserId' in object) {\n filter.keycloakUserId = object.keycloakUserId;\n }\n if('userId' in object) {\n filter.userId = new Types.ObjectId(object.userId as string);\n }\n if('appId' in object) {\n filter.appId = object.appId;\n }\n if('realmId' in object) {\n filter.realmId = object.realmId;\n }\n if('clientId' in object) {\n filter.clientId = object.clientId;\n }\n if('expiresAt' in object) {\n filter.expiresAt = object.expiresAt;\n }\n return await this.getModel().findOne(filter);\n }\n\n @WithDb\n async deleteTokenMapping(tokenMappingId: string): Promise<void> {\n await this.getModel().findByIdAndDelete(tokenMappingId);\n }\n\n @WithDb\n async updateTokenMapping(tokenMappingId: string, tokenMappingData: Partial<IFilterTokenMapping>): Promise<ITokenMapping | null> {\n let filter: any = {};\n if('userId' in tokenMappingData) {\n filter.userId = new Types.ObjectId(tokenMappingData.userId as string);\n }\n if('appId' in tokenMappingData) {\n filter.appId = tokenMappingData.appId;\n }\n if('realmId' in tokenMappingData) {\n filter.realmId = tokenMappingData.realmId;\n }\n if('clientId' in tokenMappingData) {\n filter.clientId = tokenMappingData.clientId;\n }\n if('accessToken' in tokenMappingData) {\n filter.accessToken = tokenMappingData.accessToken;\n }\n if('refreshToken' in tokenMappingData) {\n filter.refreshToken = tokenMappingData.refreshToken;\n }\n if('expiresAt' in tokenMappingData) {\n filter.expiresAt = tokenMappingData.expiresAt;\n }\n return await this.getModel().findByIdAndUpdate(tokenMappingId, filter, { new: true });\n }\n\n @WithDb\n async deleteTokenMappingBy(object: Partial<IFilterTokenMapping>): Promise<void> {\n let filter: any = {};\n if('keycloakUserId' in object) {\n filter.keycloakUserId = object.keycloakUserId;\n }\n if('userId' in object) {\n filter.userId = new Types.ObjectId(object.userId as string);\n }\n if('appId' in object) {\n filter.appId = object.appId;\n }\n if('realmId' in object) {\n filter.realmId = object.realmId;\n }\n if('clientId' in object) {\n filter.clientId = object.clientId;\n }\n if('expiresAt' in object) {\n filter.expiresAt = object.expiresAt;\n }\n await this.getModel().deleteMany(filter);\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"tokenMapping.service.js","names":["_mongoose","require","_tokenMapping","_utils","_class","_applyDecoratedDescriptor","i","e","r","n","l","a","Object","keys","forEach","enumerable","configurable","initializer","writable","slice","reverse","reduce","value","call","defineProperty","TokenMappingService","exports","Initializers","constructor","context","dbUrl","schema","TokenMappingModel","getModel","connection","getConnection","Error","model","modelName","createTokenMapping","tokenMappingData","create","keycloakUserId","appId","userId","Types","ObjectId","realmId","clientId","accessToken","refreshToken","expiresAt","getTokenMappingById","tokenMappingId","findById","getTokenMappingByUserId","findOne","getTokenMappingBy","object","filter","deleteTokenMapping","findByIdAndDelete","updateTokenMapping","findByIdAndUpdate","new","deleteTokenMappingBy","deleteMany","prototype","WithDb","getOwnPropertyDescriptor"],"sources":["../../../src/service/tokenMapping.service.ts"],"sourcesContent":["import { Types } from \"mongoose\";\nimport { InvocationContext } from \"@azure/functions\";\nimport { ITokenMapping, TokenMappingModel } from \"../models/tokenMapping.model\";\nimport { ICreateTokenMapping, IFilterTokenMapping } from \"../interfaces/tokenMapping\";\nimport { Initializers, WithDb } from \"../utils\";\n\nexport class TokenMappingService extends Initializers {\n\n private readonly schema = TokenMappingModel.schema;\n constructor(context: InvocationContext, dbUrl: string) {\n super(context, dbUrl);\n }\n\n private getModel() {\n const connection = (this as any).getConnection();\n if (!connection) {\n throw new Error('Database connection not established');\n }\n return connection.model(TokenMappingModel.modelName, this.schema);\n }\n\n @WithDb\n async createTokenMapping(tokenMappingData: ICreateTokenMapping): Promise<ITokenMapping> {\n return await this.getModel().create({\n keycloakUserId: tokenMappingData.keycloakUserId,\n appId: tokenMappingData.appId,\n userId: new Types.ObjectId(tokenMappingData.userId as string),\n realmId: tokenMappingData.realmId,\n clientId: tokenMappingData.clientId,\n accessToken: tokenMappingData.accessToken,\n refreshToken: tokenMappingData.refreshToken,\n expiresAt: tokenMappingData.expiresAt,\n });\n }\n\n @WithDb\n async getTokenMappingById(tokenMappingId: string): Promise<ITokenMapping | null> {\n return await this.getModel().findById(tokenMappingId);\n }\n\n @WithDb\n async getTokenMappingByUserId(userId: string): Promise<ITokenMapping | null> {\n return await this.getModel().findOne({ userId: new Types.ObjectId(userId) });\n }\n\n @WithDb\n async getTokenMappingBy(object: Partial<IFilterTokenMapping>): Promise<ITokenMapping | null> {\n let filter: any = {};\n if('keycloakUserId' in object) {\n filter.keycloakUserId = object.keycloakUserId;\n }\n if('userId' in object) {\n filter.userId = new Types.ObjectId(object.userId as string);\n }\n if('appId' in object) {\n filter.appId = object.appId;\n }\n if('realmId' in object) {\n filter.realmId = object.realmId;\n }\n if('clientId' in object) {\n filter.clientId = object.clientId;\n }\n if('expiresAt' in object) {\n filter.expiresAt = object.expiresAt;\n }\n return await this.getModel().findOne(filter);\n }\n\n @WithDb\n async deleteTokenMapping(tokenMappingId: string): Promise<void> {\n await this.getModel().findByIdAndDelete(tokenMappingId);\n }\n\n @WithDb\n async updateTokenMapping(tokenMappingId: string, tokenMappingData: Partial<IFilterTokenMapping>): Promise<ITokenMapping | null> {\n let filter: any = {};\n if('userId' in tokenMappingData) {\n filter.userId = new Types.ObjectId(tokenMappingData.userId as string);\n }\n if('appId' in tokenMappingData) {\n filter.appId = tokenMappingData.appId;\n }\n if('realmId' in tokenMappingData) {\n filter.realmId = tokenMappingData.realmId;\n }\n if('clientId' in tokenMappingData) {\n filter.clientId = tokenMappingData.clientId;\n }\n if('accessToken' in tokenMappingData) {\n filter.accessToken = tokenMappingData.accessToken;\n }\n if('refreshToken' in tokenMappingData) {\n filter.refreshToken = tokenMappingData.refreshToken;\n }\n if('expiresAt' in tokenMappingData) {\n filter.expiresAt = tokenMappingData.expiresAt;\n }\n return await this.getModel().findByIdAndUpdate(tokenMappingId, filter, { new: true });\n }\n\n @WithDb\n async deleteTokenMappingBy(object: Partial<IFilterTokenMapping>): Promise<void> {\n let filter: any = {};\n if('keycloakUserId' in object) {\n filter.keycloakUserId = object.keycloakUserId;\n }\n if('userId' in object) {\n filter.userId = new Types.ObjectId(object.userId as string);\n }\n if('appId' in object) {\n filter.appId = object.appId;\n }\n if('realmId' in object) {\n filter.realmId = object.realmId;\n }\n if('clientId' in object) {\n filter.clientId = object.clientId;\n }\n if('expiresAt' in object) {\n filter.expiresAt = object.expiresAt;\n }\n await this.getModel().deleteMany(filter);\n }\n}\n"],"mappings":";;;;AAAA,IAAAA,SAAA,GAAAC,OAAA;AAEA,IAAAC,aAAA,GAAAD,OAAA;AAEA,IAAAE,MAAA,GAAAF,OAAA;AAAgD,IAAAG,MAAA;AAAA,SAAAC,0BAAAC,CAAA,EAAAC,CAAA,EAAAC,CAAA,EAAAC,CAAA,EAAAC,CAAA,QAAAC,CAAA,cAAAC,MAAA,CAAAC,IAAA,CAAAJ,CAAA,EAAAK,OAAA,WAAAR,CAAA,IAAAK,CAAA,CAAAL,CAAA,IAAAG,CAAA,CAAAH,CAAA,OAAAK,CAAA,CAAAI,UAAA,KAAAJ,CAAA,CAAAI,UAAA,EAAAJ,CAAA,CAAAK,YAAA,KAAAL,CAAA,CAAAK,YAAA,cAAAL,CAAA,IAAAA,CAAA,CAAAM,WAAA,MAAAN,CAAA,CAAAO,QAAA,QAAAP,CAAA,GAAAH,CAAA,CAAAW,KAAA,GAAAC,OAAA,GAAAC,MAAA,WAAAb,CAAA,EAAAC,CAAA,WAAAA,CAAA,CAAAH,CAAA,EAAAC,CAAA,EAAAC,CAAA,KAAAA,CAAA,KAAAG,CAAA,GAAAD,CAAA,eAAAC,CAAA,CAAAM,WAAA,KAAAN,CAAA,CAAAW,KAAA,GAAAX,CAAA,CAAAM,WAAA,GAAAN,CAAA,CAAAM,WAAA,CAAAM,IAAA,CAAAb,CAAA,YAAAC,CAAA,CAAAM,WAAA,uBAAAN,CAAA,CAAAM,WAAA,IAAAL,MAAA,CAAAY,cAAA,CAAAlB,CAAA,EAAAC,CAAA,EAAAI,CAAA,WAAAA,CAAA;AAAA,IAEnCc,mBAAmB,GAAAC,OAAA,CAAAD,mBAAA,IAAArB,MAAA,GAAzB,MAAMqB,mBAAmB,SAASE,mBAAY,CAAC;EAGlDC,WAAWA,CAACC,OAA0B,EAAEC,KAAa,EAAE;IACnD,KAAK,CAACD,OAAO,EAAEC,KAAK,CAAC;IAAC,KAFTC,MAAM,GAAGC,+BAAiB,CAACD,MAAM;EAGlD;EAEQE,QAAQA,CAAA,EAAG;IACf,MAAMC,UAAU,GAAI,IAAI,CAASC,aAAa,CAAC,CAAC;IAChD,IAAI,CAACD,UAAU,EAAE;MACb,MAAM,IAAIE,KAAK,CAAC,qCAAqC,CAAC;IAC1D;IACA,OAAOF,UAAU,CAACG,KAAK,CAACL,+BAAiB,CAACM,SAAS,EAAE,IAAI,CAACP,MAAM,CAAC;EACrE;EAEA,MACMQ,kBAAkBA,CAACC,gBAAqC,EAA0B;IACpF,OAAO,MAAM,IAAI,CAACP,QAAQ,CAAC,CAAC,CAACQ,MAAM,CAAC;MAChCC,cAAc,EAAEF,gBAAgB,CAACE,cAAc;MAC/CC,KAAK,EAAEH,gBAAgB,CAACG,KAAK;MAC7BC,MAAM,EAAE,IAAIC,eAAK,CAACC,QAAQ,CAACN,gBAAgB,CAACI,MAAgB,CAAC;MAC7DG,OAAO,EAAEP,gBAAgB,CAACO,OAAO;MACjCC,QAAQ,EAAER,gBAAgB,CAACQ,QAAQ;MACnCC,WAAW,EAAET,gBAAgB,CAACS,WAAW;MACzCC,YAAY,EAAEV,gBAAgB,CAACU,YAAY;MAC3CC,SAAS,EAAEX,gBAAgB,CAACW;IAChC,CAAC,CAAC;EACN;EAEA,MACMC,mBAAmBA,CAACC,cAAsB,EAAiC;IAC7E,OAAO,MAAM,IAAI,CAACpB,QAAQ,CAAC,CAAC,CAACqB,QAAQ,CAACD,cAAc,CAAC;EACzD;EAEA,MACME,uBAAuBA,CAACX,MAAc,EAAiC;IACzE,OAAO,MAAM,IAAI,CAACX,QAAQ,CAAC,CAAC,CAACuB,OAAO,CAAC;MAAEZ,MAAM,EAAE,IAAIC,eAAK,CAACC,QAAQ,CAACF,MAAM;IAAE,CAAC,CAAC;EAChF;EAEA,MACMa,iBAAiBA,CAACC,MAAoC,EAAiC;IACzF,IAAIC,MAAW,GAAG,CAAC,CAAC;IACpB,IAAG,gBAAgB,IAAID,MAAM,EAAE;MAC3BC,MAAM,CAACjB,cAAc,GAAGgB,MAAM,CAAChB,cAAc;IACjD;IACA,IAAG,QAAQ,IAAIgB,MAAM,EAAE;MACnBC,MAAM,CAACf,MAAM,GAAG,IAAIC,eAAK,CAACC,QAAQ,CAACY,MAAM,CAACd,MAAgB,CAAC;IAC/D;IACA,IAAG,OAAO,IAAIc,MAAM,EAAE;MAClBC,MAAM,CAAChB,KAAK,GAAGe,MAAM,CAACf,KAAK;IAC/B;IACA,IAAG,SAAS,IAAIe,MAAM,EAAE;MACpBC,MAAM,CAACZ,OAAO,GAAGW,MAAM,CAACX,OAAO;IACnC;IACA,IAAG,UAAU,IAAIW,MAAM,EAAE;MACrBC,MAAM,CAACX,QAAQ,GAAGU,MAAM,CAACV,QAAQ;IACrC;IACA,IAAG,WAAW,IAAIU,MAAM,EAAE;MACtBC,MAAM,CAACR,SAAS,GAAGO,MAAM,CAACP,SAAS;IACvC;IACA,OAAO,MAAM,IAAI,CAAClB,QAAQ,CAAC,CAAC,CAACuB,OAAO,CAACG,MAAM,CAAC;EAChD;EAEA,MACMC,kBAAkBA,CAACP,cAAsB,EAAiB;IAC5D,MAAM,IAAI,CAACpB,QAAQ,CAAC,CAAC,CAAC4B,iBAAiB,CAACR,cAAc,CAAC;EAC3D;EAEA,MACMS,kBAAkBA,CAACT,cAAsB,EAAEb,gBAA8C,EAAiC;IAC5H,IAAImB,MAAW,GAAG,CAAC,CAAC;IACpB,IAAG,QAAQ,IAAInB,gBAAgB,EAAE;MAC7BmB,MAAM,CAACf,MAAM,GAAG,IAAIC,eAAK,CAACC,QAAQ,CAACN,gBAAgB,CAACI,MAAgB,CAAC;IACzE;IACA,IAAG,OAAO,IAAIJ,gBAAgB,EAAE;MAC5BmB,MAAM,CAAChB,KAAK,GAAGH,gBAAgB,CAACG,KAAK;IACzC;IACA,IAAG,SAAS,IAAIH,gBAAgB,EAAE;MAC9BmB,MAAM,CAACZ,OAAO,GAAGP,gBAAgB,CAACO,OAAO;IAC7C;IACA,IAAG,UAAU,IAAIP,gBAAgB,EAAE;MAC/BmB,MAAM,CAACX,QAAQ,GAAGR,gBAAgB,CAACQ,QAAQ;IAC/C;IACA,IAAG,aAAa,IAAIR,gBAAgB,EAAE;MAClCmB,MAAM,CAACV,WAAW,GAAGT,gBAAgB,CAACS,WAAW;IACrD;IACA,IAAG,cAAc,IAAIT,gBAAgB,EAAE;MACnCmB,MAAM,CAACT,YAAY,GAAGV,gBAAgB,CAACU,YAAY;IACvD;IACA,IAAG,WAAW,IAAIV,gBAAgB,EAAE;MAChCmB,MAAM,CAACR,SAAS,GAAGX,gBAAgB,CAACW,SAAS;IACjD;IACA,OAAO,MAAM,IAAI,CAAClB,QAAQ,CAAC,CAAC,CAAC8B,iBAAiB,CAACV,cAAc,EAAEM,MAAM,EAAE;MAAEK,GAAG,EAAE;IAAK,CAAC,CAAC;EACzF;EAEA,MACMC,oBAAoBA,CAACP,MAAoC,EAAiB;IAC5E,IAAIC,MAAW,GAAG,CAAC,CAAC;IACpB,IAAG,gBAAgB,IAAID,MAAM,EAAE;MAC3BC,MAAM,CAACjB,cAAc,GAAGgB,MAAM,CAAChB,cAAc;IACjD;IACA,IAAG,QAAQ,IAAIgB,MAAM,EAAE;MACnBC,MAAM,CAACf,MAAM,GAAG,IAAIC,eAAK,CAACC,QAAQ,CAACY,MAAM,CAACd,MAAgB,CAAC;IAC/D;IACA,IAAG,OAAO,IAAIc,MAAM,EAAE;MAClBC,MAAM,CAAChB,KAAK,GAAGe,MAAM,CAACf,KAAK;IAC/B;IACA,IAAG,SAAS,IAAIe,MAAM,EAAE;MACpBC,MAAM,CAACZ,OAAO,GAAGW,MAAM,CAACX,OAAO;IACnC;IACA,IAAG,UAAU,IAAIW,MAAM,EAAE;MACrBC,MAAM,CAACX,QAAQ,GAAGU,MAAM,CAACV,QAAQ;IACrC;IACA,IAAG,WAAW,IAAIU,MAAM,EAAE;MACtBC,MAAM,CAACR,SAAS,GAAGO,MAAM,CAACP,SAAS;IACvC;IACA,MAAM,IAAI,CAAClB,QAAQ,CAAC,CAAC,CAACiC,UAAU,CAACP,MAAM,CAAC;EAC5C;AACJ,CAAC,EAAAtD,yBAAA,CAAAD,MAAA,CAAA+D,SAAA,yBAvGIC,aAAM,GAAAxD,MAAA,CAAAyD,wBAAA,CAAAjE,MAAA,CAAA+D,SAAA,yBAAA/D,MAAA,CAAA+D,SAAA,GAAA9D,yBAAA,CAAAD,MAAA,CAAA+D,SAAA,0BAcNC,aAAM,GAAAxD,MAAA,CAAAyD,wBAAA,CAAAjE,MAAA,CAAA+D,SAAA,0BAAA/D,MAAA,CAAA+D,SAAA,GAAA9D,yBAAA,CAAAD,MAAA,CAAA+D,SAAA,8BAKNC,aAAM,GAAAxD,MAAA,CAAAyD,wBAAA,CAAAjE,MAAA,CAAA+D,SAAA,8BAAA/D,MAAA,CAAA+D,SAAA,GAAA9D,yBAAA,CAAAD,MAAA,CAAA+D,SAAA,wBAKNC,aAAM,GAAAxD,MAAA,CAAAyD,wBAAA,CAAAjE,MAAA,CAAA+D,SAAA,wBAAA/D,MAAA,CAAA+D,SAAA,GAAA9D,yBAAA,CAAAD,MAAA,CAAA+D,SAAA,yBAwBNC,aAAM,GAAAxD,MAAA,CAAAyD,wBAAA,CAAAjE,MAAA,CAAA+D,SAAA,yBAAA/D,MAAA,CAAA+D,SAAA,GAAA9D,yBAAA,CAAAD,MAAA,CAAA+D,SAAA,yBAKNC,aAAM,GAAAxD,MAAA,CAAAyD,wBAAA,CAAAjE,MAAA,CAAA+D,SAAA,yBAAA/D,MAAA,CAAA+D,SAAA,GAAA9D,yBAAA,CAAAD,MAAA,CAAA+D,SAAA,2BA2BNC,aAAM,GAAAxD,MAAA,CAAAyD,wBAAA,CAAAjE,MAAA,CAAA+D,SAAA,2BAAA/D,MAAA,CAAA+D,SAAA,GAAA/D,MAAA","ignoreList":[]}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
4
|
exports.UserService = void 0;
|
|
5
|
-
var
|
|
6
|
-
class UserService extends
|
|
5
|
+
var _utils = require("../utils");
|
|
6
|
+
class UserService extends _utils.Initializers {
|
|
7
7
|
// private readonly schema = UserModel.schema;
|
|
8
8
|
constructor(context, dbUrl) {
|
|
9
9
|
super(context, dbUrl);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.service.js","names":["
|
|
1
|
+
{"version":3,"file":"user.service.js","names":["_utils","require","UserService","Initializers","constructor","context","dbUrl","exports"],"sources":["../../../src/service/user.service.ts"],"sourcesContent":["import { Types } from \"mongoose\";\nimport { InvocationContext } from \"@azure/functions\";\nimport { Initializers } from \"../utils\";\n\nexport class UserService extends Initializers {\n\n // private readonly schema = UserModel.schema;\n constructor(context: InvocationContext, dbUrl:string) {\n super(context, dbUrl);\n }\n\n // private getModel() {\n // const connection = (this as any).getConnection();\n // if (!connection) {\n // throw new Error('Database connection not established');\n // }\n // return connection.model(UserModel.modelName, this.schema);\n // }\n\n // @WithDb\n // async getUserById(userId: string): Promise<IUser | null> {\n // try {\n // let model = this.getModel();\n // this.context.log(\"UserId:\", JSON.stringify(userId));\n \n // // Handle both string and SchemaObjectId inputs\n // let objectId: Types.ObjectId;\n // if (typeof userId === 'string') {\n // objectId = new Types.ObjectId(userId);\n // } else {\n // // If it's already a SchemaObjectId, extract the string value\n // const userIdString = (userId as any).path || (userId as any).toString();\n // objectId = new Types.ObjectId(userIdString);\n // }\n \n // this.context.log(\"ObjectId:\", JSON.stringify(objectId));\n // const user = await model.findById(objectId);\n // this.context.log(\"User:\", JSON.stringify(user));\n // return user;\n // } catch (error) {\n // this.context.error(\"Error in getUserById\", error);\n // throw error;\n // }\n // }\n\n // @WithDb\n // async getUserByBusinessId(businessId: string, email: string): Promise<IUser | null> {\n // try {\n // let model = this.getModel();\n // this.context.log(\"BusinessId:\", JSON.stringify(businessId));\n // this.context.log(\"Email:\", JSON.stringify(email));\n\n // if(!businessId) return null;\n // if(!email) return null;\n\n // businessId = businessId.toLowerCase();\n // businessId = businessId.trim();\n\n // email = email.toLowerCase();\n // email = email.trim();\n\n // // Handle both string and SchemaObjectId inputs\n // let objectId: Types.ObjectId;\n // if (typeof businessId === 'string') {\n // objectId = new Types.ObjectId(businessId);\n // } else {\n // // If it's already a SchemaObjectId, extract the string value\n // const businessIdString = (businessId as any).path || (businessId as any).toString();\n // objectId = new Types.ObjectId(businessIdString);\n // }\n \n // this.context.log(\"ObjectId:\", JSON.stringify(objectId));\n // const user = await model.findOne({ businessId: objectId, email: email });\n // this.context.log(\"User:\", JSON.stringify(user));\n // return user;\n // } catch (error) {\n // this.context.error(\"Error in getUserByBusinessId\", error);\n // throw error;\n // }\n // }\n\n // @WithDb\n // async getUserByEmail(email: string) {\n // try {\n // let model = this.getModel();\n // this.context.log(\"Email:\", JSON.stringify(email));\n\n // email = email.toLowerCase();\n // email = email.trim();\n // const user = await model.findOne({ email: email });\n // this.context.log(\"User:\", JSON.stringify(user));\n // return user;\n // } catch (error) {\n // this.context.error(\"Error in getUserByEmail\", error);\n // throw error;\n // }\n // }\n}\n"],"mappings":";;;;AAEA,IAAAA,MAAA,GAAAC,OAAA;AAEO,MAAMC,WAAW,SAASC,mBAAY,CAAC;EAE1C;EACAC,WAAWA,CAACC,OAA0B,EAAEC,KAAY,EAAE;IAClD,KAAK,CAACD,OAAO,EAAEC,KAAK,CAAC;EACzB;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;;EAEA;EACA;;EAEA;EACA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AACJ;AAACC,OAAA,CAAAL,WAAA,GAAAA,WAAA","ignoreList":[]}
|
package/build/cjs/utils/cache.js
CHANGED
|
@@ -60,7 +60,10 @@ const getRedisClient = async ctx => {
|
|
|
60
60
|
const options = await buildRedisOptions(ctx);
|
|
61
61
|
redis = new _ioredis.default(options);
|
|
62
62
|
redis.on("error", err => ctx == null || ctx.error == null ? void 0 : ctx.error("Redis error", err));
|
|
63
|
-
redis.on("connect", () =>
|
|
63
|
+
redis.on("connect", () => {
|
|
64
|
+
(0, _secrets.registerSecretsRedis)(redis);
|
|
65
|
+
ctx == null || ctx.info == null || ctx.info("Redis connected");
|
|
66
|
+
});
|
|
64
67
|
return redis;
|
|
65
68
|
};
|
|
66
69
|
exports.getRedisClient = getRedisClient;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.js","names":["_ioredis","_interopRequireDefault","require","_enums","_secrets","e","__esModule","default","redis","redisOptionsCache","redisOptionsPromise","resolveRedisConfig","ctx","vaultName","process","env","AZURE_KEY_VAULT_NAME","Error","redisHost","redisKey","redisPortSecret","Promise","all","getAzureVaultSecretByKey","AzureSecretKeysEnum","REDIS_HOST","REDIS_KEY","REDIS_PORT","redisPort","Number","host","key","port","buildRedisOptions","password","tls","servername","maxRetriesPerRequest","enableReadyCheck","then","options","finally","getRedisClient","Redis","on","err","error","info","exports","buildKey","namespace","parts","map","part","join","createCache","ttlSeconds","get","client","set","value","getOrSet","fetcher","cached","delete","del","Cacheable","_target","_propertyKey","descriptor","originalMethod","args","_options$getContext","getContext","context","keyParts","cache","apply"],"sources":["../../../src/utils/cache.ts"],"sourcesContent":["import Redis, { RedisOptions } from \"ioredis\";\nimport { InvocationContext } from \"@azure/functions\";\nimport { AzureSecretKeysEnum } from \"../enums\";\nimport { getAzureVaultSecretByKey } from \"./secrets\";\n\nlet redis: Redis | null = null;\nlet redisOptionsCache: RedisOptions | string | null = null;\nlet redisOptionsPromise: Promise<RedisOptions | string> | null = null;\n\ntype RedisConfig = {\n host: string;\n key: string;\n port: number;\n};\n\nconst resolveRedisConfig = async (\n ctx?: InvocationContext,\n): Promise<RedisConfig> => {\n const vaultName = process.env.AZURE_KEY_VAULT_NAME || \"\";\n if (!vaultName) {\n throw new Error(\"AZURE_KEY_VAULT_NAME is required to fetch Redis secrets\");\n }\n if (!ctx) {\n throw new Error(\"InvocationContext is required to fetch Redis secrets\");\n }\n\n const [redisHost, redisKey, redisPortSecret] = await Promise.all([\n getAzureVaultSecretByKey(ctx, vaultName, AzureSecretKeysEnum.REDIS_HOST),\n getAzureVaultSecretByKey(ctx, vaultName, AzureSecretKeysEnum.REDIS_KEY),\n getAzureVaultSecretByKey(ctx, vaultName, AzureSecretKeysEnum.REDIS_PORT),\n ]);\n\n const redisPort = redisPortSecret ? Number(redisPortSecret) : 6380;\n\n if (!redisHost || !redisKey) {\n throw new Error(\"Redis configuration missing in Key Vault\");\n }\n\n return {\n host: redisHost,\n key: redisKey,\n port: redisPort,\n };\n};\n\nconst buildRedisOptions = async (\n ctx?: InvocationContext,\n): Promise<RedisOptions | string> => {\n if (redisOptionsCache) return redisOptionsCache;\n if (redisOptionsPromise) return redisOptionsPromise;\n\n redisOptionsPromise = (async () => {\n const { host, key, port } = await resolveRedisConfig(ctx);\n\n return {\n host,\n port,\n password: key,\n tls: { servername: host },\n maxRetriesPerRequest: 3,\n enableReadyCheck: false,\n };\n })()\n .then((options) => {\n redisOptionsCache = options;\n return options;\n })\n .finally(() => {\n redisOptionsPromise = null;\n });\n\n return redisOptionsPromise;\n};\n\nexport const getRedisClient = async (ctx?: InvocationContext): Promise<Redis> => {\n if (redis) return redis;\n\n const options = await buildRedisOptions(ctx);\n\n redis = new Redis(options as RedisOptions);\n redis.on(\"error\", (err) => ctx?.error?.(\"Redis error\", err));\n redis.on(\"connect\", () => ctx?.info?.(\"Redis connected\"));\n return redis;\n};\n\nconst buildKey = (namespace: string, parts: Array<string | number | undefined>) =>\n [namespace, ...parts.map((part) => part ?? \"_\")].join(\":\");\n\nexport const createCache = (namespace: string, ttlSeconds: number) => {\n return {\n key: (...parts: Array<string | number | undefined>) =>\n buildKey(namespace, parts),\n get: async (\n ctx: InvocationContext | undefined,\n ...parts: Array<string | number | undefined>\n ) => {\n const client = await getRedisClient(ctx);\n try {\n return await client.get(buildKey(namespace, parts));\n } catch (error) {\n ctx?.error?.(\"Redis get failed\", error);\n return null;\n }\n },\n set: async (\n ctx: InvocationContext | undefined,\n value: string,\n ...parts: Array<string | number | undefined>\n ) => {\n const client = await getRedisClient(ctx);\n try {\n await client.set(buildKey(namespace, parts), value, \"EX\", ttlSeconds);\n } catch (error) {\n ctx?.error?.(\"Redis set failed\", error);\n }\n },\n getOrSet: async (\n ctx: InvocationContext | undefined,\n parts: Array<string | number | undefined>,\n fetcher: () => Promise<string>,\n ) => {\n const cached = await (async () => {\n const client = await getRedisClient(ctx);\n try {\n return await client.get(buildKey(namespace, parts));\n } catch (error) {\n ctx?.error?.(\"Redis get failed\", error);\n return null;\n }\n })();\n\n if (cached) return cached;\n const value = await fetcher();\n await (async () => {\n const client = await getRedisClient(ctx);\n try {\n await client.set(buildKey(namespace, parts), value, \"EX\", ttlSeconds);\n } catch (error) {\n ctx?.error?.(\"Redis set failed\", error);\n }\n })();\n return value;\n },\n delete: async (\n ctx: InvocationContext | undefined,\n ...parts: Array<string | number | undefined>\n ) => {\n const client = await getRedisClient(ctx);\n try {\n await client.del(buildKey(namespace, parts));\n } catch (error) {\n ctx?.error?.(\"Redis delete failed\", error);\n }\n },\n };\n};\n\ntype CacheableOptions<TArgs extends unknown[]> = {\n cache: ReturnType<typeof createCache>;\n key: (...args: TArgs) => Array<unknown>;\n getContext?: (instance: unknown) => InvocationContext | undefined;\n};\n\nexport const Cacheable = <TArgs extends unknown[]>(\n options: CacheableOptions<TArgs>,\n): MethodDecorator => {\n return (\n _target,\n _propertyKey,\n descriptor: PropertyDescriptor,\n ): void => {\n const originalMethod = descriptor.value as\n | ((...args: TArgs) => Promise<string>)\n | undefined;\n if (!originalMethod) return;\n descriptor.value = async function (...args: TArgs) {\n const ctx =\n options.getContext?.(this) ??\n (this as { context?: InvocationContext }).context;\n const keyParts = options.key(...args) as Array<string | number | undefined>;\n return options.cache.getOrSet(ctx, keyParts, () =>\n originalMethod.apply(this, args),\n );\n };\n };\n};\n"],"mappings":";;;;AAAA,IAAAA,QAAA,GAAAC,sBAAA,CAAAC,OAAA;AAEA,IAAAC,MAAA,GAAAD,OAAA;AACA,IAAAE,QAAA,GAAAF,OAAA;AAAqD,SAAAD,uBAAAI,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAErD,IAAIG,KAAmB,GAAG,IAAI;AAC9B,IAAIC,iBAA+C,GAAG,IAAI;AAC1D,IAAIC,mBAA0D,GAAG,IAAI;AAQrE,MAAMC,kBAAkB,GAAG,MACzBC,GAAuB,IACE;EACzB,MAAMC,SAAS,GAAGC,OAAO,CAACC,GAAG,CAACC,oBAAoB,IAAI,EAAE;EACxD,IAAI,CAACH,SAAS,EAAE;IACd,MAAM,IAAII,KAAK,CAAC,yDAAyD,CAAC;EAC5E;EACA,IAAI,CAACL,GAAG,EAAE;IACR,MAAM,IAAIK,KAAK,CAAC,sDAAsD,CAAC;EACzE;EAEA,MAAM,CAACC,SAAS,EAAEC,QAAQ,EAAEC,eAAe,CAAC,GAAG,MAAMC,OAAO,CAACC,GAAG,CAAC,CAC/D,IAAAC,iCAAwB,EAACX,GAAG,EAAEC,SAAS,EAAEW,0BAAmB,CAACC,UAAU,CAAC,EACxE,IAAAF,iCAAwB,EAACX,GAAG,EAAEC,SAAS,EAAEW,0BAAmB,CAACE,SAAS,CAAC,EACvE,IAAAH,iCAAwB,EAACX,GAAG,EAAEC,SAAS,EAAEW,0BAAmB,CAACG,UAAU,CAAC,CACzE,CAAC;EAEF,MAAMC,SAAS,GAAGR,eAAe,GAAGS,MAAM,CAACT,eAAe,CAAC,GAAG,IAAI;EAElE,IAAI,CAACF,SAAS,IAAI,CAACC,QAAQ,EAAE;IAC3B,MAAM,IAAIF,KAAK,CAAC,0CAA0C,CAAC;EAC7D;EAEA,OAAO;IACLa,IAAI,EAAEZ,SAAS;IACfa,GAAG,EAAEZ,QAAQ;IACba,IAAI,EAAEJ;EACR,CAAC;AACH,CAAC;AAED,MAAMK,iBAAiB,GAAG,MACxBrB,GAAuB,IACY;EACnC,IAAIH,iBAAiB,EAAE,OAAOA,iBAAiB;EAC/C,IAAIC,mBAAmB,EAAE,OAAOA,mBAAmB;EAEnDA,mBAAmB,GAAG,CAAC,YAAY;IACjC,MAAM;MAAEoB,IAAI;MAAEC,GAAG;MAAEC;IAAK,CAAC,GAAG,MAAMrB,kBAAkB,CAACC,GAAG,CAAC;IAEzD,OAAO;MACLkB,IAAI;MACJE,IAAI;MACJE,QAAQ,EAAEH,GAAG;MACbI,GAAG,EAAE;QAAEC,UAAU,EAAEN;MAAK,CAAC;MACzBO,oBAAoB,EAAE,CAAC;MACvBC,gBAAgB,EAAE;IACpB,CAAC;EACH,CAAC,EAAE,CAAC,CACDC,IAAI,CAAEC,OAAO,IAAK;IACjB/B,iBAAiB,GAAG+B,OAAO;IAC3B,OAAOA,OAAO;EAChB,CAAC,CAAC,CACDC,OAAO,CAAC,MAAM;IACb/B,mBAAmB,GAAG,IAAI;EAC5B,CAAC,CAAC;EAEJ,OAAOA,mBAAmB;AAC5B,CAAC;AAEM,MAAMgC,cAAc,GAAG,MAAO9B,GAAuB,IAAqB;EAC/E,IAAIJ,KAAK,EAAE,OAAOA,KAAK;EAEvB,MAAMgC,OAAO,GAAG,MAAMP,iBAAiB,CAACrB,GAAG,CAAC;EAE5CJ,KAAK,GAAG,IAAImC,gBAAK,CAACH,OAAuB,CAAC;EAC1ChC,KAAK,CAACoC,EAAE,CAAC,OAAO,EAAGC,GAAG,IAAKjC,GAAG,YAAHA,GAAG,CAAEkC,KAAK,oBAAVlC,GAAG,CAAEkC,KAAK,CAAG,aAAa,EAAED,GAAG,CAAC,CAAC;EAC5DrC,KAAK,CAACoC,EAAE,CAAC,SAAS,EAAE,MAAMhC,GAAG,YAAHA,GAAG,CAAEmC,IAAI,oBAATnC,GAAG,CAAEmC,IAAI,CAAG,iBAAiB,CAAC,CAAC;EACzD,OAAOvC,KAAK;AACd,CAAC;AAACwC,OAAA,CAAAN,cAAA,GAAAA,cAAA;AAEF,MAAMO,QAAQ,GAAGA,CAACC,SAAiB,EAAEC,KAAyC,KAC5E,CAACD,SAAS,EAAE,GAAGC,KAAK,CAACC,GAAG,CAAEC,IAAI,IAAKA,IAAI,WAAJA,IAAI,GAAI,GAAG,CAAC,CAAC,CAACC,IAAI,CAAC,GAAG,CAAC;AAErD,MAAMC,WAAW,GAAGA,CAACL,SAAiB,EAAEM,UAAkB,KAAK;EACpE,OAAO;IACLzB,GAAG,EAAEA,CAAC,GAAGoB,KAAyC,KAChDF,QAAQ,CAACC,SAAS,EAAEC,KAAK,CAAC;IAC5BM,GAAG,EAAE,MAAAA,CACH7C,GAAkC,EAClC,GAAGuC,KAAyC,KACzC;MACH,MAAMO,MAAM,GAAG,MAAMhB,cAAc,CAAC9B,GAAG,CAAC;MACxC,IAAI;QACF,OAAO,MAAM8C,MAAM,CAACD,GAAG,CAACR,QAAQ,CAACC,SAAS,EAAEC,KAAK,CAAC,CAAC;MACrD,CAAC,CAAC,OAAOL,KAAK,EAAE;QACdlC,GAAG,YAAHA,GAAG,CAAEkC,KAAK,YAAVlC,GAAG,CAAEkC,KAAK,CAAG,kBAAkB,EAAEA,KAAK,CAAC;QACvC,OAAO,IAAI;MACb;IACF,CAAC;IACDa,GAAG,EAAE,MAAAA,CACH/C,GAAkC,EAClCgD,KAAa,EACb,GAAGT,KAAyC,KACzC;MACH,MAAMO,MAAM,GAAG,MAAMhB,cAAc,CAAC9B,GAAG,CAAC;MACxC,IAAI;QACF,MAAM8C,MAAM,CAACC,GAAG,CAACV,QAAQ,CAACC,SAAS,EAAEC,KAAK,CAAC,EAAES,KAAK,EAAE,IAAI,EAAEJ,UAAU,CAAC;MACvE,CAAC,CAAC,OAAOV,KAAK,EAAE;QACdlC,GAAG,YAAHA,GAAG,CAAEkC,KAAK,YAAVlC,GAAG,CAAEkC,KAAK,CAAG,kBAAkB,EAAEA,KAAK,CAAC;MACzC;IACF,CAAC;IACDe,QAAQ,EAAE,MAAAA,CACRjD,GAAkC,EAClCuC,KAAyC,EACzCW,OAA8B,KAC3B;MACH,MAAMC,MAAM,GAAG,MAAM,CAAC,YAAY;QAChC,MAAML,MAAM,GAAG,MAAMhB,cAAc,CAAC9B,GAAG,CAAC;QACxC,IAAI;UACF,OAAO,MAAM8C,MAAM,CAACD,GAAG,CAACR,QAAQ,CAACC,SAAS,EAAEC,KAAK,CAAC,CAAC;QACrD,CAAC,CAAC,OAAOL,KAAK,EAAE;UACdlC,GAAG,YAAHA,GAAG,CAAEkC,KAAK,YAAVlC,GAAG,CAAEkC,KAAK,CAAG,kBAAkB,EAAEA,KAAK,CAAC;UACvC,OAAO,IAAI;QACb;MACF,CAAC,EAAE,CAAC;MAEJ,IAAIiB,MAAM,EAAE,OAAOA,MAAM;MACzB,MAAMH,KAAK,GAAG,MAAME,OAAO,CAAC,CAAC;MAC7B,MAAM,CAAC,YAAY;QACjB,MAAMJ,MAAM,GAAG,MAAMhB,cAAc,CAAC9B,GAAG,CAAC;QACxC,IAAI;UACF,MAAM8C,MAAM,CAACC,GAAG,CAACV,QAAQ,CAACC,SAAS,EAAEC,KAAK,CAAC,EAAES,KAAK,EAAE,IAAI,EAAEJ,UAAU,CAAC;QACvE,CAAC,CAAC,OAAOV,KAAK,EAAE;UACdlC,GAAG,YAAHA,GAAG,CAAEkC,KAAK,YAAVlC,GAAG,CAAEkC,KAAK,CAAG,kBAAkB,EAAEA,KAAK,CAAC;QACzC;MACF,CAAC,EAAE,CAAC;MACJ,OAAOc,KAAK;IACd,CAAC;IACDI,MAAM,EAAE,MAAAA,CACNpD,GAAkC,EAClC,GAAGuC,KAAyC,KACzC;MACH,MAAMO,MAAM,GAAG,MAAMhB,cAAc,CAAC9B,GAAG,CAAC;MACxC,IAAI;QACF,MAAM8C,MAAM,CAACO,GAAG,CAAChB,QAAQ,CAACC,SAAS,EAAEC,KAAK,CAAC,CAAC;MAC9C,CAAC,CAAC,OAAOL,KAAK,EAAE;QACdlC,GAAG,YAAHA,GAAG,CAAEkC,KAAK,YAAVlC,GAAG,CAAEkC,KAAK,CAAG,qBAAqB,EAAEA,KAAK,CAAC;MAC5C;IACF;EACF,CAAC;AACH,CAAC;AAACE,OAAA,CAAAO,WAAA,GAAAA,WAAA;AAQK,MAAMW,SAAS,GACpB1B,OAAgC,IACZ;EACpB,OAAO,CACL2B,OAAO,EACPC,YAAY,EACZC,UAA8B,KACrB;IACT,MAAMC,cAAc,GAAGD,UAAU,CAACT,KAErB;IACb,IAAI,CAACU,cAAc,EAAE;IACrBD,UAAU,CAACT,KAAK,GAAG,gBAAgB,GAAGW,IAAW,EAAE;MAAA,IAAAC,mBAAA;MACjD,MAAM5D,GAAG,IAAA4D,mBAAA,GACPhC,OAAO,CAACiC,UAAU,oBAAlBjC,OAAO,CAACiC,UAAU,CAAG,IAAI,CAAC,YAAAD,mBAAA,GACzB,IAAI,CAAqCE,OAAO;MACnD,MAAMC,QAAQ,GAAGnC,OAAO,CAACT,GAAG,CAAC,GAAGwC,IAAI,CAAuC;MAC3E,OAAO/B,OAAO,CAACoC,KAAK,CAACf,QAAQ,CAACjD,GAAG,EAAE+D,QAAQ,EAAE,MAC3CL,cAAc,CAACO,KAAK,CAAC,IAAI,EAAEN,IAAI,CACjC,CAAC;IACH,CAAC;EACH,CAAC;AACH,CAAC;AAACvB,OAAA,CAAAkB,SAAA,GAAAA,SAAA","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"cache.js","names":["_ioredis","_interopRequireDefault","require","_enums","_secrets","e","__esModule","default","redis","redisOptionsCache","redisOptionsPromise","resolveRedisConfig","ctx","vaultName","process","env","AZURE_KEY_VAULT_NAME","Error","redisHost","redisKey","redisPortSecret","Promise","all","getAzureVaultSecretByKey","AzureSecretKeysEnum","REDIS_HOST","REDIS_KEY","REDIS_PORT","redisPort","Number","host","key","port","buildRedisOptions","password","tls","servername","maxRetriesPerRequest","enableReadyCheck","then","options","finally","getRedisClient","Redis","on","err","error","registerSecretsRedis","info","exports","buildKey","namespace","parts","map","part","join","createCache","ttlSeconds","get","client","set","value","getOrSet","fetcher","cached","delete","del","Cacheable","_target","_propertyKey","descriptor","originalMethod","args","_options$getContext","getContext","context","keyParts","cache","apply"],"sources":["../../../src/utils/cache.ts"],"sourcesContent":["import Redis, { RedisOptions } from \"ioredis\";\nimport { InvocationContext } from \"@azure/functions\";\nimport { AzureSecretKeysEnum } from \"../enums\";\nimport { getAzureVaultSecretByKey, registerSecretsRedis } from \"./secrets\";\n\nlet redis: Redis | null = null;\nlet redisOptionsCache: RedisOptions | string | null = null;\nlet redisOptionsPromise: Promise<RedisOptions | string> | null = null;\n\ntype RedisConfig = {\n host: string;\n key: string;\n port: number;\n};\n\nconst resolveRedisConfig = async (\n ctx?: InvocationContext,\n): Promise<RedisConfig> => {\n const vaultName = process.env.AZURE_KEY_VAULT_NAME || \"\";\n if (!vaultName) {\n throw new Error(\"AZURE_KEY_VAULT_NAME is required to fetch Redis secrets\");\n }\n if (!ctx) {\n throw new Error(\"InvocationContext is required to fetch Redis secrets\");\n }\n\n const [redisHost, redisKey, redisPortSecret] = await Promise.all([\n getAzureVaultSecretByKey(ctx, vaultName, AzureSecretKeysEnum.REDIS_HOST),\n getAzureVaultSecretByKey(ctx, vaultName, AzureSecretKeysEnum.REDIS_KEY),\n getAzureVaultSecretByKey(ctx, vaultName, AzureSecretKeysEnum.REDIS_PORT),\n ]);\n\n const redisPort = redisPortSecret ? Number(redisPortSecret) : 6380;\n\n if (!redisHost || !redisKey) {\n throw new Error(\"Redis configuration missing in Key Vault\");\n }\n\n return {\n host: redisHost,\n key: redisKey,\n port: redisPort,\n };\n};\n\nconst buildRedisOptions = async (\n ctx?: InvocationContext,\n): Promise<RedisOptions | string> => {\n if (redisOptionsCache) return redisOptionsCache;\n if (redisOptionsPromise) return redisOptionsPromise;\n\n redisOptionsPromise = (async () => {\n const { host, key, port } = await resolveRedisConfig(ctx);\n\n return {\n host,\n port,\n password: key,\n tls: { servername: host },\n maxRetriesPerRequest: 3,\n enableReadyCheck: false,\n };\n })()\n .then((options) => {\n redisOptionsCache = options;\n return options;\n })\n .finally(() => {\n redisOptionsPromise = null;\n });\n\n return redisOptionsPromise;\n};\n\nexport const getRedisClient = async (ctx?: InvocationContext): Promise<Redis> => {\n if (redis) return redis;\n\n const options = await buildRedisOptions(ctx);\n\n redis = new Redis(options as RedisOptions);\n redis.on(\"error\", (err) => ctx?.error?.(\"Redis error\", err));\n redis.on(\"connect\", () => {\n registerSecretsRedis(redis!);\n ctx?.info?.(\"Redis connected\");\n });\n return redis;\n};\n\nconst buildKey = (namespace: string, parts: Array<string | number | undefined>) =>\n [namespace, ...parts.map((part) => part ?? \"_\")].join(\":\");\n\nexport const createCache = (namespace: string, ttlSeconds: number) => {\n return {\n key: (...parts: Array<string | number | undefined>) =>\n buildKey(namespace, parts),\n get: async (\n ctx: InvocationContext | undefined,\n ...parts: Array<string | number | undefined>\n ) => {\n const client = await getRedisClient(ctx);\n try {\n return await client.get(buildKey(namespace, parts));\n } catch (error) {\n ctx?.error?.(\"Redis get failed\", error);\n return null;\n }\n },\n set: async (\n ctx: InvocationContext | undefined,\n value: string,\n ...parts: Array<string | number | undefined>\n ) => {\n const client = await getRedisClient(ctx);\n try {\n await client.set(buildKey(namespace, parts), value, \"EX\", ttlSeconds);\n } catch (error) {\n ctx?.error?.(\"Redis set failed\", error);\n }\n },\n getOrSet: async (\n ctx: InvocationContext | undefined,\n parts: Array<string | number | undefined>,\n fetcher: () => Promise<string>,\n ) => {\n const cached = await (async () => {\n const client = await getRedisClient(ctx);\n try {\n return await client.get(buildKey(namespace, parts));\n } catch (error) {\n ctx?.error?.(\"Redis get failed\", error);\n return null;\n }\n })();\n\n if (cached) return cached;\n const value = await fetcher();\n await (async () => {\n const client = await getRedisClient(ctx);\n try {\n await client.set(buildKey(namespace, parts), value, \"EX\", ttlSeconds);\n } catch (error) {\n ctx?.error?.(\"Redis set failed\", error);\n }\n })();\n return value;\n },\n delete: async (\n ctx: InvocationContext | undefined,\n ...parts: Array<string | number | undefined>\n ) => {\n const client = await getRedisClient(ctx);\n try {\n await client.del(buildKey(namespace, parts));\n } catch (error) {\n ctx?.error?.(\"Redis delete failed\", error);\n }\n },\n };\n};\n\ntype CacheableOptions<TArgs extends unknown[]> = {\n cache: ReturnType<typeof createCache>;\n key: (...args: TArgs) => Array<unknown>;\n getContext?: (instance: unknown) => InvocationContext | undefined;\n};\n\nexport const Cacheable = <TArgs extends unknown[]>(\n options: CacheableOptions<TArgs>,\n): MethodDecorator => {\n return (\n _target,\n _propertyKey,\n descriptor: PropertyDescriptor,\n ): void => {\n const originalMethod = descriptor.value as\n | ((...args: TArgs) => Promise<string>)\n | undefined;\n if (!originalMethod) return;\n descriptor.value = async function (...args: TArgs) {\n const ctx =\n options.getContext?.(this) ??\n (this as { context?: InvocationContext }).context;\n const keyParts = options.key(...args) as Array<string | number | undefined>;\n return options.cache.getOrSet(ctx, keyParts, () =>\n originalMethod.apply(this, args),\n );\n };\n };\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -3,41 +3,111 @@
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
4
|
exports.getAzureVaultSecretByKey = getAzureVaultSecretByKey;
|
|
5
5
|
exports.getInterservicesCommunicationKey = getInterservicesCommunicationKey;
|
|
6
|
+
exports.registerSecretsRedis = registerSecretsRedis;
|
|
6
7
|
var _identity = require("@azure/identity");
|
|
7
8
|
var _keyvaultSecrets = require("@azure/keyvault-secrets");
|
|
8
9
|
var _enums = require("../enums");
|
|
9
10
|
var _mapper = require("./mapper");
|
|
11
|
+
// L1: in-memory cache — permanent for the lifetime of the Function host instance
|
|
12
|
+
const secretCache = new Map();
|
|
13
|
+
// Deduplicate concurrent in-flight fetches for the same key
|
|
14
|
+
const secretInflight = new Map();
|
|
15
|
+
|
|
16
|
+
// Singleton SecretClient per vault URL
|
|
17
|
+
const secretClients = new Map();
|
|
18
|
+
|
|
19
|
+
// L2: Redis cache — injected by cache.ts after Redis connects (avoids circular import)
|
|
20
|
+
const SECRET_REDIS_TTL = 60; // seconds
|
|
21
|
+
const SECRET_REDIS_NS = "kv-secret";
|
|
22
|
+
let _redis = null;
|
|
23
|
+
|
|
24
|
+
// These secrets are needed to bootstrap the Redis connection itself —
|
|
25
|
+
// they must never be looked up via Redis to prevent infinite recursion.
|
|
26
|
+
const BOOTSTRAP_KEYS = new Set([_enums.AzureSecretKeysEnum.REDIS_HOST, _enums.AzureSecretKeysEnum.REDIS_KEY, _enums.AzureSecretKeysEnum.REDIS_PORT]);
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Called by cache.ts after the Redis client successfully connects.
|
|
30
|
+
* Enables L2 Redis caching for Key Vault secrets without a circular import.
|
|
31
|
+
*/
|
|
32
|
+
function registerSecretsRedis(client) {
|
|
33
|
+
_redis = client;
|
|
34
|
+
}
|
|
35
|
+
function getSecretClient(vaultName) {
|
|
36
|
+
const vaultUrl = `https://${vaultName}.vault.azure.net`;
|
|
37
|
+
if (!secretClients.has(vaultUrl)) {
|
|
38
|
+
secretClients.set(vaultUrl, new _keyvaultSecrets.SecretClient(vaultUrl, new _identity.DefaultAzureCredential()));
|
|
39
|
+
}
|
|
40
|
+
return secretClients.get(vaultUrl);
|
|
41
|
+
}
|
|
42
|
+
|
|
10
43
|
/**
|
|
11
44
|
* Fetches a secret value from Azure Key Vault by key.
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
|
|
45
|
+
*
|
|
46
|
+
* Lookup order (fastest to slowest):
|
|
47
|
+
* L1 in-memory → L2 Redis (60s TTL) → Azure Key Vault
|
|
48
|
+
*
|
|
49
|
+
* Bootstrap secrets (REDIS_HOST/KEY/PORT) skip Redis to avoid circular calls.
|
|
50
|
+
*/
|
|
16
51
|
async function getAzureVaultSecretByKey(context, vaultName, key) {
|
|
17
|
-
// Build the list of valid enum values once
|
|
18
52
|
const validKeys = (0, _mapper.enumMapper)(_enums.AzureSecretKeysEnum);
|
|
19
|
-
|
|
20
|
-
// Validate
|
|
21
53
|
if (!validKeys.includes(key)) {
|
|
22
54
|
const msg = `Invalid secret key requested: ${key}`;
|
|
23
55
|
context.error(msg);
|
|
24
56
|
throw new Error(msg);
|
|
25
57
|
}
|
|
58
|
+
const cacheKey = `${vaultName}:${key}`;
|
|
26
59
|
|
|
27
|
-
//
|
|
28
|
-
const
|
|
60
|
+
// L1 — in-memory
|
|
61
|
+
const l1 = secretCache.get(cacheKey);
|
|
62
|
+
if (l1 !== undefined) return l1;
|
|
29
63
|
|
|
30
|
-
//
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
64
|
+
// L2 — Redis (skipped for bootstrap keys)
|
|
65
|
+
const useRedis = _redis !== null && !BOOTSTRAP_KEYS.has(key);
|
|
66
|
+
if (useRedis) {
|
|
67
|
+
try {
|
|
68
|
+
const l2 = await _redis.get(`${SECRET_REDIS_NS}:${cacheKey}`);
|
|
69
|
+
if (l2 !== null) {
|
|
70
|
+
secretCache.set(cacheKey, l2);
|
|
71
|
+
return l2;
|
|
72
|
+
}
|
|
73
|
+
} catch (err) {
|
|
74
|
+
context.warn == null || context.warn(`Redis L2 secret cache read failed for "${key}", falling through to Key Vault`, err);
|
|
75
|
+
}
|
|
40
76
|
}
|
|
77
|
+
|
|
78
|
+
// Deduplicate concurrent fetches for the same key
|
|
79
|
+
const inflight = secretInflight.get(cacheKey);
|
|
80
|
+
if (inflight) return inflight;
|
|
81
|
+
const fetchPromise = (async () => {
|
|
82
|
+
const client = getSecretClient(vaultName);
|
|
83
|
+
try {
|
|
84
|
+
var _secret$value;
|
|
85
|
+
const secret = await client.getSecret(key);
|
|
86
|
+
const value = (_secret$value = secret.value) != null ? _secret$value : "";
|
|
87
|
+
|
|
88
|
+
// Populate L1
|
|
89
|
+
secretCache.set(cacheKey, value);
|
|
90
|
+
|
|
91
|
+
// Populate L2 — re-check _redis at write time in case Redis connected
|
|
92
|
+
// during the Key Vault round-trip (cold-start race)
|
|
93
|
+
const redisForWrite = !BOOTSTRAP_KEYS.has(key) ? _redis : null;
|
|
94
|
+
if (redisForWrite) {
|
|
95
|
+
try {
|
|
96
|
+
await redisForWrite.set(`${SECRET_REDIS_NS}:${cacheKey}`, value, "EX", SECRET_REDIS_TTL);
|
|
97
|
+
} catch (err) {
|
|
98
|
+
context.warn == null || context.warn(`Redis L2 secret cache write failed for "${key}"`, err);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return value;
|
|
102
|
+
} catch (err) {
|
|
103
|
+
context.error(`Error fetching secret "${key}" from vault "${vaultName}"`, err);
|
|
104
|
+
throw new Error(`Failed to fetch secret "${key}": ${err.message}`);
|
|
105
|
+
} finally {
|
|
106
|
+
secretInflight.delete(cacheKey);
|
|
107
|
+
}
|
|
108
|
+
})();
|
|
109
|
+
secretInflight.set(cacheKey, fetchPromise);
|
|
110
|
+
return fetchPromise;
|
|
41
111
|
}
|
|
42
112
|
async function getInterservicesCommunicationKey(context) {
|
|
43
113
|
var _process$env$INTERSER;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secrets.js","names":["_identity","require","_keyvaultSecrets","_enums","_mapper","
|
|
1
|
+
{"version":3,"file":"secrets.js","names":["_identity","require","_keyvaultSecrets","_enums","_mapper","secretCache","Map","secretInflight","secretClients","SECRET_REDIS_TTL","SECRET_REDIS_NS","_redis","BOOTSTRAP_KEYS","Set","AzureSecretKeysEnum","REDIS_HOST","REDIS_KEY","REDIS_PORT","registerSecretsRedis","client","getSecretClient","vaultName","vaultUrl","has","set","SecretClient","DefaultAzureCredential","get","getAzureVaultSecretByKey","context","key","validKeys","enumMapper","includes","msg","error","Error","cacheKey","l1","undefined","useRedis","l2","err","warn","inflight","fetchPromise","_secret$value","secret","getSecret","value","redisForWrite","message","delete","getInterservicesCommunicationKey","_process$env$INTERSER","localKey","process","env","INTERSERVICES_COMMUNICATION_KEY","trim","AZURE_KEY_VAULT_NAME"],"sources":["../../../src/utils/secrets.ts"],"sourcesContent":["import type Redis from \"ioredis\";\nimport { DefaultAzureCredential } from \"@azure/identity\";\nimport { SecretClient } from \"@azure/keyvault-secrets\";\nimport { InvocationContext } from \"@azure/functions\";\nimport { AzureSecretKeysEnum } from \"../enums\";\nimport { enumMapper } from \"./mapper\";\n\n// L1: in-memory cache — permanent for the lifetime of the Function host instance\nconst secretCache = new Map<string, string>();\n// Deduplicate concurrent in-flight fetches for the same key\nconst secretInflight = new Map<string, Promise<string>>();\n\n// Singleton SecretClient per vault URL\nconst secretClients = new Map<string, SecretClient>();\n\n// L2: Redis cache — injected by cache.ts after Redis connects (avoids circular import)\nconst SECRET_REDIS_TTL = 60; // seconds\nconst SECRET_REDIS_NS = \"kv-secret\";\nlet _redis: Redis | null = null;\n\n// These secrets are needed to bootstrap the Redis connection itself —\n// they must never be looked up via Redis to prevent infinite recursion.\nconst BOOTSTRAP_KEYS = new Set<AzureSecretKeysEnum>([\n AzureSecretKeysEnum.REDIS_HOST,\n AzureSecretKeysEnum.REDIS_KEY,\n AzureSecretKeysEnum.REDIS_PORT,\n]);\n\n/**\n * Called by cache.ts after the Redis client successfully connects.\n * Enables L2 Redis caching for Key Vault secrets without a circular import.\n */\nexport function registerSecretsRedis(client: Redis): void {\n _redis = client;\n}\n\nfunction getSecretClient(vaultName: string): SecretClient {\n const vaultUrl = `https://${vaultName}.vault.azure.net`;\n if (!secretClients.has(vaultUrl)) {\n secretClients.set(vaultUrl, new SecretClient(vaultUrl, new DefaultAzureCredential()));\n }\n return secretClients.get(vaultUrl)!;\n}\n\n/**\n * Fetches a secret value from Azure Key Vault by key.\n *\n * Lookup order (fastest to slowest):\n * L1 in-memory → L2 Redis (60s TTL) → Azure Key Vault\n *\n * Bootstrap secrets (REDIS_HOST/KEY/PORT) skip Redis to avoid circular calls.\n */\nexport async function getAzureVaultSecretByKey(\n context: InvocationContext,\n vaultName: string,\n key: AzureSecretKeysEnum\n): Promise<string> {\n const validKeys = enumMapper(AzureSecretKeysEnum);\n\n if (!validKeys.includes(key)) {\n const msg = `Invalid secret key requested: ${key}`;\n context.error(msg);\n throw new Error(msg);\n }\n\n const cacheKey = `${vaultName}:${key}`;\n\n // L1 — in-memory\n const l1 = secretCache.get(cacheKey);\n if (l1 !== undefined) return l1;\n\n // L2 — Redis (skipped for bootstrap keys)\n const useRedis = _redis !== null && !BOOTSTRAP_KEYS.has(key);\n if (useRedis) {\n try {\n const l2 = await _redis!.get(`${SECRET_REDIS_NS}:${cacheKey}`);\n if (l2 !== null) {\n secretCache.set(cacheKey, l2);\n return l2;\n }\n } catch (err) {\n context.warn?.(`Redis L2 secret cache read failed for \"${key}\", falling through to Key Vault`, err);\n }\n }\n\n // Deduplicate concurrent fetches for the same key\n const inflight = secretInflight.get(cacheKey);\n if (inflight) return inflight;\n\n const fetchPromise = (async () => {\n const client = getSecretClient(vaultName);\n try {\n const secret = await client.getSecret(key);\n const value = secret.value ?? \"\";\n\n // Populate L1\n secretCache.set(cacheKey, value);\n\n // Populate L2 — re-check _redis at write time in case Redis connected\n // during the Key Vault round-trip (cold-start race)\n const redisForWrite = !BOOTSTRAP_KEYS.has(key) ? _redis : null;\n if (redisForWrite) {\n try {\n await redisForWrite.set(`${SECRET_REDIS_NS}:${cacheKey}`, value, \"EX\", SECRET_REDIS_TTL);\n } catch (err) {\n context.warn?.(`Redis L2 secret cache write failed for \"${key}\"`, err);\n }\n }\n\n return value;\n } catch (err: any) {\n context.error(`Error fetching secret \"${key}\" from vault \"${vaultName}\"`, err);\n throw new Error(`Failed to fetch secret \"${key}\": ${err.message}`);\n } finally {\n secretInflight.delete(cacheKey);\n }\n })();\n\n secretInflight.set(cacheKey, fetchPromise);\n return fetchPromise;\n}\n\nexport async function getInterservicesCommunicationKey(\n context: InvocationContext\n): Promise<string> {\n const localKey = process.env.INTERSERVICES_COMMUNICATION_KEY?.trim();\n if (localKey) {\n return localKey;\n }\n\n const vaultName = process.env.AZURE_KEY_VAULT_NAME || \"\";\n if (!vaultName) {\n throw new Error(\"AZURE_KEY_VAULT_NAME is required to fetch interservices key\");\n }\n\n const key = await getAzureVaultSecretByKey(\n context,\n vaultName,\n AzureSecretKeysEnum.INTERSERVICES_COMMUNICATION_KEY\n );\n\n if (!key) {\n throw new Error(\"Interservices communication key not found\");\n }\n\n return key;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
const USER_WITH_PERMISSIONS_PATH = "/v1/user/user-with-permissions";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Fetches current user permissions (roleId.features) from shared-user GET user-with-permissions.
|
|
5
|
+
* Sets state.auth.features and optional state.auth.industry from user.business.
|
|
6
|
+
* Run after verifyMw. Same behaviour as former modules/shared_goals middleware.
|
|
7
|
+
*/
|
|
8
|
+
export const withPermissionsMw = async (req, ctx, next) => {
|
|
9
|
+
var _req$headers$get, _req$headers$get2, _ref2, _req$headers$get3;
|
|
10
|
+
const baseUrl = (process.env.SHARED_USER_URL || "").replace(/\s+/g, "").replace(/\/$/, "");
|
|
11
|
+
if (!baseUrl) {
|
|
12
|
+
var _ref, _ref$state, _state, _state$auth;
|
|
13
|
+
ctx.warn == null || ctx.warn("withPermissionsMw: SHARED_USER_URL not set, skipping permissions fetch");
|
|
14
|
+
(_ref$state = (_ref = ctx).state) != null ? _ref$state : _ref.state = {};
|
|
15
|
+
(_state$auth = (_state = ctx.state).auth) != null ? _state$auth : _state.auth = {};
|
|
16
|
+
ctx.state.auth.features = [];
|
|
17
|
+
return next();
|
|
18
|
+
}
|
|
19
|
+
const url = `${baseUrl}${USER_WITH_PERMISSIONS_PATH}`;
|
|
20
|
+
const cookie = (_req$headers$get = req.headers.get("cookie")) != null ? _req$headers$get : "";
|
|
21
|
+
const appId = (_req$headers$get2 = req.headers.get("app-id")) != null ? _req$headers$get2 : "";
|
|
22
|
+
const sessionMapping = (_ref2 = (_req$headers$get3 = req.headers.get("x-session-mapping")) != null ? _req$headers$get3 : req.headers.get("x-token-mapping")) != null ? _ref2 : "";
|
|
23
|
+
const headers = {
|
|
24
|
+
"Content-Type": "application/json",
|
|
25
|
+
Accept: "application/json"
|
|
26
|
+
};
|
|
27
|
+
if (cookie) headers.Cookie = cookie;
|
|
28
|
+
if (appId) headers["app-id"] = appId;
|
|
29
|
+
if (sessionMapping) headers["x-session-mapping"] = sessionMapping;
|
|
30
|
+
try {
|
|
31
|
+
var _body$data, _user$roleId, _industry, _user$business, _ref4, _ref4$state, _state3, _state3$auth;
|
|
32
|
+
const res = await fetch(url, {
|
|
33
|
+
method: "GET",
|
|
34
|
+
headers
|
|
35
|
+
});
|
|
36
|
+
const body = await res.json().catch(() => ({}));
|
|
37
|
+
if (!res.ok) {
|
|
38
|
+
var _ref3, _ref3$state, _state2, _state2$auth;
|
|
39
|
+
ctx.warn == null || ctx.warn(`withPermissionsMw: user-with-permissions returned ${res.status}`, {
|
|
40
|
+
url,
|
|
41
|
+
status: res.status
|
|
42
|
+
});
|
|
43
|
+
(_ref3$state = (_ref3 = ctx).state) != null ? _ref3$state : _ref3.state = {};
|
|
44
|
+
(_state2$auth = (_state2 = ctx.state).auth) != null ? _state2$auth : _state2.auth = {};
|
|
45
|
+
ctx.state.auth.features = [];
|
|
46
|
+
return next();
|
|
47
|
+
}
|
|
48
|
+
const user = (_body$data = body == null ? void 0 : body.data) != null ? _body$data : body;
|
|
49
|
+
const features = Array.isArray(user == null || (_user$roleId = user.roleId) == null ? void 0 : _user$roleId.features) ? user.roleId.features : [];
|
|
50
|
+
const industry = (_industry = user == null || (_user$business = user.business) == null ? void 0 : _user$business.industry) != null ? _industry : null;
|
|
51
|
+
(_ref4$state = (_ref4 = ctx).state) != null ? _ref4$state : _ref4.state = {};
|
|
52
|
+
(_state3$auth = (_state3 = ctx.state).auth) != null ? _state3$auth : _state3.auth = {};
|
|
53
|
+
ctx.state.auth.features = features;
|
|
54
|
+
if (industry) ctx.state.auth.industry = industry;
|
|
55
|
+
} catch (err) {
|
|
56
|
+
var _ref5, _ref5$state, _state4, _state4$auth;
|
|
57
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
58
|
+
ctx.error == null || ctx.error("withPermissionsMw: fetch failed", {
|
|
59
|
+
message,
|
|
60
|
+
url
|
|
61
|
+
});
|
|
62
|
+
(_ref5$state = (_ref5 = ctx).state) != null ? _ref5$state : _ref5.state = {};
|
|
63
|
+
(_state4$auth = (_state4 = ctx.state).auth) != null ? _state4$auth : _state4.auth = {};
|
|
64
|
+
ctx.state.auth.features = [];
|
|
65
|
+
}
|
|
66
|
+
return next();
|
|
67
|
+
};
|
|
68
|
+
//# sourceMappingURL=withPermissionsMw.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"withPermissionsMw.js","names":["USER_WITH_PERMISSIONS_PATH","withPermissionsMw","req","ctx","next","_req$headers$get","_req$headers$get2","_ref2","_req$headers$get3","baseUrl","process","env","SHARED_USER_URL","replace","_ref","_ref$state","_state","_state$auth","warn","state","auth","features","url","cookie","headers","get","appId","sessionMapping","Accept","Cookie","_body$data","_user$roleId","_industry","_user$business","_ref4","_ref4$state","_state3","_state3$auth","res","fetch","method","body","json","catch","ok","_ref3","_ref3$state","_state2","_state2$auth","status","user","data","Array","isArray","roleId","industry","business","err","_ref5","_ref5$state","_state4","_state4$auth","message","Error","String","error"],"sources":["../../../src/middlewares/withPermissionsMw.ts"],"sourcesContent":["import { HttpRequest, HttpResponseInit, InvocationContext } from \"@azure/functions\";\nimport { IMiddleware } from \"../types/middleware\";\n\nconst USER_WITH_PERMISSIONS_PATH = \"/v1/user/user-with-permissions\";\n\n/**\n * Fetches current user permissions (roleId.features) from shared-user GET user-with-permissions.\n * Sets state.auth.features and optional state.auth.industry from user.business.\n * Run after verifyMw. Same behaviour as former modules/shared_goals middleware.\n */\nexport const withPermissionsMw: IMiddleware = async (\n req: HttpRequest,\n ctx: InvocationContext,\n next: () => Promise<HttpResponseInit>,\n): Promise<HttpResponseInit> => {\n const baseUrl = (process.env.SHARED_USER_URL || \"\").replace(/\\s+/g, \"\").replace(/\\/$/, \"\");\n if (!baseUrl) {\n ctx.warn?.(\"withPermissionsMw: SHARED_USER_URL not set, skipping permissions fetch\");\n (ctx as any).state ??= {};\n (ctx as any).state.auth ??= {};\n (ctx as any).state.auth.features = [];\n return next();\n }\n\n const url = `${baseUrl}${USER_WITH_PERMISSIONS_PATH}`;\n const cookie = req.headers.get(\"cookie\") ?? \"\";\n const appId = req.headers.get(\"app-id\") ?? \"\";\n const sessionMapping = req.headers.get(\"x-session-mapping\") ?? req.headers.get(\"x-token-mapping\") ?? \"\";\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n };\n if (cookie) headers.Cookie = cookie;\n if (appId) headers[\"app-id\"] = appId;\n if (sessionMapping) headers[\"x-session-mapping\"] = sessionMapping;\n\n try {\n const res = await fetch(url, { method: \"GET\", headers });\n const body = await res.json().catch(() => ({}));\n\n if (!res.ok) {\n ctx.warn?.(`withPermissionsMw: user-with-permissions returned ${res.status}`, { url, status: res.status });\n (ctx as any).state ??= {};\n (ctx as any).state.auth ??= {};\n (ctx as any).state.auth.features = [];\n return next();\n }\n\n const user = body?.data ?? body;\n const features = Array.isArray(user?.roleId?.features) ? user.roleId.features : [];\n const industry = (user?.business as { industry?: string } | undefined)?.industry ?? null;\n (ctx as any).state ??= {};\n (ctx as any).state.auth ??= {};\n (ctx as any).state.auth.features = features;\n if (industry) (ctx as any).state.auth.industry = industry;\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n ctx.error?.(\"withPermissionsMw: fetch failed\", { message, url });\n (ctx as any).state ??= {};\n (ctx as any).state.auth ??= {};\n (ctx as any).state.auth.features = [];\n }\n\n return next();\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
var _class;
|
|
2
2
|
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; }
|
|
3
3
|
import { Types } from "mongoose";
|
|
4
|
-
import { Initializers, WithDb } from "@culturefy/shared";
|
|
5
4
|
import { TokenMappingModel } from "../models/tokenMapping.model";
|
|
5
|
+
import { Initializers, WithDb } from "../utils";
|
|
6
6
|
export let TokenMappingService = (_class = class TokenMappingService extends Initializers {
|
|
7
7
|
constructor(context, dbUrl) {
|
|
8
8
|
super(context, dbUrl);
|