@sebastienrousseau/crypto-server 0.0.8 → 0.0.24

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 (102) hide show
  1. package/README.md +159 -56
  2. package/dist/@types/types.d.ts +1 -2
  3. package/dist/@types/types.d.ts.map +1 -1
  4. package/dist/config/auth-policy.d.ts +18 -0
  5. package/dist/config/auth-policy.d.ts.map +1 -1
  6. package/dist/config/auth-policy.js +126 -0
  7. package/dist/config/constants.d.ts.map +1 -1
  8. package/dist/config/constants.js +7 -1
  9. package/dist/enterprise/metering.d.ts.map +1 -1
  10. package/dist/enterprise/metering.js +2 -4
  11. package/dist/index.d.ts +1 -0
  12. package/dist/index.js +1 -0
  13. package/dist/lib/auth.d.ts +4 -1
  14. package/dist/lib/auth.d.ts.map +1 -1
  15. package/dist/lib/auth.js +87 -40
  16. package/dist/lib/kdf-runner.d.ts +18 -0
  17. package/dist/lib/kdf-runner.d.ts.map +1 -0
  18. package/dist/lib/kdf-runner.js +27 -0
  19. package/dist/lib/key-store.d.ts +37 -0
  20. package/dist/lib/key-store.d.ts.map +1 -0
  21. package/dist/lib/key-store.js +223 -0
  22. package/dist/lib/opaque-store.d.ts +34 -0
  23. package/dist/lib/opaque-store.d.ts.map +1 -0
  24. package/dist/lib/opaque-store.js +72 -0
  25. package/dist/lib/problem.d.ts +67 -0
  26. package/dist/lib/problem.d.ts.map +1 -0
  27. package/dist/lib/problem.js +162 -0
  28. package/dist/routes/v1/decrypt.d.ts.map +1 -1
  29. package/dist/routes/v1/decrypt.js +24 -16
  30. package/dist/routes/v1/encrypt.d.ts.map +1 -1
  31. package/dist/routes/v1/encrypt.js +12 -13
  32. package/dist/routes/v1/generate.d.ts.map +1 -1
  33. package/dist/routes/v1/generate.js +22 -25
  34. package/dist/routes/v1/revoke.d.ts.map +1 -1
  35. package/dist/routes/v1/revoke.js +6 -11
  36. package/dist/routes/v1/verify.d.ts.map +1 -1
  37. package/dist/routes/v1/verify.js +10 -12
  38. package/dist/routes/v2/algorithms.js +1 -1
  39. package/dist/routes/v2/compliance.js +1 -1
  40. package/dist/routes/v2/encrypt.d.ts.map +1 -1
  41. package/dist/routes/v2/encrypt.js +1 -1
  42. package/dist/routes/v2/hash.d.ts.map +1 -1
  43. package/dist/routes/v2/hash.js +1 -1
  44. package/dist/routes/v2/hpke.d.ts +3 -0
  45. package/dist/routes/v2/hpke.d.ts.map +1 -0
  46. package/dist/routes/v2/hpke.js +168 -0
  47. package/dist/routes/v2/index.d.ts.map +1 -1
  48. package/dist/routes/v2/index.js +6 -0
  49. package/dist/routes/v2/kdf.d.ts +5 -0
  50. package/dist/routes/v2/kdf.d.ts.map +1 -1
  51. package/dist/routes/v2/kdf.js +27 -12
  52. package/dist/routes/v2/key-wrap.d.ts.map +1 -1
  53. package/dist/routes/v2/key-wrap.js +9 -3
  54. package/dist/routes/v2/keys.d.ts.map +1 -1
  55. package/dist/routes/v2/keys.js +39 -26
  56. package/dist/routes/v2/kms.d.ts +7 -0
  57. package/dist/routes/v2/kms.d.ts.map +1 -0
  58. package/dist/routes/v2/kms.js +310 -0
  59. package/dist/routes/v2/mac.d.ts.map +1 -1
  60. package/dist/routes/v2/mac.js +10 -3
  61. package/dist/routes/v2/multi-recipient.d.ts.map +1 -1
  62. package/dist/routes/v2/multi-recipient.js +12 -11
  63. package/dist/routes/v2/opaque.d.ts +4 -0
  64. package/dist/routes/v2/opaque.d.ts.map +1 -0
  65. package/dist/routes/v2/opaque.js +174 -0
  66. package/dist/routes/v2/password-encrypt.d.ts.map +1 -1
  67. package/dist/routes/v2/password-encrypt.js +13 -46
  68. package/dist/routes/v2/password.d.ts +4 -0
  69. package/dist/routes/v2/password.d.ts.map +1 -1
  70. package/dist/routes/v2/password.js +28 -53
  71. package/dist/routes/v2/pq-hash-sign.d.ts.map +1 -1
  72. package/dist/routes/v2/pq-hash-sign.js +33 -24
  73. package/dist/routes/v2/pq-sign.d.ts.map +1 -1
  74. package/dist/routes/v2/pq-sign.js +31 -24
  75. package/dist/routes/v2/pq.d.ts.map +1 -1
  76. package/dist/routes/v2/pq.js +57 -38
  77. package/dist/routes/v2/sealedbox.d.ts.map +1 -1
  78. package/dist/routes/v2/sealedbox.js +32 -14
  79. package/dist/routes/v2/secretbox.d.ts.map +1 -1
  80. package/dist/routes/v2/secretbox.js +10 -3
  81. package/dist/routes/v2/signing.d.ts.map +1 -1
  82. package/dist/routes/v2/signing.js +17 -13
  83. package/dist/routes/v2/stream-schemas.d.ts +296 -0
  84. package/dist/routes/v2/stream-schemas.d.ts.map +1 -0
  85. package/dist/routes/v2/stream-schemas.js +207 -0
  86. package/dist/routes/v2/stream.d.ts.map +1 -1
  87. package/dist/routes/v2/stream.js +144 -151
  88. package/dist/server.d.ts.map +1 -1
  89. package/dist/server.js +19 -5
  90. package/dist/utils/keys.d.ts +17 -0
  91. package/dist/utils/keys.d.ts.map +1 -0
  92. package/dist/utils/keys.js +36 -0
  93. package/dist/utils/route-helpers.d.ts +1 -5
  94. package/dist/utils/route-helpers.d.ts.map +1 -1
  95. package/dist/utils/route-helpers.js +16 -10
  96. package/dist/utils/trace.d.ts +12 -0
  97. package/dist/utils/trace.d.ts.map +1 -0
  98. package/dist/utils/trace.js +62 -0
  99. package/dist/utils/validation.d.ts +1 -0
  100. package/dist/utils/validation.d.ts.map +1 -1
  101. package/dist/utils/validation.js +17 -9
  102. package/package.json +22 -18
