agentlock-shared 0.1.0 → 0.3.0

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 (171) hide show
  1. package/dist/__tests__/billing.test.d.ts +2 -0
  2. package/dist/__tests__/billing.test.d.ts.map +1 -0
  3. package/dist/__tests__/billing.test.js +31 -0
  4. package/dist/__tests__/billing.test.js.map +1 -0
  5. package/dist/__tests__/crypto.test.js +137 -47
  6. package/dist/__tests__/crypto.test.js.map +1 -1
  7. package/dist/__tests__/dns-pinning.test.d.ts +2 -0
  8. package/dist/__tests__/dns-pinning.test.d.ts.map +1 -0
  9. package/dist/__tests__/dns-pinning.test.js +33 -0
  10. package/dist/__tests__/dns-pinning.test.js.map +1 -0
  11. package/dist/__tests__/llm-classifier-cache-store.test.d.ts +2 -0
  12. package/dist/__tests__/llm-classifier-cache-store.test.d.ts.map +1 -0
  13. package/dist/__tests__/llm-classifier-cache-store.test.js +65 -0
  14. package/dist/__tests__/llm-classifier-cache-store.test.js.map +1 -0
  15. package/dist/__tests__/llm-classifier-cache.test.d.ts +2 -0
  16. package/dist/__tests__/llm-classifier-cache.test.d.ts.map +1 -0
  17. package/dist/__tests__/llm-classifier-cache.test.js +44 -0
  18. package/dist/__tests__/llm-classifier-cache.test.js.map +1 -0
  19. package/dist/__tests__/llm-classifier.test.d.ts +2 -0
  20. package/dist/__tests__/llm-classifier.test.d.ts.map +1 -0
  21. package/dist/__tests__/llm-classifier.test.js +167 -0
  22. package/dist/__tests__/llm-classifier.test.js.map +1 -0
  23. package/dist/__tests__/messaging.test.d.ts +2 -0
  24. package/dist/__tests__/messaging.test.d.ts.map +1 -0
  25. package/dist/__tests__/messaging.test.js +75 -0
  26. package/dist/__tests__/messaging.test.js.map +1 -0
  27. package/dist/__tests__/plans-classifier-limits.test.d.ts +2 -0
  28. package/dist/__tests__/plans-classifier-limits.test.d.ts.map +1 -0
  29. package/dist/__tests__/plans-classifier-limits.test.js +22 -0
  30. package/dist/__tests__/plans-classifier-limits.test.js.map +1 -0
  31. package/dist/__tests__/policy-category-floor.test.d.ts +2 -0
  32. package/dist/__tests__/policy-category-floor.test.d.ts.map +1 -0
  33. package/dist/__tests__/policy-category-floor.test.js +46 -0
  34. package/dist/__tests__/policy-category-floor.test.js.map +1 -0
  35. package/dist/__tests__/policy-claude-bash.test.d.ts +2 -0
  36. package/dist/__tests__/policy-claude-bash.test.d.ts.map +1 -0
  37. package/dist/__tests__/policy-claude-bash.test.js +401 -0
  38. package/dist/__tests__/policy-claude-bash.test.js.map +1 -0
  39. package/dist/__tests__/policy-llm-floor.test.d.ts +2 -0
  40. package/dist/__tests__/policy-llm-floor.test.d.ts.map +1 -0
  41. package/dist/__tests__/policy-llm-floor.test.js +107 -0
  42. package/dist/__tests__/policy-llm-floor.test.js.map +1 -0
  43. package/dist/__tests__/policy-ssh-e2e.test.d.ts +2 -0
  44. package/dist/__tests__/policy-ssh-e2e.test.d.ts.map +1 -0
  45. package/dist/__tests__/policy-ssh-e2e.test.js +89 -0
  46. package/dist/__tests__/policy-ssh-e2e.test.js.map +1 -0
  47. package/dist/__tests__/policy-ssh-sessions.test.d.ts +2 -0
  48. package/dist/__tests__/policy-ssh-sessions.test.d.ts.map +1 -0
  49. package/dist/__tests__/policy-ssh-sessions.test.js +139 -0
  50. package/dist/__tests__/policy-ssh-sessions.test.js.map +1 -0
  51. package/dist/__tests__/policy-ssh.test.d.ts +2 -0
  52. package/dist/__tests__/policy-ssh.test.d.ts.map +1 -0
  53. package/dist/__tests__/policy-ssh.test.js +180 -0
  54. package/dist/__tests__/policy-ssh.test.js.map +1 -0
  55. package/dist/__tests__/policy.test.js +522 -7
  56. package/dist/__tests__/policy.test.js.map +1 -1
  57. package/dist/__tests__/redact.test.js +76 -0
  58. package/dist/__tests__/redact.test.js.map +1 -1
  59. package/dist/__tests__/signing.test.js +89 -0
  60. package/dist/__tests__/signing.test.js.map +1 -1
  61. package/dist/__tests__/ssh-fingerprint.test.d.ts +2 -0
  62. package/dist/__tests__/ssh-fingerprint.test.d.ts.map +1 -0
  63. package/dist/__tests__/ssh-fingerprint.test.js +19 -0
  64. package/dist/__tests__/ssh-fingerprint.test.js.map +1 -0
  65. package/dist/__tests__/vpn-route.test.d.ts +2 -0
  66. package/dist/__tests__/vpn-route.test.d.ts.map +1 -0
  67. package/dist/__tests__/vpn-route.test.js +72 -0
  68. package/dist/__tests__/vpn-route.test.js.map +1 -0
  69. package/dist/__tests__/wireguard.test.d.ts +2 -0
  70. package/dist/__tests__/wireguard.test.d.ts.map +1 -0
  71. package/dist/__tests__/wireguard.test.js +114 -0
  72. package/dist/__tests__/wireguard.test.js.map +1 -0
  73. package/dist/billing.d.ts +12 -0
  74. package/dist/billing.d.ts.map +1 -0
  75. package/dist/billing.js +41 -0
  76. package/dist/billing.js.map +1 -0
  77. package/dist/crypto.d.ts +41 -0
  78. package/dist/crypto.d.ts.map +1 -1
  79. package/dist/crypto.js +208 -6
  80. package/dist/crypto.js.map +1 -1
  81. package/dist/dns-pinning.d.ts +28 -0
  82. package/dist/dns-pinning.d.ts.map +1 -0
  83. package/dist/dns-pinning.js +113 -0
  84. package/dist/dns-pinning.js.map +1 -0
  85. package/dist/index.d.ts +6 -0
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +9 -0
  88. package/dist/index.js.map +1 -1
  89. package/dist/llm-classifier-cache-store.d.ts +49 -0
  90. package/dist/llm-classifier-cache-store.d.ts.map +1 -0
  91. package/dist/llm-classifier-cache-store.js +63 -0
  92. package/dist/llm-classifier-cache-store.js.map +1 -0
  93. package/dist/llm-classifier-cache.d.ts +6 -0
  94. package/dist/llm-classifier-cache.d.ts.map +1 -0
  95. package/dist/llm-classifier-cache.js +52 -0
  96. package/dist/llm-classifier-cache.js.map +1 -0
  97. package/dist/llm-classifier.d.ts +29 -0
  98. package/dist/llm-classifier.d.ts.map +1 -0
  99. package/dist/llm-classifier.js +191 -0
  100. package/dist/llm-classifier.js.map +1 -0
  101. package/dist/observability.d.ts +36 -0
  102. package/dist/observability.d.ts.map +1 -0
  103. package/dist/observability.js +75 -0
  104. package/dist/observability.js.map +1 -0
  105. package/dist/plans.d.ts +21 -0
  106. package/dist/plans.d.ts.map +1 -1
  107. package/dist/plans.js +52 -14
  108. package/dist/plans.js.map +1 -1
  109. package/dist/policy.d.ts +173 -3
  110. package/dist/policy.d.ts.map +1 -1
  111. package/dist/policy.js +951 -58
  112. package/dist/policy.js.map +1 -1
  113. package/dist/redact.d.ts.map +1 -1
  114. package/dist/redact.js +104 -7
  115. package/dist/redact.js.map +1 -1
  116. package/dist/regex-safety.d.ts +21 -0
  117. package/dist/regex-safety.d.ts.map +1 -0
  118. package/dist/regex-safety.js +49 -0
  119. package/dist/regex-safety.js.map +1 -0
  120. package/dist/sanitize.d.ts +31 -0
  121. package/dist/sanitize.d.ts.map +1 -0
  122. package/dist/sanitize.js +54 -0
  123. package/dist/sanitize.js.map +1 -0
  124. package/dist/schemas.d.ts +267 -14
  125. package/dist/schemas.d.ts.map +1 -1
  126. package/dist/schemas.js +152 -10
  127. package/dist/schemas.js.map +1 -1
  128. package/dist/signing.d.ts +15 -0
  129. package/dist/signing.d.ts.map +1 -1
  130. package/dist/signing.js +53 -4
  131. package/dist/signing.js.map +1 -1
  132. package/dist/ssh-fingerprint.d.ts +10 -0
  133. package/dist/ssh-fingerprint.d.ts.map +1 -0
  134. package/dist/ssh-fingerprint.js +52 -0
  135. package/dist/ssh-fingerprint.js.map +1 -0
  136. package/dist/ssrf.d.ts +36 -0
  137. package/dist/ssrf.d.ts.map +1 -0
  138. package/dist/ssrf.js +140 -0
  139. package/dist/ssrf.js.map +1 -0
  140. package/dist/types.d.ts +131 -0
  141. package/dist/types.d.ts.map +1 -1
  142. package/dist/wireguard.d.ts +63 -0
  143. package/dist/wireguard.d.ts.map +1 -0
  144. package/dist/wireguard.js +226 -0
  145. package/dist/wireguard.js.map +1 -0
  146. package/package.json +42 -29
  147. package/.turbo/turbo-build.log +0 -4
  148. package/.turbo/turbo-test.log +0 -34
  149. package/dist/__tests__/content-crypto.test.d.ts +0 -2
  150. package/dist/__tests__/content-crypto.test.d.ts.map +0 -1
  151. package/dist/__tests__/content-crypto.test.js +0 -117
  152. package/dist/__tests__/content-crypto.test.js.map +0 -1
  153. package/dist/content-crypto.d.ts +0 -24
  154. package/dist/content-crypto.d.ts.map +0 -1
  155. package/dist/content-crypto.js +0 -58
  156. package/dist/content-crypto.js.map +0 -1
  157. package/src/__tests__/policy.test.ts +0 -88
  158. package/src/__tests__/redact.test.ts +0 -41
  159. package/src/__tests__/signing.test.ts +0 -55
  160. package/src/crypto.ts +0 -87
  161. package/src/index.ts +0 -8
  162. package/src/mcp-catalog.ts +0 -181
  163. package/src/plans.ts +0 -96
  164. package/src/policy.ts +0 -186
  165. package/src/redact.ts +0 -114
  166. package/src/schemas.ts +0 -53
  167. package/src/signing.ts +0 -120
  168. package/src/types.ts +0 -212
  169. package/test-gateway.mjs +0 -47
  170. package/tsconfig.json +0 -10
  171. package/vitest.config.ts +0 -8
