@private.me/xbind 3.0.1 → 3.0.2

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 (210) hide show
  1. package/README.md +55 -14
  2. package/dist-standalone/_deps/mldsa-wasm/dist/mldsa.js +1920 -1
  3. package/dist-standalone/_deps/shared/cjs/errors.js +729 -1
  4. package/dist-standalone/_deps/shared/cjs/index.js +463 -1
  5. package/dist-standalone/_deps/shared/cjs/types.js +315 -1
  6. package/dist-standalone/_deps/shared/errors.js +244 -1
  7. package/dist-standalone/_deps/shared/index.js +72 -1
  8. package/dist-standalone/_deps/shared/types.js +86 -1
  9. package/dist-standalone/_deps/ux-helpers/cjs/errors.js +1 -1
  10. package/dist-standalone/_deps/ux-helpers/cjs/index.js +1 -1
  11. package/dist-standalone/_deps/ux-helpers/cjs/pagination.js +1 -1
  12. package/dist-standalone/_deps/ux-helpers/cjs/progress.js +1 -1
  13. package/dist-standalone/_deps/ux-helpers/cjs/search.js +1 -1
  14. package/dist-standalone/_deps/ux-helpers/cjs/types.js +1 -1
  15. package/dist-standalone/_deps/ux-helpers/errors.js +1 -1
  16. package/dist-standalone/_deps/ux-helpers/index.js +1 -1
  17. package/dist-standalone/_deps/ux-helpers/pagination.js +1 -1
  18. package/dist-standalone/_deps/ux-helpers/progress.js +1 -1
  19. package/dist-standalone/_deps/ux-helpers/search.js +1 -1
  20. package/dist-standalone/_deps/xchange/auto-accept.js +1 -1
  21. package/dist-standalone/_deps/xchange/cjs/auto-accept.js +1 -1
  22. package/dist-standalone/_deps/xchange/cjs/errors.js +1 -1
  23. package/dist-standalone/_deps/xchange/cjs/index.js +1 -1
  24. package/dist-standalone/_deps/xchange/cjs/invite-client.js +1 -1
  25. package/dist-standalone/_deps/xchange/cjs/lazy-init.js +1 -1
  26. package/dist-standalone/_deps/xchange/cjs/trust-integration.js +1 -1
  27. package/dist-standalone/_deps/xchange/cjs/xchange.js +1 -1
  28. package/dist-standalone/_deps/xchange/errors.js +1 -1
  29. package/dist-standalone/_deps/xchange/index.js +1 -1
  30. package/dist-standalone/_deps/xchange/invite-client.js +1 -1
  31. package/dist-standalone/_deps/xchange/lazy-init.js +1 -1
  32. package/dist-standalone/_deps/xchange/trust-integration.js +1 -1
  33. package/dist-standalone/_deps/xchange/xchange.js +1 -1
  34. package/dist-standalone/_deps/xregistry/cjs/discovery.js +1 -1
  35. package/dist-standalone/_deps/xregistry/cjs/errors.js +1 -1
  36. package/dist-standalone/_deps/xregistry/cjs/index.js +1 -1
  37. package/dist-standalone/_deps/xregistry/cjs/registry.js +1 -1
  38. package/dist-standalone/_deps/xregistry/cjs/schema.js +1 -1
  39. package/dist-standalone/_deps/xregistry/cjs/types.js +1 -1
  40. package/dist-standalone/_deps/xregistry/discovery.js +1 -1
  41. package/dist-standalone/_deps/xregistry/errors.js +1 -1
  42. package/dist-standalone/_deps/xregistry/index.js +1 -1
  43. package/dist-standalone/_deps/xregistry/registry.js +1 -1
  44. package/dist-standalone/_deps/xregistry/schema.js +1 -1
  45. package/dist-standalone/_deps/xregistry/types.js +1 -1
  46. package/dist-standalone/agent-call.js +659 -1
  47. package/dist-standalone/agent-sdk.js +328 -1
  48. package/dist-standalone/agent.js +1800 -1
  49. package/dist-standalone/approval.js +193 -1
  50. package/dist-standalone/async-iterators.js +382 -1
  51. package/dist-standalone/auth.js +219 -1
  52. package/dist-standalone/auto-accept.js +229 -1
  53. package/dist-standalone/backup-config.js +201 -1
  54. package/dist-standalone/backup.js +326 -1
  55. package/dist-standalone/batch-operations.js +388 -1
  56. package/dist-standalone/cancellation.js +477 -1
  57. package/dist-standalone/checkpoint.js +186 -1
  58. package/dist-standalone/circuit-breaker.js +468 -1
  59. package/dist-standalone/cjs/agent-call.js +701 -1
  60. package/dist-standalone/cjs/agent-sdk.js +332 -1
  61. package/dist-standalone/cjs/agent.js +1837 -1
  62. package/dist-standalone/cjs/approval.js +199 -1
  63. package/dist-standalone/cjs/async-iterators.js +392 -1
  64. package/dist-standalone/cjs/auth.js +225 -1
  65. package/dist-standalone/cjs/auto-accept.js +233 -1
  66. package/dist-standalone/cjs/backup-config.js +207 -1
  67. package/dist-standalone/cjs/backup.js +330 -1
  68. package/dist-standalone/cjs/batch-operations.js +397 -1
  69. package/dist-standalone/cjs/cancellation.js +490 -1
  70. package/dist-standalone/cjs/checkpoint.js +193 -1
  71. package/dist-standalone/cjs/circuit-breaker.js +476 -1
  72. package/dist-standalone/cjs/cli/init.js +492 -1
  73. package/dist-standalone/cjs/config-validation.js +522 -1
  74. package/dist-standalone/cjs/connect.js +312 -1
  75. package/dist-standalone/cjs/connection-pool.js +506 -1
  76. package/dist-standalone/cjs/correlation-id.js +339 -1
  77. package/dist-standalone/cjs/crypto-utils.js +176 -1
  78. package/dist-standalone/cjs/debug-mode.js +534 -1
  79. package/dist-standalone/cjs/did-document.js +101 -1
  80. package/dist-standalone/cjs/did-privateme.js +130 -1
  81. package/dist-standalone/cjs/did-web.js +201 -1
  82. package/dist-standalone/cjs/discovery.js +462 -1
  83. package/dist-standalone/cjs/dual-mode.js +251 -1
  84. package/dist-standalone/cjs/email-templates.js +313 -1
  85. package/dist-standalone/cjs/email-transport.js +239 -1
  86. package/dist-standalone/cjs/envelope.js +538 -1
  87. package/dist-standalone/cjs/errors.js +913 -1
  88. package/dist-standalone/cjs/event-emitter.js +461 -1
  89. package/dist-standalone/cjs/gateway-state.js +55 -1
  90. package/dist-standalone/cjs/gateway-transport.js +120 -1
  91. package/dist-standalone/cjs/graceful-degradation.js +403 -1
  92. package/dist-standalone/cjs/guardrails.js +223 -1
  93. package/dist-standalone/cjs/health-check.js +336 -1
  94. package/dist-standalone/cjs/http-compat.js +272 -1
  95. package/dist-standalone/cjs/http-status-map.js +571 -1
  96. package/dist-standalone/cjs/identity.js +645 -1
  97. package/dist-standalone/cjs/index.js +406 -1
  98. package/dist-standalone/cjs/invitation.js +421 -1
  99. package/dist-standalone/cjs/invite.js +328 -1
  100. package/dist-standalone/cjs/key-agreement.js +335 -1
  101. package/dist-standalone/cjs/lazy-init.js +300 -1
  102. package/dist-standalone/cjs/logger.js +291 -1
  103. package/dist-standalone/cjs/mdns-discovery.js +202 -1
  104. package/dist-standalone/cjs/nonce-store.js +80 -1
  105. package/dist-standalone/cjs/pairing-manager.js +223 -1
  106. package/dist-standalone/cjs/plugin-system.js +264 -1
  107. package/dist-standalone/cjs/plugins/logging.js +168 -1
  108. package/dist-standalone/cjs/plugins/metrics.js +181 -1
  109. package/dist-standalone/cjs/plugins/validation.js +302 -1
  110. package/dist-standalone/cjs/policy.js +320 -1
  111. package/dist-standalone/cjs/progress-callbacks.js +583 -1
  112. package/dist-standalone/cjs/redis-nonce-store.js +76 -1
  113. package/dist-standalone/cjs/registry-middleware.js +50 -1
  114. package/dist-standalone/cjs/retry-strategies.js +544 -1
  115. package/dist-standalone/cjs/retry-transport.js +102 -1
  116. package/dist-standalone/cjs/runtime/browser.js +533 -1
  117. package/dist-standalone/cjs/runtime/edge.js +526 -1
  118. package/dist-standalone/cjs/runtime/react-native.js +394 -1
  119. package/dist-standalone/cjs/security-policy.js +245 -1
  120. package/dist-standalone/cjs/serialization.js +1040 -1
  121. package/dist-standalone/cjs/split-channel.js +225 -1
  122. package/dist-standalone/cjs/subscription-proof.js +230 -1
  123. package/dist-standalone/cjs/succession.js +148 -1
  124. package/dist-standalone/cjs/timeouts.js +412 -1
  125. package/dist-standalone/cjs/trace-context.js +424 -1
  126. package/dist-standalone/cjs/trace-spans.js +495 -1
  127. package/dist-standalone/cjs/transport.js +63 -1
  128. package/dist-standalone/cjs/trust-registry.js +991 -1
  129. package/dist-standalone/cjs/types/error-response.js +56 -1
  130. package/dist-standalone/cjs/vault-auth.js +178 -1
  131. package/dist-standalone/cjs/vault-store-loader.js +194 -1
  132. package/dist-standalone/cjs/verify.js +25 -1
  133. package/dist-standalone/cjs/version-info.js +543 -1
  134. package/dist-standalone/cjs/xfetch.js +340 -1
  135. package/dist-standalone/cli/init.js +455 -1
  136. package/dist-standalone/cli/setup.js +514 -1
  137. package/dist-standalone/cli/types.js +27 -1
  138. package/dist-standalone/cli/xbind.js +148 -1
  139. package/dist-standalone/config-validation.js +513 -1
  140. package/dist-standalone/connect.js +274 -1
  141. package/dist-standalone/connection-pool.js +500 -1
  142. package/dist-standalone/correlation-id.js +326 -1
  143. package/dist-standalone/crypto-utils.js +157 -1
  144. package/dist-standalone/debug-mode.js +510 -1
  145. package/dist-standalone/did-document.js +96 -1
  146. package/dist-standalone/did-privateme.js +121 -1
  147. package/dist-standalone/did-web.js +196 -1
  148. package/dist-standalone/discovery.js +458 -1
  149. package/dist-standalone/dual-mode.js +247 -1
  150. package/dist-standalone/email-templates.js +309 -1
  151. package/dist-standalone/email-transport.js +232 -1
  152. package/dist-standalone/envelope.js +525 -1
  153. package/dist-standalone/errors.js +896 -1
  154. package/dist-standalone/event-emitter.js +456 -1
  155. package/dist-standalone/gateway-state.js +51 -1
  156. package/dist-standalone/gateway-transport.js +116 -1
  157. package/dist-standalone/graceful-degradation.js +396 -1
  158. package/dist-standalone/guardrails.js +216 -1
  159. package/dist-standalone/health-check.js +332 -1
  160. package/dist-standalone/http-compat.js +267 -1
  161. package/dist-standalone/http-status-map.js +561 -1
  162. package/dist-standalone/identity.js +619 -1
  163. package/dist-standalone/index.js +78 -1
  164. package/dist-standalone/invitation.js +415 -1
  165. package/dist-standalone/invite.js +324 -1
  166. package/dist-standalone/key-agreement.js +325 -1
  167. package/dist-standalone/lazy-init.js +295 -1
  168. package/dist-standalone/logger.js +285 -1
  169. package/dist-standalone/mdns-discovery.js +195 -1
  170. package/dist-standalone/nonce-store.js +76 -1
  171. package/dist-standalone/pairing-manager.js +219 -1
  172. package/dist-standalone/plugin-system.js +257 -1
  173. package/dist-standalone/plugins/logging.js +163 -1
  174. package/dist-standalone/plugins/metrics.js +176 -1
  175. package/dist-standalone/plugins/validation.js +297 -1
  176. package/dist-standalone/policy.js +315 -1
  177. package/dist-standalone/progress-callbacks.js +576 -1
  178. package/dist-standalone/redis-nonce-store.js +72 -1
  179. package/dist-standalone/registry-middleware.js +47 -1
  180. package/dist-standalone/retry-strategies.js +534 -1
  181. package/dist-standalone/retry-transport.js +98 -1
  182. package/dist-standalone/runtime/browser.js +516 -1
  183. package/dist-standalone/runtime/edge.js +511 -1
  184. package/dist-standalone/runtime/react-native.js +383 -1
  185. package/dist-standalone/security-policy.js +239 -1
  186. package/dist-standalone/serialization.js +1031 -1
  187. package/dist-standalone/split-channel.js +219 -1
  188. package/dist-standalone/subscription-proof.js +224 -1
  189. package/dist-standalone/succession.js +142 -1
  190. package/dist-standalone/timeouts.js +398 -1
  191. package/dist-standalone/trace-context.js +414 -1
  192. package/dist-standalone/trace-spans.js +488 -1
  193. package/dist-standalone/transport.js +59 -1
  194. package/dist-standalone/trust-registry.js +950 -1
  195. package/dist-standalone/types/error-response.js +52 -1
  196. package/dist-standalone/vault-auth.js +174 -1
  197. package/dist-standalone/vault-store-loader.js +187 -1
  198. package/dist-standalone/verify.js +16 -1
  199. package/dist-standalone/version-info.js +530 -1
  200. package/dist-standalone/xfetch.js +335 -1
  201. package/package.json +4 -13
  202. package/share1.dat +0 -0
  203. package/dist-standalone/_deps/mldsa-wasm/LICENSE +0 -24
  204. package/dist-standalone/_deps/mldsa-wasm/package.json +0 -46
  205. package/dist-standalone/_deps/shared/cjs/package.json +0 -1
  206. package/dist-standalone/_deps/ux-helpers/cjs/package.json +0 -1
  207. package/dist-standalone/_deps/xchange/cjs/package.json +0 -1
  208. package/dist-standalone/_deps/xregistry/cjs/package.json +0 -1
  209. package/dist-standalone/cjs/package.json +0 -3
  210. package/dist-standalone/package.json +0 -10
