@hmcts/opal-frontend-common-node 0.0.15 → 0.0.17

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/index.d.ts CHANGED
@@ -5,5 +5,6 @@ export * from './helmet';
5
5
  export * from './properties-volume';
6
6
  export * from './csrf-token';
7
7
  export * from './routes';
8
+ export * from './services';
8
9
  export * from './interfaces';
9
10
  //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AAGzB,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAG3B,cAAc,cAAc,CAAC"}
package/index.js CHANGED
@@ -5,6 +5,7 @@ export * from './helmet';
5
5
  export * from './properties-volume';
6
6
  export * from './csrf-token';
7
7
  export * from './routes';
8
+ export * from './services';
8
9
  // INTERFACES
9
10
  export * from './interfaces';
10
11
  //# sourceMappingURL=index.js.map
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AAEzB,aAAa;AACb,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAE3B,aAAa;AACb,cAAc,cAAc,CAAC"}
@@ -7,4 +7,5 @@ export { default as SessionStorageConfiguration } from './session-storage-config
7
7
  export { default as RoutesConfiguration } from './routes-config';
8
8
  export { default as SsoConfiguration } from './sso-config';
9
9
  export { default as SessionConfiguration } from './session-config';
10
+ export { default as OpalUserServiceConfiguration } from './opal-user-service-config';
10
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interfaces/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAE,OAAO,IAAI,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAClF,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interfaces/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAE,OAAO,IAAI,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAClF,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,OAAO,IAAI,4BAA4B,EAAE,MAAM,4BAA4B,CAAC"}
@@ -7,4 +7,5 @@ export { default as SessionStorageConfiguration } from './session-storage-config
7
7
  export { default as RoutesConfiguration } from './routes-config';
8
8
  export { default as SsoConfiguration } from './sso-config';
9
9
  export { default as SessionConfiguration } from './session-config';
10
+ export { default as OpalUserServiceConfiguration } from './opal-user-service-config';
10
11
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/interfaces/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAE,OAAO,IAAI,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAClF,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/interfaces/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAE,OAAO,IAAI,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAClF,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,OAAO,IAAI,4BAA4B,EAAE,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,7 @@
1
+ declare class OpalUserServiceConfiguration {
2
+ userStateUrl: string;
3
+ addUserUrl: string;
4
+ updateUserUrl: string;
5
+ }
6
+ export default OpalUserServiceConfiguration;
7
+ //# sourceMappingURL=opal-user-service-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opal-user-service-config.d.ts","sourceRoot":"","sources":["../../src/interfaces/opal-user-service-config.ts"],"names":[],"mappings":"AAAA,cAAM,4BAA4B;IAChC,YAAY,EAAG,MAAM,CAAC;IACtB,UAAU,EAAG,MAAM,CAAC;IACpB,aAAa,EAAG,MAAM,CAAC;CACxB;AAED,eAAe,4BAA4B,CAAC"}
@@ -0,0 +1,7 @@
1
+ class OpalUserServiceConfiguration {
2
+ userStateUrl;
3
+ addUserUrl;
4
+ updateUserUrl;
5
+ }
6
+ export default OpalUserServiceConfiguration;
7
+ //# sourceMappingURL=opal-user-service-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opal-user-service-config.js","sourceRoot":"","sources":["../../src/interfaces/opal-user-service-config.ts"],"names":[],"mappings":"AAAA,MAAM,4BAA4B;IAChC,YAAY,CAAU;IACtB,UAAU,CAAU;IACpB,aAAa,CAAU;CACxB;AAED,eAAe,4BAA4B,CAAC"}
@@ -4,6 +4,7 @@ declare class TransferServerState {
4
4
  launchDarklyConfig: LaunchDarklyConfig;
5
5
  ssoEnabled: boolean;
6
6
  appInsightsConfig: AppInsightsConfig;
7
+ userStateCacheExpirationMilliseconds: number;
7
8
  }
