@hmcts/rpx-xui-node-lib 2.30.21-package-update-01 → 2.30.21-package-update-04

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.
@@ -10,6 +10,21 @@ export declare class RedisSessionStore extends SessionStore {
10
10
  redisClientReadyListener: (redisClient: RedisClientType) => void;
11
11
  redisClientErrorListener: (redisClient: RedisClientType) => void;
12
12
  emitEvent: (eventName: string, eventObject: any) => void;
13
+ normalizeRedisUrl: (redisCloudUrl: string) => string;
14
+ parseTtl: (redisTtl: number | string | undefined) => number | undefined;
15
+ getRedisClientConfig: (redisCloudUrl: string) => {
16
+ url: string;
17
+ socket?: undefined;
18
+ password?: undefined;
19
+ } | {
20
+ socket: {
21
+ tls?: true | undefined;
22
+ host: string;
23
+ port: number;
24
+ };
25
+ password: string;
26
+ url?: undefined;
27
+ };
13
28
  }
14
29
  export declare const redisStore: RedisSessionStore;
15
30
  //# sourceMappingURL=redisSessionStore.class.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"redisSessionStore.class.d.ts","sourceRoot":"","sources":["../../../src/session/models/redisSessionStore.class.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAA;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,EAAgB,eAAe,EAAE,MAAM,OAAO,CAAA;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAEnD,OAAO,EAAa,SAAS,EAAE,MAAM,cAAc,CAAA;AAEnD,qBAAa,iBAAkB,SAAQ,YAAY;IAC/C,SAAS,CAAC,WAAW,EAAG,eAAe,CAAA;gBAE3B,MAAM,6CAAgC,EAAE,MAAM,GAAE,SAAsC;IAI3F,QAAQ,GAAI,SAAS,oBAAoB,KAAG,UAAU,CAsB5D;IAKM,wBAAwB,GAAI,aAAa,eAAe,UAM9D;IAEM,wBAAwB,GAAI,aAAa,eAAe,UAM9D;IAEM,SAAS,GAAI,WAAW,MAAM,EAAE,aAAa,GAAG,UAItD;CACJ;AAED,eAAO,MAAM,UAAU,mBAA0B,CAAA"}
