@prosopo/api-express-router 3.0.40 → 3.0.47

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 (41) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +3 -3
  2. package/.turbo/turbo-build$colon$tsc.log +56 -0
  3. package/.turbo/turbo-build.log +8 -4
  4. package/CHANGELOG.md +64 -0
  5. package/dist/apiExpressRouterFactory.d.ts +9 -0
  6. package/dist/apiExpressRouterFactory.d.ts.map +1 -0
  7. package/dist/apiExpressRouterFactory.js.map +1 -0
  8. package/dist/cjs/middlewares/authMiddleware.cjs +18 -41
  9. package/dist/endpointAdapter/apiExpressDefaultEndpointAdapter.d.ts +13 -0
  10. package/dist/endpointAdapter/apiExpressDefaultEndpointAdapter.d.ts.map +1 -0
  11. package/dist/endpointAdapter/apiExpressDefaultEndpointAdapter.js.map +1 -0
  12. package/dist/endpointAdapter/apiExpressEndpointAdapter.d.ts +8 -0
  13. package/dist/endpointAdapter/apiExpressEndpointAdapter.d.ts.map +1 -0
  14. package/dist/endpointAdapter/apiExpressEndpointAdapter.js +2 -0
  15. package/dist/endpointAdapter/apiExpressEndpointAdapter.js.map +1 -0
  16. package/dist/errorHandler.d.ts +5 -0
  17. package/dist/errorHandler.d.ts.map +1 -0
  18. package/dist/errorHandler.js.map +1 -0
  19. package/dist/index.d.ts +10 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/middlewares/authMiddleware.d.ts +5 -0
  23. package/dist/middlewares/authMiddleware.d.ts.map +1 -0
  24. package/dist/middlewares/authMiddleware.js +19 -42
  25. package/dist/middlewares/authMiddleware.js.map +1 -0
  26. package/dist/middlewares/requestLoggerMiddleware.d.ts +4 -0
  27. package/dist/middlewares/requestLoggerMiddleware.d.ts.map +1 -0
  28. package/dist/middlewares/requestLoggerMiddleware.js.map +1 -0
  29. package/dist/tests/unit/errorHandler.unit.test.d.ts +2 -0
  30. package/dist/tests/unit/errorHandler.unit.test.d.ts.map +1 -0
  31. package/dist/tests/unit/errorHandler.unit.test.js +140 -0
  32. package/dist/tests/unit/errorHandler.unit.test.js.map +1 -0
  33. package/dist/tests/unit/middlewares/authMiddleware.unit.test.d.ts +2 -0
  34. package/dist/tests/unit/middlewares/authMiddleware.unit.test.d.ts.map +1 -0
  35. package/dist/tests/unit/middlewares/authMiddleware.unit.test.js +143 -0
  36. package/dist/tests/unit/middlewares/authMiddleware.unit.test.js.map +1 -0
  37. package/express.d.ts +1 -1
  38. package/package.json +10 -8
  39. package/vite.cjs.config.ts +1 -1
  40. package/vite.esm.config.ts +1 -1
  41. package/vite.test.config.ts +1 -1
@@ -1,5 +1,5 @@
1
1
 
2
- > @prosopo/api-express-router@3.0.40 build:cjs
2
+ > @prosopo/api-express-router@3.0.47 build:cjs
3
3
  > NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
4
4
 
5
5
  ViteCommonJSConfig: .
@@ -50,5 +50,5 @@ rendering chunks...
50
50
  dist/cjs/apiExpressRouterFactory.cjs 0.92 kB
51
51
  dist/cjs/endpointAdapter/apiExpressDefaultEndpointAdapter.cjs 1.09 kB
52
52
  dist/cjs/index.cjs 1.16 kB
53
- dist/cjs/middlewares/authMiddleware.cjs 2.60 kB
54
- ✓ built in 132ms
53
+ dist/cjs/middlewares/authMiddleware.cjs 1.86 kB
54
+ ✓ built in 118ms
@@ -0,0 +1,56 @@
1
+
2
+ > @prosopo/api-express-router@3.0.47 build:tsc
3
+ > tsc --build --verbose
4
+
5
+ 4:57:39 PM - Projects in this build:
6
+ * ../../dev/config/tsconfig.json
7
+ * ../locale/tsconfig.json
8
+ * ../util/tsconfig.json
9
+ * ../util-crypto/tsconfig.json
10
+ * ../types/tsconfig.json
11
+ * ../common/tsconfig.json
12
+ * ../api-route/tsconfig.json
13
+ * ../redis-client/tsconfig.json
14
+ * ../api/tsconfig.json
15
+ * ../user-access-policy/tsconfig.json
16
+ * ../types-database/tsconfig.json
17
+ * ../database/tsconfig.json
18
+ * ../keyring/tsconfig.json
19
+ * ../types-env/tsconfig.json
20
+ * ../env/tsconfig.json
21
+ * tsconfig.json
22
+
23
+ 4:57:39 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/dependencies.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
24
+
25
+ 4:57:39 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
26
+
27
+ 4:57:39 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/verifyRecency.ts' is older than output '../util/tsconfig.tsbuildinfo'
28
+
29
+ 4:57:39 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
30
+
31
+ 4:57:39 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/procaptcha/api.ts' is older than output '../types/tsconfig.tsbuildinfo'
32
+
33
+ 4:57:39 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/logger.ts' is older than output '../common/tsconfig.tsbuildinfo'
34
+
35
+ 4:57:39 PM - Project '../api-route/tsconfig.json' is up to date because newest input '../api-route/src/index.ts' is older than output '../api-route/tsconfig.tsbuildinfo'
36
+
37
+ 4:57:39 PM - Project '../redis-client/tsconfig.json' is up to date because newest input '../redis-client/src/index.ts' is older than output '../redis-client/tsconfig.tsbuildinfo'
38
+
39
+ 4:57:39 PM - Project '../api/tsconfig.json' is up to date because newest input '../api/src/index.ts' is older than output '../api/tsconfig.tsbuildinfo'
40
+
41
+ 4:57:39 PM - Project '../user-access-policy/tsconfig.json' is up to date because newest input '../user-access-policy/src/transformRule.ts' is older than output '../user-access-policy/tsconfig.tsbuildinfo'
42
+
43
+ 4:57:39 PM - Project '../types-database/tsconfig.json' is up to date because newest input '../types-database/src/index.ts' is older than output '../types-database/tsconfig.tsbuildinfo'
44
+
45
+ 4:57:39 PM - Project '../database/tsconfig.json' is up to date because newest input '../database/src/index.ts' is older than output '../database/tsconfig.tsbuildinfo'
46
+
47
+ 4:57:39 PM - Project '../keyring/tsconfig.json' is up to date because newest input '../keyring/src/index.ts' is older than output '../keyring/tsconfig.tsbuildinfo'
48
+
49
+ 4:57:39 PM - Project '../types-env/tsconfig.json' is up to date because newest input '../types-env/src/env.ts' is older than output '../types-env/tsconfig.tsbuildinfo'
50
+
51
+ 4:57:39 PM - Project '../env/tsconfig.json' is up to date because newest input '../env/src/env.ts' is older than output '../env/tsconfig.tsbuildinfo'
52
+
53
+ 4:57:39 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
54
+
55
+ 4:57:39 PM - Building project '/home/runner/work/captcha/captcha/packages/api-express-router/tsconfig.json'...
56
+
@@ -1,6 +1,10 @@
1
1
 