8
9
  export default TransferServerState;
9
10
  //# sourceMappingURL=transfer-server-state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"transfer-server-state.d.ts","sourceRoot":"","sources":["../../src/interfaces/transfer-server-state.ts"],"names":[],"mappings":"AAAA,OAAO,iBAAiB,MAAM,uBAAuB,CAAC;AACtD,OAAO,kBAAkB,MAAM,wBAAwB,CAAC;AAExD,cAAM,mBAAmB;IACvB,kBAAkB,EAAG,kBAAkB,CAAC;IACxC,UAAU,EAAG,OAAO,CAAC;IACrB,iBAAiB,EAAG,iBAAiB,CAAC;CACvC;AAED,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"transfer-server-state.d.ts","sourceRoot":"","sources":["../../src/interfaces/transfer-server-state.ts"],"names":[],"mappings":"AAAA,OAAO,iBAAiB,MAAM,uBAAuB,CAAC;AACtD,OAAO,kBAAkB,MAAM,wBAAwB,CAAC;AAExD,cAAM,mBAAmB;IACvB,kBAAkB,EAAG,kBAAkB,CAAC;IACxC,UAAU,EAAG,OAAO,CAAC;IACrB,iBAAiB,EAAG,iBAAiB,CAAC;IACtC,oCAAoC,EAAG,MAAM,CAAC;CAC/C;AAED,eAAe,mBAAmB,CAAC"}
@@ -2,6 +2,7 @@ class TransferServerState {
2
2
  launchDarklyConfig;
3
3
  ssoEnabled;
4
4
  appInsightsConfig;
5
+ userStateCacheExpirationMilliseconds;
5
6
  }
6
7
  export default TransferServerState;
7
8
  //# sourceMappingURL=transfer-server-state.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transfer-server-state.js","sourceRoot":"","sources":["../../src/interfaces/transfer-server-state.ts"],"names":[],"mappings":"AAGA,MAAM,mBAAmB;IACvB,kBAAkB,CAAsB;IACxC,UAAU,CAAW;IACrB,iBAAiB,CAAqB;CACvC;AAED,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"transfer-server-state.js","sourceRoot":"","sources":["../../src/interfaces/transfer-server-state.ts"],"names":[],"mappings":"AAGA,MAAM,mBAAmB;IACvB,kBAAkB,CAAsB;IACxC,UAAU,CAAW;IACrB,iBAAiB,CAAqB;IACtC,oCAAoC,CAAU;CAC/C;AAED,eAAe,mBAAmB,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hmcts/opal-frontend-common-node",
3
3
  "type": "module",
4
- "version": "0.0.15",
4
+ "version": "0.0.17",
5
5
  "license": "MIT",
6
6
  "description": "Common nodejs library components for opal",
7
7
  "main": "dist/index",
@@ -43,10 +43,10 @@
43
43
  "@types/cookie-parser": "^1.4.6",
44
44
  "@types/express": "^5.0.0",
45
45
  "@types/luxon": "^3.4.2",
46
- "@types/node": "^22.0.0",
46
+ "@types/node": "^24.0.0",
47
47
  "@types/session-file-store": "^1.2.5",
48
- "@typescript-eslint/eslint-plugin": "8.45.0",
49
- "@typescript-eslint/parser": "8.45.0",
48
+ "@typescript-eslint/eslint-plugin": "8.46.4",
49
+ "@typescript-eslint/parser": "8.46.4",
50
50
  "eslint": "^9.0.0",
51
51
  "eslint-plugin-prettier": "^5.2.6",
52
52
  "typescript": "~5.9.0",
@@ -86,6 +86,10 @@
86
86
  "import": "./routes/index.js",
87
87
  "types": "./routes/index.d.ts"
88
88
  },
