@kagal/taistamp 0.1.0 → 0.1.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.
package/README.md CHANGED
@@ -69,7 +69,7 @@ absent (no echo, no signature) per [spec §5.4][spec-nonce].
69
69
  Response headers on success:
70
70
 
71
71
  | Header | Value |
72
- |--------|-------|
72
+ | ------ | ----- |
73
73
  | `Content-Type` | `application/tai64n` |
74
74
  | `Content-Length` | `25` |
75
75
  | `Cache-Control` | `no-store` |
@@ -99,7 +99,7 @@ newTaistampHandler({ cors: false }); // CORS-specific headers of
99
99
  When CORS is enabled, responses carry:
100
100
 
101
101
  | Response | CORS headers added | `Vary: Origin` (scoped origin only) |
102
- |----------|--------------------|------|
102
+ | -------- | ------------------ | ----------------------------------- |
103
103
  | `OPTIONS` 200 | `Access-Control-Allow-Origin`, `Access-Control-Allow-Methods: GET, HEAD`, `Access-Control-Allow-Headers: TAI-Nonce`, `Access-Control-Expose-Headers: TAI-Leap-Seconds, TAI-Nonce, TAI-Key-Selector, TAI-Signature`, `Access-Control-Max-Age: 600` | yes |
104
104
  | `GET` / `HEAD` 200 | `Access-Control-Allow-Origin`, `Access-Control-Expose-Headers` (so browser JS can read the `TAI-*` headers) | yes |
105
105
  | `405` | `Access-Control-Allow-Origin` | yes |
@@ -215,7 +215,7 @@ v=tai1; k=ed25519; p=<base64-of-32-raw-pubkey-bytes>
215
215
  ```
216
216
 
217
217
  | Tag | Value |
218
- |-----|-------|
218
+ | --- | ----- |
219
219
  | `v` | Protocol version. `tai1` for the framing in this README. |
220
220
  | `k` | Key algorithm. `ed25519` for the only algorithm currently defined. |
221
221
  | `p` | Public key, standard base64. For Ed25519: 32 raw bytes → 43-44 chars. |
@@ -239,14 +239,19 @@ or fall back to a strict-verify library such as
239
239
  ```typescript
240
240
  import {
241
241
  asNonce,
242
- extractLeapSeconds,
243
242
  composeSignaturePayload,
243
+ extractLeapSeconds,
244
+ readLabel,
244
245
  } from '@kagal/taistamp';
245
246
 
246
247
  const response = await fetch(taistampURL, {
247
248
  headers: { 'TAI-Nonce': clientNonce },
248
249
  });
249
- const label = await response.text();
250
+ // `application/tai64n` is octet-typed, not text. `readLabel`
251
+ // reads the raw body and decodes the 25-octet ASCII label;
252
+ // never `response.text()`, which UTF-8-decodes and would
253
+ // mangle a non-ASCII octet instead of surfacing it.
254
+ const label = await readLabel(response);
250
255
  const selector = response.headers.get('TAI-Key-Selector')!;
251
256
  const sigSf = response.headers.get('TAI-Signature')!;
252
257
 
@@ -342,6 +347,16 @@ Re-exported from `@kagal/ed25519-secret`:
342
347
  For verifier-side validation of a signed response
343
348
  (see [Verifying a signature](#verifying-a-signature)):
344
349
 
350
+ - `readLabel(response, context?)` — read the TAI64N
351
+ label from a response body. Use this instead of
352
+ `response.text()`, which UTF-8-decodes the octet-typed
353
+ `application/tai64n` body. Throws `TypeError` unless
354
+ the body is exactly 25 ASCII octets; pass `context` to
355
+ prefix the error. Consumes the body.
356
+ - `readASCII(response, context?)` — the unvalidated
357
+ reader behind `readLabel`: decode any response body as
358
+ 7-bit ASCII, with no length check. Throws `TypeError`
359
+ on any byte ≥ `0x80`; consumes the body.
345
360
  - `composeSignaturePayload(label, leapSeconds,
346
361
  selector, nonce)` — reconstructs the exact byte
347
362
  sequence the server signed.
@@ -368,7 +383,7 @@ are re-exported for callers that need raw TAI64N
368
383
  construction:
369
384
 
370
385
  | Export | Description |
371
- |--------|-------------|
386
+ | ------ | ----------- |
372
387
  | `now()` | Current TAI as `{ sec, nano, offset }` |
373
388
  | `fromUTC(utc)` | `Date.now()`-shaped milliseconds → TAI timestamp |
374
389
  | `tai64nLabel(t?)` | 25-byte label string for a timestamp (or `now()`) |
@@ -383,7 +398,7 @@ history.
383
398
  ### Constants
384
399
 
385
400
  | Name | Value |
386
- |------|-------|
401
+ | ---- | ----- |
387
402
  | `TAISTAMP_PATH` | `/.well-known/taistamp` |
388
403
  | `TAI64N_CONTENT_TYPE` | `application/tai64n` |
389
404
  | `TAI64N_CONTENT_LENGTH` | `25` |