2
- > @prosopo/api-express-router@3.0.40 build
3
- > NODE_ENV=${NODE_ENV:-development}; vite build --config vite.esm.config.ts --mode $NODE_ENV
2
+ > @prosopo/api-express-router@3.0.47 build
3
+ > npm run build:cross-env -- --mode ${NODE_ENV:-development}
4
+
5
+
6
+ > @prosopo/api-express-router@3.0.47 build:cross-env
7
+ > vite build --config vite.esm.config.ts --mode production
4
8
 
5
9
  ViteEsmConfig: .
6
10
  {
@@ -50,5 +54,5 @@ rendering chunks...
50
54
  dist/index.js 0.78 kB
51
55
  dist/apiExpressRouterFactory.js 0.78 kB
52
56
  dist/endpointAdapter/apiExpressDefaultEndpointAdapter.js 0.98 kB
53
- dist/middlewares/authMiddleware.js 2.46 kB
54
- ✓ built in 204ms
57
+ dist/middlewares/authMiddleware.js 1.73 kB
58
+ ✓ built in 205ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,69 @@
1
1
  # @prosopo/api-express-router
2
2
 
3
+ ## 3.0.47
4
+ ### Patch Changes
5
+
6
+ - 3acc333: Add JWT issuance to keypairs
7
+ - 0a38892: feat/cross-os-testing
8
+ - a8faa9a: bump license year
9
+ - 7543d17: mouse movements bot stopping
10
+ - 3acc333: Release 3.3.0
11
+ - Updated dependencies [3acc333]
12
+ - Updated dependencies [0a38892]
13
+ - Updated dependencies [1ee3d80]
14
+ - Updated dependencies [a8faa9a]
15
+ - Updated dependencies [7543d17]
16
+ - Updated dependencies [fe9fe22]
17
+ - Updated dependencies [3acc333]
18
+ - @prosopo/util-crypto@13.5.29
19
+ - @prosopo/types@3.8.0
20
+ - @prosopo/api-route@2.6.36
21
+ - @prosopo/common@3.1.28
22
+ - @prosopo/locale@3.1.28
23
+ - @prosopo/env@3.2.35
24
+
25
+ ## 3.0.46
26
+ ### Patch Changes
27
+
28
+ - @prosopo/env@3.2.34
29
+
30
+ ## 3.0.45
31
+ ### Patch Changes
32
+
33
+ - @prosopo/env@3.2.33
34
+
35
+ ## 3.0.44
36
+ ### Patch Changes
37
+
38
+ - @prosopo/env@3.2.32
39
+
40
+ ## 3.0.43
41
+ ### Patch Changes
42
+
43
+ - Updated dependencies [141e462]
44
+ - @prosopo/types@3.7.2
45
+ - @prosopo/env@3.2.31
46
+
47
+ ## 3.0.42
48
+ ### Patch Changes
49
+
50
+ - Updated dependencies [345b25b]
51
+ - @prosopo/types@3.7.1
52
+ - @prosopo/env@3.2.30
53
+
54
+ ## 3.0.41
55
+ ### Patch Changes
56
+
57
+ - Updated dependencies [ce70a2b]
58
+ - Updated dependencies [c2b940f]
59
+ - Updated dependencies [f6b5094]
60
+ - Updated dependencies [e01227b]
61
+ - @prosopo/types@3.7.0
62
+ - @prosopo/locale@3.1.27
63
+ - @prosopo/common@3.1.27
64
+ - @prosopo/env@3.2.29
65
+ - @prosopo/api-route@2.6.35
66
+
3
67
  ## 3.0.40
4
68
  ### Patch Changes
5
69
 
@@ -0,0 +1,9 @@
1
+ import type { ApiRoutes, ApiRoutesProvider } from "@prosopo/api-route";
2
+ import { Router } from "express";
3
+ import type { ApiExpressEndpointAdapter } from "./endpointAdapter/apiExpressEndpointAdapter.js";
4
+ declare class ApiExpressRouterFactory {
5
+ createRouter(routersProvider: ApiRoutesProvider, apiEndpointAdapter: ApiExpressEndpointAdapter): Router;
6
+ protected registerRoutes(router: Router, routes: ApiRoutes, apiEndpointAdapter: ApiExpressEndpointAdapter): void;
7
+ }
8
+ export { ApiExpressRouterFactory };
9
+ //# sourceMappingURL=apiExpressRouterFactory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiExpressRouterFactory.d.ts","sourceRoot":"","sources":["../src/apiExpressRouterFactory.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAIN,MAAM,EACN,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gDAAgD,CAAC;AAGhG,cAAM,uBAAuB;IACrB,YAAY,CAClB,eAAe,EAAE,iBAAiB,EAClC,kBAAkB,EAAE,yBAAyB,GAC3C,MAAM;IAcT,SAAS,CAAC,cAAc,CACvB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,SAAS,EACjB,kBAAkB,EAAE,yBAAyB,GAC3C,IAAI;CAmBP;AAED,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiExpressRouterFactory.js","sourceRoot":"","sources":["../src/apiExpressRouterFactory.ts"],"names":[],"mappings":"AAeA,OAAO,EAIN,MAAM,GACN,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,uBAAuB;IACrB,YAAY,CAClB,eAAkC,EAClC,kBAA6C;QAE7C,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;QACxB,MAAM,SAAS,GAAG,eAAe,CAAC,SAAS,EAAE,CAAC;QAE9C,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE,kBAAkB,CAAC,CAAC;QAK3D,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAEzB,OAAO,MAAM,CAAC;IACf,CAAC;IAES,cAAc,CACvB,MAAc,EACd,MAAiB,EACjB,kBAA6C;QAE7C,KAAK,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACxD,MAAM,CAAC,IAAI,CACV,KAAK,EACL,KAAK,EACJ,OAAgB,EAChB,QAAkB,EAClB,IAAkB,EACF,EAAE;gBAClB,OAAO,MAAM,kBAAkB,CAAC,aAAa,CAC5C,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,IAAI,CACJ,CAAC;YACH,CAAC,CACD,CAAC;QACH,CAAC;IACF,CAAC;CACD;AAED,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
@@ -5,31 +5,20 @@ const common = require("@prosopo/common");
5
5
  const authMiddleware = (pair, authAccount) => {
6
6
  return async (req, res, next) => {
7
7
  try {
8
- const { signature, timestamp } = extractHeaders(req);
8
+ const jwt = extractJWT(req);
9
9
  let error;
10
- if (authAccount) {
11
- try {
12
- verifySignature(signature, timestamp, authAccount);
13
- next();
14
- return;
15
- } catch (e) {
16
- req.logger.warn(() => ({
17
- err: e,
18
- data: {
19
- account: authAccount?.address
20
- }
21
- }));
22
- error = e;
23
- }
10
+ if (authAccount?.jwtVerify(jwt).isValid) {
11
+ next();
12
+ return;
24
13
  }
25
- if (pair) {
26
- verifySignature(signature, timestamp, pair);
14
+ if (pair?.jwtVerify(jwt).isValid) {
27
15
  next();
28
16
  return;
29
17
  }
30
18
  res.status(401).json({
31
- error: "Unauthorized",
32
- message: new common.ProsopoEnvError(error || "CONTRACT.CANNOT_FIND_KEYPAIR")
19
+ error: new common.ProsopoEnvError(error || "API.UNAUTHORIZED", {
20
+ context: { i18n: req.i18n, code: 401 }
21
+ })
33
22
  });
34
23
  return;
35
24
  } catch (err) {
@@ -39,32 +28,20 @@ const authMiddleware = (pair, authAccount) => {
39
28
  }
40
29
  };
41
30
  };
42
- const extractHeaders = (req) => {
43
- const signature = req.headers.signature;
44
- const timestamp = req.headers.timestamp;
45
- if (!timestamp) {
46
- throw new common.ProsopoApiError("GENERAL.INVALID_TIMESTAMP", {
47
- context: { error: "Missing timestamp", code: 400 }
48
- });
49
- }
50
- if (!signature) {
51
- throw new common.ProsopoApiError("GENERAL.INVALID_SIGNATURE", {
52
- context: { error: "Missing signature", code: 400 }
53
- });
54
- }
55
- if (Array.isArray(signature) || Array.isArray(timestamp) || !util.isHex(signature)) {
56
- throw new common.ProsopoApiError("CONTRACT.INVALID_DATA_FORMAT", {
57
- context: { error: "Invalid header format", code: 400 }
31
+ const extractJWT = (req) => {
32
+ const authHeader = req.headers.Authorization || req.headers.authorization;
33
+ if (!authHeader || typeof authHeader !== "string") {
34
+ throw new common.ProsopoApiError("GENERAL.MISSING_AUTH_HEADER", {
35
+ context: { error: "Missing Authorization header", code: 401 }
58
36
  });
59
37
  }
60
- const now = (/* @__PURE__ */ new Date()).getTime();
61
- const ts = Number.parseInt(timestamp);
62
- if (now - ts > 3e5) {
63
- throw new common.ProsopoApiError("GENERAL.INVALID_TIMESTAMP", {
64
- context: { error: "Timestamp is too old", code: 400 }
38
+ const jwt = authHeader.replace("Bearer ", "");
39
+ if (!jwt) {
40
+ throw new common.ProsopoApiError("GENERAL.INVALID_JWT", {
41
+ context: { error: "Missing JWT", code: 400 }
65
42
  });
66
43
  }
67
- return { signature, timestamp };
44
+ return jwt;
68
45
  };
69
46
  const verifySignature = (signature, message, pair) => {
70
47
  const u8Sig = util.hexToU8a(signature);
@@ -0,0 +1,13 @@
1
+ import type { ApiEndpoint } from "@prosopo/api-route";
2
+ import { type LogLevel } from "@prosopo/common";
3
+ import type { NextFunction, Request, Response } from "express";
4
+ import type { ZodType } from "zod";
5
+ import type { ApiExpressEndpointAdapter } from "./apiExpressEndpointAdapter.js";
6
+ declare class ApiExpressDefaultEndpointAdapter implements ApiExpressEndpointAdapter {
7
+ private readonly logLevel;
8
+ private readonly errorStatusCode;
9
+ constructor(logLevel: LogLevel, errorStatusCode: number);
10
+ handleRequest(endpoint: ApiEndpoint<ZodType | undefined>, request: Request, response: Response, next: NextFunction): Promise<void>;
11
+ }
12
+ export { ApiExpressDefaultEndpointAdapter };
13
+ //# sourceMappingURL=apiExpressDefaultEndpointAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiExpressDefaultEndpointAdapter.d.ts","sourceRoot":"","sources":["../../src/endpointAdapter/apiExpressDefaultEndpointAdapter.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EACN,KAAK,QAAQ,EAGb,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AACnC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAEhF,cAAM,gCAAiC,YAAW,yBAAyB;IAEzE,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,eAAe;gBADf,QAAQ,EAAE,QAAQ,EAClB,eAAe,EAAE,MAAM;IAG5B,aAAa,CACzB,QAAQ,EAAE,WAAW,CAAC,OAAO,GAAG,SAAS,CAAC,EAC1C,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,YAAY,GAChB,OAAO,CAAC,IAAI,CAAC;CA8BhB;AAED,OAAO,EAAE,gCAAgC,EAAE,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiExpressDefaultEndpointAdapter.js","sourceRoot":"","sources":["../../src/endpointAdapter/apiExpressDefaultEndpointAdapter.ts"],"names":[],"mappings":"AAeA,OAAO,EAEN,eAAe,EACf,gBAAgB,GAChB,MAAM,iBAAiB,CAAC;AAKzB,MAAM,gCAAgC;IACrC,YACkB,QAAkB,EAClB,eAAuB;QADvB,aAAQ,GAAR,QAAQ,CAAU;QAClB,oBAAe,GAAf,eAAe,CAAQ;IACtC,CAAC;IAEG,KAAK,CAAC,aAAa,CACzB,QAA0C,EAC1C,OAAgB,EAChB,QAAkB,EAClB,IAAkB;QAElB,IAAI,IAAa,CAAC;QAClB,IAAI,CAAC;YACJ,IAAI,GAAG,QAAQ,CAAC,oBAAoB,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,OAAO,IAAI,CACV,IAAI,eAAe,CAAC,iBAAiB,EAAE;gBACtC,OAAO,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE;aACpC,CAAC,CACF,CAAC;QACH,CAAC;QAED,IAAI,CAAC;YACJ,MAAM,mBAAmB,GAAG,MAAM,QAAQ,CAAC,cAAc,CACxD,IAAI,EACJ,OAAO,CAAC,MAAM,CACd,CAAC;YAGF,MAAM,cAAc,GAAG,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;YAE7D,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;gBAC3B,GAAG,EAAE,KAAK;aACV,CAAC,CAAC,CAAC;YAEJ,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;QACjE,CAAC;IACF,CAAC;CACD;AAED,OAAO,EAAE,gCAAgC,EAAE,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { ApiEndpoint } from "@prosopo/api-route";
2
+ import type { NextFunction, Request, Response } from "express";
3
+ import type { ZodType } from "zod";
4
+ interface ApiExpressEndpointAdapter {
5
+ handleRequest(endpoint: ApiEndpoint<ZodType | undefined>, request: Request, response: Response, next: NextFunction): Promise<void>;
6
+ }
7
+ export type { ApiExpressEndpointAdapter };
8
+ //# sourceMappingURL=apiExpressEndpointAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiExpressEndpointAdapter.d.ts","sourceRoot":"","sources":["../../src/endpointAdapter/apiExpressEndpointAdapter.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAEnC,UAAU,yBAAyB;IAClC,aAAa,CACZ,QAAQ,EAAE,WAAW,CAAC,OAAO,GAAG,SAAS,CAAC,EAC1C,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,YAAY,GAChB,OAAO,CAAC,IAAI,CAAC,CAAC;CACjB;AAED,YAAY,EAAE,yBAAyB,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=apiExpressEndpointAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiExpressEndpointAdapter.js","sourceRoot":"","sources":["../../src/endpointAdapter/apiExpressEndpointAdapter.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ import { type ProsopoApiError } from "@prosopo/common";
2
+ import type { NextFunction, Request, Response } from "express";
3
+ import type { ZodError } from "zod";
4
+ export declare const handleErrors: (err: ProsopoApiError | SyntaxError | ZodError, request: Request, response: Response, next: NextFunction) => void;
5
+ //# sourceMappingURL=errorHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../src/errorHandler.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,KAAK,eAAe,EAAe,MAAM,iBAAiB,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAEpC,eAAO,MAAM,YAAY,QACnB,eAAe,GAAG,WAAW,GAAG,QAAQ,WACpC,OAAO,YACN,QAAQ,QACZ,YAAY,SAQlB,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../src/errorHandler.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAwB,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAIpE,MAAM,CAAC,MAAM,YAAY,GAAG,CAC3B,GAA6C,EAC7C,OAAgB,EAChB,QAAkB,EAClB,IAAkB,EACjB,EAAE;IACH,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,QAAQ,CAAC,aAAa,GAAG,aAAa,CAAC;IACvC,QAAQ,CAAC,GAAG,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;IACjD,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACpC,QAAQ,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { LogLevel } from "@prosopo/common";
2
+ import { ApiExpressRouterFactory } from "./apiExpressRouterFactory.js";
3
+ import type { ApiExpressEndpointAdapter } from "./endpointAdapter/apiExpressEndpointAdapter.js";
4
+ declare const apiExpressRouterFactory: ApiExpressRouterFactory;
5
+ declare const createApiExpressDefaultEndpointAdapter: (logLevel: LogLevel, errorStatusCode?: number) => ApiExpressEndpointAdapter;
6
+ export { apiExpressRouterFactory, createApiExpressDefaultEndpointAdapter, type ApiExpressEndpointAdapter, };
7
+ export * from "./errorHandler.js";
8
+ export * from "./middlewares/authMiddleware.js";
9
+ export * from "./middlewares/requestLoggerMiddleware.js";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAEvE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gDAAgD,CAAC;AAEhG,QAAA,MAAM,uBAAuB,yBAAgC,CAAC;AAE9D,QAAA,MAAM,sCAAsC,aACjC,QAAQ,+BAEhB,yBAEF,CAAC;AAEF,OAAO,EACN,uBAAuB,EACvB,sCAAsC,EACtC,KAAK,yBAAyB,GAC9B,CAAC;AAEF,cAAc,mBAAmB,CAAC;AAClC,cAAc,iCAAiC,CAAC;AAChD,cAAc,0CAA0C,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,gCAAgC,EAAE,MAAM,uDAAuD,CAAC;AAGzG,MAAM,uBAAuB,GAAG,IAAI,uBAAuB,EAAE,CAAC;AAE9D,MAAM,sCAAsC,GAAG,CAC9C,QAAkB,EAClB,eAAe,GAAG,GAAG,EACO,EAAE;IAC9B,OAAO,IAAI,gCAAgC,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;AACxE,CAAC,CAAC;AAEF,OAAO,EACN,uBAAuB,EACvB,sCAAsC,GAEtC,CAAC;AAEF,cAAc,mBAAmB,CAAC;AAClC,cAAc,iCAAiC,CAAC;AAChD,cAAc,0CAA0C,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { KeyringPair } from "@prosopo/types";
2
+ import type { NextFunction, Request, Response } from "express";
3
+ export declare const authMiddleware: (pair: KeyringPair | undefined, authAccount?: KeyringPair | undefined) => (req: Request, res: Response, next: NextFunction) => Promise<void>;
4
+ export declare const verifySignature: (signature: string, message: string, pair: KeyringPair) => void;
5
+ //# sourceMappingURL=authMiddleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authMiddleware.d.ts","sourceRoot":"","sources":["../../src/middlewares/authMiddleware.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE/D,eAAO,MAAM,cAAc,SACpB,WAAW,GAAG,SAAS,gBACf,WAAW,GAAG,SAAS,WAElB,OAAO,OAAO,QAAQ,QAAQ,YAAY,kBA4B7D,CAAC;AAsBF,eAAO,MAAM,eAAe,cAChB,MAAM,WACR,MAAM,QACT,WAAW,SAejB,CAAC"}
@@ -1,33 +1,22 @@
1
- import { isHex, hexToU8a } from "@polkadot/util";
1
+ import { hexToU8a } from "@polkadot/util";
2
2
  import { ProsopoEnvError, ProsopoApiError } from "@prosopo/common";
3
3
  const authMiddleware = (pair, authAccount) => {
4
4
  return async (req, res, next) => {
5
5
  try {
6
- const { signature, timestamp } = extractHeaders(req);
6
+ const jwt = extractJWT(req);
7
7
  let error;
8
- if (authAccount) {
9
- try {
10
- verifySignature(signature, timestamp, authAccount);
11
- next();
12
- return;
13
- } catch (e) {
14
- req.logger.warn(() => ({
15
- err: e,
16
- data: {
17
- account: authAccount?.address
18
- }
19
- }));
20
- error = e;
21
- }
8
+ if (authAccount?.jwtVerify(jwt).isValid) {
9
+ next();
10
+ return;
22
11
  }
23
- if (pair) {
24
- verifySignature(signature, timestamp, pair);
12
+ if (pair?.jwtVerify(jwt).isValid) {
25
13
  next();
26
14
  return;
27
15
  }
28
16
  res.status(401).json({
29
- error: "Unauthorized",
30
- message: new ProsopoEnvError(error || "CONTRACT.CANNOT_FIND_KEYPAIR")
17
+ error: new ProsopoEnvError(error || "API.UNAUTHORIZED", {
18
+ context: { i18n: req.i18n, code: 401 }
19
+ })
31
20
  });
32
21
  return;
33
22
  } catch (err) {
@@ -37,32 +26,20 @@ const authMiddleware = (pair, authAccount) => {
37
26
  }
38
27
  };
39
28
  };
40
- const extractHeaders = (req) => {
41
- const signature = req.headers.signature;
42
- const timestamp = req.headers.timestamp;
43
- if (!timestamp) {
44
- throw new ProsopoApiError("GENERAL.INVALID_TIMESTAMP", {
45
- context: { error: "Missing timestamp", code: 400 }
46
- });
47
- }
48
- if (!signature) {
49
- throw new ProsopoApiError("GENERAL.INVALID_SIGNATURE", {
50
- context: { error: "Missing signature", code: 400 }
51
- });
52
- }
53
- if (Array.isArray(signature) || Array.isArray(timestamp) || !isHex(signature)) {
54
- throw new ProsopoApiError("CONTRACT.INVALID_DATA_FORMAT", {
55
- context: { error: "Invalid header format", code: 400 }
29
+ const extractJWT = (req) => {
30
+ const authHeader = req.headers.Authorization || req.headers.authorization;
31
+ if (!authHeader || typeof authHeader !== "string") {
32
+ throw new ProsopoApiError("GENERAL.MISSING_AUTH_HEADER", {
33
+ context: { error: "Missing Authorization header", code: 401 }
56
34
  });
57
35
  }
58
- const now = (/* @__PURE__ */ new Date()).getTime();
59
- const ts = Number.parseInt(timestamp);
60
- if (now - ts > 3e5) {
61
- throw new ProsopoApiError("GENERAL.INVALID_TIMESTAMP", {
62
- context: { error: "Timestamp is too old", code: 400 }
36
+ const jwt = authHeader.replace("Bearer ", "");
37
+ if (!jwt) {
38
+ throw new ProsopoApiError("GENERAL.INVALID_JWT", {
39
+ context: { error: "Missing JWT", code: 400 }
63
40
  });
64
41
  }
65
- return { signature, timestamp };
42
+ return jwt;
66
43
  };
67
44
  const verifySignature = (signature, message, pair) => {
68
45
  const u8Sig = hexToU8a(signature);
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authMiddleware.js","sourceRoot":"","sources":["../../src/middlewares/authMiddleware.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAKnE,MAAM,CAAC,MAAM,cAAc,GAAG,CAC7B,IAA6B,EAC7B,WAAqC,EACpC,EAAE;IACH,OAAO,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QAChE,IAAI,CAAC;YACJ,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;YAE5B,IAAI,KAAkC,CAAC;YAEvC,IAAI,WAAW,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;gBACzC,IAAI,EAAE,CAAC;gBACP,OAAO;YACR,CAAC;YAED,IAAI,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;gBAClC,IAAI,EAAE,CAAC;gBACP,OAAO;YACR,CAAC;YAED,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACpB,KAAK,EAAE,IAAI,eAAe,CAAC,KAAK,IAAI,kBAAkB,EAAE;oBACvD,OAAO,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;iBACtC,CAAC;aACF,CAAC,CAAC;YACH,OAAO;QACR,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,uBAAuB,EAAE,CAAC,CAAC,CAAC;YAChE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;YAC9D,OAAO;QACR,CAAC;IACF,CAAC,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,GAAY,EAAE,EAAE;IACnC,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,IAAI,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC;IAE1E,IAAI,CAAC,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QACnD,MAAM,IAAI,eAAe,CAAC,6BAA6B,EAAE;YACxD,OAAO,EAAE,EAAE,KAAK,EAAE,8BAA8B,EAAE,IAAI,EAAE,GAAG,EAAE;SAC7D,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAE9C,IAAI,CAAC,GAAG,EAAE,CAAC;QACV,MAAM,IAAI,eAAe,CAAC,qBAAqB,EAAE;YAChD,OAAO,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,GAAG,EAAE;SAC5C,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,GAAU,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAC9B,SAAiB,EACjB,OAAe,EACf,IAAiB,EAChB,EAAE;IACH,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;IAElC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,eAAe,CAAC,2BAA2B,EAAE;YACtD,OAAO,EAAE;gBACR,KAAK,EAAE,+BAA+B;gBACtC,IAAI,EAAE,GAAG;gBACT,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,OAAO;gBACP,SAAS;aACT;SACD,CAAC,CAAC;IACJ,CAAC;AACF,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { ProviderEnvironment } from "@prosopo/env";
2
+ import type { NextFunction, Request, Response } from "express";
3
+ export declare function requestLoggerMiddleware(env: ProviderEnvironment): (req: Request, res: Response, next: NextFunction) => void;
4
+ //# sourceMappingURL=requestLoggerMiddleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requestLoggerMiddleware.d.ts","sourceRoot":"","sources":["../../src/middlewares/requestLoggerMiddleware.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAG/D,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,mBAAmB,SAClD,OAAO,OAAO,QAAQ,QAAQ,YAAY,UAqBvD"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requestLoggerMiddleware.js","sourceRoot":"","sources":["../../src/middlewares/requestLoggerMiddleware.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAG3D,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AAEpC,MAAM,UAAU,uBAAuB,CAAC,GAAwB;IAC/D,OAAO,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QAC1D,MAAM,SAAS,GACb,GAAG,CAAC,OAAO,CAAC,cAAc,CAAY,IAAI,KAAK,MAAM,EAAE,EAAE,CAAC;QAE5D,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;QAElE,MAAM,MAAM,GAAG,SAAS,CACvB,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,EAClC,gBAAgB,CAChB,CAAC,IAAI,CAAC;YACN,SAAS;YACT,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnC,CAAC,CAAC;QAGH,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;QACpB,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC;QAG1B,IAAI,EAAE,CAAC;IACR,CAAC,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=errorHandler.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errorHandler.unit.test.d.ts","sourceRoot":"","sources":["../../../src/tests/unit/errorHandler.unit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,140 @@
1
+ import { ProsopoApiError, ProsopoEnvError } from "@prosopo/common";
2
+ import { loadI18next } from "@prosopo/locale";
3
+ import { describe, expect, it, vi } from "vitest";
4
+ import { ZodError } from "zod";
5
+ import { handleErrors } from "../../errorHandler.js";
6
+ describe("handleErrors", async () => {
7
+ const i18n = await loadI18next(true);
8
+ await i18n.changeLanguage("en");
9
+ it("should handle ProsopoApiError", async () => {
10
+ const mockRequest = { i18n };
11
+ const mockResponse = {
12
+ writeHead: vi.fn().mockReturnThis(),
13
+ set: vi.fn().mockReturnThis(),
14
+ status: vi.fn().mockReturnThis(),
15
+ send: vi.fn(),
16
+ end: vi.fn(),
17
+ };
18
+ const mockNext = vi.fn();
19
+ const error = new ProsopoApiError("CONTRACT.INVALID_DATA_FORMAT", {
20
+ context: { code: 400 },
21
+ i18n,
22
+ });
23
+ console.log(error);
24
+ handleErrors(error, mockRequest, mockResponse, mockNext);
25
+ expect(mockResponse.set).toHaveBeenCalledWith("content-type", "application/json");
26
+ expect(mockResponse.send).toHaveBeenCalledWith({
27
+ error: {
28
+ code: 400,
29
+ key: "CONTRACT.INVALID_DATA_FORMAT",
30
+ message: "Invalid data format",
31
+ },
32
+ });
33
+ expect(mockResponse.status).toHaveBeenCalledWith(400);
34
+ expect(mockResponse.end).toHaveBeenCalled();
35
+ });
36
+ it("should not return SyntaxError", async () => {
37
+ const mockRequest = { i18n };
38
+ const mockResponse = {
39
+ writeHead: vi.fn().mockReturnThis(),
40
+ set: vi.fn().mockReturnThis(),
41
+ status: vi.fn().mockReturnThis(),
42
+ send: vi.fn(),
43
+ end: vi.fn(),
44
+ };
45
+ const mockNext = vi.fn();
46
+ const message = "Unknown API error";
47
+ const error = new SyntaxError(message);
48
+ handleErrors(error, mockRequest, mockResponse, mockNext);
49
+ expect(mockResponse.set).toHaveBeenCalledWith("content-type", "application/json");
50
+ expect(mockResponse.status).toHaveBeenCalledWith(400);
51
+ expect(mockResponse.send).toHaveBeenCalledWith({
52
+ error: {
53
+ message,
54
+ key: "API.UNKNOWN",
55
+ code: 400,
56
+ },
57
+ });
58
+ expect(mockResponse.end).toHaveBeenCalled();
59
+ });
60
+ it("should handle ZodError", () => {
61
+ const mockRequest = { i18n };
62
+ const mockResponse = {
63
+ writeHead: vi.fn().mockReturnThis(),
64
+ set: vi.fn().mockReturnThis(),
65
+ status: vi.fn().mockReturnThis(),
66
+ send: vi.fn(),
67
+ end: vi.fn(),
68
+ };
69
+ const mockNext = vi.fn();
70
+ const zodError = {
71
+ code: "custom",
72
+ message: "Invalid input",
73
+ path: ["some", "variable"],
74
+ };
75
+ const error = new ZodError([zodError]);
76
+ handleErrors(error, mockRequest, mockResponse, mockNext);
77
+ expect(mockResponse.set).toHaveBeenCalledWith("content-type", "application/json");
78
+ expect(mockResponse.status).toHaveBeenCalledWith(400);
79
+ expect(mockResponse.send).toHaveBeenCalledWith({
80
+ error: { code: 400, key: "API.INVALID_BODY", message: [zodError] },
81
+ });
82
+ expect(mockResponse.end).toHaveBeenCalled();
83
+ });
84
+ it("should unwrap nested ProsopoBaseError", async () => {
85
+ const mockRequest = { i18n };
86
+ const mockResponse = {
87
+ writeHead: vi.fn().mockReturnThis(),
88
+ set: vi.fn().mockReturnThis(),
89
+ status: vi.fn().mockReturnThis(),
90
+ send: vi.fn(),
91
+ end: vi.fn(),
92
+ };
93
+ const mockNext = vi.fn();
94
+ const envError = new ProsopoEnvError("GENERAL.ENVIRONMENT_NOT_READY", {
95
+ i18n,
96
+ });
97
+ const apiError = new ProsopoApiError(envError);
98
+ handleErrors(apiError, mockRequest, mockResponse, mockNext);
99
+ expect(mockResponse.set).toHaveBeenCalledWith("content-type", "application/json");
100
+ expect(mockResponse.status).toHaveBeenCalledWith(500);
101
+ expect(mockResponse.send).toHaveBeenCalledWith({
102
+ error: {
103
+ code: 500,
104
+ key: "GENERAL.ENVIRONMENT_NOT_READY",
105
+ message: "Environment not ready",
106
+ },
107
+ });
108
+ expect(mockResponse.end).toHaveBeenCalled();
109
+ });
110
+ it("should unwrap nested ProsopoBaseErrors but not an Error that is nested inside them", async () => {
111
+ const mockRequest = { i18n };
112
+ const mockResponse = {
113
+ writeHead: vi.fn().mockReturnThis(),
114
+ set: vi.fn().mockReturnThis(),
115
+ status: vi.fn().mockReturnThis(),
116
+ send: vi.fn(),
117
+ end: vi.fn(),
118
+ };
119
+ const mockNext = vi.fn();
120
+ const code = 400;
121
+ const key = "API.UNKNOWN";
122
+ const error = new Error("Some error");
123
+ const apiError = new ProsopoApiError(key, {
124
+ context: { code, error },
125
+ i18n,
126
+ });
127
+ handleErrors(apiError, mockRequest, mockResponse, mockNext);
128
+ expect(mockResponse.set).toHaveBeenCalledWith("content-type", "application/json");
129
+ expect(mockResponse.status).toHaveBeenCalledWith(code);
130
+ expect(mockResponse.send).toHaveBeenCalledWith({
131
+ error: {
132
+ code,
133
+ key,
134
+ message: "Unknown API error",
135
+ },
136
+ });
137
+ expect(mockResponse.end).toHaveBeenCalled();
138
+ });
139
+ });
140
+ //# sourceMappingURL=errorHandler.unit.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errorHandler.unit.test.js","sourceRoot":"","sources":["../../../src/tests/unit/errorHandler.unit.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=authMiddleware.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authMiddleware.unit.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/unit/middlewares/authMiddleware.unit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,143 @@
1
+ import { hexToU8a, isHex } from "@polkadot/util";
2
+ import { ProsopoEnvError, getLogger } from "@prosopo/common";
3
+ import { describe, expect, it, vi } from "vitest";
4
+ import { authMiddleware } from "../../../middlewares/authMiddleware.js";
5
+ const loggerOuter = getLogger("info", import.meta.url);
6
+ const mockLogger = {
7
+ debug: vi.fn().mockImplementation(loggerOuter.debug.bind(loggerOuter)),
8
+ log: vi.fn().mockImplementation(loggerOuter.log.bind(loggerOuter)),
9
+ info: vi.fn().mockImplementation(loggerOuter.info.bind(loggerOuter)),
10
+ error: vi.fn().mockImplementation(loggerOuter.error.bind(loggerOuter)),
11
+ trace: vi.fn().mockImplementation(loggerOuter.trace.bind(loggerOuter)),
12
+ fatal: vi.fn().mockImplementation(loggerOuter.fatal.bind(loggerOuter)),
13
+ warn: vi.fn().mockImplementation(loggerOuter.warn.bind(loggerOuter)),
14
+ };
15
+ vi.mock("@polkadot/util", async (importOriginal) => {
16
+ const actual = await importOriginal();
17
+ return {
18
+ ...actual,
19
+ hexToU8a: vi.fn(),
20
+ isHex: vi.fn(),
21
+ };
22
+ });
23
+ const mockPair = {
24
+ publicKey: "mockPublicKey",
25
+ verify: vi.fn(),
26
+ jwtVerify: vi.fn(),
27
+ };
28
+ const mockEnv = {
29
+ pair: mockPair,
30
+ authAccount: mockPair,
31
+ logger: mockLogger,
32
+ jwtVerify: vi.fn(),
33
+ };
34
+ describe("authMiddleware", () => {
35
+ it("should call next() if signature is valid", async () => {
36
+ const mockLogger = {
37
+ debug: vi.fn().mockImplementation(loggerOuter.debug.bind(loggerOuter)),
38
+ log: vi.fn().mockImplementation(loggerOuter.log.bind(loggerOuter)),
39
+ info: vi.fn().mockImplementation(loggerOuter.info.bind(loggerOuter)),
40
+ error: vi.fn().mockImplementation(loggerOuter.error.bind(loggerOuter)),
41
+ trace: vi.fn().mockImplementation(loggerOuter.trace.bind(loggerOuter)),
42
+ fatal: vi.fn().mockImplementation(loggerOuter.fatal.bind(loggerOuter)),
43
+ warn: vi.fn().mockImplementation(loggerOuter.warn.bind(loggerOuter)),
44
+ };
45
+ const mockReq = {
46
+ url: "/v1/prosopo/provider/captcha/image",
47
+ originalUrl: "/v1/prosopo/provider/captcha/image",
48
+ headers: {
49
+ Authorization: "Bearer mockToken",
50
+ },
51
+ logger: mockLogger,
52
+ };
53
+ const mockRes = {
54
+ status: vi.fn().mockReturnThis(),
55
+ json: vi.fn(),
56
+ };
57
+ const mockNext = vi.fn();
58
+ vi.mocked(isHex).mockReturnValue(true);
59
+ vi.mocked(hexToU8a).mockReturnValue(new Uint8Array());
60
+ vi.mocked(mockPair.jwtVerify).mockReturnValue({
61
+ isValid: true,
62
+ });
63
+ const middleware = authMiddleware(mockEnv.pair, mockEnv.authAccount);
64
+ await middleware(mockReq, mockRes, mockNext);
65
+ expect(mockNext).toHaveBeenCalled();
66
+ expect(mockRes.status).not.toHaveBeenCalled();
67
+ });
68
+ it("should return 401 if jwt is invalid", async () => {
69
+ const mockLogger = {
70
+ debug: vi.fn().mockImplementation(loggerOuter.debug.bind(loggerOuter)),
71
+ log: vi.fn().mockImplementation(loggerOuter.log.bind(loggerOuter)),
72
+ info: vi.fn().mockImplementation(loggerOuter.info.bind(loggerOuter)),
73
+ error: vi.fn().mockImplementation(loggerOuter.error.bind(loggerOuter)),
74
+ trace: vi.fn().mockImplementation(loggerOuter.trace.bind(loggerOuter)),
75
+ fatal: vi.fn().mockImplementation(loggerOuter.fatal.bind(loggerOuter)),
76
+ warn: vi.fn().mockImplementation(loggerOuter.warn.bind(loggerOuter)),
77
+ };
78
+ const mockReq = {
79
+ url: "/v1/prosopo/provider/captcha/image",
80
+ originalUrl: "/v1/prosopo/provider/captcha/image",
81
+ headers: {
82
+ Authorization: "Bearer mockToken",
83
+ },
84
+ logger: mockLogger,
85
+ i18n: vi.fn().mockReturnValue({
86
+ t: (key) => key,
87
+ }),
88
+ };
89
+ const mockRes = {
90
+ status: vi.fn().mockReturnThis(),
91
+ json: vi.fn(),
92
+ };
93
+ const mockNext = vi.fn();
94
+ vi.mocked(isHex).mockReturnValue(true);
95
+ vi.mocked(hexToU8a).mockReturnValue(new Uint8Array());
96
+ vi.mocked(mockPair.jwtVerify).mockReturnValue({
97
+ isValid: false,
98
+ });
99
+ const middleware = authMiddleware(mockEnv.pair, mockEnv.authAccount);
100
+ await middleware(mockReq, mockRes, mockNext);
101
+ expect(mockNext).not.toHaveBeenCalled();
102
+ expect(mockRes.status).toHaveBeenCalledWith(401);
103
+ expect(mockRes.json).toHaveBeenCalledWith({
104
+ error: new ProsopoEnvError("API.UNAUTHORIZED", {
105
+ context: { i18n: mockReq.i18n, code: 401 },
106
+ }),
107
+ });
108
+ });
109
+ it("should return 401 if key pair is missing", async () => {
110
+ const mockLogger = {
111
+ debug: vi.fn().mockImplementation(loggerOuter.debug.bind(loggerOuter)),
112
+ log: vi.fn().mockImplementation(loggerOuter.log.bind(loggerOuter)),
113
+ info: vi.fn().mockImplementation(loggerOuter.info.bind(loggerOuter)),
114
+ error: vi.fn().mockImplementation(loggerOuter.error.bind(loggerOuter)),
115
+ trace: vi.fn().mockImplementation(loggerOuter.trace.bind(loggerOuter)),
116
+ fatal: vi.fn().mockImplementation(loggerOuter.fatal.bind(loggerOuter)),
117
+ warn: vi.fn().mockImplementation(loggerOuter.warn.bind(loggerOuter)),
118
+ };
119
+ const mockReq = {
120
+ url: "/v1/prosopo/provider/captcha/image",
121
+ originalUrl: "/v1/prosopo/provider/captcha/image",
122
+ headers: {
123
+ Authorization: "Bearer mockToken",
124
+ },
125
+ logger: mockLogger,
126
+ };
127
+ const mockRes = {
128
+ status: vi.fn().mockReturnThis(),
129
+ json: vi.fn(),
130
+ };
131
+ const mockNext = vi.fn();
132
+ const middleware = authMiddleware(undefined, undefined);
133
+ await middleware(mockReq, mockRes, mockNext);
134
+ expect(mockNext).not.toHaveBeenCalled();
135
+ expect(mockRes.status).toHaveBeenCalledWith(401);
136
+ expect(mockRes.json).toHaveBeenCalledWith({
137
+ error: new ProsopoEnvError("API.UNAUTHORIZED", {
138
+ context: { i18n: mockReq.i18n, code: 401 },
139
+ }),
140
+ });
141
+ });
142
+ });
143
+ //# sourceMappingURL=authMiddleware.unit.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authMiddleware.unit.test.js","sourceRoot":"","sources":["../../../../src/tests/unit/middlewares/authMiddleware.unit.test.ts"],"names":[],"mappings":"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"}
package/express.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Prosopo (UK) Ltd.
1
+ // Copyright 2021-2026 Prosopo (UK) Ltd.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prosopo/api-express-router",
3
- "version": "3.0.40",
3
+ "version": "3.0.47",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -17,7 +17,8 @@
17
17
  },
18
18
  "scripts": {
19
19
  "clean": "del-cli --verbose dist tsconfig.tsbuildinfo",
20
- "build": "NODE_ENV=${NODE_ENV:-development}; vite build --config vite.esm.config.ts --mode $NODE_ENV",
20
+ "build": "npm run build:cross-env -- --mode ${NODE_ENV:-development}",
21
+ "build:cross-env": "vite build --config vite.esm.config.ts",
21
22
  "build:tsc": "tsc --build --verbose",
22
23
  "build:cjs": "NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV",
23
24
  "typecheck": "tsc --project tsconfig.types.json",
@@ -25,11 +26,12 @@
25
26
  },
26
27
  "dependencies": {
27
28
  "@polkadot/util": "13.5.7",
28
- "@prosopo/api-route": "2.6.34",
29
- "@prosopo/common": "3.1.26",
30
- "@prosopo/env": "3.2.28",
31
- "@prosopo/locale": "3.1.26",
32
- "@prosopo/types": "3.6.4",
29
+ "@prosopo/api-route": "2.6.36",
30
+ "@prosopo/common": "3.1.28",
31
+ "@prosopo/env": "3.2.35",
32
+ "@prosopo/locale": "3.1.28",
33
+ "@prosopo/types": "3.8.0",
34
+ "@prosopo/util-crypto": "13.5.29",
33
35
  "dotenv": "16.4.5",
34
36
  "express": "4.21.2",
35
37
  "i18next": "24.1.0",
@@ -37,7 +39,7 @@
37
39
  "zod": "3.23.8"
38
40
  },
39
41
  "devDependencies": {
40
- "@prosopo/config": "3.1.26",
42
+ "@prosopo/config": "3.3.0",
41
43
  "@types/node": "22.10.2",
42
44
  "vitest": "3.2.4"
43
45
  },
@@ -1,5 +1,5 @@
1
1
  import path from "node:path";
2
- // Copyright 2021-2025 Prosopo (UK) Ltd.
2
+ // Copyright 2021-2026 Prosopo (UK) Ltd.
3
3
  //
4
4
  // Licensed under the Apache License, Version 2.0 (the "License");
5
5
  // you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- // Copyright 2021-2025 Prosopo (UK) Ltd.
1
+ // Copyright 2021-2026 Prosopo (UK) Ltd.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -1,6 +1,6 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- // Copyright 2021-2025 Prosopo (UK) Ltd.
3
+ // Copyright 2021-2026 Prosopo (UK) Ltd.
4
4
  //
5
5
  // Licensed under the Apache License, Version 2.0 (the "License");
6
6
  // you may not use this file except in compliance with the License.