@@ -35,5 +35,81 @@ const redact_js_1 = require("../redact.js");
35
35
  (0, vitest_1.expect)(result.url).toBe('https://example.com');
36
36
  (0, vitest_1.expect)(result.status).toBe(200);
37
37
  });
38
+ (0, vitest_1.it)('redacts SSH public keys in output', () => {
39
+ const input = 'host-1.internal ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKxxxxxxxxxxxxxxxxx';
40
+ (0, vitest_1.expect)((0, redact_js_1.redact)(input)).not.toContain('AAAAC3');
41
+ });
42
+ (0, vitest_1.it)('redacts shadow-style password hashes', () => {
43
+ const input = 'root:$6$saltsalt$hashedpasswordhere:12345:0:99999:7:::';
44
+ (0, vitest_1.expect)((0, redact_js_1.redact)(input)).not.toContain('hashedpasswordhere');
45
+ });
46
+ });
47
+ (0, vitest_1.describe)('WireGuard redaction', () => {
48
+ (0, vitest_1.it)('redacts PrivateKey = ... lines', () => {
49
+ const input = 'Loaded config: PrivateKey = yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=';
50
+ (0, vitest_1.expect)((0, redact_js_1.redact)(input)).not.toContain('yAnz5TF');
51
+ });
52
+ (0, vitest_1.it)('redacts PresharedKey = ... lines', () => {
53
+ const input = 'PresharedKey = FpCyhws9cxwWoV4xELtfJvjJN+zQVRPISllRWgeopVE=';
54
+ (0, vitest_1.expect)((0, redact_js_1.redact)(input)).not.toContain('FpCyhws9');
55
+ });
56
+ (0, vitest_1.it)('redacts bare base64 44-char keys in JSON-ish dumps', () => {
57
+ const input = '{"key":"yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk="}';
58
+ (0, vitest_1.expect)((0, redact_js_1.redact)(input)).not.toContain('yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=');
59
+ });
60
+ });
61
+ (0, vitest_1.describe)('Inline secret redaction (e.g. command output / logs)', () => {
62
+ (0, vitest_1.it)('redacts OpenAI keys embedded in env-style text', () => {
63
+ const input = 'OPENAI_API_KEY=sk-abc123def456ghi789jkl012mno345pqr678';
64
+ const out = (0, redact_js_1.redact)(input);
65
+ (0, vitest_1.expect)(out).toContain('OPENAI_API_KEY=');
66
+ (0, vitest_1.expect)(out).toContain('[REDACTED]');
67
+ (0, vitest_1.expect)(out).not.toMatch(/sk-[a-zA-Z0-9]{20,}/);
68
+ });
69
+ (0, vitest_1.it)('redacts Anthropic keys (sk-ant-) without double-matching as OpenAI', () => {
70
+ const input = 'export ANTHROPIC_KEY=sk-ant-api03-abc123def456ghi789jkl012mno345pqr678';
71
+ const out = (0, redact_js_1.redact)(input);
72
+ (0, vitest_1.expect)(out).not.toContain('sk-ant-api03');
73
+ (0, vitest_1.expect)(out).toContain('[REDACTED]');
74
+ });
75
+ (0, vitest_1.it)('redacts GitHub PATs in shell output', () => {
76
+ const input = '$ echo $GITHUB_TOKEN\nghp_1234567890abcdef1234567890abcdef1234';
77
+ const out = (0, redact_js_1.redact)(input);
78
+ (0, vitest_1.expect)(out).not.toContain('ghp_1234567890abcdef1234567890abcdef1234');
79
+ });
80
+ (0, vitest_1.it)('redacts AWS access key IDs inline', () => {
81
+ const input = '[default]\naws_access_key_id = AKIAIOSFODNN7EXAMPLE';
82
+ const out = (0, redact_js_1.redact)(input);
83
+ (0, vitest_1.expect)(out).not.toContain('AKIAIOSFODNN7EXAMPLE');
84
+ });
85
+ (0, vitest_1.it)('redacts JWTs inline (eyJ prefix)', () => {
86
+ const input = 'Authorization cookie: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.abcdef';
87
+ const out = (0, redact_js_1.redact)(input);
88
+ (0, vitest_1.expect)(out).not.toContain('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9');
89
+ });
90
+ (0, vitest_1.it)('redacts multiple different secrets in the same string', () => {
91
+ const input = 'ANTHROPIC=sk-ant-api03-xxxxxxxxxxxxxxxxxxxxxxxxxxxx AWS=AKIAIOSFODNN7EXAMPLE';
92
+ const out = (0, redact_js_1.redact)(input);
93
+ (0, vitest_1.expect)(out).not.toContain('sk-ant-api03');
94
+ (0, vitest_1.expect)(out).not.toContain('AKIAIOSFODNN7EXAMPLE');
95
+ (0, vitest_1.expect)((out.match(/\[REDACTED\]/g) ?? []).length).toBe(2);
96
+ });
97
+ (0, vitest_1.it)('does not redact short-looking non-secret strings', () => {
98
+ const input = 'hello world this is just some text';
99
+ (0, vitest_1.expect)((0, redact_js_1.redact)(input)).toBe(input);
100
+ });
101
+ (0, vitest_1.it)('does not redact "sk-" appearing inside a word', () => {
102
+ const input = 'Turks-and-Caicos islands';
103
+ // "sk-" inline but followed by too few chars + word continuation — negative lookbehind on '-' boundary still ok
104
+ (0, vitest_1.expect)((0, redact_js_1.redact)(input)).toBe(input);
105
+ });
106
+ (0, vitest_1.it)('redacts inline secret inside SSH-style stdout', () => {
107
+ // Google key format: `AIza` + exactly 35 [A-Za-z0-9_-] chars.
108
+ const googleKey = 'AIza' + 'A'.repeat(35);
109
+ const input = `$ env | grep API\nSTRIPE_KEY=sk_live_abcdef1234567890abcdef1234\nGOOGLE_KEY=${googleKey}`;
110
+ const out = (0, redact_js_1.redact)(input);
111
+ (0, vitest_1.expect)(out).not.toContain('sk_live_abcdef1234567890abcdef1234');
112
+ (0, vitest_1.expect)(out).not.toContain(googleKey);
113
+ });
38
114
  });
