@hmcts/opal-frontend-common-node 0.0.2 → 0.0.4

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.
Files changed (212) hide show
  1. package/app-insights/app-insights-configuration.d.ts +5 -0
  2. package/app-insights/app-insights-configuration.d.ts.map +1 -0
  3. package/app-insights/app-insights-configuration.js +15 -0
  4. package/app-insights/app-insights-configuration.js.map +1 -0
  5. package/app-insights/index.d.ts +5 -0
  6. package/app-insights/index.d.ts.map +1 -0
  7. package/app-insights/index.js +34 -0
  8. package/app-insights/index.js.map +1 -0
  9. package/csrf-token/index.d.ts +5 -0
  10. package/csrf-token/index.d.ts.map +1 -0
  11. package/csrf-token/index.js +33 -0
  12. package/csrf-token/index.js.map +1 -0
  13. package/health/index.d.ts +8 -0
  14. package/health/index.d.ts.map +1 -0
  15. package/health/index.js +30 -0
  16. package/health/index.js.map +1 -0
  17. package/helmet/index.d.ts +10 -0
  18. package/helmet/index.d.ts.map +1 -0
  19. package/helmet/index.js +54 -0
  20. package/helmet/index.js.map +1 -0
  21. package/index.d.ts +9 -0
  22. package/index.d.ts.map +1 -0
  23. package/{src/index.ts → index.js} +1 -1
  24. package/index.js.map +1 -0
  25. package/interfaces/app-insights-config.d.ts +7 -0
  26. package/interfaces/app-insights-config.d.ts.map +1 -0
  27. package/interfaces/app-insights-config.js +7 -0
  28. package/interfaces/app-insights-config.js.map +1 -0
  29. package/interfaces/index.d.ts +12 -0
  30. package/interfaces/index.d.ts.map +1 -0
  31. package/{src/interfaces/index.ts → interfaces/index.js} +2 -13
  32. package/interfaces/index.js.map +1 -0
  33. package/interfaces/launch-darkly-config.d.ts +7 -0
  34. package/interfaces/launch-darkly-config.d.ts.map +1 -0
  35. package/interfaces/launch-darkly-config.js +7 -0
  36. package/interfaces/launch-darkly-config.js.map +1 -0
  37. package/interfaces/routes-config.d.ts +8 -0
  38. package/interfaces/routes-config.d.ts.map +1 -0
  39. package/interfaces/routes-config.js +8 -0
  40. package/interfaces/routes-config.js.map +1 -0
  41. package/interfaces/securityToken.d.ts +7 -0
  42. package/interfaces/securityToken.d.ts.map +1 -0
  43. package/interfaces/securityToken.js +6 -0
  44. package/interfaces/securityToken.js.map +1 -0
  45. package/interfaces/session-config.d.ts +6 -0
  46. package/interfaces/session-config.d.ts.map +1 -0
  47. package/interfaces/session-config.js +6 -0
  48. package/interfaces/session-config.js.map +1 -0
  49. package/interfaces/session-expiry-config.d.ts +7 -0
  50. package/interfaces/session-expiry-config.d.ts.map +1 -0
  51. package/interfaces/session-expiry-config.js +7 -0
  52. package/interfaces/session-expiry-config.js.map +1 -0
  53. package/interfaces/session-storage-config.d.ts +12 -0
  54. package/interfaces/session-storage-config.d.ts.map +1 -0
  55. package/interfaces/session-storage-config.js +12 -0
  56. package/interfaces/session-storage-config.js.map +1 -0
  57. package/interfaces/sso-config.d.ts +9 -0
  58. package/interfaces/sso-config.d.ts.map +1 -0
  59. package/interfaces/sso-config.js +9 -0
  60. package/interfaces/sso-config.js.map +1 -0
  61. package/interfaces/transfer-server-state.d.ts +9 -0
  62. package/interfaces/transfer-server-state.d.ts.map +1 -0
  63. package/interfaces/transfer-server-state.js +7 -0
  64. package/interfaces/transfer-server-state.js.map +1 -0
  65. package/interfaces/userState.d.ts +16 -0
  66. package/interfaces/userState.d.ts.map +1 -0
  67. package/interfaces/userState.js +16 -0
  68. package/interfaces/userState.js.map +1 -0
  69. package/launch-darkly/index.d.ts +5 -0
  70. package/launch-darkly/index.d.ts.map +1 -0
  71. package/launch-darkly/index.js +14 -0
  72. package/launch-darkly/index.js.map +1 -0
  73. package/package.json +2 -2
  74. package/properties-volume/index.d.ts +6 -0
  75. package/properties-volume/index.d.ts.map +1 -0
  76. package/properties-volume/index.js +10 -0
  77. package/properties-volume/index.js.map +1 -0
  78. package/proxy/index.d.ts +2 -0
  79. package/proxy/index.d.ts.map +1 -0
  80. package/{src/proxy/index.ts → proxy/index.js} +1 -0
  81. package/proxy/index.js.map +1 -0
  82. package/proxy/opal-api-proxy/index.d.ts +3 -0
  83. package/proxy/opal-api-proxy/index.d.ts.map +1 -0
  84. package/proxy/opal-api-proxy/index.js +18 -0
  85. package/proxy/opal-api-proxy/index.js.map +1 -0
  86. package/routes/index.d.ts +10 -0
  87. package/routes/index.d.ts.map +1 -0
  88. package/routes/index.js +36 -0
  89. package/routes/index.js.map +1 -0
  90. package/session/index.d.ts +5 -0
  91. package/session/index.d.ts.map +1 -0
  92. package/{src/session/index.ts → session/index.js} +1 -1
  93. package/session/index.js.map +1 -0
  94. package/session/session-expiry/index.d.ts +4 -0
  95. package/session/session-expiry/index.d.ts.map +1 -0
  96. package/session/session-expiry/index.js +23 -0
  97. package/session/session-expiry/index.js.map +1 -0
  98. package/session/session-storage/index.d.ts +7 -0
  99. package/session/session-storage/index.d.ts.map +1 -0
  100. package/session/session-storage/index.js +58 -0
  101. package/session/session-storage/index.js.map +1 -0
  102. package/session/session-user-state/index.d.ts +4 -0
  103. package/session/session-user-state/index.d.ts.map +1 -0
  104. package/session/session-user-state/index.js +20 -0
  105. package/session/session-user-state/index.js.map +1 -0
  106. package/sso/index.d.ts +7 -0
  107. package/sso/index.d.ts.map +1 -0
  108. package/{src/sso/index.ts → sso/index.js} +1 -1
  109. package/sso/index.js.map +1 -0
  110. package/sso/sso-authenticated.d.ts +4 -0
  111. package/sso/sso-authenticated.d.ts.map +1 -0
  112. package/sso/sso-authenticated.js +14 -0
  113. package/sso/sso-authenticated.js.map +1 -0
  114. package/sso/sso-login-callback.d.ts +4 -0
  115. package/sso/sso-login-callback.d.ts.map +1 -0
  116. package/sso/sso-login-callback.js +26 -0
  117. package/sso/sso-login-callback.js.map +1 -0
  118. package/sso/sso-login.d.ts +4 -0
  119. package/sso/sso-login.d.ts.map +1 -0
  120. package/sso/sso-login.js +24 -0
  121. package/sso/sso-login.js.map +1 -0
  122. package/sso/sso-logout-callback.d.ts +4 -0
  123. package/sso/sso-logout-callback.d.ts.map +1 -0
  124. package/sso/sso-logout-callback.js +13 -0
  125. package/sso/sso-logout-callback.js.map +1 -0
  126. package/sso/sso-logout.d.ts +4 -0
  127. package/sso/sso-logout.d.ts.map +1 -0
  128. package/sso/sso-logout.js +31 -0
  129. package/sso/sso-logout.js.map +1 -0
  130. package/stubs/sso/index.d.ts +7 -0
  131. package/stubs/sso/index.d.ts.map +1 -0
  132. package/{src/stubs/sso/index.ts → stubs/sso/index.js} +1 -1
  133. package/stubs/sso/index.js.map +1 -0
  134. package/stubs/sso/sso-authenticated.stub.d.ts +4 -0
  135. package/stubs/sso/sso-authenticated.stub.d.ts.map +1 -0
  136. package/stubs/sso/sso-authenticated.stub.js +14 -0
  137. package/stubs/sso/sso-authenticated.stub.js.map +1 -0
  138. package/stubs/sso/sso-login-callback.stub.d.ts +4 -0
  139. package/stubs/sso/sso-login-callback.stub.d.ts.map +1 -0
  140. package/stubs/sso/sso-login-callback.stub.js +26 -0
  141. package/stubs/sso/sso-login-callback.stub.js.map +1 -0
  142. package/stubs/sso/sso-login.stub.d.ts +4 -0
  143. package/stubs/sso/sso-login.stub.d.ts.map +1 -0
  144. package/stubs/sso/sso-login.stub.js +14 -0
  145. package/stubs/sso/sso-login.stub.js.map +1 -0
  146. package/stubs/sso/sso-logout-callback.stub.d.ts +4 -0
  147. package/stubs/sso/sso-logout-callback.stub.d.ts.map +1 -0
  148. package/stubs/sso/sso-logout-callback.stub.js +13 -0
  149. package/stubs/sso/sso-logout-callback.stub.js.map +1 -0
  150. package/stubs/sso/sso-logout.stub.d.ts +4 -0
  151. package/stubs/sso/sso-logout.stub.d.ts.map +1 -0
  152. package/stubs/sso/sso-logout.stub.js +5 -0
  153. package/stubs/sso/sso-logout.stub.js.map +1 -0
  154. package/utils/base64.d.ts +3 -0
  155. package/utils/base64.d.ts.map +1 -0
  156. package/utils/base64.js +7 -0
  157. package/utils/base64.js.map +1 -0
  158. package/utils/index.d.ts +3 -0
  159. package/utils/index.d.ts.map +1 -0
  160. package/{src/utils/index.ts → utils/index.js} +1 -1
  161. package/utils/index.js.map +1 -0
  162. package/utils/jwt.d.ts +5 -0
  163. package/utils/jwt.d.ts.map +1 -0
  164. package/utils/jwt.js +32 -0
  165. package/utils/jwt.js.map +1 -0
  166. package/.editorconfig +0 -16
  167. package/.github/renovate.json +0 -11
  168. package/.github/workflows/npm_build.yml +0 -67
  169. package/.prettierignore +0 -12
  170. package/.prettierrc +0 -7
  171. package/.vscode/settings.json +0 -6
  172. package/LICENSE +0 -21
  173. package/eslint.config.js +0 -22
  174. package/sonar-project.properties +0 -9
  175. package/src/app-insights/app-insights-configuration.ts +0 -18
  176. package/src/app-insights/index.ts +0 -39
  177. package/src/csrf-token/index.ts +0 -36
  178. package/src/health/index.ts +0 -32
  179. package/src/helmet/index.ts +0 -60
  180. package/src/interfaces/app-insights-config.ts +0 -7
  181. package/src/interfaces/launch-darkly-config.ts +0 -7
  182. package/src/interfaces/routes-config.ts +0 -8
  183. package/src/interfaces/securityToken.ts +0 -8
  184. package/src/interfaces/session-config.ts +0 -5
  185. package/src/interfaces/session-expiry-config.ts +0 -7
  186. package/src/interfaces/session-storage-config.ts +0 -12
  187. package/src/interfaces/sso-config.ts +0 -9
  188. package/src/interfaces/transfer-server-state.ts +0 -10
  189. package/src/interfaces/userState.ts +0 -18
  190. package/src/launch-darkly/index.ts +0 -17
  191. package/src/properties-volume/index.ts +0 -12
  192. package/src/proxy/opal-api-proxy/index.ts +0 -19
  193. package/src/routes/index.ts +0 -91
  194. package/src/session/session-expiry/index.ts +0 -31
  195. package/src/session/session-storage/index.ts +0 -68
  196. package/src/session/session-user-state/index.ts +0 -24
  197. package/src/sso/sso-authenticated.ts +0 -15
  198. package/src/sso/sso-login-callback.ts +0 -30
  199. package/src/sso/sso-login.ts +0 -31
  200. package/src/sso/sso-logout-callback.ts +0 -17
  201. package/src/sso/sso-logout.ts +0 -41
  202. package/src/stubs/sso/sso-authenticated.stub.ts +0 -16
  203. package/src/stubs/sso/sso-login-callback.stub.ts +0 -29
  204. package/src/stubs/sso/sso-login.stub.ts +0 -16
  205. package/src/stubs/sso/sso-logout-callback.stub.ts +0 -16
  206. package/src/stubs/sso/sso-logout.stub.ts +0 -6
  207. package/src/utils/base64.ts +0 -7
  208. package/src/utils/jwt.ts +0 -35
  209. package/tsconfig.json +0 -72
  210. /package/{src/global.d.ts → global.d.ts} +0 -0
  211. /package/{src/session.d.ts → session.d.ts} +0 -0
  212. /package/{src/type.d.ts → type.d.ts} +0 -0
