@siglo/crypto 0.0.0-stage → 1.0.1

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 (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +123 -2
  3. package/dist/cipher/aes-gcm.d.ts +43 -0
  4. package/dist/cipher/aes-gcm.d.ts.map +1 -0
  5. package/dist/cipher/aes-gcm.js +152 -0
  6. package/dist/cipher/aes-gcm.js.map +1 -0
  7. package/dist/cipher/decrypt-step.d.ts +13 -0
  8. package/dist/cipher/decrypt-step.d.ts.map +1 -0
  9. package/dist/cipher/decrypt-step.js +113 -0
  10. package/dist/cipher/decrypt-step.js.map +1 -0
  11. package/dist/cipher/encrypt-step.d.ts +13 -0
  12. package/dist/cipher/encrypt-step.d.ts.map +1 -0
  13. package/dist/cipher/encrypt-step.js +84 -0
  14. package/dist/cipher/encrypt-step.js.map +1 -0
  15. package/dist/cipher/key-ring.d.ts +24 -0
  16. package/dist/cipher/key-ring.d.ts.map +1 -0
  17. package/dist/cipher/key-ring.js +67 -0
  18. package/dist/cipher/key-ring.js.map +1 -0
  19. package/dist/index.d.ts +19 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +35 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/redaction/mask-step.d.ts +28 -0
  24. package/dist/redaction/mask-step.d.ts.map +1 -0
  25. package/dist/redaction/mask-step.js +85 -0
  26. package/dist/redaction/mask-step.js.map +1 -0
  27. package/dist/redaction/paths.d.ts +28 -0
  28. package/dist/redaction/paths.d.ts.map +1 -0
  29. package/dist/redaction/paths.js +149 -0
  30. package/dist/redaction/paths.js.map +1 -0
  31. package/dist/registry.d.ts +14 -0
  32. package/dist/registry.d.ts.map +1 -0
  33. package/dist/registry.js +44 -0
  34. package/dist/registry.js.map +1 -0
  35. package/dist/types.d.ts +115 -0
  36. package/dist/types.d.ts.map +1 -0
  37. package/dist/types.js +3 -0
  38. package/dist/types.js.map +1 -0
  39. package/dist/webhooks/dedup.d.ts +24 -0
  40. package/dist/webhooks/dedup.d.ts.map +1 -0
  41. package/dist/webhooks/dedup.js +69 -0
  42. package/dist/webhooks/dedup.js.map +1 -0
  43. package/dist/webhooks/protocols/base.d.ts +15 -0
  44. package/dist/webhooks/protocols/base.d.ts.map +1 -0
  45. package/dist/webhooks/protocols/base.js +42 -0
  46. package/dist/webhooks/protocols/base.js.map +1 -0
  47. package/dist/webhooks/protocols/generic-hmac.d.ts +16 -0
  48. package/dist/webhooks/protocols/generic-hmac.d.ts.map +1 -0
  49. package/dist/webhooks/protocols/generic-hmac.js +68 -0
  50. package/dist/webhooks/protocols/generic-hmac.js.map +1 -0
  51. package/dist/webhooks/protocols/github.d.ts +9 -0
  52. package/dist/webhooks/protocols/github.d.ts.map +1 -0
  53. package/dist/webhooks/protocols/github.js +49 -0
  54. package/dist/webhooks/protocols/github.js.map +1 -0
  55. package/dist/webhooks/protocols/shopify.d.ts +9 -0
  56. package/dist/webhooks/protocols/shopify.d.ts.map +1 -0
  57. package/dist/webhooks/protocols/shopify.js +37 -0
  58. package/dist/webhooks/protocols/shopify.js.map +1 -0
  59. package/dist/webhooks/protocols/slack.d.ts +9 -0
  60. package/dist/webhooks/protocols/slack.d.ts.map +1 -0
  61. package/dist/webhooks/protocols/slack.js +52 -0
  62. package/dist/webhooks/protocols/slack.js.map +1 -0
  63. package/dist/webhooks/protocols/stripe.d.ts +9 -0
  64. package/dist/webhooks/protocols/stripe.d.ts.map +1 -0
  65. package/dist/webhooks/protocols/stripe.js +56 -0
  66. package/dist/webhooks/protocols/stripe.js.map +1 -0
  67. package/dist/webhooks/protocols/svix.d.ts +9 -0
  68. package/dist/webhooks/protocols/svix.d.ts.map +1 -0
  69. package/dist/webhooks/protocols/svix.js +85 -0
  70. package/dist/webhooks/protocols/svix.js.map +1 -0
  71. package/dist/webhooks/timing.d.ts +6 -0
  72. package/dist/webhooks/timing.d.ts.map +1 -0
  73. package/dist/webhooks/timing.js +25 -0
  74. package/dist/webhooks/timing.js.map +1 -0
  75. package/dist/webhooks/verify-step.d.ts +25 -0
  76. package/dist/webhooks/verify-step.d.ts.map +1 -0
  77. package/dist/webhooks/verify-step.js +351 -0
  78. package/dist/webhooks/verify-step.js.map +1 -0
  79. package/package.json +52 -4
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StaticKeyRing = void 0;
4
+ exports.isKeyRing = isKeyRing;
5
+ /**
6
+ * Type guard to check if an object satisfies the KeyRing interface.
7
+ */
8
+ function isKeyRing(val) {
9
+ return (typeof val === 'object' &&
10
+ val !== null &&
11
+ typeof val.getActiveKey === 'function' &&
12
+ typeof val.getKey === 'function');
13
+ }
14
+ /**
15
+ * In-memory multi-key provider supporting active key generation and historical key retrieval.
16
+ */
17
+ class StaticKeyRing {
18
+ activeKeyId;
19
+ keys = new Map();
20
+ constructor(activeKeyId, keys) {
21
+ this.activeKeyId = activeKeyId;
22
+ if (keys instanceof Map) {
23
+ this.keys = new Map(keys);
24
+ }
25
+ else {
26
+ for (const [kid, key] of Object.entries(keys)) {
27
+ this.keys.set(kid, key);
28
+ }
29
+ }
30
+ if (!this.keys.has(activeKeyId)) {
31
+ throw new Error(`Active key ID '${activeKeyId}' not found in provided keys`);
32
+ }
33
+ }
34
+ getActiveKey() {
35
+ const key = this.keys.get(this.activeKeyId);
36
+ if (!key) {
37
+ throw new Error(`Active key '${this.activeKeyId}' not found in KeyRing`);
38
+ }
39
+ return {
40
+ kid: this.activeKeyId,
41
+ key
42
+ };
43
+ }
44
+ getKey(kid) {
45
+ return this.keys.get(kid) ?? null;
46
+ }
47
+ /**
48
+ * Adds or rotates a key in the ring.
49
+ */
50
+ addKey(kid, key, makeActive = false) {
51
+ this.keys.set(kid, key);
52
+ if (makeActive) {
53
+ this.activeKeyId = kid;
54
+ }
55
+ }
56
+ /**
57
+ * Sets the active key ID for subsequent encryption operations.
58
+ */
59
+ setActiveKey(kid) {
60
+ if (!this.keys.has(kid)) {
61
+ throw new Error(`Cannot set active key to '${kid}': key not found in KeyRing`);
62
+ }
63
+ this.activeKeyId = kid;
64
+ }
65
+ }
66
+ exports.StaticKeyRing = StaticKeyRing;
67
+ //# sourceMappingURL=key-ring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-ring.js","sourceRoot":"","sources":["../../src/cipher/key-ring.ts"],"names":[],"mappings":";;;AAKA,8BAOC;AAVD;;GAEG;AACH,SAAgB,SAAS,CAAC,GAAY;IACpC,OAAO,CACL,OAAO,GAAG,KAAK,QAAQ;QACvB,GAAG,KAAK,IAAI;QACZ,OAAQ,GAAW,CAAC,YAAY,KAAK,UAAU;QAC/C,OAAQ,GAAW,CAAC,MAAM,KAAK,UAAU,CAC1C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAa,aAAa;IAChB,WAAW,CAAS;IACpB,IAAI,GAAiC,IAAI,GAAG,EAAE,CAAC;IAEvD,YACE,WAAmB,EACnB,IAAoE;QAEpE,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,IAAI,YAAY,GAAG,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,kBAAkB,WAAW,8BAA8B,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IAED,YAAY;QACV,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC5C,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,CAAC,WAAW,wBAAwB,CAAC,CAAC;QAC3E,CAAC;QACD,OAAO;YACL,GAAG,EAAE,IAAI,CAAC,WAAW;YACrB,GAAG;SACJ,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,GAAW,EAAE,GAAoB,EAAE,aAAsB,KAAK;QACnE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACxB,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;QACzB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,GAAW;QACtB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,6BAA6B,CAAC,CAAC;QACjF,CAAC;QACD,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;IACzB,CAAC;CACF;AAvDD,sCAuDC"}
@@ -0,0 +1,19 @@
1
+ export * from './types';
2
+ export * from './registry';
3
+ export * from './webhooks/timing';
4
+ export * from './webhooks/dedup';
5
+ export * from './webhooks/verify-step';
6
+ export * from './webhooks/protocols/base';
7
+ export * from './webhooks/protocols/stripe';
8
+ export * from './webhooks/protocols/github';
9
+ export * from './webhooks/protocols/shopify';
10
+ export * from './webhooks/protocols/slack';
11
+ export * from './webhooks/protocols/svix';
12
+ export * from './webhooks/protocols/generic-hmac';
13
+ export * from './cipher/key-ring';
14
+ export * from './cipher/aes-gcm';
15
+ export * from './cipher/encrypt-step';
16
+ export * from './cipher/decrypt-step';
17
+ export * from './redaction/paths';
18
+ export * from './redaction/mask-step';
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types"), exports);
18
+ __exportStar(require("./registry"), exports);
19
+ __exportStar(require("./webhooks/timing"), exports);
20
+ __exportStar(require("./webhooks/dedup"), exports);
21
+ __exportStar(require("./webhooks/verify-step"), exports);
22
+ __exportStar(require("./webhooks/protocols/base"), exports);
23
+ __exportStar(require("./webhooks/protocols/stripe"), exports);
24
+ __exportStar(require("./webhooks/protocols/github"), exports);
25
+ __exportStar(require("./webhooks/protocols/shopify"), exports);
26
+ __exportStar(require("./webhooks/protocols/slack"), exports);
27
+ __exportStar(require("./webhooks/protocols/svix"), exports);
28
+ __exportStar(require("./webhooks/protocols/generic-hmac"), exports);
29
+ __exportStar(require("./cipher/key-ring"), exports);
30
+ __exportStar(require("./cipher/aes-gcm"), exports);
31
+ __exportStar(require("./cipher/encrypt-step"), exports);
32
+ __exportStar(require("./cipher/decrypt-step"), exports);
33
+ __exportStar(require("./redaction/paths"), exports);
34
+ __exportStar(require("./redaction/mask-step"), exports);
35
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,6CAA2B;AAC3B,oDAAkC;AAClC,mDAAiC;AACjC,yDAAuC;AACvC,4DAA0C;AAC1C,8DAA4C;AAC5C,8DAA4C;AAC5C,+DAA6C;AAC7C,6DAA2C;AAC3C,4DAA0C;AAC1C,oEAAkD;AAClD,oDAAkC;AAClC,mDAAiC;AACjC,wDAAsC;AACtC,wDAAsC;AACtC,oDAAkC;AAClC,wDAAsC"}
@@ -0,0 +1,28 @@
1
+ import { Step, ExecutionOptions } from '@siglo/core';
2
+ import { MaskFieldsOptions } from '../types';
3
+ /**
4
+ * Common masking pattern presets for PII sanitization.
5
+ */
6
+ export declare const maskPatterns: {
7
+ /** Replaces entire value with [REDACTED] */
8
+ redact: (_value: unknown) => string;
9
+ /** Keeps the last 4 characters visible; masks earlier characters with asterisks */
10
+ last4: (value: unknown) => string;
11
+ /** Formats digits as masked credit card number: ****-****-****-1234 */
12
+ creditCard: (value: unknown) => string;
13
+ /** Formats digits as masked US Social Security Number: ***-**-1234 */
14
+ ssn: (value: unknown) => string;
15
+ /** Masks email local-part: j***@example.com */
16
+ email: (value: unknown) => string;
17
+ };
18
+ export declare class MaskFieldsStep<TInput = any, TName extends string = string> extends Step<TInput, TInput, TName> {
19
+ constructor(name: TName, options: MaskFieldsOptions<TInput>);
20
+ execute(param?: TInput, options?: ExecutionOptions): Promise<TInput>;
21
+ run(param?: TInput, options?: ExecutionOptions): Promise<TInput>;
22
+ }
23
+ /**
24
+ * Creates a step that masks sensitive context fields before DevTools/telemetry emission.
25
+ * Supports dot-notation paths, array wildcards, and structural sharing.
26
+ */
27
+ export declare function maskFieldsStep<const TName extends string, TInput>(name: TName, options: MaskFieldsOptions<TInput>): MaskFieldsStep<TInput, TName>;
28
+ //# sourceMappingURL=mask-step.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mask-step.d.ts","sourceRoot":"","sources":["../../src/redaction/mask-step.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAgB7C;;GAEG;AACH,eAAO,MAAM,YAAY;IACvB,4CAA4C;qBAC3B,OAAO,KAAG,MAAM;IAEjC,mFAAmF;mBACpE,OAAO,KAAG,MAAM;IAQ/B,uEAAuE;wBACnD,OAAO,KAAG,MAAM;IAMpC,sEAAsE;iBACzD,OAAO,KAAG,MAAM;IAM7B,+CAA+C;mBAChC,OAAO,KAAG,MAAM;CAQhC,CAAC;AAEF,qBAAa,cAAc,CAAC,MAAM,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,GAAG,MAAM,CACrE,SAAQ,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC;gBAEvB,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,iBAAiB,CAAC,MAAM,CAAC;IAiBlD,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC;IAKpE,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC;CAG1E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,CAAC,KAAK,SAAS,MAAM,EAAE,MAAM,EAC/D,IAAI,EAAE,KAAK,EACX,OAAO,EAAE,iBAAiB,CAAC,MAAM,CAAC,GACjC,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAE/B"}
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MaskFieldsStep = exports.maskPatterns = void 0;
4
+ exports.maskFieldsStep = maskFieldsStep;
5
+ const core_1 = require("@siglo/core");
6
+ const paths_1 = require("./paths");
7
+ function sanitizeStepInput(param) {
8
+ if (!param || typeof param !== 'object' || Array.isArray(param)) {
9
+ return param;
10
+ }
11
+ const clean = {};
12
+ for (const [key, val] of Object.entries(param)) {
13
+ if (key !== '$steps' && key !== '$history' && key !== '$stackId') {
14
+ clean[key] = val;
15
+ }
16
+ }
17
+ return clean;
18
+ }
19
+ /**
20
+ * Common masking pattern presets for PII sanitization.
21
+ */
22
+ exports.maskPatterns = {
23
+ /** Replaces entire value with [REDACTED] */
24
+ redact: (_value) => '[REDACTED]',
25
+ /** Keeps the last 4 characters visible; masks earlier characters with asterisks */
26
+ last4: (value) => {
27
+ const str = String(value ?? '');
28
+ if (str.length <= 4) {
29
+ return '*'.repeat(str.length || 4);
30
+ }
31
+ return '*'.repeat(str.length - 4) + str.slice(-4);
32
+ },
33
+ /** Formats digits as masked credit card number: ****-****-****-1234 */
34
+ creditCard: (value) => {
35
+ const digits = String(value ?? '').replace(/\D/g, '');
36
+ const last4 = digits.slice(-4) || '****';
37
+ return `****-****-****-${last4}`;
38
+ },
39
+ /** Formats digits as masked US Social Security Number: ***-**-1234 */
40
+ ssn: (value) => {
41
+ const digits = String(value ?? '').replace(/\D/g, '');
42
+ const last4 = digits.slice(-4) || '****';
43
+ return `***-**-${last4}`;
44
+ },
45
+ /** Masks email local-part: j***@example.com */
46
+ email: (value) => {
47
+ const str = String(value ?? '');
48
+ const atIdx = str.indexOf('@');
49
+ if (atIdx <= 1) {
50
+ return str.replace(/^./, '*') || '***';
51
+ }
52
+ return `${str[0]}***${str.slice(atIdx)}`;
53
+ }
54
+ };
55
+ class MaskFieldsStep extends core_1.Step {
56
+ constructor(name, options) {
57
+ const action = async (ctx) => {
58
+ const maskFn = options.maskPattern || exports.maskPatterns.last4;
59
+ const result = (0, paths_1.transformFields)(ctx, options.fields, (val) => {
60
+ if (val !== undefined && val !== null) {
61
+ return maskFn(val);
62
+ }
63
+ return val;
64
+ });
65
+ return result;
66
+ };
67
+ super(name, action);
68
+ }
69
+ execute(param, options) {
70
+ const cleanParam = param ? sanitizeStepInput(param) : param;
71
+ return super.execute(cleanParam, { pojo: true, ...options });
72
+ }
73
+ run(param, options) {
74
+ return this.execute(param, options);
75
+ }
76
+ }
77
+ exports.MaskFieldsStep = MaskFieldsStep;
78
+ /**
79
+ * Creates a step that masks sensitive context fields before DevTools/telemetry emission.
80
+ * Supports dot-notation paths, array wildcards, and structural sharing.
81
+ */
82
+ function maskFieldsStep(name, options) {
83
+ return new MaskFieldsStep(name, options);
84
+ }
85
+ //# sourceMappingURL=mask-step.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mask-step.js","sourceRoot":"","sources":["../../src/redaction/mask-step.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Utilities for dot-notation path traversal, wildcards, and immutable structural sharing.
3
+ */
4
+ export declare function splitPath(pattern: string): string[];
5
+ /**
6
+ * Returns all concrete paths in `obj` that match the wildcard pattern.
7
+ * Supports '*' to match any object property or array index.
8
+ */
9
+ export declare function getMatchingPaths(obj: unknown, pattern: string): (string | number)[][];
10
+ /**
11
+ * Retrieves the value at a concrete path.
12
+ */
13
+ export declare function getValueAtPath(obj: unknown, path: (string | number)[]): unknown;
14
+ /**
15
+ * Immutably updates the value at a concrete path using structural sharing (copy-on-write).
16
+ * Only the ancestor nodes along the path are cloned; sibling branches remain untouched.
17
+ */
18
+ export declare function setValueAtPath(obj: any, path: (string | number)[], transform: (currentVal: unknown) => unknown): any;
19
+ /**
20
+ * Transforms all fields in `obj` matching the provided string/keyof patterns.
21
+ * Supports both top-level property keys and nested dot-notation/wildcard paths.
22
+ */
23
+ export declare function transformFields(obj: any, patterns: (string | number | symbol)[], transform: (val: unknown, concretePath: (string | number)[]) => unknown): any;
24
+ /**
25
+ * Deep freezes an object (used in dev mode to assert context immutability).
26
+ */
27
+ export declare function deepFreeze<T>(obj: T): T;
28
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/redaction/paths.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAEnD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EAAE,CAwCrF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,OAAO,CAS/E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EACzB,SAAS,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,OAAO,GAC1C,GAAG,CA6BL;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC,EAAE,EACtC,SAAS,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK,OAAO,GACtE,GAAG,CA+BL;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAYvC"}
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ /**
3
+ * Utilities for dot-notation path traversal, wildcards, and immutable structural sharing.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.splitPath = splitPath;
7
+ exports.getMatchingPaths = getMatchingPaths;
8
+ exports.getValueAtPath = getValueAtPath;
9
+ exports.setValueAtPath = setValueAtPath;
10
+ exports.transformFields = transformFields;
11
+ exports.deepFreeze = deepFreeze;
12
+ function splitPath(pattern) {
13
+ return pattern.split('.').filter(Boolean);
14
+ }
15
+ /**
16
+ * Returns all concrete paths in `obj` that match the wildcard pattern.
17
+ * Supports '*' to match any object property or array index.
18
+ */
19
+ function getMatchingPaths(obj, pattern) {
20
+ const segments = splitPath(pattern);
21
+ const results = [];
22
+ function traverse(current, segmentIdx, currentPath) {
23
+ if (segmentIdx >= segments.length) {
24
+ results.push(currentPath);
25
+ return;
26
+ }
27
+ if (current === null || current === undefined || typeof current !== 'object') {
28
+ return;
29
+ }
30
+ const seg = segments[segmentIdx];
31
+ if (seg === '*') {
32
+ if (Array.isArray(current)) {
33
+ for (let i = 0; i < current.length; i++) {
34
+ traverse(current[i], segmentIdx + 1, [...currentPath, i]);
35
+ }
36
+ }
37
+ else {
38
+ for (const key of Object.keys(current)) {
39
+ traverse(current[key], segmentIdx + 1, [...currentPath, key]);
40
+ }
41
+ }
42
+ }
43
+ else {
44
+ if (Array.isArray(current)) {
45
+ const num = Number(seg);
46
+ if (!Number.isNaN(num) && num in current) {
47
+ traverse(current[num], segmentIdx + 1, [...currentPath, num]);
48
+ }
49
+ }
50
+ else if (seg in current) {
51
+ traverse(current[seg], segmentIdx + 1, [...currentPath, seg]);
52
+ }
53
+ }
54
+ }
55
+ traverse(obj, 0, []);
56
+ return results;
57
+ }
58
+ /**
59
+ * Retrieves the value at a concrete path.
60
+ */
61
+ function getValueAtPath(obj, path) {
62
+ let curr = obj;
63
+ for (const part of path) {
64
+ if (curr === null || curr === undefined) {
65
+ return undefined;
66
+ }
67
+ curr = curr[part];
68
+ }
69
+ return curr;
70
+ }
71
+ /**
72
+ * Immutably updates the value at a concrete path using structural sharing (copy-on-write).
73
+ * Only the ancestor nodes along the path are cloned; sibling branches remain untouched.
74
+ */
75
+ function setValueAtPath(obj, path, transform) {
76
+ if (path.length === 0) {
77
+ return transform(obj);
78
+ }
79
+ const [head, ...tail] = path;
80
+ if (Array.isArray(obj)) {
81
+ const copy = [...obj];
82
+ const index = Number(head);
83
+ const existingChild = copy[index];
84
+ const childTarget = tail.length === 0
85
+ ? existingChild
86
+ : (existingChild !== undefined && existingChild !== null && typeof existingChild === 'object'
87
+ ? existingChild
88
+ : typeof tail[0] === 'number' ? [] : {});
89
+ copy[index] = setValueAtPath(childTarget, tail, transform);
90
+ return copy;
91
+ }
92
+ const copy = obj && typeof obj === 'object' ? { ...obj } : {};
93
+ const existingChild = copy[head];
94
+ const childTarget = tail.length === 0
95
+ ? existingChild
96
+ : (existingChild !== undefined && existingChild !== null && typeof existingChild === 'object'
97
+ ? existingChild
98
+ : typeof tail[0] === 'number' ? [] : {});
99
+ copy[head] = setValueAtPath(childTarget, tail, transform);
100
+ return copy;
101
+ }
102
+ /**
103
+ * Transforms all fields in `obj` matching the provided string/keyof patterns.
104
+ * Supports both top-level property keys and nested dot-notation/wildcard paths.
105
+ */
106
+ function transformFields(obj, patterns, transform) {
107
+ if (!obj || typeof obj !== 'object') {
108
+ return obj;
109
+ }
110
+ let result = obj;
111
+ for (const pattern of patterns) {
112
+ const patternStr = String(pattern);
113
+ // If simple property key without dot or asterisk, fast-path with shallow clone
114
+ if (!patternStr.includes('.') && !patternStr.includes('*')) {
115
+ if (patternStr in result) {
116
+ const val = result[patternStr];
117
+ const transformed = transform(val, [patternStr]);
118
+ if (transformed !== val) {
119
+ result = Array.isArray(result) ? [...result] : { ...result };
120
+ result[patternStr] = transformed;
121
+ }
122
+ }
123
+ continue;
124
+ }
125
+ // Nested or wildcard pattern
126
+ const matchingPaths = getMatchingPaths(result, patternStr);
127
+ for (const concretePath of matchingPaths) {
128
+ result = setValueAtPath(result, concretePath, (curr) => transform(curr, concretePath));
129
+ }
130
+ }
131
+ return result;
132
+ }
133
+ /**
134
+ * Deep freezes an object (used in dev mode to assert context immutability).
135
+ */
136
+ function deepFreeze(obj) {
137
+ if (!obj || typeof obj !== 'object' || Object.isFrozen(obj)) {
138
+ return obj;
139
+ }
140
+ Object.freeze(obj);
141
+ for (const key of Object.keys(obj)) {
142
+ const val = obj[key];
143
+ if (val && typeof val === 'object' && !Object.isFrozen(val)) {
144
+ deepFreeze(val);
145
+ }
146
+ }
147
+ return obj;
148
+ }
149
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/redaction/paths.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { WebhookProtocol } from './types';
2
+ /**
3
+ * Registers a global webhook protocol strategy.
4
+ */
5
+ export declare function registerWebhookProtocol(name: string, protocol: WebhookProtocol): void;
6
+ /**
7
+ * Retrieves a registered webhook protocol by name.
8
+ */
9
+ export declare function getWebhookProtocol(name: string): WebhookProtocol | undefined;
10
+ /**
11
+ * Clears custom registered protocols, resetting to built-ins (useful for test isolation).
12
+ */
13
+ export declare function resetWebhookProtocols(): void;
14
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAkB1C;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI,CAErF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAE5E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAQ5C"}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerWebhookProtocol = registerWebhookProtocol;
4
+ exports.getWebhookProtocol = getWebhookProtocol;
5
+ exports.resetWebhookProtocols = resetWebhookProtocols;
6
+ const stripe_1 = require("./webhooks/protocols/stripe");
7
+ const github_1 = require("./webhooks/protocols/github");
8
+ const shopify_1 = require("./webhooks/protocols/shopify");
9
+ const slack_1 = require("./webhooks/protocols/slack");
10
+ const svix_1 = require("./webhooks/protocols/svix");
11
+ const generic_hmac_1 = require("./webhooks/protocols/generic-hmac");
12
+ const protocolRegistry = new Map();
13
+ // Register default built-in protocols
14
+ protocolRegistry.set('stripe', stripe_1.stripeProtocol);
15
+ protocolRegistry.set('github', github_1.gitHubProtocol);
16
+ protocolRegistry.set('shopify', shopify_1.shopifyProtocol);
17
+ protocolRegistry.set('slack', slack_1.slackProtocol);
18
+ protocolRegistry.set('svix', svix_1.svixProtocol);
19
+ protocolRegistry.set('generic-hmac', generic_hmac_1.genericHmacProtocol);
20
+ /**
21
+ * Registers a global webhook protocol strategy.
22
+ */
23
+ function registerWebhookProtocol(name, protocol) {
24
+ protocolRegistry.set(name.toLowerCase(), protocol);
25
+ }
26
+ /**
27
+ * Retrieves a registered webhook protocol by name.
28
+ */
29
+ function getWebhookProtocol(name) {
30
+ return protocolRegistry.get(name.toLowerCase());
31
+ }
32
+ /**
33
+ * Clears custom registered protocols, resetting to built-ins (useful for test isolation).
34
+ */
35
+ function resetWebhookProtocols() {
36
+ protocolRegistry.clear();
37
+ protocolRegistry.set('stripe', stripe_1.stripeProtocol);
38
+ protocolRegistry.set('github', github_1.gitHubProtocol);
39
+ protocolRegistry.set('shopify', shopify_1.shopifyProtocol);
40
+ protocolRegistry.set('slack', slack_1.slackProtocol);
41
+ protocolRegistry.set('svix', svix_1.svixProtocol);
42
+ protocolRegistry.set('generic-hmac', generic_hmac_1.genericHmacProtocol);
43
+ }
44
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":";;AAqBA,0DAEC;AAKD,gDAEC;AAKD,sDAQC;AA1CD,wDAA6D;AAC7D,wDAA6D;AAC7D,0DAA+D;AAC/D,sDAA2D;AAC3D,oDAAyD;AACzD,oEAAwE;AAExE,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAA2B,CAAC;AAE5D,sCAAsC;AACtC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,uBAAc,CAAC,CAAC;AAC/C,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,uBAAc,CAAC,CAAC;AAC/C,gBAAgB,CAAC,GAAG,CAAC,SAAS,EAAE,yBAAe,CAAC,CAAC;AACjD,gBAAgB,CAAC,GAAG,CAAC,OAAO,EAAE,qBAAa,CAAC,CAAC;AAC7C,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,mBAAY,CAAC,CAAC;AAC3C,gBAAgB,CAAC,GAAG,CAAC,cAAc,EAAE,kCAAmB,CAAC,CAAC;AAE1D;;GAEG;AACH,SAAgB,uBAAuB,CAAC,IAAY,EAAE,QAAyB;IAC7E,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,QAAQ,CAAC,CAAC;AACrD,CAAC;AAED;;GAEG;AACH,SAAgB,kBAAkB,CAAC,IAAY;IAC7C,OAAO,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AAClD,CAAC;AAED;;GAEG;AACH,SAAgB,qBAAqB;IACnC,gBAAgB,CAAC,KAAK,EAAE,CAAC;IACzB,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,uBAAc,CAAC,CAAC;IAC/C,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,uBAAc,CAAC,CAAC;IAC/C,gBAAgB,CAAC,GAAG,CAAC,SAAS,EAAE,yBAAe,CAAC,CAAC;IACjD,gBAAgB,CAAC,GAAG,CAAC,OAAO,EAAE,qBAAa,CAAC,CAAC;IAC7C,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,mBAAY,CAAC,CAAC;IAC3C,gBAAgB,CAAC,GAAG,CAAC,cAAc,EAAE,kCAAmB,CAAC,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,115 @@
1
+ /** Built-in provider preset identifiers with open string autocomplete */
2
+ export type BuiltInWebhookProvider = 'stripe' | 'github' | 'shopify' | 'slack' | 'svix' | 'generic-hmac';
3
+ export type WebhookProviderName = BuiltInWebhookProvider | (string & {});
4
+ export interface WebhookProtocolVerificationParams {
5
+ secret: string | Buffer;
6
+ rawPayload: string | Buffer;
7
+ headers: Record<string, string | string[] | undefined>;
8
+ signatureHeader: string;
9
+ toleranceSeconds?: number;
10
+ clock?: {
11
+ now(): number;
12
+ };
13
+ algorithm?: 'sha256' | 'sha512' | 'sha1';
14
+ }
15
+ export interface ParsedWebhookHeaders {
16
+ timestamp?: number;
17
+ signatures: string[];
18
+ version?: string;
19
+ }
20
+ export interface WebhookProtocol {
21
+ name: string;
22
+ /** Parses timestamps, signatures, and version identifiers from raw headers */
23
+ parseHeaders?(headers: Record<string, string | string[] | undefined>, signatureHeader: string): ParsedWebhookHeaders;
24
+ /** Formats the exact string or buffer to be signed (e.g. `${timestamp}.${rawBody}`) */
25
+ formatSignedPayload?(rawBody: string | Buffer, timestamp?: number): string | Buffer;
26
+ /** Custom verification logic (HMAC, asymmetric Ed25519, RSA, etc.) */
27
+ verify(params: WebhookProtocolVerificationParams): Promise<boolean> | boolean;
28
+ }
29
+ /** Nonce / signature deduplication store interface */
30
+ export interface WebhookDedupStore {
31
+ claim(key: string, ttlSeconds: number): Promise<boolean> | boolean;
32
+ }
33
+ /** Reference to spooled or stream-verified payload */
34
+ export interface WebhookPayloadRef {
35
+ storage: 'memory' | 'file';
36
+ path?: string;
37
+ bytes: number;
38
+ }
39
+ export interface WebhookVerifyOptions<TInput> {
40
+ /**
41
+ * Built-in provider name, registered protocol name, custom WebhookProtocol instance,
42
+ * or dynamic resolver function based on workflow context.
43
+ */
44
+ provider?: WebhookProviderName | WebhookProtocol | ((ctx: TInput) => WebhookProviderName | WebhookProtocol);
45
+ /** Webhook signing secret (or public key for asymmetric protocols) */
46
+ secret: string | Buffer | ((ctx: TInput) => string | Buffer);
47
+ /** Raw unparsed payload buffer, UTF-8 string, or Readable stream / AsyncIterable */
48
+ payload: (ctx: TInput) => string | Buffer | NodeJS.ReadableStream | AsyncIterable<Buffer>;
49
+ /** Signature header string or entire headers dictionary */
50
+ signature: (ctx: TInput) => string | Record<string, string | string[] | undefined>;
51
+ /** Optional headers extractor if signature returns only the signature string */
52
+ headers?: (ctx: TInput) => Record<string, string | string[] | undefined>;
53
+ /** Hash algorithm for generic HMAC (default: 'sha256') */
54
+ algorithm?: 'sha256' | 'sha512' | 'sha1';
55
+ /** Max allowed difference between current time and signature timestamp in seconds (default: 300) */
56
+ toleranceSeconds?: number;
57
+ /** Optional clock interface for deterministic time testing */
58
+ clock?: {
59
+ now(): number;
60
+ };
61
+ /** Deduplication store for intra-window replay protection */
62
+ dedupStore?: WebhookDedupStore;
63
+ /** Maximum allowed payload size in bytes before rejecting with 413 ValidationException (default: 10MB) */
64
+ maxBodyBytes?: number;
65
+ /** Byte threshold above which streaming payloads are spooled to ephemeral disk (default: 5MB) */
66
+ spoolThresholdBytes?: number;
67
+ /** Directory for ephemeral disk spooling (default: os.tmpdir()) */
68
+ spoolDir?: string;
69
+ }
70
+ export interface WebhookVerificationResult {
71
+ webhookVerified: true;
72
+ verifiedAt: number;
73
+ provider: string;
74
+ idempotencyKey?: string;
75
+ payloadRef?: WebhookPayloadRef;
76
+ }
77
+ export interface EncryptedEnvelope {
78
+ __sigloCipher: 'aes-256-gcm';
79
+ v?: number;
80
+ kid?: string;
81
+ iv: string;
82
+ tag: string;
83
+ data: string;
84
+ edek?: string;
85
+ kekId?: string;
86
+ }
87
+ export interface KeyRingKey {
88
+ kid: string;
89
+ key: string | Buffer;
90
+ }
91
+ export interface KeyRing {
92
+ getActiveKey(): Promise<KeyRingKey> | KeyRingKey;
93
+ getKey(kid: string): Promise<string | Buffer | null | undefined> | string | Buffer | null | undefined;
94
+ }
95
+ export interface FieldCipherOptions<TInput> {
96
+ /** Fields to encrypt/decrypt. Supports top-level keys or dot-notation paths (e.g. 'billing.card.number', 'items.*.token') */
97
+ fields: (keyof TInput | string)[];
98
+ /** Secret key string, Buffer, KeyRing instance, or dynamic resolver callback */
99
+ secretKey?: string | Buffer | KeyRing | ((ctx: TInput) => string | Buffer | KeyRing | Promise<string | Buffer | KeyRing>);
100
+ /** KeyRing instance for multi-key rotation and checkpoint archaeology */
101
+ keyRing?: KeyRing;
102
+ /** Optional Additional Authenticated Data (AAD) for tenant/context isolation */
103
+ aad?: string | Buffer | ((ctx: TInput) => string | Buffer | undefined);
104
+ /** Optional HKDF context info for deriving per-workflow/tenant subkeys */
105
+ deriveKeyContext?: string | Buffer | ((ctx: TInput) => string | Buffer | undefined);
106
+ /** Callback invoked when a decrypted envelope was encrypted with a retired/historical key */
107
+ onNeedsRekey?: (ctx: TInput, field: string, oldKid?: string, activeKid?: string) => void;
108
+ }
109
+ export interface MaskFieldsOptions<TInput> {
110
+ /** Fields to mask. Supports top-level keys or dot-notation paths (e.g. 'user.ssn', 'passengers.*.passport') */
111
+ fields: (keyof TInput | string)[];
112
+ /** Custom or preset mask function */
113
+ maskPattern?: (value: unknown) => string;
114
+ }
115
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}