39
115
  //# sourceMappingURL=redact.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"redact.test.js","sourceRoot":"","sources":["../../src/__tests__/redact.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"redact.test.js","sourceRoot":"","sources":["../../src/__tests__/redact.test.ts"],"names":[],"mappings":";;AAAA,mCAA8C;AAC9C,4CAAqD;AAErD,IAAA,iBAAQ,EAAC,WAAW,EAAE,GAAG,EAAE;IACzB,IAAA,WAAE,EAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC;QAClF,MAAM,MAAM,GAAG,IAAA,kBAAM,EAAC,GAAG,CAA4B,CAAC;QACtD,IAAA,eAAM,EAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC1C,IAAA,eAAM,EAAE,MAAM,CAAC,IAAgC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC1E,IAAA,eAAM,EAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,OAAO,GAAG,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;QACvF,MAAM,MAAM,GAAG,IAAA,yBAAa,EAAC,OAAO,CAAC,CAAC;QACtC,IAAA,eAAM,EAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACnD,IAAA,eAAM,EAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,GAAG,GAAG,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QACvE,MAAM,MAAM,GAAG,IAAA,kBAAM,EAAC,GAAG,CAA+D,CAAC;QACzF,IAAA,eAAM,EAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACzD,IAAA,eAAM,EAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,GAAG,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;QACpE,MAAM,MAAM,GAAG,IAAA,kBAAM,EAAC,GAAG,CAAmC,CAAC;QAC7D,IAAA,eAAM,EAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACjD,IAAA,eAAM,EAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,qBAAqB,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;QACtE,MAAM,MAAM,GAAG,IAAA,kBAAM,EAAC,GAAG,CAAe,CAAC;QACzC,IAAA,eAAM,EAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,IAAA,eAAM,EAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAC/C,IAAA,eAAM,EAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,KAAK,GAAG,yEAAyE,CAAC;QACxF,IAAA,eAAM,EAAC,IAAA,kBAAM,EAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,KAAK,GAAG,wDAAwD,CAAC;QACvE,IAAA,eAAM,EAAC,IAAA,kBAAM,EAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,IAAA,WAAE,EAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,KAAK,GAAG,0EAA0E,CAAC;QACzF,IAAA,eAAM,EAAC,IAAA,kBAAM,EAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,KAAK,GAAG,6DAA6D,CAAC;QAC5E,IAAA,eAAM,EAAC,IAAA,kBAAM,EAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,KAAK,GAAG,wDAAwD,CAAC;QACvE,IAAA,eAAM,EAAC,IAAA,kBAAM,EAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,8CAA8C,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,sDAAsD,EAAE,GAAG,EAAE;IACpE,IAAA,WAAE,EAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,KAAK,GAAG,wDAAwD,CAAC;QACvE,MAAM,GAAG,GAAG,IAAA,kBAAM,EAAC,KAAK,CAAW,CAAC;QACpC,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QACzC,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACpC,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,KAAK,GAAG,wEAAwE,CAAC;QACvF,MAAM,GAAG,GAAG,IAAA,kBAAM,EAAC,KAAK,CAAW,CAAC;QACpC,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QAC1C,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,KAAK,GAAG,gEAAgE,CAAC;QAC/E,MAAM,GAAG,GAAG,IAAA,kBAAM,EAAC,KAAK,CAAW,CAAC;QACpC,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,0CAA0C,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,KAAK,GAAG,qDAAqD,CAAC;QACpE,MAAM,GAAG,GAAG,IAAA,kBAAM,EAAC,KAAK,CAAW,CAAC;QACpC,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,KAAK,GAAG,+FAA+F,CAAC;QAC9G,MAAM,GAAG,GAAG,IAAA,kBAAM,EAAC,KAAK,CAAW,CAAC;QACpC,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,sCAAsC,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,KAAK,GAAG,8EAA8E,CAAC;QAC7F,MAAM,GAAG,GAAG,IAAA,kBAAM,EAAC,KAAK,CAAW,CAAC;QACpC,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QAC1C,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;QAClD,IAAA,eAAM,EAAC,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,KAAK,GAAG,oCAAoC,CAAC;QACnD,IAAA,eAAM,EAAC,IAAA,kBAAM,EAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,KAAK,GAAG,0BAA0B,CAAC;QACzC,gHAAgH;QAChH,IAAA,eAAM,EAAC,IAAA,kBAAM,EAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,8DAA8D;QAC9D,MAAM,SAAS,GAAG,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC1C,MAAM,KAAK,GACT,+EAA+E,SAAS,EAAE,CAAC;QAC7F,MAAM,GAAG,GAAG,IAAA,kBAAM,EAAC,KAAK,CAAW,CAAC;QACpC,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,oCAAoC,CAAC,CAAC;QAChE,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,7 +1,25 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  const vitest_1 = require("vitest");