89
+ "./services": {
90
+ "import": "./services/index.js",
91
+ "types": "./services/index.d.ts"
92
+ },
89
93
  "./interfaces": {
90
94
  "import": "./interfaces/index.js",
91
95
  "types": "./interfaces/index.d.ts"
package/routes/index.d.ts CHANGED
@@ -3,9 +3,10 @@ import ExpiryConfiguration from '@hmcts/opal-frontend-common-node/interfaces/ses
3
3
  import RoutesConfiguration from '@hmcts/opal-frontend-common-node/interfaces/routes-config';
4
4
  import SsoConfiguration from '@hmcts/opal-frontend-common-node/interfaces/sso-config';
5
5
  import SessionConfiguration from '@hmcts/opal-frontend-common-node/interfaces/session-config';
6
+ import OpalUserServiceConfig from '../interfaces/opal-user-service-config';
6
7
  export declare class Routes {
7
8
  private setupSSORoutes;
8
9
  private setupStubRoutes;
9
- enableFor(app: Application, ssoEnabled: boolean, expiryConfiguration: ExpiryConfiguration, routesConfiguration: RoutesConfiguration, sessionConfiguration: SessionConfiguration, ssoConfiguration: SsoConfiguration): void;
10
+ enableFor(app: Application, ssoEnabled: boolean, expiryConfiguration: ExpiryConfiguration, routesConfiguration: RoutesConfiguration, sessionConfiguration: SessionConfiguration, ssoConfiguration: SsoConfiguration, opalUserServiceConfig: OpalUserServiceConfig): void;
10
11
  }
11
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/routes/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAQtC,OAAO,mBAAmB,MAAM,mEAAmE,CAAC;AACpG,OAAO,mBAAmB,MAAM,2DAA2D,CAAC;AAC5F,OAAO,gBAAgB,MAAM,wDAAwD,CAAC;AACtF,OAAO,oBAAoB,MAAM,4DAA4D,CAAC;AAG9F,qBAAa,MAAM;IACjB,OAAO,CAAC,cAAc;IAoDtB,OAAO,CAAC,eAAe;IA2BhB,SAAS,CACd,GAAG,EAAE,WAAW,EAChB,UAAU,EAAE,OAAO,EACnB,mBAAmB,EAAE,mBAAmB,EACxC,mBAAmB,EAAE,mBAAmB,EACxC,oBAAoB,EAAE,oBAAoB,EAC1C,gBAAgB,EAAE,gBAAgB,GACjC,IAAI;CAqBR"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/routes/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAQtC,OAAO,mBAAmB,MAAM,mEAAmE,CAAC;AACpG,OAAO,mBAAmB,MAAM,2DAA2D,CAAC;AAC5F,OAAO,gBAAgB,MAAM,wDAAwD,CAAC;AACtF,OAAO,oBAAoB,MAAM,4DAA4D,CAAC;AAE9F,OAAO,qBAAqB,MAAM,wCAAwC,CAAC;AAE3E,qBAAa,MAAM;IACjB,OAAO,CAAC,cAAc;IAqDtB,OAAO,CAAC,eAAe;IA2BhB,SAAS,CACd,GAAG,EAAE,WAAW,EAChB,UAAU,EAAE,OAAO,EACnB,mBAAmB,EAAE,mBAAmB,EACxC,mBAAmB,EAAE,mBAAmB,EACxC,oBAAoB,EAAE,oBAAoB,EAC1C,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,qBAAqB,GAC3C,IAAI;CAqBR"}
package/routes/index.js CHANGED
@@ -6,7 +6,7 @@ import { ssoAuthenticatedStub, ssoLogoutCallbackStub, ssoLoginStub, ssoLoginCall
6
6
  import sessionExpiry from '@hmcts/opal-frontend-common-node/session/session-expiry';
7
7
  import ssoLogoutCallback from '../sso/sso-logout-callback';
8
8
  export class Routes {
9
- setupSSORoutes(app, ssoConfiguration, routesConfiguration) {
9
+ setupSSORoutes(app, ssoConfiguration, routesConfiguration, opalUserServiceConfig) {
10
10
  if (!routesConfiguration.clientId || !routesConfiguration.clientSecret || !routesConfiguration.tenantId) {
11
11
  throw new Error('Missing essential SSO configuration fields: clientId, clientSecret, or tenantId');
12
12
  }
@@ -15,7 +15,7 @@ export class Routes {
15
15
  // LOGIN
16
16
  app.get(ssoConfiguration.login, (req, res, next) => ssoLogin(res, next, confidentialClient, routesConfiguration.frontendHostname, ssoConfiguration.loginCallback));
17
17
  // LOGIN CALLBACK
18
- app.post(ssoConfiguration.loginCallback, (req, res) => ssoLoginCallback(req, res, confidentialClient, routesConfiguration.clientId, routesConfiguration.frontendHostname, ssoConfiguration.loginCallback));
18
+ app.post(ssoConfiguration.loginCallback, (req, res) => ssoLoginCallback(req, res, confidentialClient, ssoConfiguration.loginCallback, routesConfiguration, opalUserServiceConfig));
19
19
  // LOGOUT
20
20
  app.get(ssoConfiguration.logout, (req, res) => ssoLogout(res, `${routesConfiguration.microsoftUrl}${routesConfiguration.tenantId}`, `${routesConfiguration.frontendHostname}${ssoConfiguration.logoutCallback}`));
21
21
  // LOGOUT CALLBACK
@@ -27,7 +27,7 @@ export class Routes {
27
27
  // LOGIN
28
28
  app.get(ssoConfiguration.login, (req, res, next) => ssoLoginStub(req, res, next));
29
29
  // LOGIN CALLBACK
30
- app.get(ssoConfiguration.loginCallback, (req, res, next) => ssoLoginCallbackStub(req, res, next, routesConfiguration.opalApiTarget));
30
+ app.get(ssoConfiguration.loginCallback, (req, res, next) => ssoLoginCallbackStub(req, res, next, routesConfiguration.opalUserServiceTarget));
31
31
  // LOGOUT
32
32
  app.get(ssoConfiguration.logout, (req, res, next) => ssoLogoutCallbackStub(req, res, next, routesConfiguration.prefix));
33
33
  // LOGOUT CALLBACK
@@ -35,12 +35,12 @@ export class Routes {
35
35
  // AUTHENTICATED
36
36
  app.get(ssoConfiguration.authenticated, (req, res) => ssoAuthenticatedStub(req, res));
37
37
  }
38
- enableFor(app, ssoEnabled, expiryConfiguration, routesConfiguration, sessionConfiguration, ssoConfiguration) {
38
+ enableFor(app, ssoEnabled, expiryConfiguration, routesConfiguration, sessionConfiguration, ssoConfiguration, opalUserServiceConfig) {
39
39
  // Declare use of body-parser AFTER the use of proxy https://github.com/villadora/express-http-proxy
40
40
  app.use(bodyParser.json());
41
41
  app.use(bodyParser.urlencoded({ extended: false }));
42
42
  if (ssoEnabled) {
43
- this.setupSSORoutes(app, ssoConfiguration, routesConfiguration);
43
+ this.setupSSORoutes(app, ssoConfiguration, routesConfiguration, opalUserServiceConfig);
44
44
  }
45
45
  else {
46
46
  this.setupStubRoutes(app, ssoConfiguration, routesConfiguration);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/routes/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/routes/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { handleCheckUser } from './opal-user-service';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { handleCheckUser } from './opal-user-service';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import OpalUserServiceConfiguration from '../interfaces/opal-user-service-config';
2
+ /**
3
+ * Handles user validation and management after successful SSO login
4
+ * @param opalUserServiceTarget - The base URL of the opal-user-service
5
+ * @param accessToken - The access token for authentication
6
+ * @returns Promise<boolean> - true if user management was successful, false otherwise
7
+ */
8
+ export declare function handleCheckUser(opalUserServiceTarget: string, accessToken: string, config: OpalUserServiceConfiguration): Promise<boolean>;
9
+ //# sourceMappingURL=opal-user-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opal-user-service.d.ts","sourceRoot":"","sources":["../../src/services/opal-user-service.ts"],"names":[],"mappings":"AAEA,OAAO,4BAA4B,MAAM,wCAAwC,CAAC;AA0HlF;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,qBAAqB,EAAE,MAAM,EAC7B,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,4BAA4B,GACnC,OAAO,CAAC,OAAO,CAAC,CAoDlB"}
@@ -0,0 +1,152 @@
1
+ import axios from 'axios';
2
+ import { Logger } from '@hmcts/nodejs-logging';
3
+ const logger = Logger.getLogger('opal-user-service');
4
+ /**
5
+ * Checks if a user exists in the opal-user-service
6
+ * @param opalUserServiceTarget - The base URL of the opal-user-service
7
+ * @param accessToken - The access token for authentication
8
+ * @returns Promise<{status: number, user_id?: string, version?: string}>
9
+ */
10
+ async function checkUserExists(opalUserServiceTarget, accessToken, userStateUrl) {
11
+ try {
12
+ const response = await axios.get(`${opalUserServiceTarget}${userStateUrl}`, {
13
+ headers: {
14
+ Authorization: `Bearer ${accessToken}`,
15
+ 'Content-Type': 'application/json',
16
+ },
17
+ });
18
+ return {
19
+ status: response.status,
20
+ user_id: response.data?.user_id,
21
+ version: response.headers['etag'],
22
+ };
23
+ }
24
+ catch (error) {
25
+ if (axios.isAxiosError(error)) {
26
+ const status = error.response?.status;
27
+ if (status) {
28
+ return {
29
+ status,
30
+ // For 409 conflicts, extract user_id from resourceId
31
+ user_id: error.response?.data?.resourceId,
32
+ // Extract version from ETag header (same as success case)
33
+ version: error.response?.headers['etag'],
34
+ };
35
+ }
36
+ logger.error('Axios error without response status when checking user state', {
37
+ message: error.message,
38
+ code: error.code,
39
+ });
40
+ return { status: 500 };
41
+ }
42
+ logger.error('Unexpected error when checking user state', error);
43
+ return { status: 500 };
44
+ }
45
+ }
46
+ /**
47
+ * Adds a new user via the opal-user-service
48
+ * @param opalUserServiceTarget - The base URL of the opal-user-service
49
+ * @param accessToken - The access token for authentication
50
+ * @returns Promise<boolean> - true if successful, false otherwise
51
+ */
52
+ async function addUser(opalUserServiceTarget, accessToken, addUserUrl) {
53
+ try {
54
+ const response = await axios.post(`${opalUserServiceTarget}${addUserUrl}`, {}, {
55
+ headers: {
56
+ Authorization: `Bearer ${accessToken}`,
57
+ 'Content-Type': 'application/json',
58
+ },
59
+ });
60
+ return response.status === 201 || response.status === 200;
61
+ }
62
+ catch (error) {
63
+ logger.error('Error adding user', error);
64
+ return false;
65
+ }
66
+ }
67
+ /**
68
+ * Updates an existing user via the opal-user-service
69
+ * @param opalUserServiceTarget - The base URL of the opal-user-service
70
+ * @param accessToken - The access token for authentication
71
+ * @param updateUserUrl - The update user endpoint URL
72
+ * @param userId - The user ID to update
73
+ * @param version - The version number for optimistic locking
74
+ * @returns Promise<boolean> - true if successful, false otherwise
75
+ */
76
+ async function updateUser(opalUserServiceTarget, accessToken, updateUserUrl, userId, version) {
77
+ try {
78
+ const headers = {
79
+ Authorization: `Bearer ${accessToken}`,
80
+ 'Content-Type': 'application/json',
81
+ 'If-Match': version,
82
+ };
83
+ const response = await axios.put(`${opalUserServiceTarget}${updateUserUrl}/${userId}`, {}, { headers });
84
+ return response.status === 200;
85
+ }
86
+ catch (error) {
87
+ if (axios.isAxiosError(error)) {
88
+ logger.error('updateUser axios error', {
89
+ status: error.response?.status,
90
+ statusText: error.response?.statusText,
91
+ data: error.response?.data,
92
+ url: error.config?.url,
93
+ method: error.config?.method,
94
+ message: error.message,
95
+ });
96
+ }
97
+ else {
98
+ logger.error('updateUser non-axios error', { error: String(error) });
99
+ }
100
+ return false;
101
+ }
102
+ }
103
+ /**
104
+ * Handles user validation and management after successful SSO login
105
+ * @param opalUserServiceTarget - The base URL of the opal-user-service
106
+ * @param accessToken - The access token for authentication
107
+ * @returns Promise<boolean> - true if user management was successful, false otherwise
108
+ */
109
+ export async function handleCheckUser(opalUserServiceTarget, accessToken, config) {
110
+ const userResult = await checkUserExists(opalUserServiceTarget, accessToken, config.userStateUrl);
111
+ switch (userResult.status) {
112
+ case 200:
113
+ logger.info('User exists, proceeding to frontend');
114
+ return true;
115
+ case 404: {
116
+ logger.info('User not found, attempting to add user');
117
+ const addResult = await addUser(opalUserServiceTarget, accessToken, config.addUserUrl);
118
+ if (addResult) {
119
+ logger.info('User successfully added');
120
+ return true;
121
+ }
122
+ else {
123
+ logger.error('Failed to add user');
124
+ return false;
125
+ }
126
+ }
127
+ case 409: {
128
+ logger.info('User conflict detected, attempting to update user');
129
+ if (!userResult.user_id) {
130
+ logger.error('Cannot update user: userId not available');
131
+ return false;
132
+ }
133
+ if (!userResult.version) {
134
+ logger.error('Cannot update user: version not available');
135
+ return false;
136
+ }
137
+ const updateResult = await updateUser(opalUserServiceTarget, accessToken, config.updateUserUrl, userResult.user_id, userResult.version);
138
+ if (updateResult) {
139
+ logger.info('User successfully updated');
140
+ return true;
141
+ }
142
+ else {
143
+ logger.error('Failed to update user');
144
+ return false;
145
+ }
146
+ }
147
+ default:
148
+ logger.error('Error during user validation', { status: userResult.status });
149
+ return false;
150
+ }
151
+ }
152
+ //# sourceMappingURL=opal-user-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opal-user-service.js","sourceRoot":"","sources":["../../src/services/opal-user-service.ts"],"names":[],"mappings":"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"}
@@ -1,22 +1,25 @@
1
1
  import { Request, Response } from 'express';
2
2
  import { ConfidentialClientApplication } from '@azure/msal-node';
3
3
  import 'express-session';
4
+ import { RoutesConfiguration } from '../interfaces';
5
+ import OpalUserServiceConfiguration from '../interfaces/opal-user-service-config';
4
6
  /**
5
- * Handles the SSO login callback by exchanging the authorization code for tokens using MSAL,
6
- * storing the access token in the session, and redirecting the user to the frontend.
7
+ * Handles the SSO login callback by processing the authorization code, acquiring tokens,
8
+ * and managing the user in the Opal User Service. This function is designed to handle
9
+ * transient network errors during token acquisition and ensures proper session management.
7
10
  *
8
- * @param req - The Express request object, expected to contain the authorization code in the body.
9
- * @param res - The Express response object, used to send responses or perform redirects.
10
- * @param msalInstance - An instance of MSAL ConfidentialClientApplication used to acquire tokens.
11
- * @param clientId - The client ID of the application, used to build the token request scope.
12
- * @param frontendHostname - The base URL of the frontend application, used for redirect URIs.
13
- * @param ssoLoginCallback - The path of the SSO login callback, appended to the frontend hostname for redirect URI.
14
- * @returns A promise that resolves when the callback handling is complete.
11
+ * @param req - The HTTP request object containing the authorization code in the body.
12
+ * @param res - The HTTP response object used to send responses back to the client.
13
+ * @param msalInstance - An instance of the MSAL ConfidentialClientApplication used to acquire tokens.
14
+ * @param clientId - The client ID of the application registered in Azure AD.
15
+ * @param frontendHostname - The hostname of the frontend application.
16
+ * @param ssoLoginCallback - The relative path of the SSO login callback endpoint.
17
+ * @param opalUserServiceTarget - The target URL of the Opal User Service for user validation.
18
+ * @param opalUserServiceConfig - Configuration options for the Opal User Service.
15
19
  *
16
- * @remarks
17
- * - If the authorization code is missing, responds with HTTP 400.
18
- * - On successful token acquisition, stores the access token in the session and redirects to the frontend.
19
- * - On error, logs the error and responds with HTTP 500.
20
+ * @returns A promise that resolves when the SSO login callback process is complete.
21
+ *
22
+ * @throws Will throw an error if token acquisition fails after retries or if user validation fails.
20
23
  */
21
- export default function ssoLoginCallbackHandler(req: Request, res: Response, msalInstance: ConfidentialClientApplication, clientId: string, frontendHostname: string, ssoLoginCallback: string): Promise<void>;
24
+ export default function ssoLoginCallbackHandler(req: Request, res: Response, msalInstance: ConfidentialClientApplication, ssoLoginCallback: string, routesConfiguration: RoutesConfiguration, opalUserServiceConfig: OpalUserServiceConfiguration): Promise<void>;
22
25
  //# sourceMappingURL=sso-login-callback.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sso-login-callback.d.ts","sourceRoot":"","sources":["../../src/sso/sso-login-callback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,iBAAiB,CAAC;AAOzB;;;;;;;;;;;;;;;;GAgBG;AACH,wBAA8B,uBAAuB,CACnD,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,YAAY,EAAE,6BAA6B,EAC3C,QAAQ,EAAE,MAAM,EAChB,gBAAgB,EAAE,MAAM,EACxB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,IAAI,CAAC,CA6Df"}
1
+ {"version":3,"file":"sso-login-callback.d.ts","sourceRoot":"","sources":["../../src/sso/sso-login-callback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,iBAAiB,CAAC;AACzB,OAAO,EAAE,mBAAmB,EAAiB,MAAM,eAAe,CAAC;AAGnE,OAAO,4BAA4B,MAAM,wCAAwC,CAAC;AAKlF;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAA8B,uBAAuB,CACnD,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,YAAY,EAAE,6BAA6B,EAC3C,gBAAgB,EAAE,MAAM,EACxB,mBAAmB,EAAE,mBAAmB,EACxC,qBAAqB,EAAE,4BAA4B,GAClD,OAAO,CAAC,IAAI,CAAC,CAyEf"}
@@ -1,30 +1,32 @@
1
1
  import 'express-session';
2
2
  import { Logger } from '@hmcts/nodejs-logging';
3
+ import { handleCheckUser } from '../services/opal-user-service';
3
4
  const logger = Logger.getLogger('sso-login-callback');
4
5
  const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
5
6
  /**
6
- * Handles the SSO login callback by exchanging the authorization code for tokens using MSAL,
7
- * storing the access token in the session, and redirecting the user to the frontend.
7
+ * Handles the SSO login callback by processing the authorization code, acquiring tokens,
8
+ * and managing the user in the Opal User Service. This function is designed to handle
9
+ * transient network errors during token acquisition and ensures proper session management.
8
10
  *
9
- * @param req - The Express request object, expected to contain the authorization code in the body.
10
- * @param res - The Express response object, used to send responses or perform redirects.
11
- * @param msalInstance - An instance of MSAL ConfidentialClientApplication used to acquire tokens.
12
- * @param clientId - The client ID of the application, used to build the token request scope.
13
- * @param frontendHostname - The base URL of the frontend application, used for redirect URIs.
14
- * @param ssoLoginCallback - The path of the SSO login callback, appended to the frontend hostname for redirect URI.
15
- * @returns A promise that resolves when the callback handling is complete.
11
+ * @param req - The HTTP request object containing the authorization code in the body.
12
+ * @param res - The HTTP response object used to send responses back to the client.
13
+ * @param msalInstance - An instance of the MSAL ConfidentialClientApplication used to acquire tokens.
14
+ * @param clientId - The client ID of the application registered in Azure AD.
15
+ * @param frontendHostname - The hostname of the frontend application.
16
+ * @param ssoLoginCallback - The relative path of the SSO login callback endpoint.
17
+ * @param opalUserServiceTarget - The target URL of the Opal User Service for user validation.
18
+ * @param opalUserServiceConfig - Configuration options for the Opal User Service.
16
19
  *
17
- * @remarks
18
- * - If the authorization code is missing, responds with HTTP 400.
19
- * - On successful token acquisition, stores the access token in the session and redirects to the frontend.
20
- * - On error, logs the error and responds with HTTP 500.
20
+ * @returns A promise that resolves when the SSO login callback process is complete.
21
+ *
22
+ * @throws Will throw an error if token acquisition fails after retries or if user validation fails.
21
23
  */
22
- export default async function ssoLoginCallbackHandler(req, res, msalInstance, clientId, frontendHostname, ssoLoginCallback) {
24
+ export default async function ssoLoginCallbackHandler(req, res, msalInstance, ssoLoginCallback, routesConfiguration, opalUserServiceConfig) {
23
25
  // Build the token request for MSAL using the auth code returned by the IdP.
24
26
  const tokenRequest = {
25
27
  code: req.body['code'],
26
- scopes: [`api://${clientId}/opalinternaluser`],
27
- redirectUri: `${frontendHostname}${ssoLoginCallback}`,
28
+ scopes: [`api://${routesConfiguration.clientId}/opalinternaluser`],
29
+ redirectUri: `${routesConfiguration.frontendHostname}${ssoLoginCallback}`,
28
30
  };
29
31
  if (!tokenRequest.code) {
30
32
  logger.warn('Missing authorization code on SSO callback');
@@ -58,12 +60,19 @@ export default async function ssoLoginCallbackHandler(req, res, msalInstance, cl
58
60
  if (!response?.accessToken)
59
61
  throw new Error('No access token in token response');
60
62
  const accessToken = response.accessToken;
63
+ // Validate and manage user in opal-user-service
64
+ const userManagementSuccess = await handleCheckUser(routesConfiguration.opalUserServiceTarget, accessToken, opalUserServiceConfig);
65
+ if (!userManagementSuccess) {
66
+ logger.error('User management failed after successful token acquisition');
67
+ res.status(500).send('User validation failed');
68
+ return;
69
+ }
61
70
  const securityToken = {
62
71
  user_state: undefined,
63
72
  access_token: accessToken,
64
73
  };
65
74
  req.session.securityToken = securityToken;
66
- req.session.save(() => res.redirect(frontendHostname));
75
+ req.session.save(() => res.redirect(routesConfiguration.frontendHostname));
67
76
  return;
68
77
  }
69
78
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"sso-login-callback.js","sourceRoot":"","sources":["../../src/sso/sso-login-callback.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sso-login-callback.js","sourceRoot":"","sources":["../../src/sso/sso-login-callback.ts"],"names":[],"mappings":"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"}