@wemush/wols 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/CHANGELOG.md +170 -0
  2. package/README.md +204 -31
  3. package/dist/cjs/compact-url.d.ts +150 -0
  4. package/dist/cjs/compact-url.d.ts.map +1 -0
  5. package/dist/cjs/crypto/decrypt.d.ts +110 -0
  6. package/dist/cjs/crypto/decrypt.d.ts.map +1 -0
  7. package/dist/cjs/crypto/decrypt.js +519 -99
  8. package/dist/cjs/crypto/decrypt.js.map +1 -1
  9. package/dist/cjs/crypto/encrypt.d.ts +132 -0
  10. package/dist/cjs/crypto/encrypt.d.ts.map +1 -0
  11. package/dist/cjs/crypto/encrypt.js +281 -200
  12. package/dist/cjs/crypto/encrypt.js.map +1 -1
  13. package/dist/cjs/crypto/index.d.ts +12 -0
  14. package/dist/cjs/crypto/index.d.ts.map +1 -0
  15. package/dist/cjs/crypto/index.js +15 -2
  16. package/dist/cjs/crypto/index.js.map +1 -1
  17. package/dist/cjs/crypto/shared.d.ts +116 -0
  18. package/dist/cjs/crypto/shared.d.ts.map +1 -0
  19. package/dist/cjs/crypto/shared.js +238 -0
  20. package/dist/cjs/crypto/shared.js.map +1 -0
  21. package/dist/cjs/errors.d.ts +133 -0
  22. package/dist/cjs/errors.d.ts.map +1 -0
  23. package/dist/cjs/errors.js +39 -1
  24. package/dist/cjs/errors.js.map +1 -1
  25. package/dist/cjs/index.d.ts +29 -0
  26. package/dist/cjs/index.d.ts.map +1 -0
  27. package/dist/cjs/index.js +19 -4
  28. package/dist/cjs/index.js.map +1 -1
  29. package/dist/cjs/package.json +3 -0
  30. package/dist/cjs/parser.d.ts +30 -0
  31. package/dist/cjs/parser.d.ts.map +1 -0
  32. package/dist/cjs/qr/generate.d.ts +62 -0
  33. package/dist/cjs/qr/generate.d.ts.map +1 -0
  34. package/dist/cjs/qr/index.d.ts +10 -0
  35. package/dist/cjs/qr/index.d.ts.map +1 -0
  36. package/dist/cjs/specimen.d.ts +96 -0
  37. package/dist/cjs/specimen.d.ts.map +1 -0
  38. package/dist/cjs/specimen.js +84 -11
  39. package/dist/cjs/specimen.js.map +1 -1
  40. package/dist/cjs/types.d.ts +735 -0
  41. package/dist/cjs/types.d.ts.map +1 -0
  42. package/dist/cjs/types.js +65 -5
  43. package/dist/cjs/types.js.map +1 -1
  44. package/dist/cjs/utils/cuid.d.ts +46 -0
  45. package/dist/cjs/utils/cuid.d.ts.map +1 -0
  46. package/dist/cjs/utils/cuid.js +6 -4
  47. package/dist/cjs/utils/cuid.js.map +1 -1
  48. package/dist/cjs/utils/environment.d.ts +137 -0
  49. package/dist/cjs/utils/environment.d.ts.map +1 -0
  50. package/dist/cjs/utils/iso8601.d.ts +79 -0
  51. package/dist/cjs/utils/iso8601.d.ts.map +1 -0
  52. package/dist/cjs/utils/migration.d.ts +162 -0
  53. package/dist/cjs/utils/migration.d.ts.map +1 -0
  54. package/dist/cjs/validator.d.ts +25 -0
  55. package/dist/cjs/validator.d.ts.map +1 -0
  56. package/dist/cjs/validator.js +33 -22
  57. package/dist/cjs/validator.js.map +1 -1
  58. package/dist/esm/crypto/decrypt.js +515 -99
  59. package/dist/esm/crypto/decrypt.js.map +1 -1
  60. package/dist/esm/crypto/encrypt.js +277 -200
  61. package/dist/esm/crypto/encrypt.js.map +1 -1
  62. package/dist/esm/crypto/index.js +5 -3
  63. package/dist/esm/crypto/index.js.map +1 -1
  64. package/dist/esm/crypto/shared.js +222 -0
  65. package/dist/esm/crypto/shared.js.map +1 -0
  66. package/dist/esm/errors.js +37 -0
  67. package/dist/esm/errors.js.map +1 -1
  68. package/dist/esm/index.js +6 -6
  69. package/dist/esm/index.js.map +1 -1
  70. package/dist/esm/specimen.js +84 -12
  71. package/dist/esm/specimen.js.map +1 -1
  72. package/dist/esm/types.js +63 -4
  73. package/dist/esm/types.js.map +1 -1
  74. package/dist/esm/utils/cuid.js +6 -4
  75. package/dist/esm/utils/cuid.js.map +1 -1
  76. package/dist/esm/validator.js +34 -23
  77. package/dist/esm/validator.js.map +1 -1
  78. package/dist/types/crypto/decrypt.d.ts +93 -22
  79. package/dist/types/crypto/decrypt.d.ts.map +1 -1
  80. package/dist/types/crypto/encrypt.d.ts +106 -61
  81. package/dist/types/crypto/encrypt.d.ts.map +1 -1
  82. package/dist/types/crypto/index.d.ts +5 -3
  83. package/dist/types/crypto/index.d.ts.map +1 -1
  84. package/dist/types/crypto/shared.d.ts +116 -0
  85. package/dist/types/crypto/shared.d.ts.map +1 -0
  86. package/dist/types/errors.d.ts +31 -1
  87. package/dist/types/errors.d.ts.map +1 -1
  88. package/dist/types/index.d.ts +7 -7
  89. package/dist/types/index.d.ts.map +1 -1
  90. package/dist/types/specimen.d.ts +29 -4
  91. package/dist/types/specimen.d.ts.map +1 -1
  92. package/dist/types/types.d.ts +265 -40
  93. package/dist/types/types.d.ts.map +1 -1
  94. package/dist/types/utils/cuid.d.ts +5 -3
  95. package/dist/types/utils/cuid.d.ts.map +1 -1
  96. package/dist/types/validator.d.ts +1 -1
  97. package/dist/types/validator.d.ts.map +1 -1
  98. package/package.json +32 -14