7
+ const tweetnacl_1 = __importDefault(require("tweetnacl"));
8
+ const tweetnacl_util_1 = require("tweetnacl-util");
4
9
  const signing_js_1 = require("../signing.js");
10
+ /**
11
+ * Sign the pre-version-binding (legacy) pre-image: `canonical:timestamp:nonce`
12
+ * with NO `:version` suffix and no version header. Models an agent built
13
+ * before the version was bound into the signature.
14
+ */
15
+ function signLegacyUnbound(body, privateKeyB64) {
16
+ const timestamp = String(Date.now());
17
+ const nonce = (0, tweetnacl_util_1.encodeBase64)(tweetnacl_1.default.randomBytes(16));
18
+ const canonical = (0, signing_js_1.canonicalStringify)(body);
19
+ const message = (0, tweetnacl_util_1.decodeUTF8)(`${canonical}:${timestamp}:${nonce}`);
20
+ const signature = tweetnacl_1.default.sign.detached(message, (0, tweetnacl_util_1.decodeBase64)(privateKeyB64));
21
+ return { timestamp, nonce, signature: (0, tweetnacl_util_1.encodeBase64)(signature) };
22
+ }
5
23
  (0, vitest_1.describe)('Ed25519 Signing', () => {
6
24
  (0, vitest_1.it)('should generate valid keypair', () => {
7
25
  const kp = (0, signing_js_1.generateKeypair)();
@@ -47,5 +65,76 @@ const signing_js_1 = require("../signing.js");
47
65
  headers['x-timestamp'] = String(Date.now() - 10 * 60 * 1000);
48
66
  (0, vitest_1.expect)(() => (0, signing_js_1.verifyRequest)(body, headers, kp.publicKey)).toThrow('Timestamp skew');
49
67
  });
68
+ (0, vitest_1.it)('should reject timestamp from the future', () => {
69
+ // A permissive check would only look at now - ts. Replay would then work
70
+ // forever if you set the timestamp 2h in the future. Math.abs() catches
71
+ // both directions; guard against a future refactor dropping the abs.
72
+ const kp = (0, signing_js_1.generateKeypair)();
73
+ const body = { action_type: 'write', tool: 'demo', payload: {} };
74
+ const headers = (0, signing_js_1.signRequest)(body, 'agent-123', kp.privateKey);
75
+ headers['x-timestamp'] = String(Date.now() + 10 * 60 * 1000);
76
+ (0, vitest_1.expect)(() => (0, signing_js_1.verifyRequest)(body, headers, kp.publicKey)).toThrow('Timestamp skew');
77
+ });
78
+ (0, vitest_1.it)('should produce unique nonces across many signs', () => {
79
+ // If nonces collide, the gateway's replay-protection unique-index
80
+ // rejects the second insert and the agent sees a 409. 200 iterations
81
+ // is enough to shake out a non-random generator without making CI slow.
82
+ const kp = (0, signing_js_1.generateKeypair)();
83
+ const body = { action_type: 'read', tool: 'demo', payload: {} };
84
+ const nonces = new Set();
85
+ for (let i = 0; i < 200; i++) {
86
+ const n = (0, signing_js_1.signRequest)(body, 'agent-123', kp.privateKey)['x-nonce'];
87
+ if (n)
88
+ nonces.add(n);
89
+ }
90
+ (0, vitest_1.expect)(nonces.size).toBe(200);
91
+ });
92
+ (0, vitest_1.it)('should reject a replayed request that only changes the nonce header', () => {
93
+ // The signature is bound to (body, timestamp, nonce). Just rotating
94
+ // the nonce without re-signing must not produce a verifying signature.
95
+ const kp = (0, signing_js_1.generateKeypair)();
96
+ const body = { action_type: 'read', tool: 'demo', payload: {} };
97
+ const headers = (0, signing_js_1.signRequest)(body, 'agent-123', kp.privateKey);
98
+ headers['x-nonce'] = 'AAAAAAAAAAAAAAAAAAAAAAAA'; // 24-char base64
99
+ (0, vitest_1.expect)(() => (0, signing_js_1.verifyRequest)(body, headers, kp.publicKey)).toThrow('Invalid signature');
100
+ });
101
+ (0, vitest_1.it)('should verify identical payloads signed concurrently with different nonces (race-safety)', () => {
102
+ // Simulate two concurrent signers of the same body. Both must verify
103
+ // independently; only the DB unique-constraint on nonce stops the
104
+ // second from actually executing in production.
105
+ const kp = (0, signing_js_1.generateKeypair)();
106
+ const body = { action_type: 'read', tool: 'demo', payload: {} };
107
+ const headersA = (0, signing_js_1.signRequest)(body, 'agent-123', kp.privateKey);
108
+ const headersB = (0, signing_js_1.signRequest)(body, 'agent-123', kp.privateKey);
109
+ (0, vitest_1.expect)(headersA['x-nonce']).toBeTruthy();
110
+ (0, vitest_1.expect)(headersA['x-nonce']).not.toBe(headersB['x-nonce']);
111
+ (0, vitest_1.expect)(() => (0, signing_js_1.verifyRequest)(body, headersA, kp.publicKey)).not.toThrow();
112
+ (0, vitest_1.expect)(() => (0, signing_js_1.verifyRequest)(body, headersB, kp.publicKey)).not.toThrow();
113
+ });
114
+ (0, vitest_1.it)('accepts a legacy unbound-preimage signature when NO version header is sent', () => {
115
+ // Transitional fallback: agents built before version-binding sign the
116
+ // unbound pre-image and send no header. They must keep verifying so the
117
+ // rollout doesn't force a simultaneous redeploy of every agent.
118
+ const kp = (0, signing_js_1.generateKeypair)();
119
+ const body = { action_type: 'read', tool: 'demo', payload: {} };
120
+ const { timestamp, nonce, signature } = signLegacyUnbound(body, kp.privateKey);
121
+ (0, vitest_1.expect)(() => (0, signing_js_1.verifyRequest)(body, { 'x-agent-id': 'a', 'x-timestamp': timestamp, 'x-signature': signature, 'x-nonce': nonce }, kp.publicKey)).not.toThrow();
122
+ });
123
+ (0, vitest_1.it)('rejects a legacy unbound-preimage signature once x-signature-version is present', () => {
124
+ // This is the property the gateway routes must preserve by FORWARDING the
125
+ // header: when a client declares its version, the unbound legacy pre-image
126
+ // is no longer an accepted downgrade. If a route drops the header, this
127
+ // downgrade path stays open for every request.
128
+ const kp = (0, signing_js_1.generateKeypair)();
129
+ const body = { action_type: 'read', tool: 'demo', payload: {} };
130
+ const { timestamp, nonce, signature } = signLegacyUnbound(body, kp.privateKey);
131
+ (0, vitest_1.expect)(() => (0, signing_js_1.verifyRequest)(body, {
132
+ 'x-agent-id': 'a',
133
+ 'x-timestamp': timestamp,
134
+ 'x-signature': signature,
135
+ 'x-nonce': nonce,
136
+ 'x-signature-version': '1',
137
+ }, kp.publicKey)).toThrow('Invalid signature');
138
+ });
50
139
  });