@@ -1 +1 @@
1
- {"version":3,"file":"route-helpers.d.ts","sourceRoot":"","sources":["../../src/utils/route-helpers.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAGL,gBAAgB,EACjB,MAAM,cAAc,CAAC;AAOtB,wBAAgB,iBAAiB,CAC/B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC,EAEnD,OAAO,EAAE,CAAC,EACV,KAAK,EAAE,YAAY,GAEjB;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,gBAAgB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CAAE,GACtE,IAAI,CAmBP;AAUD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE;IAAE,GAAG,EAAE;QAAE,KAAK,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAA;CAAE,EAChE,KAAK,EAAE;IAAE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAA;KAAE,CAAA;CAAE,EACzE,SAAS,EAAE,MAAM,GAChB,OAAO,CAkBT"}
1
+ {"version":3,"file":"route-helpers.d.ts","sourceRoot":"","sources":["../../src/utils/route-helpers.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,EAGL,gBAAgB,EACjB,MAAM,cAAc,CAAC;AAOtB,wBAAgB,iBAAiB,CAC/B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC,EAEnD,OAAO,EAAE,CAAC,EACV,KAAK,EAAE,YAAY,GAEjB;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,gBAAgB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CAAE,GACtE,IAAI,CAmBP;AAsBD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE;IAAE,GAAG,EAAE;QAAE,KAAK,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAA;CAAE,EAChE,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,GAChB,YAAY,CA6Bd"}
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.collectValidation = collectValidation;
4
4
  exports.classifyCryptoError = classifyCryptoError;
5
+ const problem_1 = require("../lib/problem");
5
6
  const validation_1 = require("./validation");
6
7
  function collectValidation(results, reply) {
7
8
  const errors = [];
@@ -22,21 +23,26 @@ function collectValidation(results, reply) {
22
23
  }
23
24
  return out;
24
25
  }
26
+ const INPUT_ERROR_PATTERNS = [
27
+ /invalid hex/i,
28
+ /must be \d+ bytes/i,
29
+ /too short/i,
30
+ /unsupported/i,
31
+ /expected.*length/i,
32
+ /of length \d+ expected/i,
33
+ ];
25
34
  function classifyCryptoError(error, request, reply, operation) {
26
35
  const msg = error instanceof Error ? error.message : String(error);
27
- const isInputError = /invalid hex/i.test(msg) ||
28
- /must be \d+ bytes/i.test(msg) ||
29
- /too short/i.test(msg) ||
30
- /unsupported/i.test(msg) ||
31
- /expected.*length/i.test(msg) ||
32
- /of length \d+ expected/i.test(msg);
36
+ const code = (0, problem_1.isCryptoError)(error) ? error.code : undefined;
37
+ const isInputError = code === undefined
38
+ ? INPUT_ERROR_PATTERNS.some((pattern) => pattern.test(msg))
39
+ : (0, problem_1.cryptoErrorStatus)(code) === 400;
40
+ const extensions = code === undefined ? {} : { code };
33
41
  if (isInputError) {
34
42
  request.log.error(error, `${operation} input error`);
35
- return reply
36
- .status(400)
37
- .send({ error: `${operation} failed: invalid input` });
43
+ return (0, problem_1.sendProblem)(reply, 400, "invalid-input", `${operation} failed: invalid input`, extensions);
38
44
  }
39
45
  request.log.error(error, `${operation} failed`);
40
- return reply.status(500).send({ error: `${operation} failed` });
46
+ return (0, problem_1.sendProblem)(reply, 500, "internal-error", `${operation} failed`, extensions);
41
47
  }
42
48
  //# sourceMappingURL=route-helpers.js.map
@@ -0,0 +1,12 @@
1
+ import type { FastifyReply, FastifyRequest } from "fastify";
2
+ export interface TraceparentComponents {
3
+ version: string;
4
+ traceId: string;
5
+ parentId: string;
6
+ flags: string;
7
+ }
8
+ export declare function isValidTraceparent(header: unknown): header is string;
9
+ export declare function parseTraceparent(header: string): TraceparentComponents | null;
10
+ export declare function generateTraceparent(sampled?: boolean): string;
11
+ export declare function propagateTraceContext(request: FastifyRequest, reply: FastifyReply): void;
12
+ //# sourceMappingURL=trace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../../src/utils/trace.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAa5D,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAQD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,IAAI,MAAM,CAUpE;AAQD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,qBAAqB,GAAG,IAAI,CAS7E;AAQD,wBAAgB,mBAAmB,CAAC,OAAO,UAAO,GAAG,MAAM,CAK1D;AASD,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,YAAY,GAClB,IAAI,CAqBN"}
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isValidTraceparent = isValidTraceparent;
4
+ exports.parseTraceparent = parseTraceparent;
5
+ exports.generateTraceparent = generateTraceparent;
6
+ exports.propagateTraceContext = propagateTraceContext;
7
+ const crypto_1 = require("crypto");
8
+ const TRACEPARENT_REGEX = /^00-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/;
9
+ const ALL_ZERO_TRACE_ID = "0".repeat(32);
10
+ const ALL_ZERO_PARENT_ID = "0".repeat(16);
11
+ function isValidTraceparent(header) {
12
+ if (typeof header !== "string")
13
+ return false;
14
+ const match = TRACEPARENT_REGEX.exec(header.trim());
15
+ if (!match)
16
+ return false;
17
+ const traceId = match[1];
18
+ const parentId = match[2];
19
+ if (traceId === ALL_ZERO_TRACE_ID || parentId === ALL_ZERO_PARENT_ID) {
20
+ return false;
21
+ }
22
+ return true;
23
+ }
24
+ function parseTraceparent(header) {
25
+ if (!isValidTraceparent(header))
26
+ return null;
27
+ const match = TRACEPARENT_REGEX.exec(header.trim());
28
+ return {
29
+ version: "00",
30
+ traceId: match[1],
31
+ parentId: match[2],
32
+ flags: match[3],
33
+ };
34
+ }
35
+ function generateTraceparent(sampled = true) {
36
+ const traceId = (0, crypto_1.randomBytes)(16).toString("hex");
37
+ const parentId = (0, crypto_1.randomBytes)(8).toString("hex");
38
+ const flags = sampled ? "01" : "00";
39
+ return `00-${traceId}-${parentId}-${flags}`;
40
+ }
41
+ function propagateTraceContext(request, reply) {
42
+ const incoming = request.headers["traceparent"];
43
+ let traceparentValue;
44
+ if (isValidTraceparent(incoming)) {
45
+ traceparentValue = incoming.trim();
46
+ const tracestate = request.headers["tracestate"];
47
+ if (typeof tracestate === "string" && tracestate.trim().length > 0) {
48
+ reply.header("tracestate", tracestate.trim());
49
+ }
50
+ }
51
+ else {
52
+ traceparentValue = generateTraceparent();
53
+ }
54
+ reply.header("traceparent", traceparentValue);
55
+ const parsed = parseTraceparent(traceparentValue);
56
+ if (parsed) {
57
+ request.traceId = parsed.traceId;
58
+ }
59
+ request.traceparent =
60
+ traceparentValue;
61
+ }
62
+ //# sourceMappingURL=trace.js.map
@@ -20,6 +20,7 @@ export declare function validateOptionalNumber(value: unknown, defaultValue: num
20
20
  max?: number;
21
21
  }): ValidationResult<number>;
22
22
  export declare function validateBase64(value: unknown, fieldName: string): ValidationResult<string>;
23
+ export declare function isEmailShaped(value: string): boolean;
23
24
  export declare function validateEmail(value: unknown, fieldName: string): ValidationResult<string>;
24
25
  export declare function validateEnum<T extends string>(value: unknown, fieldName: string, allowedValues: readonly T[]): ValidationResult<T>;
25
26
  export declare function validateDateString(value: unknown, fieldName: string): ValidationResult<Date>;
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAKvC,MAAM,WAAW,eAAe;IAE9B,KAAK,EAAE,MAAM,CAAC;IAEd,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAC1B;IAEE,KAAK,EAAE,IAAI,CAAC;IAEZ,KAAK,EAAE,CAAC,CAAC;CACV,GACD;IAEE,KAAK,EAAE,KAAK,CAAC;IAEb,KAAK,EAAE,eAAe,CAAC;CACxB,CAAC;AAKN,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,GAChB,gBAAgB,CAAC,MAAM,CAAC,CAiB1B;AAKD,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACvC,gBAAgB,CAAC,MAAM,CAAC,CAoC1B;AAKD,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,EACd,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACvC,gBAAgB,CAAC,MAAM,CAAC,CAK1B;AAKD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,GAChB,gBAAgB,CAAC,MAAM,CAAC,CAgB1B;AAKD,wBAAgB,aAAa,CAC3B,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,GAChB,gBAAgB,CAAC,MAAM,CAAC,CAe1B;AAKD,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,EAC3C,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,SAAS,CAAC,EAAE,GAC1B,gBAAgB,CAAC,CAAC,CAAC,CAcrB;AAKD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,GAChB,gBAAgB,CAAC,IAAI,CAAC,CAexB;AAKD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,eAAe,EAAE,GACxB,IAAI,CAKN;AAOD,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAKD,wBAAgB,cAAc,CAC5B,MAAM,EAAE,OAAO,EACf,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,OAAO,CAcT"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAMvC,MAAM,WAAW,eAAe;IAE9B,KAAK,EAAE,MAAM,CAAC;IAEd,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAC1B;IAEE,KAAK,EAAE,IAAI,CAAC;IAEZ,KAAK,EAAE,CAAC,CAAC;CACV,GACD;IAEE,KAAK,EAAE,KAAK,CAAC;IAEb,KAAK,EAAE,eAAe,CAAC;CACxB,CAAC;AAKN,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,GAChB,gBAAgB,CAAC,MAAM,CAAC,CAiB1B;AAKD,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACvC,gBAAgB,CAAC,MAAM,CAAC,CAqC1B;AAKD,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,EACd,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACvC,gBAAgB,CAAC,MAAM,CAAC,CAK1B;AAKD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,GAChB,gBAAgB,CAAC,MAAM,CAAC,CAgB1B;AASD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAMpD;AAKD,wBAAgB,aAAa,CAC3B,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,GAChB,gBAAgB,CAAC,MAAM,CAAC,CAc1B;AAKD,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,EAC3C,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,SAAS,CAAC,EAAE,GAC1B,gBAAgB,CAAC,CAAC,CAAC,CAcrB;AAKD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,GAChB,gBAAgB,CAAC,IAAI,CAAC,CAexB;AAMD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,eAAe,EAAE,GACxB,IAAI,CAIN;AAOD,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAKD,wBAAgB,cAAc,CAC5B,MAAM,EAAE,OAAO,EACf,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,OAAO,CAcT"}
@@ -4,6 +4,7 @@ exports.validateRequiredString = validateRequiredString;
4
4
  exports.validateRequiredNumber = validateRequiredNumber;