@@ -1,5 +0,0 @@
1
- class SessionConfiguration {
2
- userStateUrl!: string;
3
- sessionExpiryUrl!: string;
4
- }
5
- export default SessionConfiguration;
@@ -1,7 +0,0 @@
1
- class ExpiryConfiguration {
2
- testMode!: boolean;
3
- expiryTimeInMilliseconds!: number;
4
- warningThresholdInMilliseconds!: number;
5
- }
6
-
7
- export default ExpiryConfiguration;
@@ -1,12 +0,0 @@
1
- class SessionStorageConfiguration {
2
- secret!: string;
3
- prefix!: string;
4
- maxAge!: number;
5
- sameSite!: boolean;
6
- secure!: boolean;
7
- domain!: string;
8
- redisEnabled!: boolean;
9
- redisConnectionString!: string | null;
10
- }
11
-
12
- export default SessionStorageConfiguration;
@@ -1,9 +0,0 @@
1
- class SsoConfiguration {
2
- login!: string;
3
- loginCallback!: string;
4
- logout!: string;
5
- logoutCallback!: string;
6
- authenticated!: string;
7
- }
8
-
9
- export default SsoConfiguration;
@@ -1,10 +0,0 @@
1
- import AppInsightsConfig from './app-insights-config';
2
- import LaunchDarklyConfig from './launch-darkly-config';
3
-
4
- class TransferServerState {
5
- launchDarklyConfig!: LaunchDarklyConfig;
6
- ssoEnabled!: boolean;
7
- appInsightsConfig!: AppInsightsConfig;
8
- }
9
-
10
- export default TransferServerState;
@@ -1,18 +0,0 @@
1
- class UserState {
2
- user_id!: string;
3
- user_name!: string;
4
- business_unit_user?: BusinessUnitUser[];
5
- }
6
-
7
- class BusinessUnitUser {
8
- business_user_id!: string;
9
- business_unit!: string;
10
- permissions?: Permissions[];
11
- }
12
-
13
- class Permissions {
14
- permission_id!: number;
15
- permission_name!: string;
16
- }
17
-
18
- export default UserState;
@@ -1,17 +0,0 @@
1
- import LaunchDarklyConfig from '../interfaces/launch-darkly-config';
2
-
3
- export class LaunchDarkly {
4
- public enableFor(enabled: boolean, stream: boolean, clientId: string | null): LaunchDarklyConfig {
5
- const launchDarklyConfig: LaunchDarklyConfig = {
6
- enabled: enabled,
7
- clientId: null,
8
- stream: stream,
9
- };
10
-
11
- if (launchDarklyConfig.enabled && clientId) {
12
- launchDarklyConfig.clientId = clientId;
13
- }
14
-
15
- return launchDarklyConfig;
16
- }
17
- }
@@ -1,12 +0,0 @@
1
- import * as propertiesVolume from '@hmcts/properties-volume';
2
- import { IConfig } from 'config';
3
- import { Application } from 'express';
4
-
5
- export class PropertiesVolume {
6
- enableFor(server: Application, config: IConfig): IConfig {
7
- if (server.locals['ENV'] !== 'development') {
8
- propertiesVolume.addTo(config);
9
- }
10
- return config;
11
- }
12
- }
@@ -1,19 +0,0 @@
1
- import { createProxyMiddleware } from 'http-proxy-middleware';
2
-
3
- const opalApiProxy = (opalApiTarget: string) => {
4
- return createProxyMiddleware({
5
- target: opalApiTarget,
6
- changeOrigin: true,
7
- logger: console,
8
- on: {
9
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
- proxyReq: (proxyReq, req: any) => {
11
- if (req.session.securityToken?.access_token) {
12
- proxyReq.setHeader('Authorization', `Bearer ${req.session.securityToken.access_token}`);
13
- }
14
- },
15
- },
16
- });
17
- };
18
-
19
- export default opalApiProxy;
@@ -1,91 +0,0 @@
1
- import { Application } from 'express';
2
- import bodyParser from 'body-parser';
3
- import type { NextFunction, Request, Response } from 'express';
4
- import { ssoAuthenticated, ssoLoginCallback, ssoLogin, ssoLogout, ssoLogoutCallback } from '../sso';
5
- import {
6
- ssoLoginStub,
7
- ssoLoginCallbackStub,
8
- ssoAuthenticatedStub,
9
- ssoLogoutStub,
10
- ssoLogoutCallbackStub,
11
- } from '../stubs/sso';
12
- import sessionExpiry from '@hmcts/opal-frontend-common-node/session/session-expiry';
13
- import sessionUserState from '@hmcts/opal-frontend-common-node/session/session-user-state';
14
- import ExpiryConfiguration from '@hmcts/opal-frontend-common-node/interfaces/session-expiry-config';
15
- import RoutesConfiguration from '@hmcts/opal-frontend-common-node/interfaces/routes-config';
16
- import SsoConfiguration from '@hmcts/opal-frontend-common-node/interfaces/sso-config';
17
- import SessionConfiguration from '@hmcts/opal-frontend-common-node/interfaces/session-config';
18
-
19
- export class Routes {
20
- public enableFor(
21
- app: Application,
22
- ssoEnabled: boolean,
23
- expiryConfiguration: ExpiryConfiguration,
24
- routesConfiguration: RoutesConfiguration,
25
- sessionConfiguration: SessionConfiguration,
26
- ssoConfiguration: SsoConfiguration,
27
- ): void {
28
- // Declare use of body-parser AFTER the use of proxy https://github.com/villadora/express-http-proxy
29
- app.use(bodyParser.json());
30
- app.use(bodyParser.urlencoded({ extended: false }));
31
-
32
- this.setupSSORoutes(
33
- app,
34
- ssoEnabled,
35
- routesConfiguration.opalApiTarget,
36
- routesConfiguration.frontendHostname,
37
- routesConfiguration.prefix,
38
- ssoConfiguration,
39
- );
40
-
41
- app.get(sessionConfiguration.userStateUrl, (req: Request, res: Response) => sessionUserState(req, res));
42
- app.get(sessionConfiguration.sessionExpiryUrl, (req: Request, res: Response) =>
43
- sessionExpiry(
44
- req,
45
- res,
46
- expiryConfiguration.testMode,
47
- expiryConfiguration.expiryTimeInMilliseconds,
48
- expiryConfiguration.warningThresholdInMilliseconds,
49
- ),
50
- );
51
- }
52
-
53
- private setupSSORoutes(
54
- app: Application,
55
- ssoEnabled: boolean,
56
- opalApiUrl: string,
57
- frontendHostname: string,
58
- prefix: string,
59
- ssoConfiguration: SsoConfiguration,
60
- ): void {
61
- const login = ssoEnabled ? ssoLogin : ssoLoginStub;
62
- const loginCallback = ssoEnabled ? ssoLoginCallback : ssoLoginCallbackStub;
63
- const logout = ssoEnabled ? ssoLogout : ssoLogoutStub;
64
- const logoutCallback = ssoEnabled ? ssoLogoutCallback : ssoLogoutCallbackStub;
65
- const authenticated = ssoEnabled ? ssoAuthenticated : ssoAuthenticatedStub;
66
-
67
- const loginCallbackType = ssoEnabled ? 'post' : 'get';
68
-
69
- app.get(ssoConfiguration.login, (req: Request, res: Response, next: NextFunction) =>
70
- login(req, res, next, opalApiUrl, frontendHostname),
71
- );
72
-
73
- const routePath = ssoConfiguration.loginCallback;
74
- const callbackHandler = (req: Request, res: Response, next: NextFunction) =>
75
- loginCallback(req, res, next, opalApiUrl);
76
-
77
- if (loginCallbackType === 'post') {
78
- app.post(routePath, callbackHandler);
79
- } else {
80
- app.get(routePath, callbackHandler);
81
- }
82
-
83
- app.get(ssoConfiguration.logout, (req: Request, res: Response, next: NextFunction) =>
84
- logout(req, res, next, opalApiUrl, frontendHostname),
85
- );
86
- app.get(ssoConfiguration.logoutCallback, (req: Request, res: Response, next: NextFunction) =>
87
- logoutCallback(req, res, next, prefix),
88
- );
89
- app.get(ssoConfiguration.authenticated, (req: Request, res: Response) => authenticated(req, res));
90
- }
91
- }
@@ -1,31 +0,0 @@
1
- import { Request, Response } from 'express';
2
- import { DateTime } from 'luxon';
3
- import { Jwt } from '../../utils';
4
-
5
- const sessionExpiry = (
6
- req: Request,
7
- res: Response,
8
- testMode: boolean,
9
- expiryTimeInMilliseconds: number,
10
- warningThresholdInMilliseconds: number,
11
- ) => {
12
- const accessToken = req.session.securityToken?.access_token;
13
- if (accessToken) {
14
- const payload = Jwt.parseJwt(accessToken);
15
- const jwtExpiry = testMode
16
- ? DateTime.now().plus({ milliseconds: expiryTimeInMilliseconds }).toISO()
17
- : DateTime.fromMillis(payload.exp * 1000).toISO();
18
-
19
- res.status(200).send({
20
- expiry: jwtExpiry,
21
- warningThresholdInMilliseconds: warningThresholdInMilliseconds,
22
- });
23
- } else {
24
- res.status(200).send({
25
- expiry: null,
26
- warningThresholdInMilliseconds: null,
27
- });
28
- }
29
- };
30
-
31
- export default sessionExpiry;
@@ -1,68 +0,0 @@
1
- import { Logger } from '@hmcts/nodejs-logging';
2
- import SessionStorageConfiguration from '@hmcts/opal-frontend-common-node/interfaces/session-storage-config';
3
- import { RedisStore } from 'connect-redis';
4
- import cookieParser from 'cookie-parser';
5
- import { Application } from 'express';
6
- import session from 'express-session';
7
- import { createClient } from 'redis';
8
- import FileStoreFactory from 'session-file-store';
9
-
10
- const FileStore = FileStoreFactory(session);
11
- const logger = Logger.getLogger('session-storage');
12
-
13
- export default class SessionStorage {
14
- public enableFor(app: Application, sessionStorage: SessionStorageConfiguration): void {
15
- app.use(cookieParser(sessionStorage.secret));
16
- app.set('trust proxy', 1);
17
-
18
- app.use(
19
- session({
20
- name: sessionStorage.prefix,
21
- resave: false,
22
- saveUninitialized: false,
23
- secret: sessionStorage.secret,
24
- cookie: {
25
- httpOnly: true,
26
- maxAge: sessionStorage.maxAge,
27
- sameSite: sessionStorage.sameSite,
28
- secure: sessionStorage.secure,
29
- domain: sessionStorage.domain,
30
- },
31
- rolling: true,
32
- store: this.getStore(app, sessionStorage.redisEnabled, sessionStorage.redisConnectionString),
33
- }),
34
- );
35
- }
36
-
37
- private getStore(app: Application, enabled: boolean, connectionString: string | null) {
38
- if (enabled && connectionString) {
39
- logger.info('Using Redis session store', connectionString);
40
- const client = createClient({
41
- url: connectionString,
42
- socket: {
43
- reconnectStrategy: function (retries) {
44
- if (retries > 20) {
45
- logger.log('Too many attempts to reconnect. Redis connection was terminated');
46
- return new Error('Too many retries.');
47
- } else {
48
- return retries * 500;
49
- }
50
- },
51
- },
52
- });
53
-
54
- client.on('error', (err) => {
55
- logger.error('Redis Client Error', err);
56
- });
57
-
58
- client.connect().catch(() => {
59
- process.exit();
60
- });
61
-
62
- app.locals['redisClient'] = client;
63
- return new RedisStore({ client });
64
- }
65
-
66
- return new FileStore({ path: '/tmp' });
67
- }
68
- }
@@ -1,24 +0,0 @@
1
- import { Request, Response } from 'express';
2
- import { UserState } from '../../interfaces';
3
- import { Jwt } from '../../utils';
4
-
5
- const sessionUserState = (req: Request, res: Response) => {
6
- const userState: UserState | undefined = req.session.securityToken?.user_state;
7
- const accessToken = req.session.securityToken?.access_token;
8
- const name = accessToken && userState ? Jwt.parseJwt(accessToken).name : '';
9
-
10
- // Don't allow caching of this endpoint
11
- res.set({
12
- 'Cache-Control': 'no-store, no-cache, must-revalidate, max-age=0',
13
- Pragma: 'no-cache',
14
- Expires: '0',
15
- });
16
-
17
- if (!userState) {
18
- res.send({});
19
- } else {
20
- res.send({ ...userState, name });
21
- }
22
- };
23
-
24
- export default sessionUserState;
@@ -1,15 +0,0 @@
1
- import { Request, Response } from 'express';
2
- import { Jwt } from '../utils';
3
-
4
- export default (req: Request, res: Response) => {
5
- const isJwtExpired = Jwt.isJwtExpired(req.session.securityToken?.access_token);
6
- const userId = req.session.securityToken?.user_state?.user_id;
7
- // Don't allow caching of this endpoint
8
- res.header('Cache-Control', 'no-store, must-revalidate');
9
-
10
- if (isJwtExpired || !userId) {
11
- res.status(401).send(false);
12
- } else {
13
- res.status(200).send(true);
14
- }
15
- };
@@ -1,30 +0,0 @@
1
- import { NextFunction, Request, Response } from 'express';
2
- import { Logger } from '@hmcts/nodejs-logging';
3
- import axios from 'axios';
4
-
5
- export default async (req: Request, res: Response, next: NextFunction, opalApiUrl: string) => {
6
- const INTERNAL_USER_CALLBACK = `${opalApiUrl}/internal-user/handle-oauth-code`;
7
- const logger = Logger.getLogger('login-callback');
8
-
9
- try {
10
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
- const result = await axios.post<any>(INTERNAL_USER_CALLBACK, req.body, {
12
- headers: { 'content-type': 'application/x-www-form-urlencoded' },
13
- });
14
-
15
- const securityToken = result.data;
16
- req.session.securityToken = securityToken;
17
-
18
- req.session.save((err) => {
19
- if (err) {
20
- logger.error('Error saving session', err);
21
- return next(err);
22
- }
23
-
24
- res.redirect('/');
25
- });
26
- } catch (error) {
27
- logger.error('Error on login-callback', error);
28
- return next(error);
29
- }
30
- };
@@ -1,31 +0,0 @@
1
- import { NextFunction, Request, Response } from 'express';
2
- import { Logger } from '@hmcts/nodejs-logging';
3
- import axios from 'axios';
4
-
5
- export default async (
6
- req: Request,
7
- res: Response,
8
- next: NextFunction,
9
- opalApiUrl: string,
10
- frontendHostname: string,
11
- ) => {
12
- const INTERNAL_USER_LOGIN = `${opalApiUrl}/internal-user/login-or-refresh`;
13
- const logger = Logger.getLogger('login');
14
- const url = `${INTERNAL_USER_LOGIN}?redirect_uri=${frontendHostname}/sso/login-callback`;
15
-
16
- try {
17
- const response = await axios.get(url);
18
- const redirectUrl = response.request.res.responseUrl;
19
-
20
- if (redirectUrl) {
21
- res.redirect(redirectUrl);
22
- } else {
23
- const error = new Error('Error trying to fetch login page');
24
- logger.error('Error on login', error);
25
- return next(error);
26
- }
27
- } catch (error) {
28
- logger.error('Error on login', error);
29
- return next(error);
30
- }
31
- };
@@ -1,17 +0,0 @@
1
- import { NextFunction, Request, Response } from 'express';
2
- import { Logger } from '@hmcts/nodejs-logging';
3
-
4
- const logger = Logger.getLogger('logout');
5
-
6
- export default (req: Request, res: Response, next: NextFunction, prefix: string) => {
7
- req.session.destroy((err) => {
8
- if (err) {
9
- logger.error('Error destroying session', err);
10
- return next(err);
11
- }
12
-
13
- res.clearCookie(prefix);
14
-
15
- res.redirect('/');
16
- });
17
- };
@@ -1,41 +0,0 @@
1
- import axios from 'axios';
2
- import { NextFunction, Request, Response } from 'express';
3
- import { Logger } from '@hmcts/nodejs-logging';
4
-
5
- export default async (
6
- req: Request,
7
- res: Response,
8
- next: NextFunction,
9
- opalApiUrl: string,
10
- frontendHostname: string,
11
- ) => {
12
- const INTERNAL_USER_LOGOUT = `${opalApiUrl}/internal-user/logout`;
13
- const logger = Logger.getLogger('login');
14
- const url = `${INTERNAL_USER_LOGOUT}?redirect_uri=${frontendHostname}/sso/logout-callback`;
15
-
16
- try {
17
- let accessToken;
18
-
19
- if (req.session.securityToken) {
20
- accessToken = req.session.securityToken.access_token;
21
- }
22
-
23
- if (!accessToken) {
24
- return next(new Error('No access token found in session'));
25
- }
26
-
27
- const response = await axios.get(url, {
28
- headers: { Authorization: `Bearer ${accessToken}` },
29
- });
30
-
31
- const logoutRedirect = response.request.res.responseUrl;
32
- if (logoutRedirect) {
33
- res.redirect(logoutRedirect);
34
- } else {
35
- next(new Error('Error trying to fetch logout page'));
36
- }
37
- } catch (error) {
38
- logger.error('Error logging out', error);
39
- return next(error);
40
- }
41
- };
@@ -1,16 +0,0 @@
1
- import { Request, Response } from 'express';
2
- import { Jwt } from '../../utils';
3
-
4
- export default (req: Request, res: Response) => {
5
- const isJwtExpired = Jwt.isJwtExpired(req.session.securityToken?.access_token);
6
- const userId = req.session.securityToken?.user_state?.user_id;
7
-
8
- // Don't allow caching of this endpoint
9
- res.header('Cache-Control', 'no-store, must-revalidate');
10
-
11
- if (isJwtExpired || !userId) {
12
- res.status(401).send(false);
13
- } else {
14
- res.status(200).send(true);
15
- }
16
- };
@@ -1,29 +0,0 @@
1
- import { NextFunction, Request, Response } from 'express';
2
- import { Logger } from '@hmcts/nodejs-logging';
3
- import axios from 'axios';
4
-
5
- export default async (req: Request, res: Response, next: NextFunction, opalApiUrl: string) => {
6
- const INTERNAL_JWT = `${opalApiUrl}/testing-support/token/user`;
7
- const logger = Logger.getLogger('login-callback-stub');
8
-
9
- try {
10
- const email = req.query['email'] as string;
11
- const result = await axios.get(INTERNAL_JWT, {
12
- headers: { 'X-User-Email': email },
13
- });
14
-
15
- req.session.securityToken = result.data;
16
-
17
- req.session.save((err) => {
18
- if (err) {
19
- logger.error('Error saving session', err);
20
- return next(err);
21
- }
22
- logger.info('Session saved');
23
- res.redirect('/');
24
- });
25
- } catch (error) {
26
- logger.error('Error on login-stub callback', error);
27
- return next(error);
28
- }
29
- };
@@ -1,16 +0,0 @@
1
- import { Request, Response, NextFunction } from 'express';
2
- import { Logger } from '@hmcts/nodejs-logging';
3
-
4
- const logger = Logger.getLogger('login-stub');
5
-
6
- export default async (req: Request, res: Response, next: NextFunction) => {
7
- const email = req.query['email'] as string;
8
-
9
- if (email !== 'null') {
10
- res.redirect(`/sso/login-callback?email=${email}`);
11
- } else {
12
- const error = new Error('No email provided.');
13
- logger.error('Error on login-stub', error);
14
- return next(error);
15
- }
16
- };
@@ -1,16 +0,0 @@
1
- import { NextFunction, Request, Response } from 'express';
2
- import { Logger } from '@hmcts/nodejs-logging';
3
-
4
- export default (req: Request, res: Response, next: NextFunction, prefix: string) => {
5
- const logger = Logger.getLogger('logout-callback-stub');
6
-
7
- req.session.destroy((err) => {
8
- if (err) {
9
- logger.error(`Error destroying session: ${err}`);
10
- return next(err);
11
- }
12
-
13
- res.clearCookie(prefix);
14
- res.redirect('/');
15
- });
16
- };
@@ -1,6 +0,0 @@
1
- import { Request, Response, NextFunction } from 'express';
2
-
3
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
4
- export default async (req: Request, res: Response, next: NextFunction) => {
5
- res.redirect('/sso/logout-callback');
6
- };
@@ -1,7 +0,0 @@
1
- export function encode<T>(dataToEncode: T): string {
2
- return Buffer.from(JSON.stringify(dataToEncode)).toString('base64');
3
- }
4
-
5
- export function decodeObject<T>(base64string: string): T {
6
- return JSON.parse(Buffer.from(base64string, 'base64').toString());
7
- }
package/src/utils/jwt.ts DELETED
@@ -1,35 +0,0 @@
1
- import { DateTime } from 'luxon';
2
- export class Jwt {
3
- //Returns payload of JWT
4
- static parseJwt(token: string) {
5
- return JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
6
- }
7
-
8
- //If token doesn't exist, or is expired, return as invalid
9
- static isJwtExpired(token: string | undefined) {
10
- try {
11
- if (token) {
12
- const payload = this.parseJwt(token);
13
-
14
- if (payload.exp) {
15
- //Create date from expiry, argument must be in ms so multiply by 1000
16
-
17
- const jwtExpiry = DateTime.fromMillis(payload.exp * 1000).toISO();
18
- const currentDateTime = DateTime.now().toISO();
19
-
20
- if (!jwtExpiry) {
21
- return true;
22
- }
23
-
24
- //If JWT expiry is after now, then return as valid
25
- if (jwtExpiry > currentDateTime) {
26
- return false;
27
- }
28
- }
29
- }
30
- return true;
31
- } catch {
32
- return true;
33
- }
34
- }
35
- }