1
+ {"version":3,"file":"redisSessionStore.class.d.ts","sourceRoot":"","sources":["../../../src/session/models/redisSessionStore.class.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAA;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,EAAgB,eAAe,EAAE,MAAM,OAAO,CAAA;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAEnD,OAAO,EAAa,SAAS,EAAE,MAAM,cAAc,CAAA;AAEnD,qBAAa,iBAAkB,SAAQ,YAAY;IAC/C,SAAS,CAAC,WAAW,EAAG,eAAe,CAAA;gBAE3B,MAAM,6CAAgC,EAAE,MAAM,GAAE,SAAsC;IAI3F,QAAQ,GAAI,SAAS,oBAAoB,KAAG,UAAU,CAmB5D;IAKM,wBAAwB,GAAI,aAAa,eAAe,UAM9D;IAEM,wBAAwB,GAAI,aAAa,eAAe,UAM9D;IAEM,SAAS,GAAI,WAAW,MAAM,EAAE,aAAa,GAAG,UAItD;IAIM,iBAAiB,GAAI,eAAe,MAAM,KAAG,MAAM,CAgBzD;IAGM,QAAQ,GAAI,UAAU,MAAM,GAAG,MAAM,GAAG,SAAS,KAAG,MAAM,GAAG,SAAS,CAO5E;IAIM,oBAAoB,GAAI,eAAe,MAAM;;;;;;;;;;;;MAkCnD;CACJ;AAED,eAAO,MAAM,UAAU,mBAA0B,CAAA"}
@@ -11,12 +11,9 @@ class RedisSessionStore extends sessionStore_class_1.SessionStore {
11
11
  constructor(router = (0, express_1.Router)({ mergeParams: true }), logger = (0, common_1.getLogger)('session:redis')) {
12
12
  super(session_constants_1.SESSION.REDIS_STORE_NAME, router, logger);
13
13
  this.getStore = (options) => {
14
- const ttl = options.redisStoreOptions.redisTtl === undefined
15
- ? undefined
16
- : Number(options.redisStoreOptions.redisTtl);
17
- this.redisClient = (0, redis_1.createClient)({
18
- url: options.redisStoreOptions.redisCloudUrl,
19
- });
14
+ const ttl = this.parseTtl(options.redisStoreOptions.redisTtl);
15
+ const redisClientConfig = this.getRedisClientConfig(options.redisStoreOptions.redisCloudUrl);
16
+ this.redisClient = (0, redis_1.createClient)(redisClientConfig);
20
17
  this.redisClientReadyListener(this.redisClient);
21
18
  this.redisClientErrorListener(this.redisClient);
22
19
  this.redisClient.connect().catch((error) => {
@@ -51,6 +48,62 @@ class RedisSessionStore extends sessionStore_class_1.SessionStore {
51
48
  this.emit(eventName, eventObject);
52
49
  }
53
50
  };
51
+ // Keep compatibility with legacy Azure-style URLs: redis://...?...&tls=true
52
+ // redis@6 expects TLS via rediss:// or socket.tls.
53
+ this.normalizeRedisUrl = (redisCloudUrl) => {
54
+ var _a;
55
+ try {
56
+ const parsedRedisUrl = new URL(redisCloudUrl);
57
+ const tlsEnabledViaQuery = ((_a = parsedRedisUrl.searchParams.get('tls')) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'true';
58
+ if (tlsEnabledViaQuery && parsedRedisUrl.protocol === 'redis:') {
59
+ parsedRedisUrl.protocol = 'rediss:';
60
+ parsedRedisUrl.searchParams.delete('tls');
61
+ return parsedRedisUrl.toString();
62
+ }
63
+ return redisCloudUrl;
64
+ }
65
+ catch (_b) {
66
+ // Preserve previous behavior if URL parsing fails.
67
+ return redisCloudUrl;
68
+ }
69
+ };
70
+ // RedisStore defaults to 86400s when ttl is undefined.
71
+ this.parseTtl = (redisTtl) => {
72
+ if (redisTtl === undefined || redisTtl === null || redisTtl === '') {
73
+ return undefined;
74
+ }
75
+ const parsedTtl = Number(redisTtl);
76
+ return Number.isFinite(parsedTtl) && parsedTtl > 0 ? parsedTtl : undefined;
77
+ };
78
+ // Supports both URL-style values and legacy Azure cache strings:
79
+ // host:port,password=...,ssl=true,abortConnect=false
80
+ this.getRedisClientConfig = (redisCloudUrl) => {
81
+ var _a, _b;
82
+ const normalizedRedisUrl = this.normalizeRedisUrl(redisCloudUrl);
83
+ if (/^rediss?:\/\//i.test(normalizedRedisUrl)) {
84
+ return { url: normalizedRedisUrl };
85
+ }
86
+ const [hostPort, ...connectionParts] = redisCloudUrl.split(',').map((part) => part.trim());
87
+ const [host, portValue] = hostPort.split(':');
88
+ const port = Number(portValue);
89
+ if (!host || !Number.isFinite(port)) {
90
+ return { url: normalizedRedisUrl };
91
+ }
92
+ const parsedParts = connectionParts.reduce((accumulator, part) => {
93
+ const [key, ...valueParts] = part.split('=');
94
+ if (!key || valueParts.length === 0) {
95
+ return accumulator;
96
+ }
97
+ accumulator[key.trim().toLowerCase()] = valueParts.join('=').trim();
98
+ return accumulator;
99
+ }, {});
100
+ const tlsEnabled = ((_a = parsedParts.ssl) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'true' || ((_b = parsedParts.tls) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === 'true';
101
+ return {
102
+ socket: Object.assign({ host,
103
+ port }, (tlsEnabled ? { tls: true } : {})),
104
+ password: parsedParts.password,
105
+ };
106
+ };
54
107
  }
55
108
  }
56
109
  exports.RedisSessionStore = RedisSessionStore;
@@ -1 +1 @@
1
- {"version":3,"file":"redisSessionStore.class.js","sourceRoot":"","sources":["../../../src/session/models/redisSessionStore.class.ts"],"names":[],"mappings":";;;AAAA,4DAA8C;AAE9C,iDAA0C;AAC1C,iCAAqD;AACrD,6DAAmD;AACnD,qCAAgC;AAChC,yCAAmD;AAEnD,MAAa,iBAAkB,SAAQ,iCAAY;IAG/C,YAAY,MAAM,GAAG,IAAA,gBAAM,EAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,EAAE,SAAoB,IAAA,kBAAS,EAAC,eAAe,CAAC;QAC9F,KAAK,CAAC,2BAAO,CAAC,gBAAgB,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;QAG5C,aAAQ,GAAG,CAAC,OAA6B,EAAc,EAAE;YAC5D,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC,QAAQ,KAAK,SAAS;gBACxD,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAA;YAEhD,IAAI,CAAC,WAAW,GAAG,IAAA,oBAAY,EAAC;gBAC5B,GAAG,EAAE,OAAO,CAAC,iBAAiB,CAAC,aAAa;aAC/C,CAAC,CAAA;YAEF,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;YAC/C,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;YAE/C,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,KAAY,EAAE,EAAE;gBAC9C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;gBACxB,IAAI,CAAC,SAAS,CAAC,2BAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAA;YAC3D,CAAC,CAAC,CAAA;YAEF,OAAO,IAAI,0BAAU,CAAC;gBAClB,MAAM,EAAE,IAAI,CAAC,WAAW;gBACxB,MAAM,EAAE,OAAO,CAAC,iBAAiB,CAAC,cAAc;gBAChD,GAAG;aACN,CAAC,CAAA;QACN,CAAC,CAAA;QAED,8EAA8E;QAC9E,gFAAgF;QAChF,mCAAmC;QAC5B,6BAAwB,GAAG,CAAC,WAA4B,EAAE,EAAE;YAC/D,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBACzB,IAAI,CAAC,SAAS,CAAC,2BAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAA;gBAC7D,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAA;gBACvD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAA;YACpD,CAAC,CAAC,CAAA;QACN,CAAC,CAAA;QAEM,6BAAwB,GAAG,CAAC,WAA4B,EAAE,EAAE;YAC/D,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAU,EAAE,EAAE;gBACnC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;gBACxB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAA;gBAChD,IAAI,CAAC,SAAS,CAAC,2BAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAA;YAC3D,CAAC,CAAC,CAAA;QACN,CAAC,CAAA;QAEM,cAAS,GAAG,CAAC,SAAiB,EAAE,WAAgB,EAAE,EAAE;YACvD,IAAI,IAAI,CAAC,aAAa,CAAC,2BAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC;gBACvD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;YACrC,CAAC;QACL,CAAC,CAAA;IAjDD,CAAC;CAkDJ;AAvDD,8CAuDC;AAEY,QAAA,UAAU,GAAG,IAAI,iBAAiB,EAAE,CAAA"}
1
+ {"version":3,"file":"redisSessionStore.class.js","sourceRoot":"","sources":["../../../src/session/models/redisSessionStore.class.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hmcts/rpx-xui-node-lib",
3
- "version": "2.30.21-package-update-01",
3
+ "version": "2.30.21-package-update-04",
4
4
  "description": "Common nodejs library components for XUI",
5
5
  "main": "dist/index",
6
6
  "types": "dist/index.d.ts",
@@ -96,7 +96,7 @@
96
96
  "otplib": "^13.4.0",
97
97
  "passport": "^0.7.0",
98
98
  "passport-oauth2": "^1.8.0",
99
- "redis": "^6.0.0",
99
+ "redis": "^6.1.0",
100
100
  "session-file-store": "^1.5.0"
101
101
  },
102
102
  "resolutions": {