5
5
  exports.validateOptionalNumber = validateOptionalNumber;
6
6
  exports.validateBase64 = validateBase64;
7
+ exports.isEmailShaped = isEmailShaped;
7
8
  exports.validateEmail = validateEmail;
8
9
  exports.validateEnum = validateEnum;
9
10
  exports.validateDateString = validateDateString;
@@ -11,6 +12,7 @@ exports.sendValidationError = sendValidationError;
11
12
  exports.anonymousAllowed = anonymousAllowed;
12
13
  exports.validateApiKey = validateApiKey;
13
14
  const crypto_1 = require("crypto");
15
+ const problem_1 = require("../lib/problem");
14
16
  function validateRequiredString(value, fieldName) {
15
17
  if (value === undefined || value === null) {
16
18
  return {
@@ -37,6 +39,7 @@ function validateRequiredNumber(value, fieldName, options) {
37
39
  };
38
40
  }
39
41
  const numValue = typeof value === "number" ? value : Number(value);
42
+ const { min, max } = options ?? {};
40
43
  if (!Number.isFinite(numValue)) {
41
44
  return {
42
45
  valid: false,
@@ -46,21 +49,21 @@ function validateRequiredNumber(value, fieldName, options) {
46
49
  },
47
50
  };
48
51
  }
49
- if (options?.min !== undefined && numValue < options.min) {
52
+ if (min !== undefined && numValue < min) {
50
53
  return {
51
54
  valid: false,
52
55
  error: {
53
56
  field: fieldName,
54
- message: `${fieldName} must be at least ${options.min}`,
57
+ message: `${fieldName} must be at least ${min}`,
55
58
  },
56
59
  };
57
60
  }
58
- if (options?.max !== undefined && numValue > options.max) {
61
+ if (max !== undefined && numValue > max) {
59
62
  return {
60
63
  valid: false,
61
64
  error: {
62
65
  field: fieldName,
63
- message: `${fieldName} must be at most ${options.max}`,
66
+ message: `${fieldName} must be at most ${max}`,
64
67
  },
65
68
  };
66
69
  }
@@ -88,12 +91,18 @@ function validateBase64(value, fieldName) {
88
91
  }
89
92
  return { valid: true, value: stringResult.value };
90
93
  }
94
+ function isEmailShaped(value) {
95
+ const at = value.indexOf("@");
96
+ if (at < 1 || value.indexOf("@", at + 1) !== -1 || /\s/.test(value)) {
97
+ return false;
98
+ }
99
+ return value.slice(at + 2, -1).includes(".");
100
+ }
91
101
  function validateEmail(value, fieldName) {
92
102
  const stringResult = validateRequiredString(value, fieldName);
93
103
  if (!stringResult.valid)
94
104
  return stringResult;
95
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
96
- if (!emailRegex.test(stringResult.value)) {
105
+ if (!isEmailShaped(stringResult.value)) {
97
106
  return {
98
107
  valid: false,
99
108
  error: {
@@ -136,9 +145,8 @@ function validateDateString(value, fieldName) {
136
145
  return { valid: true, value: date };
137
146
  }
138
147
  function sendValidationError(reply, errors) {
139
- reply.status(400).send({
140
- error: "Validation failed",
141
- details: errors,
148
+ (0, problem_1.sendProblem)(reply, 400, "validation-failed", "Validation failed", {
149
+ errors,
142
150
  });
143
151
  }
144
152
  function anonymousAllowed() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sebastienrousseau/crypto-server",
3
- "version": "0.0.8",
3
+ "version": "0.0.24",
4
4
  "description": "Crypto Server is a Fastify web server that exposes easy consumable REST APIs to perform low-level cryptographic operations.",
5
5
  "author": "Sebastien Rousseau <sebastienrousseau@users.noreply.github.com>",
6
6
  "license": "MIT OR Apache-2.0",
@@ -16,16 +16,18 @@
16
16
  "engines": {
17
17
  "node": ">=22.0.0"
18
18
  },
19
- "main": "./dist/index.js",
20
- "types": "./dist/index.d.ts",
21
- "sideEffects": false,
19
+ "type": "commonjs",
20
+ "main": "./dist/server.js",
21
+ "types": "./dist/server.d.ts",
22
22
  "exports": {
23
23
  ".": {
24
- "types": "./dist/index.d.ts",
25
- "require": "./dist/index.js",
26
- "import": "./dist/index.js"
27
- }
24
+ "types": "./dist/server.d.ts",
25
+ "require": "./dist/server.js",
26
+ "default": "./dist/server.js"
27
+ },
28
+ "./package.json": "./package.json"
28
29
  },
30
+ "sideEffects": false,
29
31
  "bin": {
30
32
  "crypto-server": "dist/index.js"
31
33
  },
@@ -58,20 +60,22 @@
58
60
  "fastify-healthcheck": "^5.1.0",
59
61
  "uuid": "^14.0.2",
60
62
  "winston": "^3.17.0",
61
- "@sebastienrousseau/crypto-lib": "0.0.8"
63
+ "@sebastienrousseau/crypto-kms": "0.0.24",
64
+ "@sebastienrousseau/crypto-lib": "0.0.24"
62
65
  },
63
66
  "devDependencies": {
64
- "@types/chai": "^4.3.7",
67
+ "@types/chai": "^5.2.3",
65
68
  "@types/chai-as-promised": "^8.0.2",
66
- "@types/mocha": "^10.0.2",
69
+ "@types/mocha": "^10.0.10",
67
70
  "@types/node": "^26.6.3",
68
71
  "@types/uuid": "^11.0.0",
69
72
  "c8": "^12.0.0",
70
- "chai": "^4.5.0",
71
- "chai-as-promised": "^7.1.2",
72
- "mocha": "^10.8.2",
73
- "openpgp": "^6.3.1",
74
- "prettier": "^3.9.8",
73
+ "chai": "^6.3.0",
74
+ "chai-as-promised": "^8.0.2",
75
+ "fast-check": "^4.10.2",
76
+ "mocha": "^12.0.3",
77
+ "openpgp": "^6.3.2",
78
+ "prettier": "^3.9.9",
75
79
  "rimraf": "^6.1.3",
76
80
  "ts-node": "^10.9.2",
77
81
  "typedoc": "^0.28.20",
@@ -93,8 +97,8 @@
93
97
  "scripts": {
94
98
  "build": "tsc --build tsconfig.json",
95
99
  "clean": "rimraf ./coverage ./dist ./docs",
96
- "lint": "eslint --ext .ts src __tests__",
97
- "lint:fix": "eslint --cache --fix --ext .ts src __tests__",
100
+ "lint": "eslint src __tests__",
101
+ "lint:fix": "eslint --cache --fix src __tests__",
98
102
  "format": "prettier --write src/**/*.ts",
99
103
  "format:check": "prettier --check \"src/**/*.ts\"",
100
104
  "start": "node dist/index.js",