@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.
- package/CHANGELOG.md +170 -0
- package/README.md +204 -31
- package/dist/cjs/compact-url.d.ts +150 -0
- package/dist/cjs/compact-url.d.ts.map +1 -0
- package/dist/cjs/crypto/decrypt.d.ts +110 -0
- package/dist/cjs/crypto/decrypt.d.ts.map +1 -0
- package/dist/cjs/crypto/decrypt.js +519 -99
- package/dist/cjs/crypto/decrypt.js.map +1 -1
- package/dist/cjs/crypto/encrypt.d.ts +132 -0
- package/dist/cjs/crypto/encrypt.d.ts.map +1 -0
- package/dist/cjs/crypto/encrypt.js +281 -200
- package/dist/cjs/crypto/encrypt.js.map +1 -1
- package/dist/cjs/crypto/index.d.ts +12 -0
- package/dist/cjs/crypto/index.d.ts.map +1 -0
- package/dist/cjs/crypto/index.js +15 -2
- package/dist/cjs/crypto/index.js.map +1 -1
- package/dist/cjs/crypto/shared.d.ts +116 -0
- package/dist/cjs/crypto/shared.d.ts.map +1 -0
- package/dist/cjs/crypto/shared.js +238 -0
- package/dist/cjs/crypto/shared.js.map +1 -0
- package/dist/cjs/errors.d.ts +133 -0
- package/dist/cjs/errors.d.ts.map +1 -0
- package/dist/cjs/errors.js +39 -1
- package/dist/cjs/errors.js.map +1 -1
- package/dist/cjs/index.d.ts +29 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +19 -4
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/parser.d.ts +30 -0
- package/dist/cjs/parser.d.ts.map +1 -0
- package/dist/cjs/qr/generate.d.ts +62 -0
- package/dist/cjs/qr/generate.d.ts.map +1 -0
- package/dist/cjs/qr/index.d.ts +10 -0
- package/dist/cjs/qr/index.d.ts.map +1 -0
- package/dist/cjs/specimen.d.ts +96 -0
- package/dist/cjs/specimen.d.ts.map +1 -0
- package/dist/cjs/specimen.js +84 -11
- package/dist/cjs/specimen.js.map +1 -1
- package/dist/cjs/types.d.ts +735 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +65 -5
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/utils/cuid.d.ts +46 -0
- package/dist/cjs/utils/cuid.d.ts.map +1 -0
- package/dist/cjs/utils/cuid.js +6 -4
- package/dist/cjs/utils/cuid.js.map +1 -1
- package/dist/cjs/utils/environment.d.ts +137 -0
- package/dist/cjs/utils/environment.d.ts.map +1 -0
- package/dist/cjs/utils/iso8601.d.ts +79 -0
- package/dist/cjs/utils/iso8601.d.ts.map +1 -0
- package/dist/cjs/utils/migration.d.ts +162 -0
- package/dist/cjs/utils/migration.d.ts.map +1 -0
- package/dist/cjs/validator.d.ts +25 -0
- package/dist/cjs/validator.d.ts.map +1 -0
- package/dist/cjs/validator.js +33 -22
- package/dist/cjs/validator.js.map +1 -1
- package/dist/esm/crypto/decrypt.js +515 -99
- package/dist/esm/crypto/decrypt.js.map +1 -1
- package/dist/esm/crypto/encrypt.js +277 -200
- package/dist/esm/crypto/encrypt.js.map +1 -1
- package/dist/esm/crypto/index.js +5 -3
- package/dist/esm/crypto/index.js.map +1 -1
- package/dist/esm/crypto/shared.js +222 -0
- package/dist/esm/crypto/shared.js.map +1 -0
- package/dist/esm/errors.js +37 -0
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/index.js +6 -6
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/specimen.js +84 -12
- package/dist/esm/specimen.js.map +1 -1
- package/dist/esm/types.js +63 -4
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/utils/cuid.js +6 -4
- package/dist/esm/utils/cuid.js.map +1 -1
- package/dist/esm/validator.js +34 -23
- package/dist/esm/validator.js.map +1 -1
- package/dist/types/crypto/decrypt.d.ts +93 -22
- package/dist/types/crypto/decrypt.d.ts.map +1 -1
- package/dist/types/crypto/encrypt.d.ts +106 -61
- package/dist/types/crypto/encrypt.d.ts.map +1 -1
- package/dist/types/crypto/index.d.ts +5 -3
- package/dist/types/crypto/index.d.ts.map +1 -1
- package/dist/types/crypto/shared.d.ts +116 -0
- package/dist/types/crypto/shared.d.ts.map +1 -0
- package/dist/types/errors.d.ts +31 -1
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/index.d.ts +7 -7
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/specimen.d.ts +29 -4
- package/dist/types/specimen.d.ts.map +1 -1
- package/dist/types/types.d.ts +265 -40
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/utils/cuid.d.ts +5 -3
- package/dist/types/utils/cuid.d.ts.map +1 -1
- package/dist/types/validator.d.ts +1 -1
- package/dist/types/validator.d.ts.map +1 -1
- package/package.json +32 -14
package/dist/cjs/crypto/index.js
CHANGED
|
@@ -2,15 +2,28 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* WOLS Crypto Module
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* AES-256-GCM encryption and decryption for specimens in the WOLS v1.3.0
|
|
6
|
+
* encrypted format (`wemush://v1/encrypted/{id}?e=&iv=&kdf=...`).
|
|
6
7
|
*
|
|
7
8
|
* @module crypto
|
|
8
9
|
*/
|
|
9
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.decryptSpecimen = exports.isEncrypted = exports.encryptSpecimen = void 0;
|
|
11
|
+
exports.derivePassphraseKey = exports.base64UrlDecode = exports.base64UrlEncode = exports.parseEncryptedUrl = exports.decryptFields = exports.decryptField = exports.decryptPlaintext = exports.decryptSpecimen = exports.toEncryptedUrl = exports.isEncryptedField = exports.isEncryptedSpecimen = exports.isEncrypted = exports.encryptFields = exports.encryptSpecimen = void 0;
|
|
11
12
|
var encrypt_js_1 = require("./encrypt.js");
|
|
12
13
|
Object.defineProperty(exports, "encryptSpecimen", { enumerable: true, get: function () { return encrypt_js_1.encryptSpecimen; } });
|
|
14
|
+
Object.defineProperty(exports, "encryptFields", { enumerable: true, get: function () { return encrypt_js_1.encryptFields; } });
|
|
13
15
|
Object.defineProperty(exports, "isEncrypted", { enumerable: true, get: function () { return encrypt_js_1.isEncrypted; } });
|
|
16
|
+
Object.defineProperty(exports, "isEncryptedSpecimen", { enumerable: true, get: function () { return encrypt_js_1.isEncryptedSpecimen; } });
|
|
17
|
+
Object.defineProperty(exports, "isEncryptedField", { enumerable: true, get: function () { return encrypt_js_1.isEncryptedField; } });
|
|
18
|
+
Object.defineProperty(exports, "toEncryptedUrl", { enumerable: true, get: function () { return encrypt_js_1.toEncryptedUrl; } });
|
|
14
19
|
var decrypt_js_1 = require("./decrypt.js");
|
|
15
20
|
Object.defineProperty(exports, "decryptSpecimen", { enumerable: true, get: function () { return decrypt_js_1.decryptSpecimen; } });
|
|
21
|
+
Object.defineProperty(exports, "decryptPlaintext", { enumerable: true, get: function () { return decrypt_js_1.decryptPlaintext; } });
|
|
22
|
+
Object.defineProperty(exports, "decryptField", { enumerable: true, get: function () { return decrypt_js_1.decryptField; } });
|
|
23
|
+
Object.defineProperty(exports, "decryptFields", { enumerable: true, get: function () { return decrypt_js_1.decryptFields; } });
|
|
24
|
+
Object.defineProperty(exports, "parseEncryptedUrl", { enumerable: true, get: function () { return decrypt_js_1.parseEncryptedUrl; } });
|
|
25
|
+
var shared_js_1 = require("./shared.js");
|
|
26
|
+
Object.defineProperty(exports, "base64UrlEncode", { enumerable: true, get: function () { return shared_js_1.base64UrlEncode; } });
|
|
27
|
+
Object.defineProperty(exports, "base64UrlDecode", { enumerable: true, get: function () { return shared_js_1.base64UrlDecode; } });
|
|
28
|
+
Object.defineProperty(exports, "derivePassphraseKey", { enumerable: true, get: function () { return shared_js_1.derivePassphraseKey; } });
|
|
16
29
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/crypto/index.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/crypto/index.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAEH,2CAOsB;AANpB,6GAAA,eAAe,OAAA;AACf,2GAAA,aAAa,OAAA;AACb,yGAAA,WAAW,OAAA;AACX,iHAAA,mBAAmB,OAAA;AACnB,8GAAA,gBAAgB,OAAA;AAChB,4GAAA,cAAc,OAAA;AAEhB,2CAOsB;AANpB,6GAAA,eAAe,OAAA;AACf,8GAAA,gBAAgB,OAAA;AAChB,0GAAA,YAAY,OAAA;AACZ,2GAAA,aAAa,OAAA;AACb,+GAAA,iBAAiB,OAAA;AAGnB,yCAAoF;AAA3E,4GAAA,eAAe,OAAA;AAAE,4GAAA,eAAe,OAAA;AAAE,gHAAA,mBAAmB,OAAA"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared primitives for the WOLS encrypted format (v1.3.0).
|
|
3
|
+
*
|
|
4
|
+
* Uses only WebCrypto (`globalThis.crypto.subtle`), so it runs unchanged in
|
|
5
|
+
* Node.js 20+, browsers, Deno, Bun and workers.
|
|
6
|
+
*
|
|
7
|
+
* `base64UrlEncode`, `base64UrlDecode` and `derivePassphraseKey` are public
|
|
8
|
+
* (re-exported from the package root and `@wemush/wols/crypto`); everything
|
|
9
|
+
* else here is internal to the crypto module.
|
|
10
|
+
*
|
|
11
|
+
* @module crypto/shared
|
|
12
|
+
*/
|
|
13
|
+
import { WolsDecryptionError } from '../errors.js';
|
|
14
|
+
import type { DecryptionFailureReason, RawEncryptionKey } from '../types.js';
|
|
15
|
+
/** Default PBKDF2 iteration count used when generating. */
|
|
16
|
+
export declare const DEFAULT_PBKDF2_ITERATIONS = 600000;
|
|
17
|
+
/** Iteration count pre-1.3.0 payloads used when they recorded none. */
|
|
18
|
+
export declare const LEGACY_PBKDF2_ITERATIONS = 100000;
|
|
19
|
+
/** Generators MUST use at least this many PBKDF2 iterations (WOLS v1.3.0). */
|
|
20
|
+
export declare const MIN_GENERATE_ITERATIONS = 100000;
|
|
21
|
+
/** Decoders MUST reject fewer PBKDF2 iterations than this (WOLS v1.3.0). */
|
|
22
|
+
export declare const MIN_DECODE_ITERATIONS = 10000;
|
|
23
|
+
/** Default largest PBKDF2 iteration count accepted from a label when decoding. */
|
|
24
|
+
export declare const DEFAULT_MAX_DECODE_ITERATIONS = 10000000;
|
|
25
|
+
/**
|
|
26
|
+
* WOLS 1.3.0 ceiling: decoders reject more than this many iterations (alone,
|
|
27
|
+
* or in total across a field-encrypted label), and generators never exceed it.
|
|
28
|
+
* A configured `maxIterations` may be lower, never higher.
|
|
29
|
+
*/
|
|
30
|
+
export declare const MAX_ITERATIONS = 10000000;
|
|
31
|
+
/** WebCrypto's PBKDF2 `iterations` is an unsigned long; nothing above this is derivable. */
|
|
32
|
+
export declare const MAX_PBKDF2_ITERATIONS = 4294967295;
|
|
33
|
+
/** Per-label PBKDF2 salt length generated (spec minimum: 16 bytes). */
|
|
34
|
+
export declare const SALT_LENGTH = 16;
|
|
35
|
+
/** AES-GCM appends a 16-byte authentication tag, so no valid ciphertext is shorter. */
|
|
36
|
+
export declare const GCM_TAG_LENGTH = 16;
|
|
37
|
+
/** AES-GCM IV length in bytes. */
|
|
38
|
+
export declare const IV_LENGTH = 12;
|
|
39
|
+
/** Raw AES-256 key length in bytes. */
|
|
40
|
+
export declare const RAW_KEY_LENGTH = 32;
|
|
41
|
+
/** Prefix of every encrypted-format URL. */
|
|
42
|
+
export declare const ENCRYPTED_URL_PREFIX = "wemush://v1/encrypted/";
|
|
43
|
+
/**
|
|
44
|
+
* Library-wide salt used by pre-1.3.0 releases. Only for decoding legacy
|
|
45
|
+
* payloads behind `allowLegacy`; never used when generating.
|
|
46
|
+
*/
|
|
47
|
+
export declare const LEGACY_PBKDF2_SALT: Uint8Array<ArrayBuffer>;
|
|
48
|
+
/**
|
|
49
|
+
* Create a decryption error carrying a stable `details.reason` category.
|
|
50
|
+
*/
|
|
51
|
+
export declare function decryptionError(reason: DecryptionFailureReason, message: string, details?: Record<string, unknown>): WolsDecryptionError;
|
|
52
|
+
/**
|
|
53
|
+
* Whether WebCrypto (`globalThis.crypto.subtle`) is available. It is global in
|
|
54
|
+
* browsers, workers, Deno, Bun and Node.js 19+ (Node 18 needs
|
|
55
|
+
* `--experimental-global-webcrypto`).
|
|
56
|
+
*/
|
|
57
|
+
export declare function hasWebCrypto(): boolean;
|
|
58
|
+
/** Message used when WebCrypto is missing. */
|
|
59
|
+
export declare const NO_WEBCRYPTO_MESSAGE: string;
|
|
60
|
+
/** Throw a WolsEncryptionError when WebCrypto is missing (encryption paths). */
|
|
61
|
+
export declare function assertWebCrypto(): void;
|
|
62
|
+
/**
|
|
63
|
+
* Encode bytes as base64url (RFC 4648 §5) without padding.
|
|
64
|
+
*
|
|
65
|
+
* @since 1.3.0
|
|
66
|
+
*/
|
|
67
|
+
export declare function base64UrlEncode(bytes: Uint8Array | ArrayBuffer): string;
|
|
68
|
+
/**
|
|
69
|
+
* Decode base64url (RFC 4648 §5). Padded input is accepted.
|
|
70
|
+
*
|
|
71
|
+
* @throws Error if the input is not valid base64url
|
|
72
|
+
* @since 1.3.0
|
|
73
|
+
*/
|
|
74
|
+
export declare function base64UrlDecode(value: string): Uint8Array<ArrayBuffer>;
|
|
75
|
+
/** Cryptographically random bytes from WebCrypto. */
|
|
76
|
+
export declare function randomBytes(length: number): Uint8Array<ArrayBuffer>;
|
|
77
|
+
/**
|
|
78
|
+
* Derive a 256-bit key from a passphrase with PBKDF2-HMAC-SHA256.
|
|
79
|
+
*
|
|
80
|
+
* Exposed for debugging and interoperability testing (it reproduces the
|
|
81
|
+
* conformance `derive` vectors). Returns the raw key bytes.
|
|
82
|
+
*
|
|
83
|
+
* @param passphrase - Passphrase; normalized to Unicode NFC, then UTF-8 encoded (WOLS 1.3.0)
|
|
84
|
+
* @param salt - Salt bytes (the label's decoded `salt` parameter)
|
|
85
|
+
* @param iterations - PBKDF2 iteration count (positive integer)
|
|
86
|
+
* @since 1.3.0
|
|
87
|
+
*/
|
|
88
|
+
export declare function derivePassphraseKey(passphrase: string, salt: Uint8Array | ArrayBuffer, iterations: number): Promise<Uint8Array<ArrayBuffer>>;
|
|
89
|
+
/**
|
|
90
|
+
* Field-level AES-GCM additional data (WOLS 1.3.0): UTF-8 of the label's full
|
|
91
|
+
* `id`, a line feed, and the top-level field name, e.g. "wemush:clx1a2b3c4\nstrain".
|
|
92
|
+
* Binds each encrypted value to its label and field.
|
|
93
|
+
*/
|
|
94
|
+
export declare function fieldAad(id: string, field: string): Uint8Array<ArrayBuffer>;
|
|
95
|
+
/**
|
|
96
|
+
* Fields that identify or type a label. They are never encrypted, and a label
|
|
97
|
+
* in which any of them is an encrypted object is refused (WOLS 1.3.0).
|
|
98
|
+
*/
|
|
99
|
+
export declare const IDENTIFYING_FIELDS: readonly string[];
|
|
100
|
+
/** Import 32 raw key bytes as an AES-GCM key. */
|
|
101
|
+
export declare function importAesKey(bytes: Uint8Array | ArrayBuffer, usage: 'encrypt' | 'decrypt'): Promise<CryptoKey>;
|
|
102
|
+
/**
|
|
103
|
+
* Check whether a value is a WebCrypto CryptoKey without relying on the
|
|
104
|
+
* global `CryptoKey` constructor (absent in some runtimes).
|
|
105
|
+
*/
|
|
106
|
+
export declare function isCryptoKey(value: unknown): value is CryptoKey;
|
|
107
|
+
/**
|
|
108
|
+
* Resolve a raw key (bytes or CryptoKey) to an AES-256-GCM CryptoKey.
|
|
109
|
+
* Returns an error message string when the key is unusable.
|
|
110
|
+
*/
|
|
111
|
+
export declare function resolveRawKey(key: RawEncryptionKey, usage: 'encrypt' | 'decrypt'): Promise<CryptoKey | string>;
|
|
112
|
+
/** Whether a key value is a passphrase (selects kdf=pbkdf2). */
|
|
113
|
+
export declare function isPassphrase(key: unknown): key is string;
|
|
114
|
+
/** Whether a key value is raw key material (selects kdf=raw). */
|
|
115
|
+
export declare function isRawKey(key: unknown): key is RawEncryptionKey;
|
|
116
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/crypto/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared primitives for the WOLS encrypted format (v1.3.0).
|
|
4
|
+
*
|
|
5
|
+
* Uses only WebCrypto (`globalThis.crypto.subtle`), so it runs unchanged in
|
|
6
|
+
* Node.js 20+, browsers, Deno, Bun and workers.
|
|
7
|
+
*
|
|
8
|
+
* `base64UrlEncode`, `base64UrlDecode` and `derivePassphraseKey` are public
|
|
9
|
+
* (re-exported from the package root and `@wemush/wols/crypto`); everything
|
|
10
|
+
* else here is internal to the crypto module.
|
|
11
|
+
*
|
|
12
|
+
* @module crypto/shared
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.IDENTIFYING_FIELDS = exports.NO_WEBCRYPTO_MESSAGE = exports.LEGACY_PBKDF2_SALT = exports.ENCRYPTED_URL_PREFIX = exports.RAW_KEY_LENGTH = exports.IV_LENGTH = exports.GCM_TAG_LENGTH = exports.SALT_LENGTH = exports.MAX_PBKDF2_ITERATIONS = exports.MAX_ITERATIONS = exports.DEFAULT_MAX_DECODE_ITERATIONS = exports.MIN_DECODE_ITERATIONS = exports.MIN_GENERATE_ITERATIONS = exports.LEGACY_PBKDF2_ITERATIONS = exports.DEFAULT_PBKDF2_ITERATIONS = void 0;
|
|
16
|
+
exports.decryptionError = decryptionError;
|
|
17
|
+
exports.hasWebCrypto = hasWebCrypto;
|
|
18
|
+
exports.assertWebCrypto = assertWebCrypto;
|
|
19
|
+
exports.base64UrlEncode = base64UrlEncode;
|
|
20
|
+
exports.base64UrlDecode = base64UrlDecode;
|
|
21
|
+
exports.randomBytes = randomBytes;
|
|
22
|
+
exports.derivePassphraseKey = derivePassphraseKey;
|
|
23
|
+
exports.fieldAad = fieldAad;
|
|
24
|
+
exports.importAesKey = importAesKey;
|
|
25
|
+
exports.isCryptoKey = isCryptoKey;
|
|
26
|
+
exports.resolveRawKey = resolveRawKey;
|
|
27
|
+
exports.isPassphrase = isPassphrase;
|
|
28
|
+
exports.isRawKey = isRawKey;
|
|
29
|
+
const errors_js_1 = require("../errors.js");
|
|
30
|
+
// =============================================================================
|
|
31
|
+
// CONSTANTS
|
|
32
|
+
// =============================================================================
|
|
33
|
+
/** Default PBKDF2 iteration count used when generating. */
|
|
34
|
+
exports.DEFAULT_PBKDF2_ITERATIONS = 600_000;
|
|
35
|
+
/** Iteration count pre-1.3.0 payloads used when they recorded none. */
|
|
36
|
+
exports.LEGACY_PBKDF2_ITERATIONS = 100_000;
|
|
37
|
+
/** Generators MUST use at least this many PBKDF2 iterations (WOLS v1.3.0). */
|
|
38
|
+
exports.MIN_GENERATE_ITERATIONS = 100_000;
|
|
39
|
+
/** Decoders MUST reject fewer PBKDF2 iterations than this (WOLS v1.3.0). */
|
|
40
|
+
exports.MIN_DECODE_ITERATIONS = 10_000;
|
|
41
|
+
/** Default largest PBKDF2 iteration count accepted from a label when decoding. */
|
|
42
|
+
exports.DEFAULT_MAX_DECODE_ITERATIONS = 10_000_000;
|
|
43
|
+
/**
|
|
44
|
+
* WOLS 1.3.0 ceiling: decoders reject more than this many iterations (alone,
|
|
45
|
+
* or in total across a field-encrypted label), and generators never exceed it.
|
|
46
|
+
* A configured `maxIterations` may be lower, never higher.
|
|
47
|
+
*/
|
|
48
|
+
exports.MAX_ITERATIONS = 10_000_000;
|
|
49
|
+
/** WebCrypto's PBKDF2 `iterations` is an unsigned long; nothing above this is derivable. */
|
|
50
|
+
exports.MAX_PBKDF2_ITERATIONS = 0xffff_ffff;
|
|
51
|
+
/** Per-label PBKDF2 salt length generated (spec minimum: 16 bytes). */
|
|
52
|
+
exports.SALT_LENGTH = 16;
|
|
53
|
+
/** AES-GCM appends a 16-byte authentication tag, so no valid ciphertext is shorter. */
|
|
54
|
+
exports.GCM_TAG_LENGTH = 16;
|
|
55
|
+
/** AES-GCM IV length in bytes. */
|
|
56
|
+
exports.IV_LENGTH = 12;
|
|
57
|
+
/** Raw AES-256 key length in bytes. */
|
|
58
|
+
exports.RAW_KEY_LENGTH = 32;
|
|
59
|
+
/** Prefix of every encrypted-format URL. */
|
|
60
|
+
exports.ENCRYPTED_URL_PREFIX = 'wemush://v1/encrypted/';
|
|
61
|
+
/**
|
|
62
|
+
* Library-wide salt used by pre-1.3.0 releases. Only for decoding legacy
|
|
63
|
+
* payloads behind `allowLegacy`; never used when generating.
|
|
64
|
+
*/
|
|
65
|
+
exports.LEGACY_PBKDF2_SALT = new TextEncoder().encode('@wemush/wols/crypto/v1');
|
|
66
|
+
// =============================================================================
|
|
67
|
+
// ERRORS
|
|
68
|
+
// =============================================================================
|
|
69
|
+
/**
|
|
70
|
+
* Create a decryption error carrying a stable `details.reason` category.
|
|
71
|
+
*/
|
|
72
|
+
function decryptionError(reason, message, details = {}) {
|
|
73
|
+
return new errors_js_1.WolsDecryptionError(reason, message, details);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Whether WebCrypto (`globalThis.crypto.subtle`) is available. It is global in
|
|
77
|
+
* browsers, workers, Deno, Bun and Node.js 19+ (Node 18 needs
|
|
78
|
+
* `--experimental-global-webcrypto`).
|
|
79
|
+
*/
|
|
80
|
+
function hasWebCrypto() {
|
|
81
|
+
const c = globalThis.crypto;
|
|
82
|
+
return (typeof c?.subtle === 'object' && c.subtle !== null && typeof c.getRandomValues === 'function');
|
|
83
|
+
}
|
|
84
|
+
/** Message used when WebCrypto is missing. */
|
|
85
|
+
exports.NO_WEBCRYPTO_MESSAGE = 'WebCrypto (globalThis.crypto.subtle) is not available in this runtime. ' +
|
|
86
|
+
'Use Node.js 20+, a modern browser, Deno or Bun.';
|
|
87
|
+
/** Throw a WolsEncryptionError when WebCrypto is missing (encryption paths). */
|
|
88
|
+
function assertWebCrypto() {
|
|
89
|
+
if (!hasWebCrypto()) {
|
|
90
|
+
throw new errors_js_1.WolsEncryptionError(errors_js_1.WolsErrorCode.ENCRYPTION_ERROR, exports.NO_WEBCRYPTO_MESSAGE);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// =============================================================================
|
|
94
|
+
// BASE64URL
|
|
95
|
+
// =============================================================================
|
|
96
|
+
/**
|
|
97
|
+
* Encode bytes as base64url (RFC 4648 §5) without padding.
|
|
98
|
+
*
|
|
99
|
+
* @since 1.3.0
|
|
100
|
+
*/
|
|
101
|
+
function base64UrlEncode(bytes) {
|
|
102
|
+
const view = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
|
|
103
|
+
let binary = '';
|
|
104
|
+
for (const byte of view) {
|
|
105
|
+
binary += String.fromCharCode(byte);
|
|
106
|
+
}
|
|
107
|
+
return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
108
|
+
}
|
|
109
|
+
const BASE64URL_PATTERN = /^[A-Za-z0-9_-]*={0,2}$/;
|
|
110
|
+
/**
|
|
111
|
+
* Decode base64url (RFC 4648 §5). Padded input is accepted.
|
|
112
|
+
*
|
|
113
|
+
* @throws Error if the input is not valid base64url
|
|
114
|
+
* @since 1.3.0
|
|
115
|
+
*/
|
|
116
|
+
function base64UrlDecode(value) {
|
|
117
|
+
if (!BASE64URL_PATTERN.test(value)) {
|
|
118
|
+
throw new Error('Invalid base64url string');
|
|
119
|
+
}
|
|
120
|
+
const unpadded = value.replace(/=+$/, '');
|
|
121
|
+
if (unpadded.length % 4 === 1) {
|
|
122
|
+
throw new Error('Invalid base64url length');
|
|
123
|
+
}
|
|
124
|
+
const base64 = unpadded.replace(/-/g, '+').replace(/_/g, '/');
|
|
125
|
+
const binary = atob(base64.padEnd(base64.length + ((4 - (base64.length % 4)) % 4), '='));
|
|
126
|
+
const bytes = new Uint8Array(binary.length);
|
|
127
|
+
for (let i = 0; i < binary.length; i++) {
|
|
128
|
+
bytes[i] = binary.charCodeAt(i);
|
|
129
|
+
}
|
|
130
|
+
return bytes;
|
|
131
|
+
}
|
|
132
|
+
// =============================================================================
|
|
133
|
+
// RANDOMNESS
|
|
134
|
+
// =============================================================================
|
|
135
|
+
/** Cryptographically random bytes from WebCrypto. */
|
|
136
|
+
function randomBytes(length) {
|
|
137
|
+
const bytes = new Uint8Array(length);
|
|
138
|
+
crypto.getRandomValues(bytes);
|
|
139
|
+
return bytes;
|
|
140
|
+
}
|
|
141
|
+
// =============================================================================
|
|
142
|
+
// KEYS
|
|
143
|
+
// =============================================================================
|
|
144
|
+
/** Copy a byte view into a fresh ArrayBuffer-backed Uint8Array (WebCrypto-safe). */
|
|
145
|
+
function toOwnedBytes(bytes) {
|
|
146
|
+
const view = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
|
|
147
|
+
const copy = new Uint8Array(view.length);
|
|
148
|
+
copy.set(view);
|
|
149
|
+
return copy;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Derive a 256-bit key from a passphrase with PBKDF2-HMAC-SHA256.
|
|
153
|
+
*
|
|
154
|
+
* Exposed for debugging and interoperability testing (it reproduces the
|
|
155
|
+
* conformance `derive` vectors). Returns the raw key bytes.
|
|
156
|
+
*
|
|
157
|
+
* @param passphrase - Passphrase; normalized to Unicode NFC, then UTF-8 encoded (WOLS 1.3.0)
|
|
158
|
+
* @param salt - Salt bytes (the label's decoded `salt` parameter)
|
|
159
|
+
* @param iterations - PBKDF2 iteration count (positive integer)
|
|
160
|
+
* @since 1.3.0
|
|
161
|
+
*/
|
|
162
|
+
async function derivePassphraseKey(passphrase, salt, iterations) {
|
|
163
|
+
if (!Number.isInteger(iterations) || iterations < 1 || iterations > exports.MAX_PBKDF2_ITERATIONS) {
|
|
164
|
+
throw new Error(`PBKDF2 iterations must be an integer from 1 to ${exports.MAX_PBKDF2_ITERATIONS}, got ${iterations}`);
|
|
165
|
+
}
|
|
166
|
+
const material = await crypto.subtle.importKey('raw',
|
|
167
|
+
// WOLS 1.3.0: NFC so composed and decomposed input derive the same key.
|
|
168
|
+
new TextEncoder().encode(passphrase.normalize('NFC')), 'PBKDF2', false, ['deriveBits']);
|
|
169
|
+
const bits = await crypto.subtle.deriveBits({ name: 'PBKDF2', hash: 'SHA-256', salt: toOwnedBytes(salt), iterations }, material, 256);
|
|
170
|
+
return new Uint8Array(bits);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Field-level AES-GCM additional data (WOLS 1.3.0): UTF-8 of the label's full
|
|
174
|
+
* `id`, a line feed, and the top-level field name, e.g. "wemush:clx1a2b3c4\nstrain".
|
|
175
|
+
* Binds each encrypted value to its label and field.
|
|
176
|
+
*/
|
|
177
|
+
function fieldAad(id, field) {
|
|
178
|
+
return new TextEncoder().encode(`${id}\n${field}`);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Fields that identify or type a label. They are never encrypted, and a label
|
|
182
|
+
* in which any of them is an encrypted object is refused (WOLS 1.3.0).
|
|
183
|
+
*/
|
|
184
|
+
exports.IDENTIFYING_FIELDS = [
|
|
185
|
+
'@context',
|
|
186
|
+
'@type',
|
|
187
|
+
'id',
|
|
188
|
+
'version',
|
|
189
|
+
'type',
|
|
190
|
+
'species',
|
|
191
|
+
];
|
|
192
|
+
/** Import 32 raw key bytes as an AES-GCM key. */
|
|
193
|
+
async function importAesKey(bytes, usage) {
|
|
194
|
+
return crypto.subtle.importKey('raw', toOwnedBytes(bytes), { name: 'AES-GCM' }, false, [usage]);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Check whether a value is a WebCrypto CryptoKey without relying on the
|
|
198
|
+
* global `CryptoKey` constructor (absent in some runtimes).
|
|
199
|
+
*/
|
|
200
|
+
function isCryptoKey(value) {
|
|
201
|
+
return (typeof value === 'object' &&
|
|
202
|
+
value !== null &&
|
|
203
|
+
'algorithm' in value &&
|
|
204
|
+
'usages' in value &&
|
|
205
|
+
'type' in value &&
|
|
206
|
+
!(value instanceof Uint8Array) &&
|
|
207
|
+
!(value instanceof ArrayBuffer));
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Resolve a raw key (bytes or CryptoKey) to an AES-256-GCM CryptoKey.
|
|
211
|
+
* Returns an error message string when the key is unusable.
|
|
212
|
+
*/
|
|
213
|
+
async function resolveRawKey(key, usage) {
|
|
214
|
+
if (isCryptoKey(key)) {
|
|
215
|
+
const algorithm = key.algorithm;
|
|
216
|
+
if (algorithm.name !== 'AES-GCM' || algorithm.length !== 256) {
|
|
217
|
+
return `CryptoKey must be AES-GCM with length 256, got ${algorithm.name ?? 'unknown'}/${algorithm.length ?? '?'}`;
|
|
218
|
+
}
|
|
219
|
+
if (!key.usages.includes(usage)) {
|
|
220
|
+
return `CryptoKey does not allow '${usage}'`;
|
|
221
|
+
}
|
|
222
|
+
return key;
|
|
223
|
+
}
|
|
224
|
+
const length = key instanceof Uint8Array ? key.length : key.byteLength;
|
|
225
|
+
if (length !== exports.RAW_KEY_LENGTH) {
|
|
226
|
+
return `Raw key must be exactly ${exports.RAW_KEY_LENGTH} bytes, got ${length}`;
|
|
227
|
+
}
|
|
228
|
+
return importAesKey(key, usage);
|
|
229
|
+
}
|
|
230
|
+
/** Whether a key value is a passphrase (selects kdf=pbkdf2). */
|
|
231
|
+
function isPassphrase(key) {
|
|
232
|
+
return typeof key === 'string';
|
|
233
|
+
}
|
|
234
|
+
/** Whether a key value is raw key material (selects kdf=raw). */
|
|
235
|
+
function isRawKey(key) {
|
|
236
|
+
return key instanceof Uint8Array || key instanceof ArrayBuffer || isCryptoKey(key);
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/crypto/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WOLS Error Types
|
|
3
|
+
*
|
|
4
|
+
* This module defines all error classes and error codes
|
|
5
|
+
* used by the WOLS TypeScript library.
|
|
6
|
+
*
|
|
7
|
+
* @module errors
|
|
8
|
+
*/
|
|
9
|
+
import type { DecryptionFailureReason, ValidationError } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* WOLS error codes (stable, for programmatic handling).
|
|
12
|
+
*/
|
|
13
|
+
export declare enum WolsErrorCode {
|
|
14
|
+
/** General parse error */
|
|
15
|
+
PARSE_ERROR = "WOLS_PARSE_ERROR",
|
|
16
|
+
/** Invalid JSON syntax */
|
|
17
|
+
INVALID_JSON = "WOLS_INVALID_JSON",
|
|
18
|
+
/** Not a valid WOLS format */
|
|
19
|
+
INVALID_FORMAT = "WOLS_INVALID_FORMAT",
|
|
20
|
+
/** Missing or invalid @context field */
|
|
21
|
+
INVALID_CONTEXT = "WOLS_INVALID_CONTEXT",
|
|
22
|
+
/** Missing or invalid @type field */
|
|
23
|
+
INVALID_TYPE = "WOLS_INVALID_TYPE",
|
|
24
|
+
/** ID doesn't match wemush:[a-z0-9]+ pattern */
|
|
25
|
+
INVALID_ID_FORMAT = "WOLS_INVALID_ID_FORMAT",
|
|
26
|
+
/** Version not valid semver */
|
|
27
|
+
INVALID_VERSION = "WOLS_INVALID_VERSION",
|
|
28
|
+
/** Type not in SpecimenType enum */
|
|
29
|
+
INVALID_SPECIMEN_TYPE = "WOLS_INVALID_SPECIMEN_TYPE",
|
|
30
|
+
/** Required field is missing */
|
|
31
|
+
REQUIRED_FIELD = "WOLS_REQUIRED_FIELD",
|
|
32
|
+
/** Date not in ISO 8601 format */
|
|
33
|
+
INVALID_DATE_FORMAT = "WOLS_INVALID_DATE_FORMAT",
|
|
34
|
+
/** Strain generation format is invalid */
|
|
35
|
+
INVALID_GENERATION = "WOLS_INVALID_GENERATION",
|
|
36
|
+
/** Invalid compact URL format */
|
|
37
|
+
INVALID_URL = "WOLS_INVALID_URL",
|
|
38
|
+
/** Encryption operation failed */
|
|
39
|
+
ENCRYPTION_ERROR = "WOLS_ENCRYPTION_ERROR",
|
|
40
|
+
/** Decryption operation failed */
|
|
41
|
+
DECRYPTION_ERROR = "WOLS_DECRYPTION_ERROR",
|
|
42
|
+
/** Invalid encryption key */
|
|
43
|
+
INVALID_KEY = "WOLS_INVALID_KEY",
|
|
44
|
+
/** Payload exceeds QR code capacity */
|
|
45
|
+
SIZE_EXCEEDED = "WOLS_SIZE_EXCEEDED",
|
|
46
|
+
/** Unknown or unspecified error */
|
|
47
|
+
UNKNOWN_ERROR = "WOLS_UNKNOWN_ERROR"
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Base WOLS error class.
|
|
51
|
+
* All WOLS-specific errors extend this class.
|
|
52
|
+
*/
|
|
53
|
+
export declare class WolsError extends Error {
|
|
54
|
+
/** Error code for programmatic handling */
|
|
55
|
+
readonly code: WolsErrorCode;
|
|
56
|
+
/** Additional error details */
|
|
57
|
+
readonly details: Record<string, unknown> | undefined;
|
|
58
|
+
constructor(code: WolsErrorCode, message: string, details?: Record<string, unknown>);
|
|
59
|
+
/**
|
|
60
|
+
* Convert error to JSON for serialization.
|
|
61
|
+
*/
|
|
62
|
+
toJSON(): Record<string, unknown>;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Parse error (JSON/format issues).
|
|
66
|
+
* Thrown when parsing JSON or WOLS data fails.
|
|
67
|
+
*/
|
|
68
|
+
export declare class WolsParseError extends WolsError {
|
|
69
|
+
/** Character position in the input where error occurred */
|
|
70
|
+
readonly position: number | undefined;
|
|
71
|
+
constructor(code: WolsErrorCode, message: string, details?: Record<string, unknown> & {
|
|
72
|
+
position?: number;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Validation error (schema violations).
|
|
77
|
+
* Thrown when specimen data fails validation.
|
|
78
|
+
*/
|
|
79
|
+
export declare class WolsValidationError extends WolsError {
|
|
80
|
+
/** Array of validation errors */
|
|
81
|
+
readonly errors: ValidationError[];
|
|
82
|
+
constructor(message: string, errors: ValidationError[]);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Encryption/decryption error.
|
|
86
|
+
* Thrown when crypto operations fail.
|
|
87
|
+
*/
|
|
88
|
+
export declare class WolsEncryptionError extends WolsError {
|
|
89
|
+
constructor(code: WolsErrorCode, message: string, details?: Record<string, unknown>);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Decryption failure with a stable, typed {@link DecryptionFailureReason}.
|
|
93
|
+
*
|
|
94
|
+
* It extends `WolsEncryptionError` on purpose: 1.2.x returned a
|
|
95
|
+
* `WolsEncryptionError` for decryption failures, so existing
|
|
96
|
+
* `instanceof WolsEncryptionError` checks keep matching. Encryption misuse is
|
|
97
|
+
* thrown as a plain `WolsEncryptionError`; decryption failures are returned as
|
|
98
|
+
* this subclass, so check `instanceof WolsDecryptionError` to tell them apart.
|
|
99
|
+
* Malformed encrypted URLs are reported here too (`invalid-url`), not as
|
|
100
|
+
* `WolsParseError`, so every decryption input problem has one error type.
|
|
101
|
+
*
|
|
102
|
+
* Returned (never thrown) by `decryptSpecimen`, `decryptPlaintext`,
|
|
103
|
+
* `decryptField` and `decryptFields`. `reason` is also copied into
|
|
104
|
+
* `details.reason` for code that reads the generic error shape.
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```typescript
|
|
108
|
+
* const r = await decryptSpecimen(url, { key });
|
|
109
|
+
* if (!r.success && r.error.reason === 'legacy-format') {
|
|
110
|
+
* // a pre-1.3.0 label: retry with { allowLegacy: true } during migration
|
|
111
|
+
* }
|
|
112
|
+
* ```
|
|
113
|
+
*
|
|
114
|
+
* @since 1.3.0
|
|
115
|
+
*/
|
|
116
|
+
export declare class WolsDecryptionError extends WolsEncryptionError {
|
|
117
|
+
/** Stable failure category */
|
|
118
|
+
readonly reason: DecryptionFailureReason;
|
|
119
|
+
constructor(reason: DecryptionFailureReason, message: string, details?: Record<string, unknown>);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Create a required field error.
|
|
123
|
+
*/
|
|
124
|
+
export declare function requiredFieldError(field: string, path?: string): WolsValidationError;
|
|
125
|
+
/**
|
|
126
|
+
* Create an invalid format error.
|
|
127
|
+
*/
|
|
128
|
+
export declare function invalidFormatError(field: string, expected: string, path?: string): WolsValidationError;
|
|
129
|
+
/**
|
|
130
|
+
* Create a parse error from a caught exception.
|
|
131
|
+
*/
|
|
132
|
+
export declare function parseErrorFromException(error: unknown, _input?: string): WolsParseError;
|
|
133
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAM3E;;GAEG;AACH,oBAAY,aAAa;IACvB,0BAA0B;IAC1B,WAAW,qBAAqB;IAChC,0BAA0B;IAC1B,YAAY,sBAAsB;IAClC,8BAA8B;IAC9B,cAAc,wBAAwB;IACtC,wCAAwC;IACxC,eAAe,yBAAyB;IACxC,qCAAqC;IACrC,YAAY,sBAAsB;IAClC,gDAAgD;IAChD,iBAAiB,2BAA2B;IAC5C,+BAA+B;IAC/B,eAAe,yBAAyB;IACxC,oCAAoC;IACpC,qBAAqB,+BAA+B;IACpD,gCAAgC;IAChC,cAAc,wBAAwB;IACtC,kCAAkC;IAClC,mBAAmB,6BAA6B;IAChD,0CAA0C;IAC1C,kBAAkB,4BAA4B;IAC9C,iCAAiC;IACjC,WAAW,qBAAqB;IAChC,kCAAkC;IAClC,gBAAgB,0BAA0B;IAC1C,kCAAkC;IAClC,gBAAgB,0BAA0B;IAC1C,6BAA6B;IAC7B,WAAW,qBAAqB;IAChC,uCAAuC;IACvC,aAAa,uBAAuB;IACpC,mCAAmC;IACnC,aAAa,uBAAuB;CACrC;AAMD;;;GAGG;AACH,qBAAa,SAAU,SAAQ,KAAK;IAClC,2CAA2C;IAC3C,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,+BAA+B;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;gBAE1C,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAYnF;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAQlC;AAED;;;GAGG;AACH,qBAAa,cAAe,SAAQ,SAAS;IAC3C,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;gBAGpC,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE;CAU5D;AAED;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,SAAS;IAChD,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC;gBAEvB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE;CASvD;AAED;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,SAAS;gBACpC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAQpF;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,mBAAoB,SAAQ,mBAAmB;IAC1D,8BAA8B;IAC9B,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAC;gBAE7B,MAAM,EAAE,uBAAuB,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAahG;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,MAAc,GAAG,mBAAmB,CAQ3F;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,MAAc,GACnB,mBAAmB,CAQrB;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,cAAc,CAoBvF"}
|
package/dist/cjs/errors.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* @module errors
|
|
9
9
|
*/
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
exports.WolsEncryptionError = exports.WolsValidationError = exports.WolsParseError = exports.WolsError = exports.WolsErrorCode = void 0;
|
|
11
|
+
exports.WolsDecryptionError = exports.WolsEncryptionError = exports.WolsValidationError = exports.WolsParseError = exports.WolsError = exports.WolsErrorCode = void 0;
|
|
12
12
|
exports.requiredFieldError = requiredFieldError;
|
|
13
13
|
exports.invalidFormatError = invalidFormatError;
|
|
14
14
|
exports.parseErrorFromException = parseErrorFromException;
|
|
@@ -138,6 +138,44 @@ class WolsEncryptionError extends WolsError {
|
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
exports.WolsEncryptionError = WolsEncryptionError;
|
|
141
|
+
/**
|
|
142
|
+
* Decryption failure with a stable, typed {@link DecryptionFailureReason}.
|
|
143
|
+
*
|
|
144
|
+
* It extends `WolsEncryptionError` on purpose: 1.2.x returned a
|
|
145
|
+
* `WolsEncryptionError` for decryption failures, so existing
|
|
146
|
+
* `instanceof WolsEncryptionError` checks keep matching. Encryption misuse is
|
|
147
|
+
* thrown as a plain `WolsEncryptionError`; decryption failures are returned as
|
|
148
|
+
* this subclass, so check `instanceof WolsDecryptionError` to tell them apart.
|
|
149
|
+
* Malformed encrypted URLs are reported here too (`invalid-url`), not as
|
|
150
|
+
* `WolsParseError`, so every decryption input problem has one error type.
|
|
151
|
+
*
|
|
152
|
+
* Returned (never thrown) by `decryptSpecimen`, `decryptPlaintext`,
|
|
153
|
+
* `decryptField` and `decryptFields`. `reason` is also copied into
|
|
154
|
+
* `details.reason` for code that reads the generic error shape.
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```typescript
|
|
158
|
+
* const r = await decryptSpecimen(url, { key });
|
|
159
|
+
* if (!r.success && r.error.reason === 'legacy-format') {
|
|
160
|
+
* // a pre-1.3.0 label: retry with { allowLegacy: true } during migration
|
|
161
|
+
* }
|
|
162
|
+
* ```
|
|
163
|
+
*
|
|
164
|
+
* @since 1.3.0
|
|
165
|
+
*/
|
|
166
|
+
class WolsDecryptionError extends WolsEncryptionError {
|
|
167
|
+
/** Stable failure category */
|
|
168
|
+
reason;
|
|
169
|
+
constructor(reason, message, details) {
|
|
170
|
+
super(reason === 'invalid-key' ? WolsErrorCode.INVALID_KEY : WolsErrorCode.DECRYPTION_ERROR, message, { ...details, reason });
|
|
171
|
+
this.name = 'WolsDecryptionError';
|
|
172
|
+
this.reason = reason;
|
|
173
|
+
if (Error.captureStackTrace) {
|
|
174
|
+
Error.captureStackTrace(this, WolsDecryptionError);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
exports.WolsDecryptionError = WolsDecryptionError;
|
|
141
179
|
// =============================================================================
|
|
142
180
|
// ERROR FACTORY FUNCTIONS
|
|
143
181
|
// =============================================================================
|
package/dist/cjs/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"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"}
|