51
140
  //# sourceMappingURL=signing.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"signing.test.js","sourceRoot":"","sources":["../../src/__tests__/signing.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"signing.test.js","sourceRoot":"","sources":["../../src/__tests__/signing.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ssh-fingerprint.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssh-fingerprint.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/ssh-fingerprint.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const ssh_fingerprint_js_1 = require("../ssh-fingerprint.js");
5
+ (0, vitest_1.describe)('normalizeSshHostKeyFingerprint', () => {
6
+ (0, vitest_1.it)('accepts canonical hex and lowercases it', () => {
7
+ (0, vitest_1.expect)((0, ssh_fingerprint_js_1.normalizeSshHostKeyFingerprint)('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')).toBe('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa');
8
+ });
9
+ (0, vitest_1.it)('accepts OpenSSH-style SHA256 base64 and converts it to hex', () => {
10
+ (0, vitest_1.expect)((0, ssh_fingerprint_js_1.normalizeSshHostKeyFingerprint)('SHA256:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')).toBe('0000000000000000000000000000000000000000000000000000000000000000');
11
+ });
12
+ (0, vitest_1.it)('accepts url-safe base64 without the SHA256 prefix', () => {
13
+ (0, vitest_1.expect)((0, ssh_fingerprint_js_1.normalizeSshHostKeyFingerprint)('___________________________________________')).toBe('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
14
+ });
15
+ (0, vitest_1.it)('rejects malformed fingerprints', () => {
16
+ (0, vitest_1.expect)(() => (0, ssh_fingerprint_js_1.normalizeSshHostKeyFingerprint)('not-a-fingerprint')).toThrow(/Invalid SHA-256 host key fingerprint/);
17
+ });
18
+ });
19
+ //# sourceMappingURL=ssh-fingerprint.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssh-fingerprint.test.js","sourceRoot":"","sources":["../../src/__tests__/ssh-fingerprint.test.ts"],"names":[],"mappings":";;AAAA,mCAA8C;AAC9C,8DAAuE;AAEvE,IAAA,iBAAQ,EAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,IAAA,WAAE,EAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,IAAA,eAAM,EACJ,IAAA,mDAA8B,EAC5B,kEAAkE,CACnE,CACF,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,IAAA,eAAM,EACJ,IAAA,mDAA8B,EAAC,oDAAoD,CAAC,CACrF,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,IAAA,eAAM,EACJ,IAAA,mDAA8B,EAAC,6CAA6C,CAAC,CAC9E,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,IAAA,eAAM,EAAC,GAAG,EAAE,CAAC,IAAA,mDAA8B,EAAC,mBAAmB,CAAC,CAAC,CAAC,OAAO,CACvE,sCAAsC,CACvC,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=vpn-route.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vpn-route.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/vpn-route.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const policy_js_1 = require("../policy.js");
5
+ const UUID_A = '11111111-1111-4111-8111-111111111111';
6
+ const UUID_B = '22222222-2222-4222-8222-222222222222';
7
+ const UUID_C = '33333333-3333-4333-8333-333333333333';
8
+ (0, vitest_1.describe)('resolveVpnRoute', () => {
9
+ (0, vitest_1.it)('returns undefined when host or routes are missing/empty', () => {
10
+ (0, vitest_1.expect)((0, policy_js_1.resolveVpnRoute)(undefined, undefined)).toBeUndefined();
11
+ (0, vitest_1.expect)((0, policy_js_1.resolveVpnRoute)('example.com', undefined)).toBeUndefined();
12
+ (0, vitest_1.expect)((0, policy_js_1.resolveVpnRoute)('example.com', [])).toBeUndefined();
13
+ (0, vitest_1.expect)((0, policy_js_1.resolveVpnRoute)('', [{ domainPattern: 'example.com', vpnCredentialId: UUID_A }])).toBeUndefined();
14
+ });
15
+ (0, vitest_1.it)('matches exact hostname case-insensitively', () => {
16
+ const routes = [
17
+ { domainPattern: 'Internal.Corp.Example', vpnCredentialId: UUID_A },
18
+ ];
19
+ (0, vitest_1.expect)((0, policy_js_1.resolveVpnRoute)('internal.corp.example', routes)).toBe(UUID_A);
20
+ (0, vitest_1.expect)((0, policy_js_1.resolveVpnRoute)('INTERNAL.CORP.EXAMPLE', routes)).toBe(UUID_A);
21
+ // Trailing dot in FQDN form is canonicalized away.
22
+ (0, vitest_1.expect)((0, policy_js_1.resolveVpnRoute)('internal.corp.example.', routes)).toBe(UUID_A);
23
+ // Unrelated host does not match.
24
+ (0, vitest_1.expect)((0, policy_js_1.resolveVpnRoute)('other.example', routes)).toBeUndefined();
25
+ });
26
+ (0, vitest_1.it)('wildcard "*.corp.example" matches subdomains but not the bare suffix', () => {
27
+ const routes = [
28
+ { domainPattern: '*.corp.example', vpnCredentialId: UUID_A },
29
+ ];
30
+ (0, vitest_1.expect)((0, policy_js_1.resolveVpnRoute)('www.corp.example', routes)).toBe(UUID_A);
31
+ (0, vitest_1.expect)((0, policy_js_1.resolveVpnRoute)('a.b.corp.example', routes)).toBe(UUID_A);
32
+ // Bare suffix must NOT match — users who want both add a second exact entry.
33
+ (0, vitest_1.expect)((0, policy_js_1.resolveVpnRoute)('corp.example', routes)).toBeUndefined();
34
+ // Different tail.
35
+ (0, vitest_1.expect)((0, policy_js_1.resolveVpnRoute)('www.corp.other', routes)).toBeUndefined();
36
+ });
37
+ (0, vitest_1.it)('first match wins when multiple routes could apply', () => {
38
+ const routes = [
39
+ { domainPattern: 'db.corp.example', vpnCredentialId: UUID_A },
40
+ { domainPattern: '*.corp.example', vpnCredentialId: UUID_B },
41
+ { domainPattern: 'corp.example', vpnCredentialId: UUID_C },
42
+ ];
43
+ (0, vitest_1.expect)((0, policy_js_1.resolveVpnRoute)('db.corp.example', routes)).toBe(UUID_A); // exact match wins over wildcard
44
+ (0, vitest_1.expect)((0, policy_js_1.resolveVpnRoute)('web.corp.example', routes)).toBe(UUID_B); // wildcard hits here
45
+ (0, vitest_1.expect)((0, policy_js_1.resolveVpnRoute)('corp.example', routes)).toBe(UUID_C); // bare suffix exact
46
+ });
47
+ (0, vitest_1.it)('silently skips malformed pattern entries instead of throwing', () => {
48
+ // Zod rejects these at save time; this is a belt-and-suspenders guard.
49
+ const routes = [
50
+ { domainPattern: '', vpnCredentialId: UUID_A },
51
+ { domainPattern: ' ', vpnCredentialId: UUID_A },
52
+ { domainPattern: '*.', vpnCredentialId: UUID_A },
53
+ { domainPattern: 'good.example', vpnCredentialId: UUID_B },
54
+ ];
55
+ (0, vitest_1.expect)((0, policy_js_1.resolveVpnRoute)('good.example', routes)).toBe(UUID_B);
56
+ // And the malformed entries don't accidentally match:
57
+ (0, vitest_1.expect)((0, policy_js_1.resolveVpnRoute)('anything.com', routes)).toBeUndefined();
58
+ });
59
+ });
60
+ (0, vitest_1.describe)('hostnameFromUrl', () => {
61
+ (0, vitest_1.it)('extracts the lowercased hostname from http(s) URLs', () => {
62
+ (0, vitest_1.expect)((0, policy_js_1.hostnameFromUrl)('https://Api.Example.COM/path?q=1')).toBe('api.example.com');
63
+ (0, vitest_1.expect)((0, policy_js_1.hostnameFromUrl)('http://127.0.0.1:8080/x')).toBe('127.0.0.1');
64
+ });
65
+ (0, vitest_1.it)('returns undefined for non-URL inputs', () => {
66
+ (0, vitest_1.expect)((0, policy_js_1.hostnameFromUrl)(undefined)).toBeUndefined();
67
+ (0, vitest_1.expect)((0, policy_js_1.hostnameFromUrl)(null)).toBeUndefined();
68
+ (0, vitest_1.expect)((0, policy_js_1.hostnameFromUrl)('')).toBeUndefined();
69
+ (0, vitest_1.expect)((0, policy_js_1.hostnameFromUrl)('not a url')).toBeUndefined();
70
+ });
71
+ });
72
+ //# sourceMappingURL=vpn-route.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vpn-route.test.js","sourceRoot":"","sources":["../../src/__tests__/vpn-route.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=wireguard.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wireguard.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/wireguard.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const wireguard_js_1 = require("../wireguard.js");
5
+ const validConfig = `
6
+ [Interface]
7
+ PrivateKey = yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=
8
+ Address = 10.0.0.5/32
9
+ DNS = 10.0.0.1
10
+ MTU = 1420
11
+
12
+ [Peer]
13
+ PublicKey = xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg=
14
+ PresharedKey = FpCyhws9cxwWoV4xELtfJvjJN+zQVRPISllRWgeopVE=
15
+ Endpoint = vpn.example.com:51820
16
+ AllowedIPs = 10.0.0.0/24, 192.168.1.0/24
17
+ PersistentKeepalive = 25
18
+ `;
19
+ (0, vitest_1.describe)('parseWireGuardConfig', () => {
20
+ (0, vitest_1.it)('parses a complete valid config', () => {
21
+ const cfg = (0, wireguard_js_1.parseWireGuardConfig)(validConfig);
22
+ (0, vitest_1.expect)(cfg.privateKey).toBe('yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=');
23
+ (0, vitest_1.expect)(cfg.address).toBe('10.0.0.5/32');
24
+ (0, vitest_1.expect)(cfg.mtu).toBe(1420);
25
+ (0, vitest_1.expect)(cfg.dns).toEqual(['10.0.0.1']);
26
+ (0, vitest_1.expect)(cfg.peer.publicKey).toBe('xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg=');
27
+ (0, vitest_1.expect)(cfg.peer.endpoint).toBe('vpn.example.com:51820');
28
+ (0, vitest_1.expect)(cfg.peer.allowedIPs).toEqual(['10.0.0.0/24', '192.168.1.0/24']);
29
+ (0, vitest_1.expect)(cfg.peer.persistentKeepalive).toBe(25);
30
+ });
31
+ (0, vitest_1.it)('accepts minimal config (no DNS, MTU, PSK, keepalive)', () => {
32
+ const minimal = `
33
+ [Interface]
34
+ PrivateKey = yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=
35
+ Address = 10.0.0.5/32
36
+
37
+ [Peer]
38
+ PublicKey = xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg=
39
+ Endpoint = vpn.example.com:51820
40
+ AllowedIPs = 10.0.0.0/24
41
+ `;
42
+ (0, vitest_1.expect)(() => (0, wireguard_js_1.parseWireGuardConfig)(minimal)).not.toThrow();
43
+ });
44
+ (0, vitest_1.it)('rejects config missing [Interface]', () => {
45
+ (0, vitest_1.expect)(() => (0, wireguard_js_1.parseWireGuardConfig)('[Peer]\nPublicKey=x\nEndpoint=e:1\nAllowedIPs=0.0.0.0/0')).toThrow(/Interface/i);
46
+ });
47
+ (0, vitest_1.it)('rejects config with multiple [Peer] blocks', () => {
48
+ const dual = validConfig + '\n[Peer]\nPublicKey = x\nEndpoint = y:1\nAllowedIPs = 0.0.0.0/0\n';
49
+ (0, vitest_1.expect)(() => (0, wireguard_js_1.parseWireGuardConfig)(dual)).toThrow(/exactly one \[Peer\]/i);
50
+ });
51
+ (0, vitest_1.it)('rejects malformed base64 key', () => {
52
+ const bad = validConfig.replace('yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=', 'not-base64!');
53
+ (0, vitest_1.expect)(() => (0, wireguard_js_1.parseWireGuardConfig)(bad)).toThrow(/private key/i);
54
+ });
55
+ (0, vitest_1.it)('rejects invalid endpoint format', () => {
56
+ const bad = validConfig.replace('vpn.example.com:51820', 'no-port-here');
57
+ (0, vitest_1.expect)(() => (0, wireguard_js_1.parseWireGuardConfig)(bad)).toThrow(/endpoint/i);
58
+ });
59
+ (0, vitest_1.it)('Zod schema rejects extra fields', () => {
60
+ const withExtra = {
61
+ privateKey: 'yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=',
62
+ address: '10.0.0.5/32',
63
+ extraField: 'nope',
64
+ peer: {
65
+ publicKey: 'xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg=',
66
+ endpoint: 'vpn.example.com:51820',
67
+ allowedIPs: ['10.0.0.0/24'],
68
+ },
69
+ };
70
+ (0, vitest_1.expect)(() => wireguard_js_1.WireGuardConfigSchema.parse(withExtra)).toThrow();
71
+ });
72
+ (0, vitest_1.it)('rejects endpoint with port > 65535', () => {
73
+ const bad = validConfig.replace('vpn.example.com:51820', 'vpn.example.com:99999');
74
+ (0, vitest_1.expect)(() => (0, wireguard_js_1.parseWireGuardConfig)(bad)).toThrow(/port/i);
75
+ });
76
+ (0, vitest_1.it)('rejects CIDR with octet > 255', () => {
77
+ const bad = validConfig.replace('10.0.0.5/32', '999.0.0.0/32');
78
+ (0, vitest_1.expect)(() => (0, wireguard_js_1.parseWireGuardConfig)(bad)).toThrow(/ipv4 cidr/i);
79
+ });
80
+ (0, vitest_1.it)('rejects CIDR with prefix > 32', () => {
81
+ const bad = validConfig.replace('10.0.0.0/24', '10.0.0.0/99');
82
+ (0, vitest_1.expect)(() => (0, wireguard_js_1.parseWireGuardConfig)(bad)).toThrow(/ipv4 cidr/i);
83
+ });
84
+ (0, vitest_1.it)('rejects duplicate [Interface] section', () => {
85
+ const dup = validConfig + '\n[Interface]\nPrivateKey = yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=\nAddress = 10.0.0.6/32\n';
86
+ (0, vitest_1.expect)(() => (0, wireguard_js_1.parseWireGuardConfig)(dup)).toThrow(/duplicate \[interface\]/i);
87
+ });
88
+ (0, vitest_1.it)('rejects duplicate key within a section', () => {
89
+ const dup = validConfig.replace('Address = 10.0.0.5/32', 'Address = 10.0.0.5/32\nAddress = 10.0.0.6/32');
90
+ (0, vitest_1.expect)(() => (0, wireguard_js_1.parseWireGuardConfig)(dup)).toThrow(/duplicate key: address/i);
91
+ });
92
+ (0, vitest_1.it)('rejects AllowedIPs routing to cloud-metadata or loopback (SSRF-exemption pivot)', () => {
93
+ const meta = validConfig.replace('10.0.0.0/24, 192.168.1.0/24', '169.254.169.254/32');
94
+ (0, vitest_1.expect)(() => (0, wireguard_js_1.parseWireGuardConfig)(meta)).toThrow();
95
+ const loop = validConfig.replace('10.0.0.0/24, 192.168.1.0/24', '127.0.0.0/8');
96
+ (0, vitest_1.expect)(() => (0, wireguard_js_1.parseWireGuardConfig)(loop)).toThrow();
97
+ });
98
+ (0, vitest_1.it)('still allows AllowedIPs in legitimate private (RFC1918) ranges', () => {
99
+ const priv = validConfig.replace('10.0.0.0/24, 192.168.1.0/24', '172.16.0.0/12');
100
+ (0, vitest_1.expect)(() => (0, wireguard_js_1.parseWireGuardConfig)(priv)).not.toThrow();
101
+ });
102
+ (0, vitest_1.it)('rejects a DNS server pointing at the metadata address', () => {
103
+ const badDns = validConfig.replace('DNS = 10.0.0.1', 'DNS = 169.254.169.254');
104
+ (0, vitest_1.expect)(() => (0, wireguard_js_1.parseWireGuardConfig)(badDns)).toThrow();
105
+ });
106
+ });
107
+ (0, vitest_1.describe)('VPN_LIMITS_BY_PLAN', () => {
108
+ (0, vitest_1.it)('enforces free=0, pro=3, team=10', () => {
109
+ (0, vitest_1.expect)(wireguard_js_1.VPN_LIMITS_BY_PLAN.free).toBe(0);
110
+ (0, vitest_1.expect)(wireguard_js_1.VPN_LIMITS_BY_PLAN.pro).toBe(3);
111
+ (0, vitest_1.expect)(wireguard_js_1.VPN_LIMITS_BY_PLAN.team).toBe(10);
112
+ });
113
+ });
114
+ //# sourceMappingURL=wireguard.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wireguard.test.js","sourceRoot":"","sources":["../../src/__tests__/wireguard.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Stripe subscription-status helpers shared by the billing routes.
3
+ *
4
+ * Keep these rules small and explicit: checkout/self-heal and webhook
5
+ * downgrade paths must make the same decision about whether an existing
6
+ * subscription can still be recovered or should be treated as terminal.
7
+ */
8
+ export declare function isEntitledStripeSubscriptionStatus(status: string): boolean;
9
+ export declare function isRecoverableStripeSubscriptionStatus(status: string): boolean;
10
+ export declare function isTerminalStripeSubscriptionStatus(status: string): boolean;
11
+ export declare function canStartNewCheckoutForStripeSubscriptionStatus(status: string): boolean;
12
+ //# sourceMappingURL=billing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"billing.d.ts","sourceRoot":"","sources":["../src/billing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAoBH,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE1E;AAED,wBAAgB,qCAAqC,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE7E;AAED,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE1E;AAED,wBAAgB,8CAA8C,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEtF"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ /**
3
+ * Stripe subscription-status helpers shared by the billing routes.
4
+ *
5
+ * Keep these rules small and explicit: checkout/self-heal and webhook
6
+ * downgrade paths must make the same decision about whether an existing
7
+ * subscription can still be recovered or should be treated as terminal.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.isEntitledStripeSubscriptionStatus = isEntitledStripeSubscriptionStatus;
11
+ exports.isRecoverableStripeSubscriptionStatus = isRecoverableStripeSubscriptionStatus;
12
+ exports.isTerminalStripeSubscriptionStatus = isTerminalStripeSubscriptionStatus;
13
+ exports.canStartNewCheckoutForStripeSubscriptionStatus = canStartNewCheckoutForStripeSubscriptionStatus;
14
+ const ENTITLED_STATUSES = new Set([
15
+ 'active',
16
+ 'trialing',
17
+ ]);
18
+ const RECOVERABLE_STATUSES = new Set([
19
+ ...ENTITLED_STATUSES,
20
+ 'past_due',
21
+ 'unpaid',
22
+ 'incomplete',
23
+ 'paused',
24
+ ]);
25
+ const TERMINAL_STATUSES = new Set([
26
+ 'canceled',
27
+ 'incomplete_expired',
28
+ ]);
29
+ function isEntitledStripeSubscriptionStatus(status) {
30
+ return ENTITLED_STATUSES.has(status);
31
+ }
32
+ function isRecoverableStripeSubscriptionStatus(status) {
33
+ return RECOVERABLE_STATUSES.has(status);
34
+ }
35
+ function isTerminalStripeSubscriptionStatus(status) {
36
+ return TERMINAL_STATUSES.has(status);
37
+ }
38
+ function canStartNewCheckoutForStripeSubscriptionStatus(status) {
39
+ return isTerminalStripeSubscriptionStatus(status);
40
+ }
41
+ //# sourceMappingURL=billing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"billing.js","sourceRoot":"","sources":["../src/billing.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAoBH,gFAEC;AAED,sFAEC;AAED,gFAEC;AAED,wGAEC;AAhCD,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,QAAQ;IACR,UAAU;CACX,CAAC,CAAC;AAEH,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,GAAG,iBAAiB;IACpB,UAAU;IACV,QAAQ;IACR,YAAY;IACZ,QAAQ;CACT,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,UAAU;IACV,oBAAoB;CACrB,CAAC,CAAC;AAEH,SAAgB,kCAAkC,CAAC,MAAc;IAC/D,OAAO,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC;AAED,SAAgB,qCAAqC,CAAC,MAAc;IAClE,OAAO,oBAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC1C,CAAC;AAED,SAAgB,kCAAkC,CAAC,MAAc;IAC/D,OAAO,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC;AAED,SAAgB,8CAA8C,CAAC,MAAc;IAC3E,OAAO,kCAAkC,CAAC,MAAM,CAAC,CAAC;AACpD,CAAC"}
package/dist/crypto.d.ts CHANGED
@@ -1,9 +1,50 @@
1
1
  export declare function generateKey(): Uint8Array;
2
+ /**
3
+ * Low-level symmetric encryption using a provided key.
4
+ * Callers that need envelope encryption (per-data DEK) should use
5
+ * envelopeEncrypt() instead.
6
+ */
2
7
  export declare function encrypt(data: string, key: Uint8Array): string;
8
+ /**
9
+ * Low-level symmetric decryption. Handles both envelope-encrypted data
10
+ * (prefixed with "env1:") and legacy direct-key encrypted data.
11
+ *
12
+ * For envelope data: unwraps the per-data DEK using the master key,
13
+ * then decrypts the payload with the DEK.
14
+ *
15
+ * For legacy data: decrypts directly with the provided key, falling
16
+ * back to MASTER_KEY_PREVIOUS for key rotation support.
17
+ */
3
18
  export declare function decrypt(encryptedData: string, key: Uint8Array): string;
19
+ /**
20
+ * Encrypt arbitrary data using a per-data DEK (envelope encryption).
21
+ * Generates a fresh 256-bit DEK, encrypts the data with it, then wraps
22
+ * the DEK with the provided master key. Returns a single string in the
23
+ * format "env1:<wrappedDEK>:<encryptedPayload>" so it fits in a single
24
+ * database column and is backward-compatible with decrypt().
25
+ *
26
+ * Use this instead of encrypt() for all data at rest. Each encrypted
27
+ * value gets its own DEK, so compromising one ciphertext does not
28
+ * expose other data -- the attacker still needs the master key to
29
+ * unwrap any individual DEK.
30
+ */
31
+ export declare function envelopeEncrypt(data: string, masterKey: Uint8Array): string;
32
+ /**
33
+ * Decrypt data produced by envelopeEncrypt(). Expects the "env1:" prefixed
34
+ * format. For general use, call decrypt() which auto-detects the format.
35
+ */
36
+ export declare function envelopeDecrypt(encryptedData: string, masterKey: Uint8Array): string;
4
37
  export declare function encryptDEK(dek: Uint8Array, masterKey: Uint8Array): string;
5
38
  export declare function decryptDEK(encryptedDEK: string, masterKey: Uint8Array): Uint8Array;
6
39
  export declare function getMasterKey(): Uint8Array;
40
+ /** Return every retired key in rotation order (most-recent first). Used by
41
+ * the credential-decryption fallback path to try each until one succeeds.
42
+ */
43
+ export declare function getPreviousMasterKeys(): Uint8Array[];
44
+ /** Back-compat: first previous key only. Prefer `getPreviousMasterKeys()`. */
45
+ export declare function getPreviousMasterKey(): Uint8Array | null;
46
+ /** Zero and release cached master keys. Call on graceful shutdown. */
47
+ export declare function clearCachedKeys(): void;
7
48
  export declare function generateMasterKey(): string;
8
49
  export declare function encryptCredential(payload: Record<string, unknown>, masterKey: Uint8Array): {
9
50
  encryptedDEK: string;
@@ -1 +1 @@
1
- {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAGA,wBAAgB,WAAW,IAAI,UAAU,CAExC;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,MAAM,CAU7D;AAED,wBAAgB,OAAO,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,MAAM,CAWtE;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,GAAG,MAAM,CAEzE;AAED,wBAAgB,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,GAAG,UAAU,CAGlF;AAMD,wBAAgB,YAAY,IAAI,UAAU,CAMzC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,SAAS,EAAE,UAAU,GACpB;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,CAUpD;AAED,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,MAAM,EACxB,SAAS,EAAE,UAAU,GACpB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUzB"}
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAYA,wBAAgB,WAAW,IAAI,UAAU,CAExC;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,MAAM,CAU7D;AAED;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,MAAM,CAwBtE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,GAAG,MAAM,CAU3E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,GAAG,MAAM,CAKpF;AAkDD,wBAAgB,UAAU,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,GAAG,MAAM,CAEzE;AAED,wBAAgB,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,GAAG,UAAU,CAGlF;AA0BD,wBAAgB,YAAY,IAAI,UAAU,CAMzC;AAuCD;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,UAAU,EAAE,CAOpD;AAED,8EAA8E;AAC9E,wBAAgB,oBAAoB,IAAI,UAAU,GAAG,IAAI,CAExD;AAED,sEAAsE;AACtE,wBAAgB,eAAe,IAAI,IAAI,CAUtC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,SAAS,EAAE,UAAU,GACpB;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,CAUpD;AAED,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,MAAM,EACxB,SAAS,EAAE,UAAU,GACpB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUzB"}