@telia-ace/alliance-internal-node-utilities 1.0.3-next.1 → 1.0.3-next.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @telia-ace/alliance-internal-node-utilities
2
2
 
3
+ ## 1.0.3-next.3
4
+
5
+ ### Patch Changes
6
+
7
+ - c9b1488: Add `REDIS_PASSWORD` environment variable.
8
+
9
+ ## 1.0.3-next.2
10
+
11
+ ### Patch Changes
12
+
13
+ - f2aafe4: Store user session in Redis cache to avoid hitting cookie size limits (https://github.com/telia-company/ace-alliance-sdk/issues/377).
14
+
3
15
  ## 1.0.3-next.1
4
16
 
5
17
  ### Patch Changes
@@ -8,6 +8,7 @@ type Settings = {
8
8
  authRequired?: ConfigParams['authRequired'];
9
9
  authorizationParams?: ConfigParams['authorizationParams'];
10
10
  afterCallback?: ConfigParams['afterCallback'];
11
+ issuerBaseURL?: ConfigParams['issuerBaseURL'];
11
12
  };
12
- export declare function authMiddleware(configService: ConfigService, { baseURL, clientSecret, clientID, authRequired, authorizationParams, afterCallback, }?: Settings): RequestHandler;
13
+ export declare function authMiddleware(configService: ConfigService, { baseURL, clientSecret, clientID, authRequired, authorizationParams, afterCallback, issuerBaseURL, }?: Settings): RequestHandler;
13
14
  export {};
@@ -1,9 +1,10 @@
1
1
  export declare enum SharedConfigKeys {
2
- AuthAuthority = "AUTH_AUTHORITY",
3
2
  AuthCookieName = "AUTH_COOKIE_NAME",
4
3
  AuthCookieSecret = "AUTH_COOKIE_SECRET",
5
4
  DbEndpoint = "DB_ENDPOINT",
6
5
  JwtPrivateKey = "JWT_PRIVATE_KEY",
7
6
  ServiceLogLevel = "SERVICE_LOG_LEVEL",
8
- ServicePort = "SERVICE_PORT"
7
+ ServicePort = "SERVICE_PORT",
8
+ RedisHost = "REDIS_HOST",
9
+ RedisPassword = "REDIS_PASSWORD"
9
10
  }
@@ -0,0 +1,7 @@
1
+ import { GraphQLError } from 'graphql';
2
+ import { ErrorCodes } from './codes';
3
+ export declare class AllianceGqlException extends GraphQLError {
4
+ info: string;
5
+ code: ErrorCodes;
6
+ constructor(code: ErrorCodes, variables?: Record<string, string>, extensions?: any);
7
+ }
@@ -18,7 +18,8 @@ export declare enum DatabasesErrorCodes {
18
18
  NoAuthHeader = 11001,
19
19
  FailedFileStore = 11002,
20
20
  FailedFileRead = 11003,
21
- NoRecord = 11004
21
+ NoRecord = 11004,
22
+ UniqueConstrain = 11005
22
23
  }
23
24
  export declare enum PortalErrorCodes {
24
25
  NoObjectId = 12000
@@ -1,3 +1,4 @@
1
+ export * from './alliance-gql.exception';
1
2
  export * from './alliance.exception';
2
3
  export * from './codes';
3
4
  export * from './exception.filter';
package/dist/index.cjs CHANGED
@@ -1,11 +1,14 @@
1
1
  'use strict';
2
2
 
3
3
  const nestjsPino = require('nestjs-pino');
4
+ const RedisStore = require('connect-redis');
4
5
  const expressOpenidConnect = require('express-openid-connect');
6
+ const redis = require('redis');
5
7
  const jsonwebtoken = require('jsonwebtoken');
6
8
  const jsonschema = require('jsonschema');
7
9
  const node_path = require('node:path');
8
10
  const node_fs = require('node:fs');
11
+ const graphql = require('graphql');
9
12
  const common = require('@nestjs/common');
10
13
  const config = require('@nestjs/config');
11
14
  const _slugify = require('slugify');
@@ -13,16 +16,18 @@ const promises = require('node:stream/promises');
13
16
 
14
17
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
15
18
 
19
+ const RedisStore__default = /*#__PURE__*/_interopDefaultCompat(RedisStore);
16
20
  const _slugify__default = /*#__PURE__*/_interopDefaultCompat(_slugify);
17
21
 
18
22
  var SharedConfigKeys = /* @__PURE__ */ ((SharedConfigKeys2) => {
19
- SharedConfigKeys2["AuthAuthority"] = "AUTH_AUTHORITY";
20
23
  SharedConfigKeys2["AuthCookieName"] = "AUTH_COOKIE_NAME";
21
24
  SharedConfigKeys2["AuthCookieSecret"] = "AUTH_COOKIE_SECRET";
22
25
  SharedConfigKeys2["DbEndpoint"] = "DB_ENDPOINT";
23
26
  SharedConfigKeys2["JwtPrivateKey"] = "JWT_PRIVATE_KEY";
24
27
  SharedConfigKeys2["ServiceLogLevel"] = "SERVICE_LOG_LEVEL";
25
28
  SharedConfigKeys2["ServicePort"] = "SERVICE_PORT";
29
+ SharedConfigKeys2["RedisHost"] = "REDIS_HOST";
30
+ SharedConfigKeys2["RedisPassword"] = "REDIS_PASSWORD";
26
31
  return SharedConfigKeys2;
27
32
  })(SharedConfigKeys || {});
28
33
 
@@ -39,8 +44,17 @@ function authMiddleware(configService, {
39
44
  clientID = " ",
40
45
  authRequired = true,
41
46
  authorizationParams = {},
42
- afterCallback
47
+ afterCallback,
48
+ issuerBaseURL = "https://127.0.0.1"
43
49
  } = {}) {
50
+ const redisClient = redis.createClient({
51
+ url: configService.getOrThrow(SharedConfigKeys.RedisHost),
52
+ password: configService.get(SharedConfigKeys.RedisPassword)
53
+ });
54
+ redisClient.connect().catch(console.error);
55
+ const redisStore = new RedisStore__default({
56
+ client: redisClient
57
+ });
44
58
  return expressOpenidConnect.auth({
45
59
  baseURL,
46
60
  clientSecret,
@@ -48,12 +62,11 @@ function authMiddleware(configService, {
48
62
  authRequired,
49
63
  authorizationParams,
50
64
  afterCallback,
51
- issuerBaseURL: `${configService.getOrThrow(
52
- SharedConfigKeys.AuthAuthority
53
- )}/.well-known/openid-configuration`,
65
+ issuerBaseURL,
54
66
  secret: configService.getOrThrow(SharedConfigKeys.AuthCookieSecret),
55
67
  session: {
56
- name: configService.getOrThrow(SharedConfigKeys.AuthCookieName)
68
+ name: configService.getOrThrow(SharedConfigKeys.AuthCookieName),
69
+ store: redisStore
57
70
  },
58
71
  routes: {
59
72
  callback: "/signin-oidc"
@@ -539,6 +552,7 @@ var DatabasesErrorCodes = /* @__PURE__ */ ((DatabasesErrorCodes2) => {
539
552
  DatabasesErrorCodes2[DatabasesErrorCodes2["FailedFileStore"] = 11002] = "FailedFileStore";
540
553
  DatabasesErrorCodes2[DatabasesErrorCodes2["FailedFileRead"] = 11003] = "FailedFileRead";
541
554
  DatabasesErrorCodes2[DatabasesErrorCodes2["NoRecord"] = 11004] = "NoRecord";
555
+ DatabasesErrorCodes2[DatabasesErrorCodes2["UniqueConstrain"] = 11005] = "UniqueConstrain";
542
556
  return DatabasesErrorCodes2;
543
557
  })(DatabasesErrorCodes || {});
544
558
  var PortalErrorCodes = /* @__PURE__ */ ((PortalErrorCodes2) => {
@@ -616,6 +630,10 @@ const allianceErrors = {
616
630
  httpCode: common.HttpStatus.INTERNAL_SERVER_ERROR,
617
631
  message: "Missing database record."
618
632
  },
633
+ [11005 /* UniqueConstrain */]: {
634
+ httpCode: common.HttpStatus.CONFLICT,
635
+ message: "Field has to be unique."
636
+ },
619
637
  // portal
620
638
  [12e3 /* NoObjectId */]: {
621
639
  httpCode: common.HttpStatus.UNAUTHORIZED,
@@ -623,6 +641,22 @@ const allianceErrors = {
623
641
  }
624
642
  };
625
643
 
644
+ function parseTemplates$1(message, variables) {
645
+ return Object.entries(variables).reduce((acc, [key, value]) => {
646
+ return acc.replaceAll(`{{${key}}}`, value);
647
+ }, message);
648
+ }
649
+ class AllianceGqlException extends graphql.GraphQLError {
650
+ constructor(code, variables = {}, extensions) {
651
+ const { message } = allianceErrors[code];
652
+ super(parseTemplates$1(message, variables), {
653
+ extensions
654
+ });
655
+ this.code = code;
656
+ this.info = `https://github.com/telia-company/ace-alliance-sdk/wiki/error-codes#${code}`;
657
+ }
658
+ }
659
+
626
660
  function parseTemplates(message, variables) {
627
661
  return Object.entries(variables).reduce((acc, [key, value]) => {
628
662
  return acc.replaceAll(`{{${key}}}`, value);
@@ -717,13 +751,7 @@ exports.LoggerModule = class LoggerModule {
717
751
  useFactory: async (configService) => ({
718
752
  pinoHttp: {
719
753
  level: logLevel || configService.get(SharedConfigKeys.ServiceLogLevel) || "silent",
720
- redact: redact ? [
721
- "authorization",
722
- "headers.authorization",
723
- "req.headers.authorization",
724
- "req.remoteAddress",
725
- "req.remotePort"
726
- ] : [],
754
+ redact: redact ? ["authorization", "headers.authorization", "req", "res"] : [],
727
755
  transport: {
728
756
  target: "pino-pretty",
729
757
  options: {
@@ -787,6 +815,7 @@ function viteCssImportPlugin(outFilePath, relativePath = false) {
787
815
 
788
816
  exports.LoggerErrorInterceptor = nestjsPino.LoggerErrorInterceptor;
789
817
  exports.AllianceException = AllianceException;
818
+ exports.AllianceGqlException = AllianceGqlException;
790
819
  exports.AllianceHeaders = AllianceHeaders;
791
820
  exports.DatabasesErrorCodes = DatabasesErrorCodes;
792
821
  exports.GatewayErrorCodes = GatewayErrorCodes;
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ export { LoggerErrorInterceptor } from 'nestjs-pino';
2
2
  export { authMiddleware, createBearerToken, createSystemUserToken, getPrivateKey } from './auth';
3
3
  export { AllianceHeaders, SharedConfigKeys } from './constants';
4
4
  export { createPublicDistributionFiles } from './distribution';
5
- export { AllianceException, AllianceExceptionFilter, DatabasesErrorCodes, GatewayErrorCodes, PortalErrorCodes, } from './exceptions';
5
+ export { AllianceException, AllianceExceptionFilter, AllianceGqlException, DatabasesErrorCodes, GatewayErrorCodes, PortalErrorCodes, } from './exceptions';
6
6
  export { getAppManifests } from './get-app-manifests';
7
7
  export { LoggerModule, LoggerService } from './logging';
8
8
  export { slugify } from './slugify';
package/dist/index.mjs CHANGED
@@ -1,23 +1,27 @@
1
1
  import { InjectPinoLogger, LoggerModule as LoggerModule$1 } from 'nestjs-pino';
2
2
  export { LoggerErrorInterceptor } from 'nestjs-pino';
3
+ import RedisStore from 'connect-redis';
3
4
  import { auth } from 'express-openid-connect';
5
+ import { createClient } from 'redis';
4
6
  import { sign } from 'jsonwebtoken';
5
7
  import { validate } from 'jsonschema';
6
8
  import { resolve, dirname, relative } from 'node:path';
7
9
  import { readFileSync, writeFileSync, rmSync, existsSync, mkdirSync, createWriteStream, createReadStream, renameSync } from 'node:fs';
10
+ import { GraphQLError } from 'graphql';
8
11
  import { HttpStatus, HttpException, Catch, Injectable, Module } from '@nestjs/common';
9
12
  import { ConfigModule, ConfigService } from '@nestjs/config';
10
13
  import _slugify from 'slugify';
11
14
  import { pipeline } from 'node:stream/promises';
12
15
 
13
16
  var SharedConfigKeys = /* @__PURE__ */ ((SharedConfigKeys2) => {
14
- SharedConfigKeys2["AuthAuthority"] = "AUTH_AUTHORITY";
15
17
  SharedConfigKeys2["AuthCookieName"] = "AUTH_COOKIE_NAME";
16
18
  SharedConfigKeys2["AuthCookieSecret"] = "AUTH_COOKIE_SECRET";
17
19
  SharedConfigKeys2["DbEndpoint"] = "DB_ENDPOINT";
18
20
  SharedConfigKeys2["JwtPrivateKey"] = "JWT_PRIVATE_KEY";
19
21
  SharedConfigKeys2["ServiceLogLevel"] = "SERVICE_LOG_LEVEL";
20
22
  SharedConfigKeys2["ServicePort"] = "SERVICE_PORT";
23
+ SharedConfigKeys2["RedisHost"] = "REDIS_HOST";
24
+ SharedConfigKeys2["RedisPassword"] = "REDIS_PASSWORD";
21
25
  return SharedConfigKeys2;
22
26
  })(SharedConfigKeys || {});
23
27
 
@@ -34,8 +38,17 @@ function authMiddleware(configService, {
34
38
  clientID = " ",
35
39
  authRequired = true,
36
40
  authorizationParams = {},
37
- afterCallback
41
+ afterCallback,
42
+ issuerBaseURL = "https://127.0.0.1"
38
43
  } = {}) {
44
+ const redisClient = createClient({
45
+ url: configService.getOrThrow(SharedConfigKeys.RedisHost),
46
+ password: configService.get(SharedConfigKeys.RedisPassword)
47
+ });
48
+ redisClient.connect().catch(console.error);
49
+ const redisStore = new RedisStore({
50
+ client: redisClient
51
+ });
39
52
  return auth({
40
53
  baseURL,
41
54
  clientSecret,
@@ -43,12 +56,11 @@ function authMiddleware(configService, {
43
56
  authRequired,
44
57
  authorizationParams,
45
58
  afterCallback,
46
- issuerBaseURL: `${configService.getOrThrow(
47
- SharedConfigKeys.AuthAuthority
48
- )}/.well-known/openid-configuration`,
59
+ issuerBaseURL,
49
60
  secret: configService.getOrThrow(SharedConfigKeys.AuthCookieSecret),
50
61
  session: {
51
- name: configService.getOrThrow(SharedConfigKeys.AuthCookieName)
62
+ name: configService.getOrThrow(SharedConfigKeys.AuthCookieName),
63
+ store: redisStore
52
64
  },
53
65
  routes: {
54
66
  callback: "/signin-oidc"
@@ -534,6 +546,7 @@ var DatabasesErrorCodes = /* @__PURE__ */ ((DatabasesErrorCodes2) => {
534
546
  DatabasesErrorCodes2[DatabasesErrorCodes2["FailedFileStore"] = 11002] = "FailedFileStore";
535
547
  DatabasesErrorCodes2[DatabasesErrorCodes2["FailedFileRead"] = 11003] = "FailedFileRead";
536
548
  DatabasesErrorCodes2[DatabasesErrorCodes2["NoRecord"] = 11004] = "NoRecord";
549
+ DatabasesErrorCodes2[DatabasesErrorCodes2["UniqueConstrain"] = 11005] = "UniqueConstrain";
537
550
  return DatabasesErrorCodes2;
538
551
  })(DatabasesErrorCodes || {});
539
552
  var PortalErrorCodes = /* @__PURE__ */ ((PortalErrorCodes2) => {
@@ -611,6 +624,10 @@ const allianceErrors = {
611
624
  httpCode: HttpStatus.INTERNAL_SERVER_ERROR,
612
625
  message: "Missing database record."
613
626
  },
627
+ [11005 /* UniqueConstrain */]: {
628
+ httpCode: HttpStatus.CONFLICT,
629
+ message: "Field has to be unique."
630
+ },
614
631
  // portal
615
632
  [12e3 /* NoObjectId */]: {
616
633
  httpCode: HttpStatus.UNAUTHORIZED,
@@ -618,6 +635,22 @@ const allianceErrors = {
618
635
  }
619
636
  };
620
637
 
638
+ function parseTemplates$1(message, variables) {
639
+ return Object.entries(variables).reduce((acc, [key, value]) => {
640
+ return acc.replaceAll(`{{${key}}}`, value);
641
+ }, message);
642
+ }
643
+ class AllianceGqlException extends GraphQLError {
644
+ constructor(code, variables = {}, extensions) {
645
+ const { message } = allianceErrors[code];
646
+ super(parseTemplates$1(message, variables), {
647
+ extensions
648
+ });
649
+ this.code = code;
650
+ this.info = `https://github.com/telia-company/ace-alliance-sdk/wiki/error-codes#${code}`;
651
+ }
652
+ }
653
+
621
654
  function parseTemplates(message, variables) {
622
655
  return Object.entries(variables).reduce((acc, [key, value]) => {
623
656
  return acc.replaceAll(`{{${key}}}`, value);
@@ -712,13 +745,7 @@ let LoggerModule = class {
712
745
  useFactory: async (configService) => ({
713
746
  pinoHttp: {
714
747
  level: logLevel || configService.get(SharedConfigKeys.ServiceLogLevel) || "silent",
715
- redact: redact ? [
716
- "authorization",
717
- "headers.authorization",
718
- "req.headers.authorization",
719
- "req.remoteAddress",
720
- "req.remotePort"
721
- ] : [],
748
+ redact: redact ? ["authorization", "headers.authorization", "req", "res"] : [],
722
749
  transport: {
723
750
  target: "pino-pretty",
724
751
  options: {
@@ -780,4 +807,4 @@ function viteCssImportPlugin(outFilePath, relativePath = false) {
780
807
  };
781
808
  }
782
809
 
783
- export { AllianceException, AllianceExceptionFilter, AllianceHeaders, DatabasesErrorCodes, GatewayErrorCodes, LoggerModule, LoggerService, PortalErrorCodes, SharedConfigKeys, authMiddleware, createBearerToken, createPublicDistributionFiles, createSystemUserToken, getAppManifests, getPrivateKey, slugify, viteCssImportPlugin };
810
+ export { AllianceException, AllianceExceptionFilter, AllianceGqlException, AllianceHeaders, DatabasesErrorCodes, GatewayErrorCodes, LoggerModule, LoggerService, PortalErrorCodes, SharedConfigKeys, authMiddleware, createBearerToken, createPublicDistributionFiles, createSystemUserToken, getAppManifests, getPrivateKey, slugify, viteCssImportPlugin };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telia-ace/alliance-internal-node-utilities",
3
- "version": "1.0.3-next.1",
3
+ "version": "1.0.3-next.3",
4
4
  "description": "Utilities used internally by packages developed by team Alliance.",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "author": "Telia Company AB",
@@ -16,16 +16,21 @@
16
16
  "dependencies": {
17
17
  "@nestjs/common": "^10.1.0",
18
18
  "@nestjs/config": "^3.0.0",
19
+ "connect-redis": "^7.1.0",
19
20
  "express-openid-connect": "^2.16.0",
21
+ "express-session": "^1.17.3",
22
+ "graphql": "^16.7.1",
20
23
  "jsonschema": "^1.4.1",
21
24
  "jsonwebtoken": "^9.0.1",
22
25
  "nestjs-pino": "^3.3.0",
23
26
  "pino-http": "^8.3.3",
24
27
  "pino-pretty": "^10.1.0",
28
+ "redis": "^4.6.8",
25
29
  "slugify": "^1.6.6"
26
30
  },
27
31
  "devDependencies": {
28
32
  "@types/express": "^4.17.17",
33
+ "@types/express-session": "^1.17.1",
29
34
  "@types/jsonwebtoken": "^9.0.2",
30
35
  "@types/node": "^20.4.2",
31
36
  "minimist": "^1.2.8",