@@ -1 +1,326 @@
1
- export const CORRELATION_ID_HEADER="X-Correlation-ID";export const CORRELATION_ID_ALIASES=["X-Request-ID","X-Trace-ID","X-Transaction-ID"];const CORRELATION_ID_PATTERN=/^req_\d{13}_[a-f0-9]{8}$/;export function generateCorrelationId(){return`req_${Date.now()}_${generateRandomHex(8)}`}export function validateCorrelationId(r){return"string"==typeof r&&CORRELATION_ID_PATTERN.test(r)}export function parseCorrelationId(r){if(!validateCorrelationId(r))return null;const e=r.split("_");return{prefix:e[0]??"req",timestamp:parseInt(e[1]??"0",10),random:e[2]??""}}export function attachCorrelationId(r,e){const t=e??generateCorrelationId();if(!validateCorrelationId(t))throw new Error(`Invalid correlation ID format: ${t}. Expected format: req_{timestamp}_{random}`);return r instanceof Headers?r.set("X-Correlation-ID",t):r["X-Correlation-ID"]=t,r}export function extractCorrelationId(r){const e=r instanceof Headers?r.get("X-Correlation-ID"):r["X-Correlation-ID"];if(e&&validateCorrelationId(e))return e;for(const e of CORRELATION_ID_ALIASES){const t=r instanceof Headers?r.get(e):r[e];if(t&&validateCorrelationId(t))return t}}export function getOrCreateCorrelationId(r){if(!r)return generateCorrelationId();return extractCorrelationId(r)??generateCorrelationId()}export function createCorrelationIdFromTimestamp(r,e){const t=e??generateRandomHex(8);if(!/^[a-f0-9]{8}$/.test(t))throw new Error(`Invalid random component: ${t}. Expected 8 hex characters`);return`req_${r}_${t}`}export function getCorrelationIdAge(r){const e=parseCorrelationId(r);if(!e)return null;return Date.now()-e.timestamp}export function isCorrelationIdExpired(r,e=3e5){const t=getCorrelationIdAge(r);return null!==t&&t>e}function generateRandomHex(r){const e=Math.ceil(r/2);if("undefined"!=typeof crypto&&crypto.getRandomValues){const t=new Uint8Array(e);return crypto.getRandomValues(t),Array.from(t).map(r=>r.toString(16).padStart(2,"0")).join("").substring(0,r)}try{return require("node:crypto").randomBytes(e).toString("hex").substring(0,r)}catch{throw new Error("Cryptographic random generation unavailable. Install crypto polyfill or use environment with crypto support.")}}export function correlationIdMiddleware(){return(r,e,t)=>{const o=getOrCreateCorrelationId(r.headers);r.correlationId=o,e.setHeader("X-Correlation-ID",o),"function"==typeof t&&t()}}
1
+ /**
2
+ * @module correlation-id
3
+ * Client-side correlation ID utilities for request tracking
4
+ *
5
+ * Correlation IDs enable distributed tracing across xBind agent operations,
6
+ * making it easier to debug issues, track requests across microservices,
7
+ * and correlate logs between client and server.
8
+ *
9
+ * Format: `req_{timestamp}_{random}`
10
+ * Example: `req_1716234567890_a3f5c9d2`
11
+ *
12
+ * Usage:
13
+ * ```typescript
14
+ * import { generateCorrelationId, attachCorrelationId } from '@private.me/xbind';
15
+ *
16
+ * // Generate a new correlation ID
17
+ * const id = generateCorrelationId();
18
+ *
19
+ * // Attach to request headers
20
+ * const headers = attachCorrelationId(new Headers(), id);
21
+ *
22
+ * // Validate format
23
+ * if (validateCorrelationId(id)) {
24
+ * console.log('Valid correlation ID');
25
+ * }
26
+ * ```
27
+ */
28
+ /**
29
+ * Standard header name for correlation ID
30
+ */
31
+ export const CORRELATION_ID_HEADER = 'X-Correlation-ID';
32
+ /**
33
+ * Alternative header names for compatibility
34
+ */
35
+ export const CORRELATION_ID_ALIASES = [
36
+ 'X-Request-ID',
37
+ 'X-Trace-ID',
38
+ 'X-Transaction-ID',
39
+ ];
40
+ /**
41
+ * Regular expression for validating correlation ID format
42
+ */
43
+ const CORRELATION_ID_PATTERN = /^req_\d{13}_[a-f0-9]{8}$/;
44
+ /**
45
+ * Generate a new correlation ID
46
+ *
47
+ * Format: `req_{timestamp}_{random}`
48
+ * - `req`: Static prefix for identification
49
+ * - `timestamp`: Unix timestamp in milliseconds (13 digits)
50
+ * - `random`: 8-character hex string for uniqueness
51
+ *
52
+ * @returns New correlation ID string
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * const id = generateCorrelationId();
57
+ * // => "req_1716234567890_a3f5c9d2"
58
+ * ```
59
+ */
60
+ export function generateCorrelationId() {
61
+ const timestamp = Date.now();
62
+ const random = generateRandomHex(8);
63
+ return `req_${timestamp}_${random}`;
64
+ }
65
+ /**
66
+ * Validate correlation ID format
67
+ *
68
+ * Checks if the provided string matches the expected correlation ID format.
69
+ *
70
+ * @param id - String to validate
71
+ * @returns True if valid, false otherwise
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * validateCorrelationId('req_1716234567890_a3f5c9d2'); // => true
76
+ * validateCorrelationId('invalid'); // => false
77
+ * validateCorrelationId('req_123_abc'); // => false (wrong lengths)
78
+ * ```
79
+ */
80
+ export function validateCorrelationId(id) {
81
+ if (typeof id !== 'string')
82
+ return false;
83
+ return CORRELATION_ID_PATTERN.test(id);
84
+ }
85
+ /**
86
+ * Parse correlation ID into components
87
+ *
88
+ * Extracts the timestamp and random components from a correlation ID.
89
+ *
90
+ * @param id - Correlation ID to parse
91
+ * @returns Parsed components or null if invalid
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * const spec = parseCorrelationId('req_1716234567890_a3f5c9d2');
96
+ * // => { prefix: 'req', timestamp: 1716234567890, random: 'a3f5c9d2' }
97
+ * ```
98
+ */
99
+ export function parseCorrelationId(id) {
100
+ if (!validateCorrelationId(id))
101
+ return null;
102
+ const parts = id.split('_');
103
+ return {
104
+ prefix: parts[0] ?? 'req',
105
+ timestamp: parseInt(parts[1] ?? '0', 10),
106
+ random: parts[2] ?? '',
107
+ };
108
+ }
109
+ /**
110
+ * Attach correlation ID to request headers
111
+ *
112
+ * Adds the correlation ID to the X-Correlation-ID header.
113
+ * If no ID is provided, generates a new one.
114
+ * Compatible with both Headers API and plain objects.
115
+ *
116
+ * @param headers - Headers object or plain object
117
+ * @param id - Correlation ID (generates new if not provided)
118
+ * @returns Updated headers object
119
+ *
120
+ * @example
121
+ * ```typescript
122
+ * // With Headers API
123
+ * const headers = new Headers();
124
+ * attachCorrelationId(headers);
125
+ *
126
+ * // With plain object
127
+ * const headers = { 'Content-Type': 'application/json' };
128
+ * attachCorrelationId(headers, 'req_1716234567890_a3f5c9d2');
129
+ *
130
+ * // With existing correlation ID
131
+ * const id = generateCorrelationId();
132
+ * attachCorrelationId(headers, id);
133
+ * ```
134
+ */
135
+ export function attachCorrelationId(headers, id) {
136
+ const correlationId = id ?? generateCorrelationId();
137
+ if (!validateCorrelationId(correlationId)) {
138
+ throw new Error(`Invalid correlation ID format: ${correlationId}. Expected format: req_{timestamp}_{random}`);
139
+ }
140
+ if (headers instanceof Headers) {
141
+ headers.set(CORRELATION_ID_HEADER, correlationId);
142
+ }
143
+ else {
144
+ headers[CORRELATION_ID_HEADER] = correlationId;
145
+ }
146
+ return headers;
147
+ }
148
+ /**
149
+ * Extract correlation ID from request headers
150
+ *
151
+ * Checks the standard header and common aliases.
152
+ *
153
+ * @param headers - Headers object or plain object
154
+ * @returns Correlation ID if found, undefined otherwise
155
+ *
156
+ * @example
157
+ * ```typescript
158
+ * const headers = new Headers({
159
+ * 'X-Correlation-ID': 'req_1716234567890_a3f5c9d2'
160
+ * });
161
+ * const id = extractCorrelationId(headers);
162
+ * // => 'req_1716234567890_a3f5c9d2'
163
+ * ```
164
+ */
165
+ export function extractCorrelationId(headers) {
166
+ // Check primary header
167
+ const primary = headers instanceof Headers
168
+ ? headers.get(CORRELATION_ID_HEADER)
169
+ : headers[CORRELATION_ID_HEADER];
170
+ if (primary && validateCorrelationId(primary)) {
171
+ return primary;
172
+ }
173
+ // Check aliases
174
+ for (const alias of CORRELATION_ID_ALIASES) {
175
+ const value = headers instanceof Headers ? headers.get(alias) : headers[alias];
176
+ if (value && validateCorrelationId(value)) {
177
+ return value;
178
+ }
179
+ }
180
+ return undefined;
181
+ }
182
+ /**
183
+ * Get or create correlation ID from headers
184
+ *
185
+ * Returns existing correlation ID from headers, or generates a new one if not found.
186
+ * Does NOT modify the input headers.
187
+ *
188
+ * @param headers - Headers to check
189
+ * @returns Existing or new correlation ID
190
+ *
191
+ * @example
192
+ * ```typescript
193
+ * const headers = new Headers();
194
+ * const id = getOrCreateCorrelationId(headers);
195
+ * // => Generates new ID if not found in headers
196
+ * ```
197
+ */
198
+ export function getOrCreateCorrelationId(headers) {
199
+ if (!headers)
200
+ return generateCorrelationId();
201
+ const existing = extractCorrelationId(headers);
202
+ return existing ?? generateCorrelationId();
203
+ }
204
+ /**
205
+ * Create a correlation ID from a timestamp
206
+ *
207
+ * Useful for testing or when you need deterministic IDs.
208
+ *
209
+ * @param timestamp - Unix timestamp in milliseconds
210
+ * @param random - Optional random component (generates if not provided)
211
+ * @returns Correlation ID
212
+ *
213
+ * @example
214
+ * ```typescript
215
+ * const id = createCorrelationIdFromTimestamp(1716234567890);
216
+ * // => 'req_1716234567890_a3f5c9d2'
217
+ *
218
+ * const deterministicId = createCorrelationIdFromTimestamp(1716234567890, 'aaaaaaaa');
219
+ * // => 'req_1716234567890_aaaaaaaa'
220
+ * ```
221
+ */
222
+ export function createCorrelationIdFromTimestamp(timestamp, random) {
223
+ const randomComponent = random ?? generateRandomHex(8);
224
+ if (!/^[a-f0-9]{8}$/.test(randomComponent)) {
225
+ throw new Error(`Invalid random component: ${randomComponent}. Expected 8 hex characters`);
226
+ }
227
+ return `req_${timestamp}_${randomComponent}`;
228
+ }
229
+ /**
230
+ * Calculate age of correlation ID in milliseconds
231
+ *
232
+ * @param id - Correlation ID
233
+ * @returns Age in milliseconds, or null if invalid
234
+ *
235
+ * @example
236
+ * ```typescript
237
+ * const id = generateCorrelationId();
238
+ * setTimeout(() => {
239
+ * const age = getCorrelationIdAge(id);
240
+ * console.log(`Request age: ${age}ms`);
241
+ * }, 1000);
242
+ * ```
243
+ */
244
+ export function getCorrelationIdAge(id) {
245
+ const spec = parseCorrelationId(id);
246
+ if (!spec)
247
+ return null;
248
+ const now = Date.now();
249
+ return now - spec.timestamp;
250
+ }
251
+ /**
252
+ * Check if correlation ID is expired
253
+ *
254
+ * @param id - Correlation ID
255
+ * @param maxAgeMs - Maximum age in milliseconds (default: 5 minutes)
256
+ * @returns True if expired, false otherwise
257
+ *
258
+ * @example
259
+ * ```typescript
260
+ * const id = generateCorrelationId();
261
+ * if (isCorrelationIdExpired(id, 60000)) {
262
+ * console.log('Request older than 1 minute');
263
+ * }
264
+ * ```
265
+ */
266
+ export function isCorrelationIdExpired(id, maxAgeMs = 5 * 60 * 1000) {
267
+ const age = getCorrelationIdAge(id);
268
+ return age !== null && age > maxAgeMs;
269
+ }
270
+ /**
271
+ * Generate random hex string
272
+ *
273
+ * Uses Web Crypto API in browser, Node.js crypto in Node.
274
+ * Falls back to Math.random() if neither available (NOT cryptographically secure).
275
+ *
276
+ * @param length - Number of hex characters to generate
277
+ * @returns Random hex string
278
+ *
279
+ * @internal
280
+ */
281
+ function generateRandomHex(length) {
282
+ const bytes = Math.ceil(length / 2);
283
+ // Try Web Crypto API (browser)
284
+ if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
285
+ const buffer = new Uint8Array(bytes);
286
+ crypto.getRandomValues(buffer);
287
+ return Array.from(buffer)
288
+ .map((b) => b.toString(16).padStart(2, '0'))
289
+ .join('')
290
+ .substring(0, length);
291
+ }
292
+ // Try Node.js crypto
293
+ try {
294
+ const nodeCrypto = require('node:crypto');
295
+ return nodeCrypto.randomBytes(bytes).toString('hex').substring(0, length);
296
+ }
297
+ catch {
298
+ // SECURITY: Never fall back to Math.random() in production (OWASP violation)
299
+ // Correlation IDs must be cryptographically random to prevent enumeration attacks
300
+ throw new Error('Cryptographic random generation unavailable. ' +
301
+ 'Install crypto polyfill or use environment with crypto support.');
302
+ }
303
+ }
304
+ /**
305
+ * Middleware helper for Express/Koa-style frameworks
306
+ *
307
+ * Automatically attaches correlation ID to incoming requests.
308
+ *
309
+ * @example
310
+ * ```typescript
311
+ * import express from 'express';
312
+ * import { correlationIdMiddleware } from '@private.me/xbind';
313
+ *
314
+ * const app = express();
315
+ * app.use(correlationIdMiddleware());
316
+ * ```
317
+ */
318
+ export function correlationIdMiddleware() {
319
+ return (req, res, next) => {
320
+ const id = getOrCreateCorrelationId(req.headers);
321
+ req.correlationId = id;
322
+ res.setHeader(CORRELATION_ID_HEADER, id);
323
+ if (typeof next === 'function')
324
+ next();
325
+ };
326
+ }
@@ -1 +1,157 @@
1
- export function toBase64(r){if("undefined"!=typeof Buffer)return Buffer.from(r).toString("base64");const t=String.fromCharCode(...r);return btoa(t)}export function fromBase64(r){if("undefined"!=typeof Buffer)return new Uint8Array(Buffer.from(r,"base64"));const t=atob(r),e=new Uint8Array(t.length);for(let r=0;r<t.length;r++)e[r]=t.charCodeAt(r);return e}export function toBase64Url(r){return toBase64(r).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}export function fromBase64Url(r){let t=r.replace(/-/g,"+").replace(/_/g,"/");for(;t.length%4;)t+="=";return fromBase64(t)}export function generateUUID(){if("undefined"!=typeof crypto&&crypto.randomUUID)return crypto.randomUUID();const r=new Uint8Array(16);crypto.getRandomValues(r),r[6]=15&r[6]|64,r[8]=63&r[8]|128;const t=Array.from(r).map(r=>r.toString(16).padStart(2,"0")).join("");return`${t.substring(0,8)}-${t.substring(8,12)}-${t.substring(12,16)}-${t.substring(16,20)}-${t.substring(20)}`}const START_MARKER="Encrypted://",END_MARKER="=> Generated by Xecret (TM)",BRAND_PREFIX="Xecret (TM) -> PRIVATE .ME (R) -> IDA5 -> ";export function formatShareHeader(r){return`${BRAND_PREFIX}${START_MARKER} ${r} ${END_MARKER}`}export function parseShareHeader(r){const t=r.indexOf(START_MARKER);if(t<0)return r.trim();const e=t+12,o=r.indexOf(END_MARKER,e);return o<0?r.trim():r.substring(e,o).trim()}export function hasShareHeader(r){return r.includes(START_MARKER)&&r.includes(END_MARKER)}import{getCrypto,loadCryptoPackage,isCryptoLoaded}from"./vault-store-loader.js";export function splitXorIDA(r,t,e){const o=getCrypto();if(!o)throw new Error("Crypto package not loaded. Call loadCryptoPackage() first.");return o.splitXorIDA(r,t,e)}export function reconstructXorIDA(r,t,e,o){const n=getCrypto();if(!n)throw new Error("Crypto package not loaded. Call loadCryptoPackage() first.");return n.reconstructXorIDA(r,t,e,o)}export function nextOddPrime(r){const t=getCrypto();if(!t)throw new Error("Crypto package not loaded. Call loadCryptoPackage() first.");return t.nextOddPrime(r)}export function pkcs7Pad(r,t){const e=getCrypto();if(!e)throw new Error("Crypto package not loaded. Call loadCryptoPackage() first.");return e.pkcs7Pad(r,t)}export function pkcs7Unpad(r,t){const e=getCrypto();if(!e)throw new Error("Crypto package not loaded. Call loadCryptoPackage() first.");return e.pkcs7Unpad(r,t)}export async function generateHMAC(r){const t=getCrypto();if(!t)throw new Error("Crypto package not loaded. Call loadCryptoPackage() first.");return t.generateHMAC(r)}export async function verifyHMAC(r,t,e){const o=getCrypto();if(!o)throw new Error("Crypto package not loaded. Call loadCryptoPackage() first.");return o.verifyHMAC(r,t,e)}export{loadCryptoPackage,getCrypto,isCryptoLoaded};
1
+ /**
2
+ * @module crypto-utils
3
+ * Local crypto utilities (non-IP, safe for npm distribution).
4
+ *
5
+ * These are NOT proprietary - just standard Web Crypto API wrappers.
6
+ * The proprietary XorIDA algorithm is vault-gated via vault-store-loader.ts.
7
+ */
8
+ /** Convert Uint8Array to Base64 string */
9
+ export function toBase64(data) {
10
+ if (typeof Buffer !== 'undefined') {
11
+ // Node.js
12
+ return Buffer.from(data).toString('base64');
13
+ }
14
+ // Browser
15
+ const binary = String.fromCharCode(...data);
16
+ return btoa(binary);
17
+ }
18
+ /** Convert Base64 string to Uint8Array */
19
+ export function fromBase64(base64) {
20
+ if (typeof Buffer !== 'undefined') {
21
+ // Node.js
22
+ return new Uint8Array(Buffer.from(base64, 'base64'));
23
+ }
24
+ // Browser
25
+ const binary = atob(base64);
26
+ const bytes = new Uint8Array(binary.length);
27
+ for (let i = 0; i < binary.length; i++) {
28
+ bytes[i] = binary.charCodeAt(i);
29
+ }
30
+ return bytes;
31
+ }
32
+ /** Convert Uint8Array to Base64URL string (URL-safe) */
33
+ export function toBase64Url(data) {
34
+ return toBase64(data).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
35
+ }
36
+ /** Convert Base64URL string to Uint8Array */
37
+ export function fromBase64Url(base64url) {
38
+ // Add back padding
39
+ let base64 = base64url.replace(/-/g, '+').replace(/_/g, '/');
40
+ while (base64.length % 4) {
41
+ base64 += '=';
42
+ }
43
+ return fromBase64(base64);
44
+ }
45
+ /** Generate a UUID v4 (random) */
46
+ export function generateUUID() {
47
+ if (typeof crypto !== 'undefined' && crypto.randomUUID) {
48
+ return crypto.randomUUID();
49
+ }
50
+ // Fallback implementation
51
+ const bytes = new Uint8Array(16);
52
+ crypto.getRandomValues(bytes);
53
+ // Set version (4) and variant (RFC 4122)
54
+ bytes[6] = (bytes[6] & 0x0f) | 0x40;
55
+ bytes[8] = (bytes[8] & 0x3f) | 0x80;
56
+ const hex = Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
57
+ return `${hex.substring(0, 8)}-${hex.substring(8, 12)}-${hex.substring(12, 16)}-${hex.substring(16, 20)}-${hex.substring(20)}`;
58
+ }
59
+ /**
60
+ * Branded share header — IDA5 copyright layer.
61
+ * Wraps XorIDA share output with patent-locked branded string.
62
+ *
63
+ * Format: Xecret (TM) -> PRIVATE .ME (R) -> IDA5 -> Encrypted:// [data] => Generated by Xecret (TM)
64
+ */
65
+ const START_MARKER = 'Encrypted://';
66
+ const END_MARKER = '=> Generated by Xecret (TM)';
67
+ const BRAND_PREFIX = 'Xecret (TM) -> PRIVATE .ME (R) -> IDA5 -> ';
68
+ /**
69
+ * Wrap share data with branded IDA5 copyright header.
70
+ * @param data - Base64-encoded share data
71
+ * @returns Branded string with copyright header
72
+ */
73
+ export function formatShareHeader(data) {
74
+ return `${BRAND_PREFIX}${START_MARKER} ${data} ${END_MARKER}`;
75
+ }
76
+ /**
77
+ * Extract share data from branded IDA5 header.
78
+ * @param input - Branded share string or legacy raw data
79
+ * @returns Extracted share data
80
+ */
81
+ export function parseShareHeader(input) {
82
+ const startIdx = input.indexOf(START_MARKER);
83
+ if (startIdx < 0)
84
+ return input.trim();
85
+ const dataStart = startIdx + START_MARKER.length;
86
+ const endIdx = input.indexOf(END_MARKER, dataStart);
87
+ if (endIdx < 0)
88
+ return input.trim();
89
+ return input.substring(dataStart, endIdx).trim();
90
+ }
91
+ /** Check if string has branded IDA5 share header */
92
+ export function hasShareHeader(input) {
93
+ return input.includes(START_MARKER) && input.includes(END_MARKER);
94
+ }
95
+ /**
96
+ * Vault-gated XorIDA functions (loaded dynamically from payment-gated Vault Store).
97
+ * These are re-exported from vault-store-loader for convenience.
98
+ */
99
+ import { getCrypto, loadCryptoPackage, isCryptoLoaded } from './vault-store-loader.js';
100
+ /** Split data using XorIDA (vault-gated, requires payment) */
101
+ export function splitXorIDA(data, totalShares, requiredShares) {
102
+ const crypto = getCrypto();
103
+ if (!crypto) {
104
+ throw new Error('Crypto package not loaded. Call loadCryptoPackage() first.');
105
+ }
106
+ return crypto.splitXorIDA(data, totalShares, requiredShares);
107
+ }
108
+ /** Reconstruct data from XorIDA shares (vault-gated, requires payment) */
109
+ export function reconstructXorIDA(shares, indices, requiredShares, totalShares) {
110
+ const crypto = getCrypto();
111
+ if (!crypto) {
112
+ throw new Error('Crypto package not loaded. Call loadCryptoPackage() first.');
113
+ }
114
+ return crypto.reconstructXorIDA(shares, indices, requiredShares, totalShares);
115
+ }
116
+ /** Get next odd prime >= n (vault-gated utility) */
117
+ export function nextOddPrime(n) {
118
+ const crypto = getCrypto();
119
+ if (!crypto) {
120
+ throw new Error('Crypto package not loaded. Call loadCryptoPackage() first.');
121
+ }
122
+ return crypto.nextOddPrime(n);
123
+ }
124
+ /** PKCS7 padding (vault-gated utility) */
125
+ export function pkcs7Pad(data, blockSize) {
126
+ const crypto = getCrypto();
127
+ if (!crypto) {
128
+ throw new Error('Crypto package not loaded. Call loadCryptoPackage() first.');
129
+ }
130
+ return crypto.pkcs7Pad(data, blockSize);
131
+ }
132
+ /** PKCS7 unpadding (vault-gated utility) */
133
+ export function pkcs7Unpad(data, blockSize) {
134
+ const crypto = getCrypto();
135
+ if (!crypto) {
136
+ throw new Error('Crypto package not loaded. Call loadCryptoPackage() first.');
137
+ }
138
+ return crypto.pkcs7Unpad(data, blockSize);
139
+ }
140
+ /** Generate HMAC-SHA256 (vault-gated utility) */
141
+ export async function generateHMAC(data) {
142
+ const crypto = getCrypto();
143
+ if (!crypto) {
144
+ throw new Error('Crypto package not loaded. Call loadCryptoPackage() first.');
145
+ }
146
+ return crypto.generateHMAC(data);
147
+ }
148
+ /** Verify HMAC-SHA256 (vault-gated utility) */
149
+ export async function verifyHMAC(key, data, expectedHmac) {
150
+ const crypto = getCrypto();
151
+ if (!crypto) {
152
+ throw new Error('Crypto package not loaded. Call loadCryptoPackage() first.');
153
+ }
154
+ return crypto.verifyHMAC(key, data, expectedHmac);
155
+ }
156
+ // Re-export vault loader functions for convenience
157
+ export { loadCryptoPackage, getCrypto, isCryptoLoaded };