tecto 1.0.2 → 1.1.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.
- package/README.md +59 -11
- package/dist/index.d.ts +57 -8
- package/dist/index.js +3 -3
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -37,8 +37,9 @@ const key = generateSecureKey();
|
|
|
37
37
|
const store = new MemoryKeyStore();
|
|
38
38
|
store.addKey("my-key-2026", key);
|
|
39
39
|
|
|
40
|
-
// 3. Create a coder
|
|
40
|
+
// 3. Create a coder (with optional custom maxPayloadSize)
|
|
41
41
|
const coder = new TectoCoder(store);
|
|
42
|
+
// or with custom config: new TectoCoder(store, { maxPayloadSize: 10 * 1024 * 1024 })
|
|
42
43
|
|
|
43
44
|
// 4. Encrypt a payload
|
|
44
45
|
const token = coder.encrypt(
|
|
@@ -140,24 +141,50 @@ class MyDatabaseKeyStore implements KeyStoreAdapter {
|
|
|
140
141
|
### `TectoCoder`
|
|
141
142
|
|
|
142
143
|
```ts
|
|
143
|
-
const coder = new TectoCoder(store); // any KeyStoreAdapter
|
|
144
|
+
const coder = new TectoCoder(store, options?); // any KeyStoreAdapter + optional config
|
|
144
145
|
|
|
145
146
|
// Encrypt
|
|
146
|
-
const token = coder.encrypt(payload,
|
|
147
|
+
const token = coder.encrypt(payload, signOptions?);
|
|
147
148
|
|
|
148
149
|
// Decrypt
|
|
149
150
|
const payload = coder.decrypt<MyType>(token);
|
|
150
151
|
```
|
|
151
152
|
|
|
153
|
+
#### `TectoCoderOptions`
|
|
154
|
+
|
|
155
|
+
Configuration for the `TectoCoder` instance:
|
|
156
|
+
|
|
157
|
+
| Option | Type | Default | Description |
|
|
158
|
+
|---|---|---|---|
|
|
159
|
+
| `maxPayloadSize` | `number` | `1048576` (1 MB) | Maximum encrypted payload size in bytes. Prevents DoS via oversized tokens. |
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
// Custom 10 MB limit
|
|
163
|
+
const coder = new TectoCoder(store, { maxPayloadSize: 10 * 1024 * 1024 });
|
|
164
|
+
```
|
|
165
|
+
|
|
152
166
|
#### `SignOptions`
|
|
153
167
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
|
157
|
-
|
|
158
|
-
| `
|
|
159
|
-
| `
|
|
160
|
-
| `
|
|
168
|
+
Options for individual token encryption:
|
|
169
|
+
|
|
170
|
+
| Option | Type | Default | Description |
|
|
171
|
+
|---|---|---|---|
|
|
172
|
+
| `expiresIn` | `string` | undefined | Duration string: `"1h"`, `"30m"`, `"7d"`, `"120s"`. If omitted, token never expires. |
|
|
173
|
+
| `issuer` | `string` | undefined | Sets the `iss` claim |
|
|
174
|
+
| `audience` | `string` | undefined | Sets the `aud` claim |
|
|
175
|
+
| `jti` | `string` | auto-generated | Custom token ID (128-bit random UUID if omitted) |
|
|
176
|
+
| `notBefore` | `string` | undefined | Duration string for `nbf` delay (token valid after N duration from `iat`) |
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
// Token that expires in 1 hour
|
|
180
|
+
coder.encrypt({ userId: 42 }, { expiresIn: "1h" });
|
|
181
|
+
|
|
182
|
+
// Token that never expires
|
|
183
|
+
coder.encrypt({ userId: 42 });
|
|
184
|
+
|
|
185
|
+
// Token that's valid 5 minutes from now
|
|
186
|
+
coder.encrypt({ userId: 42 }, { notBefore: "5m", expiresIn: "1h" });
|
|
187
|
+
```
|
|
161
188
|
|
|
162
189
|
### Error Classes
|
|
163
190
|
|
|
@@ -171,12 +198,33 @@ const payload = coder.decrypt<MyType>(token);
|
|
|
171
198
|
|
|
172
199
|
## Security Properties
|
|
173
200
|
|
|
201
|
+
### Core Guarantees
|
|
202
|
+
|
|
174
203
|
- **Opacity:** Tokens are encrypted, not just signed. Without the key, the payload is indistinguishable from random noise.
|
|
175
204
|
- **Authenticated Encryption:** Poly1305 tag ensures integrity. Any modification to the ciphertext, nonce, or key ID causes immediate rejection.
|
|
176
|
-
- **Unique Nonces:** Every `encrypt()` call generates a fresh 24-byte nonce from CSPRNG. XChaCha20's 192-bit nonce space makes collisions negligible.
|
|
177
205
|
- **Generic Errors:** All decryption failures produce the same `InvalidSignatureError` to prevent padding/authentication oracles.
|
|
178
206
|
- **Entropy Enforcement:** Keys are validated for length (32 bytes), non-zero, non-repeating, and minimum byte diversity.
|
|
179
207
|
- **Timing-Safe Comparison:** `constantTimeCompare()` prevents timing side-channels when comparing secrets.
|
|
208
|
+
- **Type Validation:** Registered claims (`exp`, `nbf`, `iat`, `jti`, `iss`, `aud`) are type-checked during deserialization to prevent type confusion attacks.
|
|
209
|
+
- **Payload Size Limits:** Configurable maximum payload size (default 1 MB) prevents DoS via oversized tokens.
|
|
210
|
+
- **Plaintext Cleanup:** Plaintext buffers are zeroed after encryption/decryption (best-effort).
|
|
211
|
+
- **Key Cloning:** `getKey()` returns defensive clones to prevent accidental mutation of stored keys.
|
|
212
|
+
|
|
213
|
+
### Nonce Collision Bounds
|
|
214
|
+
|
|
215
|
+
Every `encrypt()` call generates a fresh 24-byte nonce from CSPRNG. XChaCha20's 192-bit nonce space provides:
|
|
216
|
+
|
|
217
|
+
- **Birthday bound:** ~2^96 messages per key before collision becomes statistically likely
|
|
218
|
+
- **Recommendation:** Rotate keys before ~1 billion encryptions or at least daily (whichever comes first)
|
|
219
|
+
- Without rotation, nonce collision risk increases significantly after exceeding the birthday bound
|
|
220
|
+
|
|
221
|
+
### JTI & Replay Protection
|
|
222
|
+
|
|
223
|
+
The `jti` claim provides **detection**, not **prevention**, of token replay:
|
|
224
|
+
|
|
225
|
+
- Generated as 128-bit random UUID (~2^64 collision birthday bound)
|
|
226
|
+
- For robust replay protection, implement a separate blacklist/allowlist mechanism
|
|
227
|
+
- Track JTI values within the token's expiration window (`exp - iat`)
|
|
180
228
|
|
|
181
229
|
## Key Rotation
|
|
182
230
|
|
package/dist/index.d.ts
CHANGED
|
@@ -20,7 +20,14 @@ interface TectoRegisteredClaims {
|
|
|
20
20
|
readonly nbf?: number;
|
|
21
21
|
/** Issued-at time (Unix timestamp in seconds). */
|
|
22
22
|
readonly iat?: number;
|
|
23
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Unique token identifier (`jti`). Used for replay detection (not prevention).
|
|
25
|
+
*
|
|
26
|
+
* @security JTI is a 128-bit random identifier generated via CSPRNG.
|
|
27
|
+
* Birthday bound suggests collision at ~2^64 tokens. For robust replay protection,
|
|
28
|
+
* implement a separate blacklist/allowlist mechanism and track JTI values
|
|
29
|
+
* within their expiration window (`exp` - `iat`).
|
|
30
|
+
*/
|
|
24
31
|
readonly jti?: string;
|
|
25
32
|
/** Issuer identifier. */
|
|
26
33
|
readonly iss?: string;
|
|
@@ -37,12 +44,28 @@ interface TectoRegisteredClaims {
|
|
|
37
44
|
* ensuring all data is opaque without the secret key.
|
|
38
45
|
*/
|
|
39
46
|
type TectoPayload<T extends Record<string, unknown> = Record<string, unknown>> = TectoRegisteredClaims & T;
|
|
47
|
+
/**
|
|
48
|
+
* Configuration options for TectoCoder instance.
|
|
49
|
+
*
|
|
50
|
+
* @security These options control codec-level security parameters like
|
|
51
|
+
* maximum payload size. Configure these based on your application's needs.
|
|
52
|
+
*/
|
|
53
|
+
interface TectoCoderOptions {
|
|
54
|
+
/**
|
|
55
|
+
* Maximum allowed payload size in bytes. Prevents DoS via oversized tokens.
|
|
56
|
+
*
|
|
57
|
+
* @default 1048576 (1 MB)
|
|
58
|
+
* @example 10485760 for 10 MB limit
|
|
59
|
+
*/
|
|
60
|
+
readonly maxPayloadSize?: number;
|
|
61
|
+
}
|
|
40
62
|
/**
|
|
41
63
|
* Options for token encryption (signing).
|
|
42
64
|
*
|
|
43
65
|
* @security The `expiresIn` field accepts human-readable duration strings
|
|
44
66
|
* (e.g., `"1h"`, `"30m"`, `"7d"`) and is converted to an absolute `exp`
|
|
45
|
-
* claim internally.
|
|
67
|
+
* claim internally. If omitted, the token never expires (infinite lifetime).
|
|
68
|
+
* For security, consider always setting an expiration.
|
|
46
69
|
*/
|
|
47
70
|
interface SignOptions {
|
|
48
71
|
/**
|
|
@@ -149,8 +172,17 @@ interface KeyStoreAdapter {
|
|
|
149
172
|
*
|
|
150
173
|
* @security
|
|
151
174
|
* - Every `encrypt()` call generates a unique 24-byte nonce from CSPRNG.
|
|
175
|
+
* XChaCha20's 192-bit nonce space provides ~2^96 birthday bound per key.
|
|
176
|
+
* Rotate keys frequently (e.g., daily/weekly) to stay well below collision risk.
|
|
152
177
|
* - Every `decrypt()` failure throws a generic `InvalidSignatureError`.
|
|
153
|
-
* - `exp
|
|
178
|
+
* - `exp`, `nbf`, `iat` claims are validated for correct types (number) to prevent
|
|
179
|
+
* type confusion attacks. Custom field types are NOT validated.
|
|
180
|
+
* - Registered claims (`exp`, `nbf`, `iat`, `jti`, `iss`, `aud`) are type-checked
|
|
181
|
+
* during deserialization.
|
|
182
|
+
* - Plaintext buffers are zeroed after encryption and decryption.
|
|
183
|
+
* - Payloads are limited to 1 MB to prevent DoS via oversized tokens.
|
|
184
|
+
* - JTI is for token replay detection, not prevention. Use a separate
|
|
185
|
+
* blacklist/allowlist for robust replay protection.
|
|
154
186
|
*
|
|
155
187
|
* @example
|
|
156
188
|
* ```ts
|
|
@@ -164,12 +196,19 @@ interface KeyStoreAdapter {
|
|
|
164
196
|
*/
|
|
165
197
|
declare class TectoCoder {
|
|
166
198
|
private readonly keyStore;
|
|
199
|
+
private readonly maxPayloadSize;
|
|
167
200
|
/**
|
|
168
201
|
* Creates a new `TectoCoder` bound to the given key store.
|
|
169
202
|
*
|
|
170
203
|
* @param keyStore - Any implementation of `KeyStoreAdapter`.
|
|
204
|
+
* @param options - Optional configuration (e.g., custom maxPayloadSize).
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```ts
|
|
208
|
+
* const coder = new TectoCoder(store, { maxPayloadSize: 10 * 1024 * 1024 });
|
|
209
|
+
* ```
|
|
171
210
|
*/
|
|
172
|
-
constructor(keyStore: KeyStoreAdapter);
|
|
211
|
+
constructor(keyStore: KeyStoreAdapter, options?: TectoCoderOptions);
|
|
173
212
|
/**
|
|
174
213
|
* Encrypts a payload into an opaque TECTO token.
|
|
175
214
|
*
|
|
@@ -233,6 +272,8 @@ declare class TectoError extends Error {
|
|
|
233
272
|
* @security This is safe to throw distinctly from `InvalidSignatureError`
|
|
234
273
|
* because expiration is checked *after* successful decryption and
|
|
235
274
|
* authentication, so no ciphertext oracle is possible.
|
|
275
|
+
* The actual expiration date is stored but not exposed in the message
|
|
276
|
+
* to prevent timing analysis.
|
|
236
277
|
*/
|
|
237
278
|
declare class TokenExpiredError extends TectoError {
|
|
238
279
|
readonly expiredAt: Date;
|
|
@@ -264,6 +305,8 @@ declare class KeyError extends TectoError {
|
|
|
264
305
|
*
|
|
265
306
|
* @security Like `TokenExpiredError`, this is checked after successful
|
|
266
307
|
* decryption so it does not leak ciphertext information.
|
|
308
|
+
* The actual activation date is stored but not exposed in the message
|
|
309
|
+
* to prevent timing analysis.
|
|
267
310
|
*/
|
|
268
311
|
declare class TokenNotActiveError extends TectoError {
|
|
269
312
|
readonly activeAt: Date;
|
|
@@ -291,11 +334,16 @@ declare class TokenNotActiveError extends TectoError {
|
|
|
291
334
|
* - On `removeKey()`, the key buffer is zeroed before deletion.
|
|
292
335
|
* - `rotate()` adds a new key without removing old ones, so existing tokens
|
|
293
336
|
* encrypted under previous keys remain decryptable during the rotation window.
|
|
337
|
+
* - **Nonce reuse prevention**: Rotate keys before encrypting ~2^96 messages
|
|
338
|
+
* (XChaCha20's birthday bound). For most applications, rotate daily or weekly.
|
|
339
|
+
* Without rotation, nonce collision becomes statistically likely after ~2^96 encryptions.
|
|
294
340
|
*
|
|
295
341
|
* @example
|
|
296
342
|
* ```ts
|
|
297
343
|
* const store = new MemoryKeyStore();
|
|
298
344
|
* store.addKey("key-2026-01", generateSecureKey());
|
|
345
|
+
* // Rotate after 1 week or ~1 billion encryptions, whichever comes first
|
|
346
|
+
* store.rotate("key-2026-02", generateSecureKey());
|
|
299
347
|
* const key = store.getKey("key-2026-01");
|
|
300
348
|
* ```
|
|
301
349
|
*/
|
|
@@ -317,11 +365,12 @@ declare class MemoryKeyStore implements KeyStoreAdapter {
|
|
|
317
365
|
* Retrieves a key by its identifier.
|
|
318
366
|
*
|
|
319
367
|
* @param id - The key identifier to look up.
|
|
320
|
-
* @returns
|
|
368
|
+
* @returns A defensive clone of the key as a `Uint8Array`.
|
|
321
369
|
* @throws {KeyError} If no key exists with the given identifier.
|
|
322
370
|
*
|
|
323
|
-
* @security Returns a
|
|
324
|
-
*
|
|
371
|
+
* @security Returns a defensive clone to prevent accidental mutation
|
|
372
|
+
* of the internal key material. The caller is free to zero or modify
|
|
373
|
+
* the returned array without affecting the stored key.
|
|
325
374
|
*/
|
|
326
375
|
getKey(id: string): Uint8Array;
|
|
327
376
|
/**
|
|
@@ -438,4 +487,4 @@ declare function constantTimeCompare(a: Uint8Array, b: Uint8Array): boolean;
|
|
|
438
487
|
*/
|
|
439
488
|
declare function assertEntropy(key: Uint8Array): void;
|
|
440
489
|
|
|
441
|
-
export { InvalidSignatureError, KeyError, type KeyStoreAdapter, MemoryKeyStore, type SignOptions, TectoCoder, TectoError, type TectoPayload, type TectoRegisteredClaims, TokenExpiredError, TokenNotActiveError, assertEntropy, constantTimeCompare, generateSecureKey };
|
|
490
|
+
export { InvalidSignatureError, KeyError, type KeyStoreAdapter, MemoryKeyStore, type SignOptions, TectoCoder, type TectoCoderOptions, TectoError, type TectoPayload, type TectoRegisteredClaims, TokenExpiredError, TokenNotActiveError, assertEntropy, constantTimeCompare, generateSecureKey };
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
"use strict";var pe=Object.defineProperty;var qe=Object.getOwnPropertyDescriptor;var Xe=Object.getOwnPropertyNames;var Qe=Object.prototype.hasOwnProperty;var Ze=(t,e)=>{for(var r in e)pe(t,r,{get:e[r],enumerable:!0})},et=(t,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Xe(e))!Qe.call(t,s)&&s!==r&&pe(t,s,{get:()=>e[s],enumerable:!(o=qe(e,s))||o.enumerable});return t};var tt=t=>et(pe({},"__esModule",{value:!0}),t);var Lt={};Ze(Lt,{InvalidSignatureError:()=>V,KeyError:()=>P,MemoryKeyStore:()=>de,TectoCoder:()=>he,TectoError:()=>z,TokenExpiredError:()=>ee,TokenNotActiveError:()=>te,assertEntropy:()=>ue,constantTimeCompare:()=>Ye,generateSecureKey:()=>Je});module.exports=tt(Lt);function ne(t){if(!Number.isSafeInteger(t)||t<0)throw new Error("positive integer expected, got "+t)}function ye(t){return t instanceof Uint8Array||ArrayBuffer.isView(t)&&t.constructor.name==="Uint8Array"}function M(t,...e){if(!ye(t))throw new Error("Uint8Array expected");if(e.length>0&&!e.includes(t.length))throw new Error("Uint8Array expected of length "+e+", got length="+t.length)}function we(t,e=!0){if(t.destroyed)throw new Error("Hash instance has been destroyed");if(e&&t.finished)throw new Error("Hash#digest() has already been called")}function Oe(t,e){M(t);let r=e.outputLen;if(t.length<r)throw new Error("digestInto() expects output buffer of length at least "+r)}function xe(t){if(typeof t!="boolean")throw new Error(`boolean expected, not ${t}`)}var G=t=>new Uint32Array(t.buffer,t.byteOffset,Math.floor(t.byteLength/4)),Se=t=>new DataView(t.buffer,t.byteOffset,t.byteLength),rt=new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68;if(!rt)throw new Error("Non little-endian hardware is not supported");function nt(t){if(typeof t!="string")throw new Error("string expected");return new Uint8Array(new TextEncoder().encode(t))}function oe(t){if(typeof t=="string")t=nt(t);else if(ye(t))t=se(t);else throw new Error("Uint8Array expected, got "+typeof t);return t}function Ce(t,e){if(e==null||typeof e!="object")throw new Error("options must be defined");return Object.assign(t,e)}function Ke(t,e){if(t.length!==e.length)return!1;let r=0;for(let o=0;o<t.length;o++)r|=t[o]^e[o];return r===0}var ge=(t,e)=>{function r(o,...s){if(M(o),t.nonceLength!==void 0){let h=s[0];if(!h)throw new Error("nonce / iv required");t.varSizeNonce?M(h):M(h,t.nonceLength)}let n=t.tagLength;n&&s[1]!==void 0&&M(s[1]);let i=e(o,...s),c=(h,d)=>{if(d!==void 0){if(h!==2)throw new Error("cipher output not supported");M(d)}},f=!1;return{encrypt(h,d){if(f)throw new Error("cannot encrypt() twice with same key + nonce");return f=!0,M(h),c(i.encrypt.length,d),i.encrypt(h,d)},decrypt(h,d){if(M(h),n&&h.length<n)throw new Error("invalid ciphertext length: smaller than tagLength="+n);return c(i.decrypt.length,d),i.decrypt(h,d)}}}return Object.assign(r,t),r};function be(t,e,r=!0){if(e===void 0)return new Uint8Array(t);if(e.length!==t)throw new Error("invalid output length, expected "+t+", got: "+e.length);if(r&&!ot(e))throw new Error("invalid output, must be aligned");return e}function me(t,e,r,o){if(typeof t.setBigUint64=="function")return t.setBigUint64(e,r,o);let s=BigInt(32),n=BigInt(4294967295),i=Number(r>>s&n),c=Number(r&n),f=o?4:0,l=o?0:4;t.setUint32(e+f,i,o),t.setUint32(e+l,c,o)}function ot(t){return t.byteOffset%4===0}function se(t){return Uint8Array.from(t)}function W(...t){for(let e=0;e<t.length;e++)t[e].fill(0)}var Ne=t=>Uint8Array.from(t.split("").map(e=>e.charCodeAt(0))),st=Ne("expand 16-byte k"),it=Ne("expand 32-byte k"),ct=G(st),ft=G(it);function a(t,e){return t<<e|t>>>32-e}function Ee(t){return t.byteOffset%4===0}var ie=64,at=16,Re=2**32-1,Ie=new Uint32Array;function ht(t,e,r,o,s,n,i,c){let f=s.length,l=new Uint8Array(ie),h=G(l),d=Ee(s)&&Ee(n),p=d?G(s):Ie,x=d?G(n):Ie;for(let y=0;y<f;i++){if(t(e,r,o,h,i,c),i>=Re)throw new Error("arx: counter overflow");let g=Math.min(ie,f-y);if(d&&g===ie){let w=y/4;if(y%4!==0)throw new Error("arx: invalid block position");for(let b=0,m;b<at;b++)m=w+b,x[m]=p[m]^h[b];y+=ie;continue}for(let w=0,b;w<g;w++)b=y+w,n[b]=s[b]^l[w];y+=g}}function Ae(t,e){let{allowShortKeys:r,extendNonceFn:o,counterLength:s,counterRight:n,rounds:i}=Ce({allowShortKeys:!1,counterLength:8,counterRight:!1,rounds:20},e);if(typeof t!="function")throw new Error("core must be a function");return ne(s),ne(i),xe(n),xe(r),(c,f,l,h,d=0)=>{M(c),M(f),M(l);let p=l.length;if(h===void 0&&(h=new Uint8Array(p)),M(h),ne(d),d<0||d>=Re)throw new Error("arx: counter overflow");if(h.length<p)throw new Error(`arx: output (${h.length}) is shorter than data (${p})`);let x=[],y=c.length,g,w;if(y===32)x.push(g=se(c)),w=ft;else if(y===16&&r)g=new Uint8Array(32),g.set(c),g.set(c,16),w=ct,x.push(g);else throw new Error(`arx: invalid 32-byte key, got length=${y}`);Ee(f)||x.push(f=se(f));let b=G(g);if(o){if(f.length!==24)throw new Error("arx: extended nonce must be 24 bytes");o(w,b,G(f.subarray(0,16)),b),f=f.subarray(16)}let m=16-s;if(m!==f.length)throw new Error(`arx: nonce must be ${m} or 16 bytes`);if(m!==12){let $=new Uint8Array(12);$.set(f,n?0:12-f.length),f=$,x.push(f)}let N=G(f);return ht(t,w,b,N,l,h,d,i),W(...x),h}}var k=(t,e)=>t[e++]&255|(t[e++]&255)<<8,Te=class{constructor(e){this.blockLen=16,this.outputLen=16,this.buffer=new Uint8Array(16),this.r=new Uint16Array(10),this.h=new Uint16Array(10),this.pad=new Uint16Array(8),this.pos=0,this.finished=!1,e=oe(e),M(e,32);let r=k(e,0),o=k(e,2),s=k(e,4),n=k(e,6),i=k(e,8),c=k(e,10),f=k(e,12),l=k(e,14);this.r[0]=r&8191,this.r[1]=(r>>>13|o<<3)&8191,this.r[2]=(o>>>10|s<<6)&7939,this.r[3]=(s>>>7|n<<9)&8191,this.r[4]=(n>>>4|i<<12)&255,this.r[5]=i>>>1&8190,this.r[6]=(i>>>14|c<<2)&8191,this.r[7]=(c>>>11|f<<5)&8065,this.r[8]=(f>>>8|l<<8)&8191,this.r[9]=l>>>5&127;for(let h=0;h<8;h++)this.pad[h]=k(e,16+2*h)}process(e,r,o=!1){let s=o?0:2048,{h:n,r:i}=this,c=i[0],f=i[1],l=i[2],h=i[3],d=i[4],p=i[5],x=i[6],y=i[7],g=i[8],w=i[9],b=k(e,r+0),m=k(e,r+2),N=k(e,r+4),$=k(e,r+6),H=k(e,r+8),_=k(e,r+10),D=k(e,r+12),j=k(e,r+14),E=n[0]+(b&8191),A=n[1]+((b>>>13|m<<3)&8191),T=n[2]+((m>>>10|N<<6)&8191),U=n[3]+((N>>>7|$<<9)&8191),v=n[4]+(($>>>4|H<<12)&8191),L=n[5]+(H>>>1&8191),B=n[6]+((H>>>14|_<<2)&8191),O=n[7]+((_>>>11|D<<5)&8191),S=n[8]+((D>>>8|j<<8)&8191),C=n[9]+(j>>>5|s),u=0,I=u+E*c+A*(5*w)+T*(5*g)+U*(5*y)+v*(5*x);u=I>>>13,I&=8191,I+=L*(5*p)+B*(5*d)+O*(5*h)+S*(5*l)+C*(5*f),u+=I>>>13,I&=8191;let R=u+E*f+A*c+T*(5*w)+U*(5*g)+v*(5*y);u=R>>>13,R&=8191,R+=L*(5*x)+B*(5*p)+O*(5*d)+S*(5*h)+C*(5*l),u+=R>>>13,R&=8191;let K=u+E*l+A*f+T*c+U*(5*w)+v*(5*g);u=K>>>13,K&=8191,K+=L*(5*y)+B*(5*x)+O*(5*p)+S*(5*d)+C*(5*h),u+=K>>>13,K&=8191;let F=u+E*h+A*l+T*f+U*c+v*(5*w);u=F>>>13,F&=8191,F+=L*(5*g)+B*(5*y)+O*(5*x)+S*(5*p)+C*(5*d),u+=F>>>13,F&=8191;let J=u+E*d+A*h+T*l+U*f+v*c;u=J>>>13,J&=8191,J+=L*(5*w)+B*(5*g)+O*(5*y)+S*(5*x)+C*(5*p),u+=J>>>13,J&=8191;let Y=u+E*p+A*d+T*h+U*l+v*f;u=Y>>>13,Y&=8191,Y+=L*c+B*(5*w)+O*(5*g)+S*(5*y)+C*(5*x),u+=Y>>>13,Y&=8191;let q=u+E*x+A*p+T*d+U*h+v*l;u=q>>>13,q&=8191,q+=L*f+B*c+O*(5*w)+S*(5*g)+C*(5*y),u+=q>>>13,q&=8191;let X=u+E*y+A*x+T*p+U*d+v*h;u=X>>>13,X&=8191,X+=L*l+B*f+O*c+S*(5*w)+C*(5*g),u+=X>>>13,X&=8191;let Q=u+E*g+A*y+T*x+U*p+v*d;u=Q>>>13,Q&=8191,Q+=L*h+B*l+O*f+S*c+C*(5*w),u+=Q>>>13,Q&=8191;let Z=u+E*w+A*g+T*y+U*x+v*p;u=Z>>>13,Z&=8191,Z+=L*d+B*h+O*l+S*f+C*c,u+=Z>>>13,Z&=8191,u=(u<<2)+u|0,u=u+I|0,I=u&8191,u=u>>>13,R+=u,n[0]=I,n[1]=R,n[2]=K,n[3]=F,n[4]=J,n[5]=Y,n[6]=q,n[7]=X,n[8]=Q,n[9]=Z}finalize(){let{h:e,pad:r}=this,o=new Uint16Array(10),s=e[1]>>>13;e[1]&=8191;for(let c=2;c<10;c++)e[c]+=s,s=e[c]>>>13,e[c]&=8191;e[0]+=s*5,s=e[0]>>>13,e[0]&=8191,e[1]+=s,s=e[1]>>>13,e[1]&=8191,e[2]+=s,o[0]=e[0]+5,s=o[0]>>>13,o[0]&=8191;for(let c=1;c<10;c++)o[c]=e[c]+s,s=o[c]>>>13,o[c]&=8191;o[9]-=8192;let n=(s^1)-1;for(let c=0;c<10;c++)o[c]&=n;n=~n;for(let c=0;c<10;c++)e[c]=e[c]&n|o[c];e[0]=(e[0]|e[1]<<13)&65535,e[1]=(e[1]>>>3|e[2]<<10)&65535,e[2]=(e[2]>>>6|e[3]<<7)&65535,e[3]=(e[3]>>>9|e[4]<<4)&65535,e[4]=(e[4]>>>12|e[5]<<1|e[6]<<14)&65535,e[5]=(e[6]>>>2|e[7]<<11)&65535,e[6]=(e[7]>>>5|e[8]<<8)&65535,e[7]=(e[8]>>>8|e[9]<<5)&65535;let i=e[0]+r[0];e[0]=i&65535;for(let c=1;c<8;c++)i=(e[c]+r[c]|0)+(i>>>16)|0,e[c]=i&65535;W(o)}update(e){we(this);let{buffer:r,blockLen:o}=this;e=oe(e);let s=e.length;for(let n=0;n<s;){let i=Math.min(o-this.pos,s-n);if(i===o){for(;o<=s-n;n+=o)this.process(e,n);continue}r.set(e.subarray(n,n+i),this.pos),this.pos+=i,n+=i,this.pos===o&&(this.process(r,0,!1),this.pos=0)}return this}destroy(){W(this.h,this.r,this.buffer,this.pad)}digestInto(e){we(this),Oe(e,this),this.finished=!0;let{buffer:r,h:o}=this,{pos:s}=this;if(s){for(r[s++]=1;s<16;s++)r[s]=0;this.process(r,0,!0)}this.finalize();let n=0;for(let i=0;i<8;i++)e[n++]=o[i]>>>0,e[n++]=o[i]>>>8;return e}digest(){let{buffer:e,outputLen:r}=this;this.digestInto(e);let o=e.slice(0,r);return this.destroy(),o}};function lt(t){let e=(o,s)=>t(s).update(oe(o)).digest(),r=t(new Uint8Array(32));return e.outputLen=r.outputLen,e.blockLen=r.blockLen,e.create=o=>t(o),e}var $e=lt(t=>new Te(t));function De(t,e,r,o,s,n=20){let i=t[0],c=t[1],f=t[2],l=t[3],h=e[0],d=e[1],p=e[2],x=e[3],y=e[4],g=e[5],w=e[6],b=e[7],m=s,N=r[0],$=r[1],H=r[2],_=i,D=c,j=f,E=l,A=h,T=d,U=p,v=x,L=y,B=g,O=w,S=b,C=m,u=N,I=$,R=H;for(let F=0;F<n;F+=2)_=_+A|0,C=a(C^_,16),L=L+C|0,A=a(A^L,12),_=_+A|0,C=a(C^_,8),L=L+C|0,A=a(A^L,7),D=D+T|0,u=a(u^D,16),B=B+u|0,T=a(T^B,12),D=D+T|0,u=a(u^D,8),B=B+u|0,T=a(T^B,7),j=j+U|0,I=a(I^j,16),O=O+I|0,U=a(U^O,12),j=j+U|0,I=a(I^j,8),O=O+I|0,U=a(U^O,7),E=E+v|0,R=a(R^E,16),S=S+R|0,v=a(v^S,12),E=E+v|0,R=a(R^E,8),S=S+R|0,v=a(v^S,7),_=_+T|0,R=a(R^_,16),O=O+R|0,T=a(T^O,12),_=_+T|0,R=a(R^_,8),O=O+R|0,T=a(T^O,7),D=D+U|0,C=a(C^D,16),S=S+C|0,U=a(U^S,12),D=D+U|0,C=a(C^D,8),S=S+C|0,U=a(U^S,7),j=j+v|0,u=a(u^j,16),L=L+u|0,v=a(v^L,12),j=j+v|0,u=a(u^j,8),L=L+u|0,v=a(v^L,7),E=E+A|0,I=a(I^E,16),B=B+I|0,A=a(A^B,12),E=E+A|0,I=a(I^E,8),B=B+I|0,A=a(A^B,7);let K=0;o[K++]=i+_|0,o[K++]=c+D|0,o[K++]=f+j|0,o[K++]=l+E|0,o[K++]=h+A|0,o[K++]=d+T|0,o[K++]=p+U|0,o[K++]=x+v|0,o[K++]=y+L|0,o[K++]=g+B|0,o[K++]=w+O|0,o[K++]=b+S|0,o[K++]=m+C|0,o[K++]=N+u|0,o[K++]=$+I|0,o[K++]=H+R|0}function ut(t,e,r,o){let s=t[0],n=t[1],i=t[2],c=t[3],f=e[0],l=e[1],h=e[2],d=e[3],p=e[4],x=e[5],y=e[6],g=e[7],w=r[0],b=r[1],m=r[2],N=r[3];for(let H=0;H<20;H+=2)s=s+f|0,w=a(w^s,16),p=p+w|0,f=a(f^p,12),s=s+f|0,w=a(w^s,8),p=p+w|0,f=a(f^p,7),n=n+l|0,b=a(b^n,16),x=x+b|0,l=a(l^x,12),n=n+l|0,b=a(b^n,8),x=x+b|0,l=a(l^x,7),i=i+h|0,m=a(m^i,16),y=y+m|0,h=a(h^y,12),i=i+h|0,m=a(m^i,8),y=y+m|0,h=a(h^y,7),c=c+d|0,N=a(N^c,16),g=g+N|0,d=a(d^g,12),c=c+d|0,N=a(N^c,8),g=g+N|0,d=a(d^g,7),s=s+l|0,N=a(N^s,16),y=y+N|0,l=a(l^y,12),s=s+l|0,N=a(N^s,8),y=y+N|0,l=a(l^y,7),n=n+h|0,w=a(w^n,16),g=g+w|0,h=a(h^g,12),n=n+h|0,w=a(w^n,8),g=g+w|0,h=a(h^g,7),i=i+d|0,b=a(b^i,16),p=p+b|0,d=a(d^p,12),i=i+d|0,b=a(b^i,8),p=p+b|0,d=a(d^p,7),c=c+f|0,m=a(m^c,16),x=x+m|0,f=a(f^x,12),c=c+f|0,m=a(m^c,8),x=x+m|0,f=a(f^x,7);let $=0;o[$++]=s,o[$++]=n,o[$++]=i,o[$++]=c,o[$++]=w,o[$++]=b,o[$++]=m,o[$++]=N}var dt=Ae(De,{counterRight:!1,counterLength:4,allowShortKeys:!1}),pt=Ae(De,{counterRight:!1,counterLength:8,extendNonceFn:ut,allowShortKeys:!1});var yt=new Uint8Array(16),ke=(t,e)=>{t.update(e);let r=e.length%16;r&&t.update(yt.subarray(r))},wt=new Uint8Array(32);function _e(t,e,r,o,s){let n=t(e,r,wt),i=$e.create(n);s&&ke(i,s),ke(i,o);let c=new Uint8Array(16),f=Se(c);me(f,0,BigInt(s?s.length:0),!0),me(f,8,BigInt(o.length),!0),i.update(c);let l=i.digest();return W(n,c),l}var je=t=>(e,r,o)=>({encrypt(n,i){let c=n.length;i=be(c+16,i,!1),i.set(n);let f=i.subarray(0,-16);t(e,r,f,f,1);let l=_e(t,e,r,f,o);return i.set(l,c),W(l),i},decrypt(n,i){i=be(n.length-16,i,!1);let c=n.subarray(0,-16),f=n.subarray(-16),l=_e(t,e,r,c,o);if(!Ke(f,l))throw new Error("invalid tag");return i.set(n.subarray(0,-16)),t(e,r,i,i,1),W(l),i}}),Pt=ge({blockSize:64,nonceLength:12,tagLength:16},je(dt)),Ue=ge({blockSize:64,nonceLength:24,tagLength:16},je(pt));function xt(t){return t instanceof Uint8Array||ArrayBuffer.isView(t)&&t.constructor.name==="Uint8Array"}function Pe(t,e){return Array.isArray(e)?e.length===0?!0:t?e.every(r=>typeof r=="string"):e.every(r=>Number.isSafeInteger(r)):!1}function ce(t,e){if(typeof e!="string")throw new Error(`${t}: string expected`);return!0}function Be(t){if(!Number.isSafeInteger(t))throw new Error(`invalid integer: ${t}`)}function Le(t){if(!Array.isArray(t))throw new Error("array expected")}function fe(t,e){if(!Pe(!0,e))throw new Error(`${t}: array of strings expected`)}function gt(t,e){if(!Pe(!1,e))throw new Error(`${t}: array of numbers expected`)}function bt(...t){let e=n=>n,r=(n,i)=>c=>n(i(c)),o=t.map(n=>n.encode).reduceRight(r,e),s=t.map(n=>n.decode).reduce(r,e);return{encode:o,decode:s}}function mt(t){let e=typeof t=="string"?t.split(""):t,r=e.length;fe("alphabet",e);let o=new Map(e.map((s,n)=>[s,n]));return{encode:s=>(Le(s),s.map(n=>{if(!Number.isSafeInteger(n)||n<0||n>=r)throw new Error(`alphabet.encode: digit index outside alphabet "${n}". Allowed: ${t}`);return e[n]})),decode:s=>(Le(s),s.map(n=>{ce("alphabet.decode",n);let i=o.get(n);if(i===void 0)throw new Error(`Unknown letter: "${n}". Allowed: ${t}`);return i}))}}function Et(t=""){return ce("join",t),{encode:e=>(fe("join.decode",e),e.join(t)),decode:e=>(ce("join.decode",e),e.split(t))}}function At(t,e="="){return Be(t),ce("padding",e),{encode(r){for(fe("padding.encode",r);r.length*t%8;)r.push(e);return r},decode(r){fe("padding.decode",r);let o=r.length;if(o*t%8)throw new Error("padding: invalid, string should have whole number of bytes");for(;o>0&&r[o-1]===e;o--)if((o-1)*t%8===0)throw new Error("padding: invalid, string has too much padding");return r.slice(0,o)}}}var Ve=(t,e)=>e===0?t:Ve(e,t%e),ae=(t,e)=>t+(e-Ve(t,e)),ve=(()=>{let t=[];for(let e=0;e<40;e++)t.push(2**e);return t})();function Me(t,e,r,o){if(Le(t),e<=0||e>32)throw new Error(`convertRadix2: wrong from=${e}`);if(r<=0||r>32)throw new Error(`convertRadix2: wrong to=${r}`);if(ae(e,r)>32)throw new Error(`convertRadix2: carry overflow from=${e} to=${r} carryBits=${ae(e,r)}`);let s=0,n=0,i=ve[e],c=ve[r]-1,f=[];for(let l of t){if(Be(l),l>=i)throw new Error(`convertRadix2: invalid data word=${l} from=${e}`);if(s=s<<e|l,n+e>32)throw new Error(`convertRadix2: carry overflow pos=${n} from=${e}`);for(n+=e;n>=r;n-=r)f.push((s>>n-r&c)>>>0);let h=ve[n];if(h===void 0)throw new Error("invalid carry");s&=h-1}if(s=s<<r-n&c,!o&&n>=e)throw new Error("Excess padding");if(!o&&s>0)throw new Error(`Non-zero padding: ${s}`);return o&&n>0&&f.push(s>>>0),f}function Tt(t,e=!1){if(Be(t),t<=0||t>32)throw new Error("radix2: bits should be in (0..32]");if(ae(8,t)>32||ae(t,8)>32)throw new Error("radix2: carry overflow");return{encode:r=>{if(!xt(r))throw new Error("radix2.encode input should be Uint8Array");return Me(Array.from(r),8,t,!e)},decode:r=>(gt("radix2.decode",r),Uint8Array.from(Me(r,t,8,e)))}}var re=bt(Tt(6),mt("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"),At(6),Et(""));var z=class extends Error{code;constructor(e,r){super(e),this.name="TectoError",this.code=r,Object.setPrototypeOf(this,new.target.prototype)}},ee=class extends z{expiredAt;constructor(e){super("Token has expired","TECTO_TOKEN_EXPIRED"),this.name="TokenExpiredError",this.expiredAt=e}},V=class extends z{constructor(){super("Invalid token","TECTO_INVALID_TOKEN"),this.name="InvalidSignatureError"}},P=class extends z{constructor(e){super(e,"TECTO_KEY_ERROR"),this.name="KeyError"}},te=class extends z{activeAt;constructor(e){super("Token is not yet active","TECTO_TOKEN_NOT_ACTIVE"),this.name="TokenNotActiveError",this.activeAt=e}};var ze="tecto",He="v1",Fe=24,Ut=5;function Ge(t){let e=/^(\d+)\s*(s|m|h|d)$/i.exec(t);if(!e)throw new z(`Invalid duration format: "${t}". Expected format: <number><unit> where unit is s, m, h, or d.`,"TECTO_INVALID_DURATION");let r=Number.parseInt(e[1],10),o=e[2].toLowerCase(),n={s:1,m:60,h:3600,d:86400}[o];if(n===void 0)throw new z(`Unknown duration unit: "${o}"`,"TECTO_INVALID_DURATION");return r*n}function vt(){let t=new Uint8Array(16);return crypto.getRandomValues(t),Array.from(t).map(e=>e.toString(16).padStart(2,"0")).join("")}var he=class{keyStore;constructor(e){this.keyStore=e}encrypt(e,r){let o=this.keyStore.getCurrentKeyId(),s=this.keyStore.getKey(o),n=Math.floor(Date.now()/1e3),i={...e,iat:n,jti:r?.jti??vt()};r?.expiresIn&&(i.exp=n+Ge(r.expiresIn)),r?.notBefore&&(i.nbf=n+Ge(r.notBefore)),r?.issuer&&(i.iss=r.issuer),r?.audience&&(i.aud=r.audience);let c=new TextEncoder().encode(JSON.stringify(i)),f=new Uint8Array(Fe);crypto.getRandomValues(f);let h=Ue(s,f).encrypt(c),d=re.encode(f),p=re.encode(h);return`${ze}.${He}.${o}.${d}.${p}`}decrypt(e){let r;try{r=e.split(".")}catch{throw new V}if(r.length!==Ut)throw new V;let[o,s,n,i,c]=r;if(o!==ze||s!==He)throw new V;let f;try{f=this.keyStore.getKey(n)}catch{throw new V}let l,h;try{l=re.decode(i),h=re.decode(c)}catch{throw new V}if(l.byteLength!==Fe)throw new V;let d;try{d=Ue(f,l).decrypt(h)}catch{throw new V}let p;try{let y=new TextDecoder().decode(d);p=JSON.parse(y)}catch{throw new V}let x=Math.floor(Date.now()/1e3);if(typeof p.exp=="number"&&p.exp<=x)throw new ee(new Date(p.exp*1e3));if(typeof p.nbf=="number"&&p.nbf>x)throw new te(new Date(p.nbf*1e3));return p}};var le=32,We=8;function Je(){let t=new Uint8Array(le);return crypto.getRandomValues(t),t}function Ye(t,e){if(t.byteLength!==e.byteLength)return!1;let r=0;for(let o=0;o<t.byteLength;o++)r|=(t[o]??0)^(e[o]??0);return r===0}function ue(t){if(!(t instanceof Uint8Array))throw new P("Key must be a Uint8Array. String keys are forbidden to prevent internalization attacks.");if(t.byteLength!==le)throw new P(`Key must be exactly ${le} bytes (${le*8}-bit). Received ${t.byteLength} bytes.`);let e=!0;for(let n=0;n<t.byteLength;n++)if((t[n]??0)!==0){e=!1;break}if(e)throw new P("Key must not be all zeros. Use generateSecureKey() for safe key generation.");let r=t[0]??0,o=!0;for(let n=1;n<t.byteLength;n++)if((t[n]??0)!==r){o=!1;break}if(o)throw new P("Key must not be a repeating single byte. Use generateSecureKey() for safe key generation.");let s=new Set;for(let n=0;n<t.byteLength;n++)s.add(t[n]??0);if(s.size<We)throw new P(`Key has insufficient entropy: only ${s.size} unique byte values. A minimum of ${We} is required. Use generateSecureKey() for safe key generation.`)}var de=class{keys=new Map;currentKeyId=null;addKey(e,r){ue(r);let o=new Uint8Array(r.byteLength);o.set(r),this.keys.set(e,o),this.currentKeyId===null&&(this.currentKeyId=e)}getKey(e){let r=this.keys.get(e);if(!r)throw new P(`Key not found: "${e}"`);return r}rotate(e,r){this.addKey(e,r),this.currentKeyId=e}removeKey(e){let r=this.keys.get(e);if(!r)throw new P(`Key not found: "${e}"`);if(this.currentKeyId===e)throw new P("Cannot remove the current active key. Rotate to a new key first.");r.fill(0),this.keys.delete(e)}getCurrentKeyId(){if(this.currentKeyId===null)throw new P("No keys in the store. Add a key with addKey() first.");return this.currentKeyId}get size(){return this.keys.size}};0&&(module.exports={InvalidSignatureError,KeyError,MemoryKeyStore,TectoCoder,TectoError,TokenExpiredError,TokenNotActiveError,assertEntropy,constantTimeCompare,generateSecureKey});
|
|
1
|
+
"use strict";var pe=Object.defineProperty;var Ye=Object.getOwnPropertyDescriptor;var Ze=Object.getOwnPropertyNames;var Je=Object.prototype.hasOwnProperty;var Xe=(t,e)=>{for(var r in e)pe(t,r,{get:e[r],enumerable:!0})},qe=(t,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Ze(e))!Je.call(t,s)&&s!==r&&pe(t,s,{get:()=>e[s],enumerable:!(o=Ye(e,s))||o.enumerable});return t};var Qe=t=>qe(pe({},"__esModule",{value:!0}),t);var It={};Xe(It,{InvalidSignatureError:()=>k,KeyError:()=>H,MemoryKeyStore:()=>de,TectoCoder:()=>he,TectoError:()=>j,TokenExpiredError:()=>te,TokenNotActiveError:()=>re,assertEntropy:()=>ue,constantTimeCompare:()=>We,generateSecureKey:()=>Ge});module.exports=Qe(It);function et(t){return t instanceof Uint8Array||ArrayBuffer.isView(t)&&t.constructor.name==="Uint8Array"}function se(t){if(typeof t!="boolean")throw new Error(`boolean expected, not ${t}`)}function ie(t){if(!Number.isSafeInteger(t)||t<0)throw new Error("positive integer expected, got "+t)}function K(t,e,r=""){let o=et(t),s=t?.length,n=e!==void 0;if(!o||n&&s!==e){let c=r&&`"${r}" `,i=n?` of length ${e}`:"",f=o?`length=${s}`:`type=${typeof t}`;throw new Error(c+"expected Uint8Array"+i+", got "+f)}return t}function ye(t,e=!0){if(t.destroyed)throw new Error("Hash instance has been destroyed");if(e&&t.finished)throw new Error("Hash#digest() has already been called")}function Ue(t,e){K(t,void 0,"output");let r=e.outputLen;if(t.length<r)throw new Error("digestInto() expects output buffer of length at least "+r)}function G(t){return new Uint32Array(t.buffer,t.byteOffset,Math.floor(t.byteLength/4))}function W(...t){for(let e=0;e<t.length;e++)t[e].fill(0)}function tt(t){return new DataView(t.buffer,t.byteOffset,t.byteLength)}var rt=new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68;function Be(t,e){if(e==null||typeof e!="object")throw new Error("options must be defined");return Object.assign(t,e)}function ve(t,e){if(t.length!==e.length)return!1;let r=0;for(let o=0;o<t.length;o++)r|=t[o]^e[o];return r===0}var we=(t,e)=>{function r(o,...s){if(K(o,void 0,"key"),!rt)throw new Error("Non little-endian hardware is not yet supported");if(t.nonceLength!==void 0){let h=s[0];K(h,t.varSizeNonce?void 0:t.nonceLength,"nonce")}let n=t.tagLength;n&&s[1]!==void 0&&K(s[1],void 0,"AAD");let c=e(o,...s),i=(h,p)=>{if(p!==void 0){if(h!==2)throw new Error("cipher output not supported");K(p,void 0,"output")}},f=!1;return{encrypt(h,p){if(f)throw new Error("cannot encrypt() twice with same key + nonce");return f=!0,K(h),i(c.encrypt.length,p),c.encrypt(h,p)},decrypt(h,p){if(K(h),n&&h.length<n)throw new Error('"ciphertext" expected length bigger than tagLength='+n);return i(c.decrypt.length,p),c.decrypt(h,p)}}}return Object.assign(r,t),r};function ge(t,e,r=!0){if(e===void 0)return new Uint8Array(t);if(e.length!==t)throw new Error('"output" expected Uint8Array of length '+t+", got: "+e.length);if(r&&!nt(e))throw new Error("invalid output, must be aligned");return e}function Oe(t,e,r){se(r);let o=new Uint8Array(16),s=tt(o);return s.setBigUint64(0,BigInt(e),r),s.setBigUint64(8,BigInt(t),r),o}function nt(t){return t.byteOffset%4===0}function ee(t){return Uint8Array.from(t)}var Ce=t=>Uint8Array.from(t.split(""),e=>e.charCodeAt(0)),ot=Ce("expand 16-byte k"),st=Ce("expand 32-byte k"),it=G(ot),ct=G(st);function a(t,e){return t<<e|t>>>32-e}function xe(t){return t.byteOffset%4===0}var ce=64,ft=16,Se=2**32-1,Ie=Uint32Array.of();function at(t,e,r,o,s,n,c,i){let f=s.length,u=new Uint8Array(ce),h=G(u),p=xe(s)&&xe(n),l=p?G(s):Ie,x=p?G(n):Ie;for(let y=0;y<f;c++){if(t(e,r,o,h,c,i),c>=Se)throw new Error("arx: counter overflow");let w=Math.min(ce,f-y);if(p&&w===ce){let g=y/4;if(y%4!==0)throw new Error("arx: invalid block position");for(let b=0,m;b<ft;b++)m=g+b,x[m]=l[m]^h[b];y+=ce;continue}for(let g=0,b;g<w;g++)b=y+g,n[b]=s[b]^u[g];y+=w}}function be(t,e){let{allowShortKeys:r,extendNonceFn:o,counterLength:s,counterRight:n,rounds:c}=Be({allowShortKeys:!1,counterLength:8,counterRight:!1,rounds:20},e);if(typeof t!="function")throw new Error("core must be a function");return ie(s),ie(c),se(n),se(r),(i,f,u,h,p=0)=>{K(i,void 0,"key"),K(f,void 0,"nonce"),K(u,void 0,"data");let l=u.length;if(h===void 0&&(h=new Uint8Array(l)),K(h,void 0,"output"),ie(p),p<0||p>=Se)throw new Error("arx: counter overflow");if(h.length<l)throw new Error(`arx: output (${h.length}) is shorter than data (${l})`);let x=[],y=i.length,w,g;if(y===32)x.push(w=ee(i)),g=ct;else if(y===16&&r)w=new Uint8Array(32),w.set(i),w.set(i,16),g=it,x.push(w);else throw K(i,32,"arx key"),new Error("invalid key size");xe(f)||x.push(f=ee(f));let b=G(w);if(o){if(f.length!==24)throw new Error("arx: extended nonce must be 24 bytes");o(g,b,G(f.subarray(0,16)),b),f=f.subarray(16)}let m=16-s;if(m!==f.length)throw new Error(`arx: nonce must be ${m} or 16 bytes`);if(m!==12){let $=new Uint8Array(12);$.set(f,n?0:12-f.length),f=$,x.push(f)}let _=G(f);return at(t,g,b,_,u,h,p,c),W(...x),h}}function P(t,e){return t[e++]&255|(t[e++]&255)<<8}var me=class{blockLen=16;outputLen=16;buffer=new Uint8Array(16);r=new Uint16Array(10);h=new Uint16Array(10);pad=new Uint16Array(8);pos=0;finished=!1;constructor(e){e=ee(K(e,32,"key"));let r=P(e,0),o=P(e,2),s=P(e,4),n=P(e,6),c=P(e,8),i=P(e,10),f=P(e,12),u=P(e,14);this.r[0]=r&8191,this.r[1]=(r>>>13|o<<3)&8191,this.r[2]=(o>>>10|s<<6)&7939,this.r[3]=(s>>>7|n<<9)&8191,this.r[4]=(n>>>4|c<<12)&255,this.r[5]=c>>>1&8190,this.r[6]=(c>>>14|i<<2)&8191,this.r[7]=(i>>>11|f<<5)&8065,this.r[8]=(f>>>8|u<<8)&8191,this.r[9]=u>>>5&127;for(let h=0;h<8;h++)this.pad[h]=P(e,16+2*h)}process(e,r,o=!1){let s=o?0:2048,{h:n,r:c}=this,i=c[0],f=c[1],u=c[2],h=c[3],p=c[4],l=c[5],x=c[6],y=c[7],w=c[8],g=c[9],b=P(e,r+0),m=P(e,r+2),_=P(e,r+4),$=P(e,r+6),V=P(e,r+8),D=P(e,r+10),z=P(e,r+12),M=P(e,r+14),E=n[0]+(b&8191),A=n[1]+((b>>>13|m<<3)&8191),T=n[2]+((m>>>10|_<<6)&8191),L=n[3]+((_>>>7|$<<9)&8191),U=n[4]+(($>>>4|V<<12)&8191),B=n[5]+(V>>>1&8191),v=n[6]+((V>>>14|D<<2)&8191),O=n[7]+((D>>>11|z<<5)&8191),I=n[8]+((z>>>8|M<<8)&8191),C=n[9]+(M>>>5|s),d=0,N=d+E*i+A*(5*g)+T*(5*w)+L*(5*y)+U*(5*x);d=N>>>13,N&=8191,N+=B*(5*l)+v*(5*p)+O*(5*h)+I*(5*u)+C*(5*f),d+=N>>>13,N&=8191;let R=d+E*f+A*i+T*(5*g)+L*(5*w)+U*(5*y);d=R>>>13,R&=8191,R+=B*(5*x)+v*(5*l)+O*(5*p)+I*(5*h)+C*(5*u),d+=R>>>13,R&=8191;let S=d+E*u+A*f+T*i+L*(5*g)+U*(5*w);d=S>>>13,S&=8191,S+=B*(5*y)+v*(5*x)+O*(5*l)+I*(5*p)+C*(5*h),d+=S>>>13,S&=8191;let F=d+E*h+A*u+T*f+L*i+U*(5*g);d=F>>>13,F&=8191,F+=B*(5*w)+v*(5*y)+O*(5*x)+I*(5*l)+C*(5*p),d+=F>>>13,F&=8191;let Y=d+E*p+A*h+T*u+L*f+U*i;d=Y>>>13,Y&=8191,Y+=B*(5*g)+v*(5*w)+O*(5*y)+I*(5*x)+C*(5*l),d+=Y>>>13,Y&=8191;let Z=d+E*l+A*p+T*h+L*u+U*f;d=Z>>>13,Z&=8191,Z+=B*i+v*(5*g)+O*(5*w)+I*(5*y)+C*(5*x),d+=Z>>>13,Z&=8191;let J=d+E*x+A*l+T*p+L*h+U*u;d=J>>>13,J&=8191,J+=B*f+v*i+O*(5*g)+I*(5*w)+C*(5*y),d+=J>>>13,J&=8191;let X=d+E*y+A*x+T*l+L*p+U*h;d=X>>>13,X&=8191,X+=B*u+v*f+O*i+I*(5*g)+C*(5*w),d+=X>>>13,X&=8191;let q=d+E*w+A*y+T*x+L*l+U*p;d=q>>>13,q&=8191,q+=B*h+v*u+O*f+I*i+C*(5*g),d+=q>>>13,q&=8191;let Q=d+E*g+A*w+T*y+L*x+U*l;d=Q>>>13,Q&=8191,Q+=B*p+v*h+O*u+I*f+C*i,d+=Q>>>13,Q&=8191,d=(d<<2)+d|0,d=d+N|0,N=d&8191,d=d>>>13,R+=d,n[0]=N,n[1]=R,n[2]=S,n[3]=F,n[4]=Y,n[5]=Z,n[6]=J,n[7]=X,n[8]=q,n[9]=Q}finalize(){let{h:e,pad:r}=this,o=new Uint16Array(10),s=e[1]>>>13;e[1]&=8191;for(let i=2;i<10;i++)e[i]+=s,s=e[i]>>>13,e[i]&=8191;e[0]+=s*5,s=e[0]>>>13,e[0]&=8191,e[1]+=s,s=e[1]>>>13,e[1]&=8191,e[2]+=s,o[0]=e[0]+5,s=o[0]>>>13,o[0]&=8191;for(let i=1;i<10;i++)o[i]=e[i]+s,s=o[i]>>>13,o[i]&=8191;o[9]-=8192;let n=(s^1)-1;for(let i=0;i<10;i++)o[i]&=n;n=~n;for(let i=0;i<10;i++)e[i]=e[i]&n|o[i];e[0]=(e[0]|e[1]<<13)&65535,e[1]=(e[1]>>>3|e[2]<<10)&65535,e[2]=(e[2]>>>6|e[3]<<7)&65535,e[3]=(e[3]>>>9|e[4]<<4)&65535,e[4]=(e[4]>>>12|e[5]<<1|e[6]<<14)&65535,e[5]=(e[6]>>>2|e[7]<<11)&65535,e[6]=(e[7]>>>5|e[8]<<8)&65535,e[7]=(e[8]>>>8|e[9]<<5)&65535;let c=e[0]+r[0];e[0]=c&65535;for(let i=1;i<8;i++)c=(e[i]+r[i]|0)+(c>>>16)|0,e[i]=c&65535;W(o)}update(e){ye(this),K(e),e=ee(e);let{buffer:r,blockLen:o}=this,s=e.length;for(let n=0;n<s;){let c=Math.min(o-this.pos,s-n);if(c===o){for(;o<=s-n;n+=o)this.process(e,n);continue}r.set(e.subarray(n,n+c),this.pos),this.pos+=c,n+=c,this.pos===o&&(this.process(r,0,!1),this.pos=0)}return this}destroy(){W(this.h,this.r,this.buffer,this.pad)}digestInto(e){ye(this),Ue(e,this),this.finished=!0;let{buffer:r,h:o}=this,{pos:s}=this;if(s){for(r[s++]=1;s<16;s++)r[s]=0;this.process(r,0,!0)}this.finalize();let n=0;for(let c=0;c<8;c++)e[n++]=o[c]>>>0,e[n++]=o[c]>>>8;return e}digest(){let{buffer:e,outputLen:r}=this;this.digestInto(e);let o=e.slice(0,r);return this.destroy(),o}};function ht(t){let e=(o,s)=>t(s).update(o).digest(),r=t(new Uint8Array(32));return e.outputLen=r.outputLen,e.blockLen=r.blockLen,e.create=o=>t(o),e}var Ne=ht(t=>new me(t));function ke(t,e,r,o,s,n=20){let c=t[0],i=t[1],f=t[2],u=t[3],h=e[0],p=e[1],l=e[2],x=e[3],y=e[4],w=e[5],g=e[6],b=e[7],m=s,_=r[0],$=r[1],V=r[2],D=c,z=i,M=f,E=u,A=h,T=p,L=l,U=x,B=y,v=w,O=g,I=b,C=m,d=_,N=$,R=V;for(let F=0;F<n;F+=2)D=D+A|0,C=a(C^D,16),B=B+C|0,A=a(A^B,12),D=D+A|0,C=a(C^D,8),B=B+C|0,A=a(A^B,7),z=z+T|0,d=a(d^z,16),v=v+d|0,T=a(T^v,12),z=z+T|0,d=a(d^z,8),v=v+d|0,T=a(T^v,7),M=M+L|0,N=a(N^M,16),O=O+N|0,L=a(L^O,12),M=M+L|0,N=a(N^M,8),O=O+N|0,L=a(L^O,7),E=E+U|0,R=a(R^E,16),I=I+R|0,U=a(U^I,12),E=E+U|0,R=a(R^E,8),I=I+R|0,U=a(U^I,7),D=D+T|0,R=a(R^D,16),O=O+R|0,T=a(T^O,12),D=D+T|0,R=a(R^D,8),O=O+R|0,T=a(T^O,7),z=z+L|0,C=a(C^z,16),I=I+C|0,L=a(L^I,12),z=z+L|0,C=a(C^z,8),I=I+C|0,L=a(L^I,7),M=M+U|0,d=a(d^M,16),B=B+d|0,U=a(U^B,12),M=M+U|0,d=a(d^M,8),B=B+d|0,U=a(U^B,7),E=E+A|0,N=a(N^E,16),v=v+N|0,A=a(A^v,12),E=E+A|0,N=a(N^E,8),v=v+N|0,A=a(A^v,7);let S=0;o[S++]=c+D|0,o[S++]=i+z|0,o[S++]=f+M|0,o[S++]=u+E|0,o[S++]=h+A|0,o[S++]=p+T|0,o[S++]=l+L|0,o[S++]=x+U|0,o[S++]=y+B|0,o[S++]=w+v|0,o[S++]=g+O|0,o[S++]=b+I|0,o[S++]=m+C|0,o[S++]=_+d|0,o[S++]=$+N|0,o[S++]=V+R|0}function lt(t,e,r,o){let s=t[0],n=t[1],c=t[2],i=t[3],f=e[0],u=e[1],h=e[2],p=e[3],l=e[4],x=e[5],y=e[6],w=e[7],g=r[0],b=r[1],m=r[2],_=r[3];for(let V=0;V<20;V+=2)s=s+f|0,g=a(g^s,16),l=l+g|0,f=a(f^l,12),s=s+f|0,g=a(g^s,8),l=l+g|0,f=a(f^l,7),n=n+u|0,b=a(b^n,16),x=x+b|0,u=a(u^x,12),n=n+u|0,b=a(b^n,8),x=x+b|0,u=a(u^x,7),c=c+h|0,m=a(m^c,16),y=y+m|0,h=a(h^y,12),c=c+h|0,m=a(m^c,8),y=y+m|0,h=a(h^y,7),i=i+p|0,_=a(_^i,16),w=w+_|0,p=a(p^w,12),i=i+p|0,_=a(_^i,8),w=w+_|0,p=a(p^w,7),s=s+u|0,_=a(_^s,16),y=y+_|0,u=a(u^y,12),s=s+u|0,_=a(_^s,8),y=y+_|0,u=a(u^y,7),n=n+h|0,g=a(g^n,16),w=w+g|0,h=a(h^w,12),n=n+h|0,g=a(g^n,8),w=w+g|0,h=a(h^w,7),c=c+p|0,b=a(b^c,16),l=l+b|0,p=a(p^l,12),c=c+p|0,b=a(b^c,8),l=l+b|0,p=a(p^l,7),i=i+f|0,m=a(m^i,16),x=x+m|0,f=a(f^x,12),i=i+f|0,m=a(m^i,8),x=x+m|0,f=a(f^x,7);let $=0;o[$++]=s,o[$++]=n,o[$++]=c,o[$++]=i,o[$++]=g,o[$++]=b,o[$++]=m,o[$++]=_}var ut=be(ke,{counterRight:!1,counterLength:4,allowShortKeys:!1}),dt=be(ke,{counterRight:!1,counterLength:8,extendNonceFn:lt,allowShortKeys:!1});var pt=new Uint8Array(16),_e=(t,e)=>{t.update(e);let r=e.length%16;r&&t.update(pt.subarray(r))},yt=new Uint8Array(32);function Re(t,e,r,o,s){s!==void 0&&K(s,void 0,"AAD");let n=t(e,r,yt),c=Oe(o.length,s?s.length:0,!0),i=Ne.create(n);s&&_e(i,s),_e(i,o),i.update(c);let f=i.digest();return W(n,c),f}var Ke=t=>(e,r,o)=>({encrypt(n,c){let i=n.length;c=ge(i+16,c,!1),c.set(n);let f=c.subarray(0,-16);t(e,r,f,f,1);let u=Re(t,e,r,f,o);return c.set(u,i),W(u),c},decrypt(n,c){c=ge(n.length-16,c,!1);let i=n.subarray(0,-16),f=n.subarray(-16),u=Re(t,e,r,i,o);if(!ve(f,u))throw new Error("invalid tag");return c.set(n.subarray(0,-16)),t(e,r,c,c,1),W(u),c}}),Ft=we({blockSize:64,nonceLength:12,tagLength:16},Ke(ut)),Ee=we({blockSize:64,nonceLength:24,tagLength:16},Ke(dt));function Pe(t){return t instanceof Uint8Array||ArrayBuffer.isView(t)&&t.constructor.name==="Uint8Array"}function wt(t){if(!Pe(t))throw new Error("Uint8Array expected")}function De(t,e){return Array.isArray(e)?e.length===0?!0:t?e.every(r=>typeof r=="string"):e.every(r=>Number.isSafeInteger(r)):!1}function ne(t,e){if(typeof e!="string")throw new Error(`${t}: string expected`);return!0}function Le(t){if(!Number.isSafeInteger(t))throw new Error(`invalid integer: ${t}`)}function Te(t){if(!Array.isArray(t))throw new Error("array expected")}function fe(t,e){if(!De(!0,e))throw new Error(`${t}: array of strings expected`)}function gt(t,e){if(!De(!1,e))throw new Error(`${t}: array of numbers expected`)}function xt(...t){let e=n=>n,r=(n,c)=>i=>n(c(i)),o=t.map(n=>n.encode).reduceRight(r,e),s=t.map(n=>n.decode).reduce(r,e);return{encode:o,decode:s}}function bt(t){let e=typeof t=="string"?t.split(""):t,r=e.length;fe("alphabet",e);let o=new Map(e.map((s,n)=>[s,n]));return{encode:s=>(Te(s),s.map(n=>{if(!Number.isSafeInteger(n)||n<0||n>=r)throw new Error(`alphabet.encode: digit index outside alphabet "${n}". Allowed: ${t}`);return e[n]})),decode:s=>(Te(s),s.map(n=>{ne("alphabet.decode",n);let c=o.get(n);if(c===void 0)throw new Error(`Unknown letter: "${n}". Allowed: ${t}`);return c}))}}function mt(t=""){return ne("join",t),{encode:e=>(fe("join.decode",e),e.join(t)),decode:e=>(ne("join.decode",e),e.split(t))}}function Et(t,e="="){return Le(t),ne("padding",e),{encode(r){for(fe("padding.encode",r);r.length*t%8;)r.push(e);return r},decode(r){fe("padding.decode",r);let o=r.length;if(o*t%8)throw new Error("padding: invalid, string should have whole number of bytes");for(;o>0&&r[o-1]===e;o--)if((o-1)*t%8===0)throw new Error("padding: invalid, string has too much padding");return r.slice(0,o)}}}var ze=(t,e)=>e===0?t:ze(e,t%e),ae=(t,e)=>t+(e-ze(t,e)),Ae=(()=>{let t=[];for(let e=0;e<40;e++)t.push(2**e);return t})();function $e(t,e,r,o){if(Te(t),e<=0||e>32)throw new Error(`convertRadix2: wrong from=${e}`);if(r<=0||r>32)throw new Error(`convertRadix2: wrong to=${r}`);if(ae(e,r)>32)throw new Error(`convertRadix2: carry overflow from=${e} to=${r} carryBits=${ae(e,r)}`);let s=0,n=0,c=Ae[e],i=Ae[r]-1,f=[];for(let u of t){if(Le(u),u>=c)throw new Error(`convertRadix2: invalid data word=${u} from=${e}`);if(s=s<<e|u,n+e>32)throw new Error(`convertRadix2: carry overflow pos=${n} from=${e}`);for(n+=e;n>=r;n-=r)f.push((s>>n-r&i)>>>0);let h=Ae[n];if(h===void 0)throw new Error("invalid carry");s&=h-1}if(s=s<<r-n&i,!o&&n>=e)throw new Error("Excess padding");if(!o&&s>0)throw new Error(`Non-zero padding: ${s}`);return o&&n>0&&f.push(s>>>0),f}function At(t,e=!1){if(Le(t),t<=0||t>32)throw new Error("radix2: bits should be in (0..32]");if(ae(8,t)>32||ae(t,8)>32)throw new Error("radix2: carry overflow");return{encode:r=>{if(!Pe(r))throw new Error("radix2.encode input should be Uint8Array");return $e(Array.from(r),8,t,!e)},decode:r=>(gt("radix2.decode",r),Uint8Array.from($e(r,t,8,e)))}}var Tt=typeof Uint8Array.from([]).toBase64=="function"&&typeof Uint8Array.fromBase64=="function",Lt=(t,e)=>{ne("base64",t);let r=e?/^[A-Za-z0-9=_-]+$/:/^[A-Za-z0-9=+/]+$/,o=e?"base64url":"base64";if(t.length>0&&!r.test(t))throw new Error("invalid base64");return Uint8Array.fromBase64(t,{alphabet:o,lastChunkHandling:"strict"})};var oe=Tt?{encode(t){return wt(t),t.toBase64({alphabet:"base64url"})},decode(t){return Lt(t,!0)}}:xt(At(6),bt("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"),Et(6),mt(""));var j=class extends Error{code;constructor(e,r){super(e),this.name="TectoError",this.code=r,Object.setPrototypeOf(this,new.target.prototype)}},te=class extends j{expiredAt;constructor(e){super("Token is invalid","TECTO_TOKEN_EXPIRED"),this.name="TokenExpiredError",this.expiredAt=e}},k=class extends j{constructor(){super("Invalid token","TECTO_INVALID_TOKEN"),this.name="InvalidSignatureError"}},H=class extends j{constructor(e){super(e,"TECTO_KEY_ERROR"),this.name="KeyError"}},re=class extends j{activeAt;constructor(e){super("Token is invalid","TECTO_TOKEN_NOT_ACTIVE"),this.name="TokenNotActiveError",this.activeAt=e}};var Me="tecto",He="v1",je=24,Ut=5,Bt=1024*1024,vt=/^[a-zA-Z0-9._-]+$/;function Ve(t){let e=/^(\d+)\s*(s|m|h|d)$/i.exec(t);if(!e)throw new j(`Invalid duration format: "${t}". Expected format: <number><unit> where unit is s, m, h, or d.`,"TECTO_INVALID_DURATION");let r=Number.parseInt(e[1],10),o=e[2].toLowerCase(),n={s:1,m:60,h:3600,d:86400}[o];if(n===void 0)throw new j(`Unknown duration unit: "${o}"`,"TECTO_INVALID_DURATION");let c=r*n,i=86400*365*10;if(c>i)throw new j(`Duration exceeds maximum allowed value of 10 years: "${t}"`,"TECTO_INVALID_DURATION");return c}function Ot(){return crypto.randomUUID().replace(/-/g,"")}var he=class{keyStore;maxPayloadSize;constructor(e,r){if(this.keyStore=e,this.maxPayloadSize=r?.maxPayloadSize??Bt,!Number.isInteger(this.maxPayloadSize)||this.maxPayloadSize<=0)throw new j("maxPayloadSize must be a positive integer","TECTO_INVALID_CONFIG")}encrypt(e,r){let o=this.keyStore.getCurrentKeyId(),s=this.keyStore.getKey(o),n=Math.floor(Date.now()/1e3),c={...e,iat:n,jti:r?.jti??Ot()};r?.expiresIn&&(c.exp=n+Ve(r.expiresIn)),r?.notBefore&&(c.nbf=n+Ve(r.notBefore)),r?.issuer&&(c.iss=r.issuer),r?.audience&&(c.aud=r.audience);let i=new TextEncoder().encode(JSON.stringify(c));if(i.byteLength>this.maxPayloadSize)throw new j(`Payload exceeds maximum size of ${this.maxPayloadSize} bytes`,"TECTO_PAYLOAD_TOO_LARGE");let f=new Uint8Array(je);crypto.getRandomValues(f);let h=Ee(s,f).encrypt(i);i.fill(0);let p=oe.encode(f).replace(/=+$/,""),l=oe.encode(h).replace(/=+$/,"");return`${Me}.${He}.${o}.${p}.${l}`}decrypt(e){let r;try{r=e.split(".")}catch{throw new k}if(r.length!==Ut)throw new k;let[o,s,n,c,i]=r;if(o!==Me||s!==He)throw new k;if(!n||!vt.test(n))throw new k;let f;try{f=this.keyStore.getKey(n)}catch{throw new k}let u,h;try{let y=w=>w+"=".repeat((4-w.length%4)%4);u=oe.decode(y(c)),h=oe.decode(y(i))}catch{throw new k}if(u.byteLength!==je)throw new k;let p;try{p=Ee(f,u).decrypt(h)}catch{throw new k}let l;try{let y=new TextDecoder().decode(p);l=JSON.parse(y)}catch{throw new k}finally{p.fill(0)}if(typeof l.exp<"u"&&typeof l.exp!="number")throw new k;if(typeof l.nbf<"u"&&typeof l.nbf!="number")throw new k;if(typeof l.iat<"u"&&typeof l.iat!="number")throw new k;if(typeof l.jti<"u"&&typeof l.jti!="string")throw new k;if(typeof l.iss<"u"&&typeof l.iss!="string")throw new k;if(typeof l.aud<"u"&&typeof l.aud!="string")throw new k;let x=Math.floor(Date.now()/1e3);if(typeof l.exp=="number"&&l.exp<=x)throw new te(new Date(l.exp*1e3));if(typeof l.nbf=="number"&&l.nbf>x)throw new re(new Date(l.nbf*1e3));return l}};var le=32,Fe=8;function Ge(){let t=new Uint8Array(le);return crypto.getRandomValues(t),t}function We(t,e){if(t.byteLength!==e.byteLength)return!1;let r=0;for(let o=0;o<t.byteLength;o++)r|=(t[o]??0)^(e[o]??0);return r===0}function ue(t){if(!(t instanceof Uint8Array))throw new H("Key must be a Uint8Array. String keys are forbidden to prevent internalization attacks.");if(t.byteLength!==le)throw new H(`Key must be exactly ${le} bytes (${le*8}-bit). Received ${t.byteLength} bytes.`);let e=!0;for(let n=0;n<t.byteLength;n++)if((t[n]??0)!==0){e=!1;break}if(e)throw new H("Key must not be all zeros. Use generateSecureKey() for safe key generation.");let r=t[0]??0,o=!0;for(let n=1;n<t.byteLength;n++)if((t[n]??0)!==r){o=!1;break}if(o)throw new H("Key must not be a repeating single byte. Use generateSecureKey() for safe key generation.");let s=new Set;for(let n=0;n<t.byteLength;n++)s.add(t[n]??0);if(s.size<Fe)throw new H(`Key has insufficient entropy: only ${s.size} unique byte values. A minimum of ${Fe} is required. Use generateSecureKey() for safe key generation.`)}var de=class{keys=new Map;currentKeyId=null;addKey(e,r){ue(r);let o=new Uint8Array(r.byteLength);o.set(r),this.keys.set(e,o),this.currentKeyId===null&&(this.currentKeyId=e)}getKey(e){let r=this.keys.get(e);if(!r)throw new H(`Key not found: "${e}"`);return new Uint8Array(r)}rotate(e,r){this.addKey(e,r),this.currentKeyId=e}removeKey(e){let r=this.keys.get(e);if(!r)throw new H(`Key not found: "${e}"`);if(this.currentKeyId===e)throw new H("Cannot remove the current active key. Rotate to a new key first.");r.fill(0),this.keys.delete(e)}getCurrentKeyId(){if(this.currentKeyId===null)throw new H("No keys in the store. Add a key with addKey() first.");return this.currentKeyId}get size(){return this.keys.size}};0&&(module.exports={InvalidSignatureError,KeyError,MemoryKeyStore,TectoCoder,TectoError,TokenExpiredError,TokenNotActiveError,assertEntropy,constantTimeCompare,generateSecureKey});
|
|
2
2
|
/*! Bundled license information:
|
|
3
3
|
|
|
4
|
-
@noble/ciphers/
|
|
4
|
+
@noble/ciphers/utils.js:
|
|
5
5
|
(*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) *)
|
|
6
6
|
|
|
7
|
-
@scure/base/
|
|
7
|
+
@scure/base/index.js:
|
|
8
8
|
(*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
9
9
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tecto",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Transport Encrypted Compact Token Object — an opaque, XChaCha20-Poly1305 encrypted token protocol",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -20,10 +20,10 @@
|
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@biomejs/biome": "2.3.14",
|
|
23
|
-
"@noble/ciphers": "
|
|
24
|
-
"@scure/base": "
|
|
25
|
-
"@types/bun": "1.
|
|
26
|
-
"tsup": "8.
|
|
23
|
+
"@noble/ciphers": "2.1.1",
|
|
24
|
+
"@scure/base": "2.0.0",
|
|
25
|
+
"@types/bun": "1.3.9",
|
|
26
|
+
"tsup": "8.5.1",
|
|
27
27
|
"typescript": "5.9.3"
|
|
28
28
|
},
|
|
29
29
|
"repository": {
|