@@ -0,0 +1,110 @@
1
+ /**
2
+ * WOLS Decryption Module (WOLS v1.3.0 encrypted format)
3
+ *
4
+ * Decrypts `wemush://v1/encrypted/...` URLs, the equivalent
5
+ * {@link EncryptedSpecimen} objects, and field-level {@link EncryptedField}
6
+ * values, using WebCrypto only.
7
+ *
8
+ * Failures never throw; they return `{ success: false, error }` where `error`
9
+ * is a {@link WolsDecryptionError} with a stable, typed `reason`.
10
+ *
11
+ * Every cheap check (parameter presence, encodings, IV length, iteration
12
+ * bounds, key type) runs before PBKDF2, so a malformed or hostile label costs
13
+ * no key derivation. The iteration count comes from the label and is bounded
14
+ * by `maxIterations` (default 10,000,000).
15
+ *
16
+ * Legacy payloads (no `kdf`, pre-1.3.0 fixed salt) are rejected with
17
+ * `legacy-format` unless `allowLegacy: true` is passed.
18
+ *
19
+ * @module crypto/decrypt
20
+ */
21
+ import type { DecryptResult, DecryptionOptions, EncryptedField, EncryptedSpecimen, FieldEncryptedSpecimen, Specimen } from '../types.js';
22
+ /**
23
+ * Parse an encrypted-format URL into an {@link EncryptedSpecimen} without decrypting.
24
+ *
25
+ * Only checks URL structure. Parameter rules (kdf, salt, iterations) are
26
+ * enforced on decryption. The path segment is percent-decoded to recover the ID.
27
+ *
28
+ * @since 1.3.0
29
+ */
30
+ export declare function parseEncryptedUrl(url: string): DecryptResult<EncryptedSpecimen>;
31
+ /**
32
+ * Decrypt an encrypted label to its exact plaintext (the embedded JSON-LD string).
33
+ *
34
+ * Enforces every v1.3.0 wire rule, including that the decrypted specimen's
35
+ * `id` equals `wemush:{id}` from the URL path. For object input the check is
36
+ * made against the object's `id`; an object without `id` is not bound to any
37
+ * ID, so prefer the URL form for untrusted input.
38
+ *
39
+ * @param input - `wemush://v1/encrypted/...` URL or an {@link EncryptedSpecimen}
40
+ * @param options - `key`, and optional `allowLegacy` and `maxIterations`
41
+ * @since 1.3.0
42
+ */
43
+ export declare function decryptPlaintext(input: string | EncryptedSpecimen, options: DecryptionOptions): Promise<DecryptResult<string>>;
44
+ /**
45
+ * Decrypt an encrypted label and parse it into a validated Specimen.
46
+ *
47
+ * @param input - `wemush://v1/encrypted/...` URL or an {@link EncryptedSpecimen}
48
+ * @param options - `key`, and optional `allowLegacy` and `maxIterations`
49
+ * @returns DecryptResult; on failure `error.reason` gives the category
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * const result = await decryptSpecimen(url, { key: 'correct horse battery staple' });
54
+ * if (result.success) console.log(result.data.species);
55
+ * else console.error(result.error.reason, result.error.message);
56
+ * ```
57
+ *
58
+ * @since 1.3.0 Accepts encrypted URLs, raw key bytes, `allowLegacy` and `maxIterations`
59
+ */
60
+ export declare function decryptSpecimen(input: string | EncryptedSpecimen, options: DecryptionOptions): Promise<DecryptResult<Specimen>>;
61
+ /**
62
+ * Decrypt a single field-level {@link EncryptedField} to its original value.
63
+ *
64
+ * `binding` names the label and field the value belongs to. It is the AES-GCM
65
+ * additional data (`"{id}\n{field}"`, WOLS 1.3.0), so a value moved to another
66
+ * field or copied from another label fails with `authentication-failed`.
67
+ * Legacy (pre-1.3.0) values, which have no `kdf`, carry no binding.
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * const r = await decryptField(partial.strain, { key }, { id: partial.id, field: 'strain' });
72
+ * ```
73
+ *
74
+ * @since 1.3.0
75
+ */
76
+ export declare function decryptField(field: EncryptedField, options: DecryptionOptions, binding: FieldBinding): Promise<DecryptResult<unknown>>;
77
+ /** The label and top-level field an encrypted value belongs to. */
78
+ export interface FieldBinding {
79
+ /** The label's full id, e.g. `"wemush:clx1a2b3c4"` */
80
+ id: string;
81
+ /** The top-level field name, e.g. `"strain"` */
82
+ field: string;
83
+ }
84
+ /**
85
+ * Decrypt every field-level encrypted value in a specimen produced by
86
+ * `encryptFields()`, and return the restored, validated Specimen.
87
+ *
88
+ * Before any key is derived:
89
+ * - a label whose identifying fields (`@context`, `@type`, `id`, `version`,
90
+ * `type`, `species`) include an encrypted object is refused
91
+ * (`identifying-field`); decrypted values never replace them
92
+ * - every encrypted field is validated
93
+ * - the iterations of each distinct (salt, iterations) pair are summed, and
94
+ * the label is refused if the total exceeds `maxIterations` (10,000,000)
95
+ *
96
+ * Fields sharing a salt and iteration count share one derivation. Each value
97
+ * is authenticated against its AAD, `"{id}\n{field}"`, so swapped or copied
98
+ * values fail with `authentication-failed`.
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * const partial = await encryptFields(specimen, { key, fields: ['strain'] });
103
+ * const restored = await decryptFields(partial, { key });
104
+ * if (restored.success) restored.data.strain?.name;
105
+ * ```
106
+ *
107
+ * @since 1.3.0
108
+ */
109
+ export declare function decryptFields(value: FieldEncryptedSpecimen | Record<string, unknown>, options: DecryptionOptions): Promise<DecryptResult<Specimen>>;
110
+ //# sourceMappingURL=decrypt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decrypt.d.ts","sourceRoot":"","sources":["../../../src/crypto/decrypt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EACV,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EAEjB,sBAAsB,EAEtB,QAAQ,EACT,MAAM,aAAa,CAAC;AAwDrB;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAC,iBAAiB,CAAC,CAuE/E;AAwSD;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,MAAM,GAAG,iBAAiB,EACjC,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CA8BhC;AAeD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,GAAG,iBAAiB,EACjC,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAIlC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAiBjC;AAED,mEAAmE;AACnE,MAAM,WAAW,YAAY;IAC3B,sDAAsD;IACtD,EAAE,EAAE,MAAM,CAAC;IACX,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;CACf;AAsCD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvD,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAyGlC"}