@blamejs/core 0.7.76 → 0.7.77

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 CHANGED
@@ -8,6 +8,8 @@ upgrading across more than a few patches at a time.
8
8
 
9
9
  ## v0.7.x
10
10
 
11
+ - **0.7.77** (2026-05-06) — Argon2 switched from vendored prebuilds to Node's built-in `crypto.argon2*` (Node 24+). The framework's `lib/vendor/argon2/` directory (with the `argon2.cjs` bundle and the `prebuilds/` tree of platform-specific `.glibc.node` / `.musl.node` artifacts for darwin-arm64 / darwin-x64 / freebsd-arm64 / freebsd-x64 / linux-arm / linux-arm64 / linux-x64 / win32-x64) is **deleted**. New `lib/argon2-builtin.js` is a thin wrapper over `crypto.argon2Sync` that produces and parses the PHC string format (`$argon2id$v=19$m=...,t=...,p=...$<salt>$<hash>`). Wire-format compatibility preserved: existing rows in operator databases continue to verify. Behavior preserved: `b.auth.password.hash` / `.verify` / `.needsRehash` retain their async signatures and return shapes; `b.vault.wrap` and `b.backupCrypto.deriveKey` use the same `raw: true` path for raw-bytes output. Operators wanting to supply their own argon2 implementation (pinned upstream, hardware-accelerated, etc.) override at the call site via `opts.argon2` — the supplied object MUST expose the same `hash` / `verify` / `needsRehash` shape. Drops ~440 KB of platform-specific native prebuilds from the repository and shipped npm tarball; eliminates a supply-chain hop. The vendor manifest's `argon2` entry is removed; `scripts/vendor-update.sh argon2` now refuses with a pointer to `lib/argon2-builtin.js`.
12
+
11
13
  - **0.7.76** (2026-05-06) — CVE-class web hardening sweep — Trojan Source (CVE-2021-42574) log defense + drive-by-MIME attachment opt for `staticServe`. **Trojan Source defense** in `b.log` output: every log line now post-processes Unicode bidi / format-control characters (U+061C / U+200E-200F / U+202A-202E / U+2066-2069) into their `\uXXXX` literal escape on the wire so a hostile log message can't re-order the visible line in a TTY / syslog / file reader. JSON.stringify alone does NOT escape these codepoints, so a captured-error message containing `U+202E` (RIGHT-TO-LEFT OVERRIDE) survives into the log surface and silently flips visible field/key associations. The escape applies to the entire serialized JSON line including any extras / bound-context fields. **`staticServe.create({ safeAttachmentForRiskyMimes: true })`** — opt-in flag that adds `Content-Disposition: attachment` to responses whose Content-Type is in the risky-inline-MIME set (`text/html`, `text/xml`, `application/xml`, `application/xhtml+xml`, `image/svg+xml`, `application/javascript`, `text/javascript`, `application/x-javascript`). Defends against drive-by execution of user-uploaded HTML / JS / SVG (CVE-2017-15012 SVG XSS / CVE-2009-1312 HTML drive-by class). Default `false` — operators serving framework asset bundles continue to render inline; operators serving user-content directories opt in. Filename is RFC 5987-encoded (ASCII filename + `filename*=UTF-8''...`) so non-ASCII filenames survive without allowing CR/LF header injection.
12
14
 
13
15
  - **0.7.75** (2026-05-06) — Audit-emit redaction pipeline. `b.audit.safeEmit` now scrubs the `actor` / `reason` / `metadata` fields through `b.redact.redact()` before they hit the audit handler. Operators who pass `metadata: { reason: e.message }` from a caught error could land DB connection strings, bearer tokens, JWT compact-serialization fixtures, AWS access keys, PEM private keys, SSH keys, credit cards, and SSNs in audit rows; the redact pipeline catches the common shapes (sensitive field names + value-shape detectors) and replaces them with markers (`[REDACTED]`, `[REDACTED-CONN-STRING]`, `[REDACTED-JWT]`, `[REDACTED-PEM]`, `[REDACTED-AWS-KEY]`, `[REDACTED-CC]`, `[REDACTED-SSN]`, `[REDACTED-SEALED]`, `[REDACTED-SSH-KEY]`). The `b.redact` primitive existed in lib/ since v0.4.x but was dead code — `audit.safeEmit` previously passed metadata through unchanged. New connection-string detector matches `protocol://user:pass@host` shapes that surface in error messages from external-DB / SMTP / HTTP drivers (RFC 3986 generic syntax). Drop-silent on redact failure — the pipeline never breaks the caller's audit attempt.
package/NOTICE CHANGED
@@ -24,16 +24,6 @@ Copyright: Copyright (c) 2023 Paul Miller (https://paulmillr.com)
24
24
  Used for: XChaCha20-Poly1305 authenticated encryption (lib/crypto.js,
25
25
  lib/vault-wrap.js, via lib/vendor/noble-ciphers.cjs)
26
26
  --------------------------------------------------------------------------------
27
- Component: argon2 (node-argon2)
28
- Version: 0.44.0
29
- Source: https://github.com/ranisalt/node-argon2
30
- License: MIT
31
- Copyright: Copyright (c) 2017 Ranieri Althoff
32
- Used for: Argon2id passphrase-derived key derivation in the vault wrap
33
- format (lib/vault-wrap.js, via lib/vendor/argon2/). Native
34
- prebuilds shipped for darwin-{arm64,x64}, freebsd-{arm64,x64},
35
- linux-{arm,arm64,x64}, win32-x64.
36
- --------------------------------------------------------------------------------
37
27
  Component: @simplewebauthn/server
38
28
  Version: 13.3.0
39
29
  Source: https://github.com/MasterKale/SimpleWebAuthn
package/README.md CHANGED
@@ -114,7 +114,6 @@ All runtime dependencies are committed to the repo — no transitive npm install
114
114
  |---|---|---|---|
115
115
  | [`@noble/ciphers`](https://github.com/paulmillr/noble-ciphers) | 2.2.0 | [Paul Miller](https://github.com/paulmillr) | XChaCha20-Poly1305 AEAD |
116
116
  | [`@simplewebauthn/server`](https://github.com/MasterKale/SimpleWebAuthn) | 13.3.0 | [Matthew Miller](https://github.com/MasterKale) | WebAuthn / passkey verification |
117
- | [`argon2`](https://github.com/ranisalt/node-argon2) | 0.44.0 | [Ranieri Althoff](https://github.com/ranisalt) | Password hashing (native prebuilds, 8 platforms) |
118
117
  | [`@peculiar/x509`](https://github.com/PeculiarVentures/x509) + [`pkijs`](https://github.com/PeculiarVentures/PKI.js) | 2.0.0 + 3.4.0 | [Peculiar Ventures](https://github.com/PeculiarVentures) | Pure-JS mTLS CA — ECDSA P-384 cert signing, PKCS#12 packaging (no openssl CLI) |
119
118
  | [`SecLists` 10k-most-common.txt](https://github.com/danielmiessler/SecLists/blob/master/Passwords/Common-Credentials/10k-most-common.txt) | master snapshot | [Daniel Miessler / SecLists contributors](https://github.com/danielmiessler/SecLists) (CC-BY-3.0) | Top-10000 common-password dictionary read by `b.auth.password.policy()` for the NIST 800-63B §5.1.1.2 "previously breached" check |
120
119
  | [`prismjs`](https://prismjs.com/) | 1.30.0 | [Lea Verou + contributors](https://github.com/PrismJS/prism) | Syntax highlighting in the example wiki's code blocks (browser-side) |
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ /**
3
+ * Thin wrapper over Node's built-in `crypto.argon2` that produces and
4
+ * parses the PHC string format
5
+ * (`$argon2id$v=19$m=65536,t=3,p=4$<salt>$<hash>`).
6
+ *
7
+ * Replaces the vendored `lib/vendor/argon2/` prebuilds (which the
8
+ * framework carried since v0.4.x). Node 24+ ships a stable
9
+ * `crypto.argon2*` API; vendoring the third-party native module is no
10
+ * longer necessary, eliminates the supply-chain weight of platform-
11
+ * specific prebuilds, and keeps the framework's "zero npm runtime
12
+ * deps" posture intact without dragging argon2 prebuild artifacts
13
+ * across every install.
14
+ *
15
+ * Operators wanting to supply their own argon2 implementation (e.g.
16
+ * pinned to a specific upstream commit, or routed through a hardware-
17
+ * backed accelerator) override at the call site by passing `argon2:`
18
+ * in opts to `b.auth.password.hash` / `.verify` / `.needsRehash`. The
19
+ * supplied object MUST expose the same `hash` / `verify` /
20
+ * `needsRehash` shape this wrapper exposes.
21
+ */
22
+
23
+ var nodeCrypto = require("crypto");
24
+ var blamejsCrypto = require("./crypto");
25
+ var C = require("./constants");
26
+
27
+ var ARGON2ID = "argon2id";
28
+
29
+ // Argon2 v1.3 — the only version current implementations emit.
30
+ var ARGON2_VERSION = 0x13; // allow:raw-byte-literal — argon2 algorithm version
31
+
32
+ var DEFAULT_HASH_LENGTH = C.BYTES.bytes(32);
33
+ var DEFAULT_SALT_LENGTH = C.BYTES.bytes(16);
34
+
35
+ // Standard PHC base64 — no padding, alphabet [A-Za-z0-9+/].
36
+ function _b64NoPad(buf) {
37
+ return buf.toString("base64").replace(/=+$/g, "");
38
+ }
39
+
40
+ function _fromB64NoPad(s) {
41
+ // Node tolerates missing padding in `Buffer.from(s, "base64")` so we
42
+ // pass straight through; the no-pad form is what PHC strings emit
43
+ // on the wire.
44
+ return Buffer.from(s, "base64");
45
+ }
46
+
47
+ function _phcEncode(salt, hash, params) {
48
+ return "$argon2id$v=" + ARGON2_VERSION +
49
+ "$m=" + params.memoryCost +
50
+ ",t=" + params.timeCost +
51
+ ",p=" + params.parallelism +
52
+ "$" + _b64NoPad(salt) +
53
+ "$" + _b64NoPad(hash);
54
+ }
55
+
56
+ // Parse a PHC string into structured form. Accepts only argon2id
57
+ // shapes — argon2i / argon2d are intentionally not supported by the
58
+ // framework wrapper.
59
+ function _phcDecode(stored) {
60
+ if (typeof stored !== "string" || stored.length === 0) return null;
61
+ var parts = stored.split("$");
62
+ if (parts.length !== 6) return null;
63
+ if (parts[0] !== "" || parts[1] !== ARGON2ID) return null;
64
+ var ver = /^v=(\d+)$/.exec(parts[2]);
65
+ if (!ver) return null;
66
+ var version = parseInt(ver[1], 10);
67
+ if (!isFinite(version) || version <= 0) return null;
68
+ var paramTokens = parts[3].split(",");
69
+ var p = { memoryCost: NaN, timeCost: NaN, parallelism: NaN };
70
+ for (var i = 0; i < paramTokens.length; i += 1) {
71
+ var t = paramTokens[i];
72
+ var eq = t.indexOf("=");
73
+ if (eq === -1) return null;
74
+ var k = t.slice(0, eq);
75
+ var v = parseInt(t.slice(eq + 1), 10);
76
+ if (!isFinite(v)) return null;
77
+ if (k === "m") p.memoryCost = v;
78
+ else if (k === "t") p.timeCost = v;
79
+ else if (k === "p") p.parallelism = v;
80
+ }
81
+ if (!isFinite(p.memoryCost) || !isFinite(p.timeCost) || !isFinite(p.parallelism)) return null;
82
+ var salt;
83
+ var hash;
84
+ try { salt = _fromB64NoPad(parts[4]); }
85
+ catch (_e) { return null; }
86
+ try { hash = _fromB64NoPad(parts[5]); }
87
+ catch (_e) { return null; }
88
+ return { version: version, params: p, salt: salt, hash: hash };
89
+ }
90
+
91
+ function _runArgon2(message, salt, params, hashLength) {
92
+ // Use the async variant so the call queues onto the libuv threadpool
93
+ // instead of blocking the main event loop. argon2 with framework
94
+ // defaults (64 MiB / 3 passes / 1 lane) takes ~100ms per call;
95
+ // blocking the loop that long stalls every concurrent timer the
96
+ // test suite is also running and trips spurious flakes in
97
+ // safe-async-loops fixtures.
98
+ return new Promise(function (resolve, reject) {
99
+ nodeCrypto.argon2(ARGON2ID, {
100
+ message: message,
101
+ nonce: salt,
102
+ memory: params.memoryCost,
103
+ passes: params.timeCost,
104
+ parallelism: params.parallelism,
105
+ tagLength: hashLength,
106
+ }, function (err, result) {
107
+ if (err) reject(err);
108
+ else resolve(result);
109
+ });
110
+ });
111
+ }
112
+
113
+ // ---- public surface ----
114
+
115
+ async function hash(plain, opts) {
116
+ opts = opts || {};
117
+ var params = {
118
+ memoryCost: opts.memoryCost || C.BYTES.kib(64), // 64 MiB
119
+ timeCost: opts.timeCost || 3,
120
+ parallelism: opts.parallelism || 1,
121
+ };
122
+ var hashLength = opts.hashLength || DEFAULT_HASH_LENGTH;
123
+ var salt = opts.salt || nodeCrypto.randomBytes(DEFAULT_SALT_LENGTH);
124
+ var message = Buffer.isBuffer(plain) ? plain : Buffer.from(String(plain), "utf8");
125
+ var raw = await _runArgon2(message, salt, params, hashLength);
126
+ // raw: true — return the unwrapped Buffer (used by vault key
127
+ // derivation + backup KDF where the bytes feed directly into
128
+ // XChaCha20). Default produces a PHC-string-encoded password hash.
129
+ if (opts.raw === true) return raw;
130
+ return _phcEncode(salt, raw, params);
131
+ }
132
+
133
+ async function verify(stored, plain) {
134
+ var dec = _phcDecode(stored);
135
+ if (!dec) return false;
136
+ var message = Buffer.isBuffer(plain) ? plain : Buffer.from(String(plain), "utf8");
137
+ var actual;
138
+ try { actual = await _runArgon2(message, dec.salt, dec.params, dec.hash.length); }
139
+ catch (_e) { return false; }
140
+ return blamejsCrypto.timingSafeEqual(actual, dec.hash);
141
+ }
142
+
143
+ function needsRehash(stored, opts) {
144
+ opts = opts || {};
145
+ var dec = _phcDecode(stored);
146
+ if (!dec) return true;
147
+ if (dec.version !== ARGON2_VERSION) return true;
148
+ var memoryCost = opts.memoryCost || C.BYTES.kib(64); // same defaults as hash()
149
+ var timeCost = opts.timeCost || 3;
150
+ var parallelism = opts.parallelism || 1;
151
+ if (dec.params.memoryCost < memoryCost) return true;
152
+ if (dec.params.timeCost < timeCost) return true;
153
+ if (dec.params.parallelism < parallelism) return true;
154
+ return false;
155
+ }
156
+
157
+ module.exports = {
158
+ argon2id: ARGON2ID,
159
+ hash: hash,
160
+ verify: verify,
161
+ needsRehash: needsRehash,
162
+ // Test-only — let the test harness exercise the PHC encode/decode
163
+ // round trip without re-running actual hashing.
164
+ _phcEncode: _phcEncode,
165
+ _phcDecode: _phcDecode,
166
+ };
@@ -46,7 +46,7 @@
46
46
  * verify is NOT an error — it returns false. Errors are reserved for
47
47
  * "the call shape was wrong" (empty plain, oversize plain).
48
48
  */
49
- var argon2 = require("../vendor/argon2");
49
+ var argon2 = require("../argon2-builtin");
50
50
  var C = require("../constants");
51
51
  var httpClient = require("../http-client");
52
52
  var hibpSha1 = require("../framework-sha1-hibp");
@@ -45,7 +45,7 @@ var nodeCrypto = require("node:crypto");
45
45
  var C = require("../constants");
46
46
  var safeBuffer = require("../safe-buffer");
47
47
  var { xchacha20poly1305 } = require("../vendor/noble-ciphers.cjs");
48
- var argon2 = require("../vendor/argon2");
48
+ var argon2 = require("../argon2-builtin");
49
49
  var { FrameworkError } = require("../framework-error");
50
50
 
51
51
  class BackupCryptoError extends FrameworkError {
package/lib/vault/wrap.js CHANGED
@@ -25,7 +25,7 @@
25
25
  * This module is PURE — no filesystem I/O. Callers handle reading/writing.
26
26
  * wrap() and unwrap() are async because Argon2 is async via its native binding.
27
27
  */
28
- var argon2 = require("../vendor/argon2");
28
+ var argon2 = require("../argon2-builtin");
29
29
  var C = require("../constants");
30
30
  var { xchacha20poly1305 } = require("../vendor/noble-ciphers.cjs");
31
31
  var { generateBytes } = require("../crypto");
@@ -18,36 +18,6 @@
18
18
  "server": "sha256:5d539dfc9ef47121d4c09bd7256d76448a1f5ac47ee09ac44c78ff6a062af9ab"
19
19
  }
20
20
  },
21
- "argon2": {
22
- "version": "0.44.0",
23
- "license": "MIT",
24
- "author": "Ranieri Althoff",
25
- "source": "https://github.com/ranisalt/node-argon2",
26
- "exports": [
27
- "hash",
28
- "verify"
29
- ],
30
- "files": {
31
- "server": "lib/vendor/argon2/argon2.cjs",
32
- "prebuilds": "lib/vendor/argon2/prebuilds/"
33
- },
34
- "platforms": [
35
- "darwin-arm64",
36
- "darwin-x64",
37
- "freebsd-arm64",
38
- "freebsd-x64",
39
- "linux-arm",
40
- "linux-arm64",
41
- "linux-x64",
42
- "win32-x64"
43
- ],
44
- "bundler": "esbuild --format=cjs --platform=node (inlines @phc/format + node-gyp-build)",
45
- "bundledAt": "2026-04-25",
46
- "hashes": {
47
- "server": "sha256:93b8d2fb7f24dc1b3304dc9420844d5e1afc199c41ab1f9a90c8de48cc7c2359",
48
- "prebuilds": "sha256-tree:65921b7cf331e0a9430a1b52440da8f26cdf9d215a4cd490edbc4804dd713df3"
49
- }
50
- },
51
21
  "@simplewebauthn/server": {
52
22
  "version": "13.3.0",
53
23
  "license": "MIT",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blamejs/core",
3
- "version": "0.7.76",
3
+ "version": "0.7.77",
4
4
  "description": "The Node framework that owns its stack.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "blamejs contributors",
@@ -2,10 +2,10 @@
2
2
  "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
3
3
  "bomFormat": "CycloneDX",
4
4
  "specVersion": "1.5",
5
- "serialNumber": "urn:uuid:16490b30-e9d2-4135-a820-485954fc745f",
5
+ "serialNumber": "urn:uuid:3d6aa43b-6da6-44c8-a687-434e93ef3b07",
6
6
  "version": 1,
7
7
  "metadata": {
8
- "timestamp": "2026-05-06T04:28:11.034Z",
8
+ "timestamp": "2026-05-06T04:48:07.561Z",
9
9
  "lifecycles": [
10
10
  {
11
11
  "phase": "build"
@@ -19,14 +19,14 @@
19
19
  }
20
20
  ],
21
21
  "component": {
22
- "bom-ref": "@blamejs/core@0.7.76",
22
+ "bom-ref": "@blamejs/core@0.7.77",
23
23
  "type": "library",
24
24
  "name": "blamejs",
25
- "version": "0.7.76",
25
+ "version": "0.7.77",
26
26
  "scope": "required",
27
27
  "author": "blamejs contributors",
28
28
  "description": "The Node framework that owns its stack.",
29
- "purl": "pkg:npm/%40blamejs/core@0.7.76",
29
+ "purl": "pkg:npm/%40blamejs/core@0.7.77",
30
30
  "properties": [],
31
31
  "externalReferences": [
32
32
  {
@@ -54,7 +54,7 @@
54
54
  "components": [],
55
55
  "dependencies": [
56
56
  {
57
- "ref": "@blamejs/core@0.7.76",
57
+ "ref": "@blamejs/core@0.7.77",
58
58
  "dependsOn": []
59
59
  }
60
60
  ]
@@ -1,466 +0,0 @@
1
- // argon2 v0.44.0 — MIT License (c) Ranieri Althoff — https://github.com/ranisalt/node-argon2
2
- var __getOwnPropNames = Object.getOwnPropertyNames;
3
- var __commonJS = (cb, mod) => function __require() {
4
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
5
- };
6
-
7
- // node_modules/@phc/format/index.js
8
- var require_format = __commonJS({
9
- "node_modules/@phc/format/index.js"(exports2, module2) {
10
- var idRegex = /^[a-z0-9-]{1,32}$/;
11
- var nameRegex = /^[a-z0-9-]{1,32}$/;
12
- var valueRegex = /^[a-zA-Z0-9/+.-]+$/;
13
- var b64Regex = /^([a-zA-Z0-9/+.-]+|)$/;
14
- var decimalRegex = /^((-)?[1-9]\d*|0)$/;
15
- var versionRegex = /^v=(\d+)$/;
16
- function objToKeyVal(obj) {
17
- return objectKeys(obj).map((k) => [k, obj[k]].join("=")).join(",");
18
- }
19
- function keyValtoObj(str) {
20
- const obj = {};
21
- str.split(",").forEach((ps) => {
22
- const pss = ps.split("=");
23
- if (pss.length < 2) {
24
- throw new TypeError(`params must be in the format name=value`);
25
- }
26
- obj[pss.shift()] = pss.join("=");
27
- });
28
- return obj;
29
- }
30
- function objectKeys(object) {
31
- return Object.keys(object);
32
- }
33
- function objectValues(object) {
34
- if (typeof Object.values === "function") return Object.values(object);
35
- return objectKeys(object).map((k) => object[k]);
36
- }
37
- function serialize(opts) {
38
- const fields = [""];
39
- if (typeof opts !== "object" || opts === null) {
40
- throw new TypeError("opts must be an object");
41
- }
42
- if (typeof opts.id !== "string") {
43
- throw new TypeError("id must be a string");
44
- }
45
- if (!idRegex.test(opts.id)) {
46
- throw new TypeError(`id must satisfy ${idRegex}`);
47
- }
48
- fields.push(opts.id);
49
- if (typeof opts.version !== "undefined") {
50
- if (typeof opts.version !== "number" || opts.version < 0 || !Number.isInteger(opts.version)) {
51
- throw new TypeError("version must be a positive integer number");
52
- }
53
- fields.push(`v=${opts.version}`);
54
- }
55
- if (typeof opts.params !== "undefined") {
56
- if (typeof opts.params !== "object" || opts.params === null) {
57
- throw new TypeError("params must be an object");
58
- }
59
- const pk = objectKeys(opts.params);
60
- if (!pk.every((p) => nameRegex.test(p))) {
61
- throw new TypeError(`params names must satisfy ${nameRegex}`);
62
- }
63
- pk.forEach((k) => {
64
- if (typeof opts.params[k] === "number") {
65
- opts.params[k] = opts.params[k].toString();
66
- } else if (Buffer.isBuffer(opts.params[k])) {
67
- opts.params[k] = opts.params[k].toString("base64").split("=")[0];
68
- }
69
- });
70
- const pv = objectValues(opts.params);
71
- if (!pv.every((v) => typeof v === "string")) {
72
- throw new TypeError("params values must be strings");
73
- }
74
- if (!pv.every((v) => valueRegex.test(v))) {
75
- throw new TypeError(`params values must satisfy ${valueRegex}`);
76
- }
77
- const strpar = objToKeyVal(opts.params);
78
- fields.push(strpar);
79
- }
80
- if (typeof opts.salt !== "undefined") {
81
- if (!Buffer.isBuffer(opts.salt)) {
82
- throw new TypeError("salt must be a Buffer");
83
- }
84
- fields.push(opts.salt.toString("base64").split("=")[0]);
85
- if (typeof opts.hash !== "undefined") {
86
- if (!Buffer.isBuffer(opts.hash)) {
87
- throw new TypeError("hash must be a Buffer");
88
- }
89
- fields.push(opts.hash.toString("base64").split("=")[0]);
90
- }
91
- }
92
- const phcstr = fields.join("$");
93
- return phcstr;
94
- }
95
- function deserialize(phcstr) {
96
- if (typeof phcstr !== "string" || phcstr === "") {
97
- throw new TypeError("pchstr must be a non-empty string");
98
- }
99
- if (phcstr[0] !== "$") {
100
- throw new TypeError("pchstr must contain a $ as first char");
101
- }
102
- const fields = phcstr.split("$");
103
- fields.shift();
104
- let maxf = 5;
105
- if (!versionRegex.test(fields[1])) maxf--;
106
- if (fields.length > maxf) {
107
- throw new TypeError(
108
- `pchstr contains too many fileds: ${fields.length}/${maxf}`
109
- );
110
- }
111
- const id = fields.shift();
112
- if (!idRegex.test(id)) {
113
- throw new TypeError(`id must satisfy ${idRegex}`);
114
- }
115
- let version;
116
- if (versionRegex.test(fields[0])) {
117
- version = parseInt(fields.shift().match(versionRegex)[1], 10);
118
- }
119
- let hash;
120
- let salt;
121
- if (b64Regex.test(fields[fields.length - 1])) {
122
- if (fields.length > 1 && b64Regex.test(fields[fields.length - 2])) {
123
- hash = Buffer.from(fields.pop(), "base64");
124
- salt = Buffer.from(fields.pop(), "base64");
125
- } else {
126
- salt = Buffer.from(fields.pop(), "base64");
127
- }
128
- }
129
- let params;
130
- if (fields.length > 0) {
131
- const parstr = fields.pop();
132
- params = keyValtoObj(parstr);
133
- if (!objectKeys(params).every((p) => nameRegex.test(p))) {
134
- throw new TypeError(`params names must satisfy ${nameRegex}`);
135
- }
136
- const pv = objectValues(params);
137
- if (!pv.every((v) => valueRegex.test(v))) {
138
- throw new TypeError(`params values must satisfy ${valueRegex}`);
139
- }
140
- const pk = objectKeys(params);
141
- pk.forEach((k) => {
142
- params[k] = decimalRegex.test(params[k]) ? parseInt(params[k], 10) : params[k];
143
- });
144
- }
145
- if (fields.length > 0) {
146
- throw new TypeError(`pchstr contains unrecognized fileds: ${fields}`);
147
- }
148
- const phcobj = { id };
149
- if (version) phcobj.version = version;
150
- if (params) phcobj.params = params;
151
- if (salt) phcobj.salt = salt;
152
- if (hash) phcobj.hash = hash;
153
- return phcobj;
154
- }
155
- module2.exports = {
156
- serialize,
157
- deserialize
158
- };
159
- }
160
- });
161
-
162
- // node_modules/node-gyp-build/node-gyp-build.js
163
- var require_node_gyp_build = __commonJS({
164
- "node_modules/node-gyp-build/node-gyp-build.js"(exports2, module2) {
165
- var fs = require("fs");
166
- var path = require("path");
167
- var os = require("os");
168
- var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
169
- var vars = process.config && process.config.variables || {};
170
- var prebuildsOnly = !!process.env.PREBUILDS_ONLY;
171
- var abi = process.versions.modules;
172
- var runtime = isElectron() ? "electron" : isNwjs() ? "node-webkit" : "node";
173
- var arch = process.env.npm_config_arch || os.arch();
174
- var platform = process.env.npm_config_platform || os.platform();
175
- var libc = process.env.LIBC || (isAlpine(platform) ? "musl" : "glibc");
176
- var armv = process.env.ARM_VERSION || (arch === "arm64" ? "8" : vars.arm_version) || "";
177
- var uv = (process.versions.uv || "").split(".")[0];
178
- module2.exports = load;
179
- function load(dir) {
180
- return runtimeRequire(load.resolve(dir));
181
- }
182
- load.resolve = load.path = function(dir) {
183
- dir = path.resolve(dir || ".");
184
- try {
185
- var name = runtimeRequire(path.join(dir, "package.json")).name.toUpperCase().replace(/-/g, "_");
186
- if (process.env[name + "_PREBUILD"]) dir = process.env[name + "_PREBUILD"];
187
- } catch (err) {
188
- }
189
- if (!prebuildsOnly) {
190
- var release = getFirst(path.join(dir, "build/Release"), matchBuild);
191
- if (release) return release;
192
- var debug = getFirst(path.join(dir, "build/Debug"), matchBuild);
193
- if (debug) return debug;
194
- }
195
- var prebuild = resolve(dir);
196
- if (prebuild) return prebuild;
197
- var nearby = resolve(path.dirname(process.execPath));
198
- if (nearby) return nearby;
199
- var target = [
200
- "platform=" + platform,
201
- "arch=" + arch,
202
- "runtime=" + runtime,
203
- "abi=" + abi,
204
- "uv=" + uv,
205
- armv ? "armv=" + armv : "",
206
- "libc=" + libc,
207
- "node=" + process.versions.node,
208
- process.versions.electron ? "electron=" + process.versions.electron : "",
209
- typeof __webpack_require__ === "function" ? "webpack=true" : ""
210
- // eslint-disable-line
211
- ].filter(Boolean).join(" ");
212
- throw new Error("No native build was found for " + target + "\n loaded from: " + dir + "\n");
213
- function resolve(dir2) {
214
- var tuples = readdirSync(path.join(dir2, "prebuilds")).map(parseTuple);
215
- var tuple = tuples.filter(matchTuple(platform, arch)).sort(compareTuples)[0];
216
- if (!tuple) return;
217
- var prebuilds = path.join(dir2, "prebuilds", tuple.name);
218
- var parsed = readdirSync(prebuilds).map(parseTags);
219
- var candidates = parsed.filter(matchTags(runtime, abi));
220
- var winner = candidates.sort(compareTags(runtime))[0];
221
- if (winner) return path.join(prebuilds, winner.file);
222
- }
223
- };
224
- function readdirSync(dir) {
225
- try {
226
- return fs.readdirSync(dir);
227
- } catch (err) {
228
- return [];
229
- }
230
- }
231
- function getFirst(dir, filter) {
232
- var files = readdirSync(dir).filter(filter);
233
- return files[0] && path.join(dir, files[0]);
234
- }
235
- function matchBuild(name) {
236
- return /\.node$/.test(name);
237
- }
238
- function parseTuple(name) {
239
- var arr = name.split("-");
240
- if (arr.length !== 2) return;
241
- var platform2 = arr[0];
242
- var architectures = arr[1].split("+");
243
- if (!platform2) return;
244
- if (!architectures.length) return;
245
- if (!architectures.every(Boolean)) return;
246
- return { name, platform: platform2, architectures };
247
- }
248
- function matchTuple(platform2, arch2) {
249
- return function(tuple) {
250
- if (tuple == null) return false;
251
- if (tuple.platform !== platform2) return false;
252
- return tuple.architectures.includes(arch2);
253
- };
254
- }
255
- function compareTuples(a, b) {
256
- return a.architectures.length - b.architectures.length;
257
- }
258
- function parseTags(file) {
259
- var arr = file.split(".");
260
- var extension = arr.pop();
261
- var tags = { file, specificity: 0 };
262
- if (extension !== "node") return;
263
- for (var i = 0; i < arr.length; i++) {
264
- var tag = arr[i];
265
- if (tag === "node" || tag === "electron" || tag === "node-webkit") {
266
- tags.runtime = tag;
267
- } else if (tag === "napi") {
268
- tags.napi = true;
269
- } else if (tag.slice(0, 3) === "abi") {
270
- tags.abi = tag.slice(3);
271
- } else if (tag.slice(0, 2) === "uv") {
272
- tags.uv = tag.slice(2);
273
- } else if (tag.slice(0, 4) === "armv") {
274
- tags.armv = tag.slice(4);
275
- } else if (tag === "glibc" || tag === "musl") {
276
- tags.libc = tag;
277
- } else {
278
- continue;
279
- }
280
- tags.specificity++;
281
- }
282
- return tags;
283
- }
284
- function matchTags(runtime2, abi2) {
285
- return function(tags) {
286
- if (tags == null) return false;
287
- if (tags.runtime && tags.runtime !== runtime2 && !runtimeAgnostic(tags)) return false;
288
- if (tags.abi && tags.abi !== abi2 && !tags.napi) return false;
289
- if (tags.uv && tags.uv !== uv) return false;
290
- if (tags.armv && tags.armv !== armv) return false;
291
- if (tags.libc && tags.libc !== libc) return false;
292
- return true;
293
- };
294
- }
295
- function runtimeAgnostic(tags) {
296
- return tags.runtime === "node" && tags.napi;
297
- }
298
- function compareTags(runtime2) {
299
- return function(a, b) {
300
- if (a.runtime !== b.runtime) {
301
- return a.runtime === runtime2 ? -1 : 1;
302
- } else if (a.abi !== b.abi) {
303
- return a.abi ? -1 : 1;
304
- } else if (a.specificity !== b.specificity) {
305
- return a.specificity > b.specificity ? -1 : 1;
306
- } else {
307
- return 0;
308
- }
309
- };
310
- }
311
- function isNwjs() {
312
- return !!(process.versions && process.versions.nw);
313
- }
314
- function isElectron() {
315
- if (process.versions && process.versions.electron) return true;
316
- if (process.env.ELECTRON_RUN_AS_NODE) return true;
317
- return typeof window !== "undefined" && window.process && window.process.type === "renderer";
318
- }
319
- function isAlpine(platform2) {
320
- return platform2 === "linux" && fs.existsSync("/etc/alpine-release");
321
- }
322
- load.parseTags = parseTags;
323
- load.matchTags = matchTags;
324
- load.compareTags = compareTags;
325
- load.parseTuple = parseTuple;
326
- load.matchTuple = matchTuple;
327
- load.compareTuples = compareTuples;
328
- }
329
- });
330
-
331
- // node_modules/node-gyp-build/index.js
332
- var require_node_gyp_build2 = __commonJS({
333
- "node_modules/node-gyp-build/index.js"(exports2, module2) {
334
- var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
335
- if (typeof runtimeRequire.addon === "function") {
336
- module2.exports = runtimeRequire.addon.bind(runtimeRequire);
337
- } else {
338
- module2.exports = require_node_gyp_build();
339
- }
340
- }
341
- });
342
-
343
- // node_modules/argon2/argon2.cjs
344
- var require_argon2 = __commonJS({
345
- "node_modules/argon2/argon2.cjs"(exports2, module2) {
346
- var { randomBytes, timingSafeEqual } = require("node:crypto");
347
- var { promisify } = require("node:util");
348
- var { deserialize, serialize } = require_format();
349
- var gypBuild = require_node_gyp_build2();
350
- var { hash: bindingsHash } = gypBuild(__dirname);
351
- var generateSalt = promisify(randomBytes);
352
- var argon2d = 0;
353
- var argon2i = 1;
354
- var argon2id = 2;
355
- module2.exports.argon2d = argon2d;
356
- module2.exports.argon2i = argon2i;
357
- module2.exports.argon2id = argon2id;
358
- var types = Object.freeze({ argon2d, argon2i, argon2id });
359
- var names = Object.freeze({
360
- [types.argon2d]: "argon2d",
361
- [types.argon2i]: "argon2i",
362
- [types.argon2id]: "argon2id"
363
- });
364
- var defaults = {
365
- hashLength: 32,
366
- timeCost: 3,
367
- memoryCost: 1 << 16,
368
- parallelism: 4,
369
- type: argon2id,
370
- version: 19
371
- };
372
- async function hash(password, options) {
373
- let { raw, salt, ...rest } = { ...defaults, ...options };
374
- if (rest.hashLength > 2 ** 32 - 1) {
375
- throw new RangeError("Hash length is too large");
376
- }
377
- if (rest.memoryCost > 2 ** 32 - 1) {
378
- throw new RangeError("Memory cost is too large");
379
- }
380
- if (rest.timeCost > 2 ** 32 - 1) {
381
- throw new RangeError("Time cost is too large");
382
- }
383
- if (rest.parallelism > 2 ** 24 - 1) {
384
- throw new RangeError("Parallelism is too large");
385
- }
386
- salt = salt ?? await generateSalt(16);
387
- const {
388
- hashLength,
389
- secret = Buffer.alloc(0),
390
- type,
391
- version,
392
- memoryCost: m,
393
- timeCost: t,
394
- parallelism: p,
395
- associatedData: data = Buffer.alloc(0)
396
- } = rest;
397
- const hash2 = await bindingsHash({
398
- password: Buffer.from(password),
399
- salt,
400
- secret,
401
- data,
402
- hashLength,
403
- m,
404
- t,
405
- p,
406
- version,
407
- type
408
- });
409
- if (raw) {
410
- return hash2;
411
- }
412
- return serialize({
413
- id: names[type],
414
- version,
415
- params: { m, t, p, ...data.byteLength > 0 ? { data } : {} },
416
- salt,
417
- hash: hash2
418
- });
419
- }
420
- module2.exports.hash = hash;
421
- function needsRehash(digest, options = {}) {
422
- const { memoryCost, timeCost, parallelism, version } = {
423
- ...defaults,
424
- ...options
425
- };
426
- const {
427
- version: v,
428
- params: { m, t, p }
429
- } = deserialize(digest);
430
- return +v !== +version || +m !== +memoryCost || +t !== +timeCost || +p !== +parallelism;
431
- }
432
- module2.exports.needsRehash = needsRehash;
433
- async function verify(digest, password, options = {}) {
434
- const { id, ...rest } = deserialize(digest);
435
- if (!(id in types)) {
436
- return false;
437
- }
438
- const {
439
- version = 16,
440
- params: { m, t, p, data = "" },
441
- salt,
442
- hash: hash2
443
- } = rest;
444
- const { secret = Buffer.alloc(0) } = options;
445
- return timingSafeEqual(
446
- await bindingsHash({
447
- password: Buffer.from(password),
448
- salt,
449
- secret,
450
- data: Buffer.from(data, "base64"),
451
- hashLength: hash2.byteLength,
452
- m: +m,
453
- t: +t,
454
- p: +p,
455
- version: +version,
456
- type: types[id]
457
- }),
458
- hash2
459
- );
460
- }
461
- module2.exports.verify = verify;
462
- }
463
- });
464
-
465
- // _bundle-argon2.cjs
466
- module.exports = require_argon2();
@@ -1,62 +0,0 @@
1
- export type Options = {
2
- hashLength?: number | undefined;
3
- timeCost?: number | undefined;
4
- memoryCost?: number | undefined;
5
- parallelism?: number | undefined;
6
- type?: 0 | 1 | 2 | undefined;
7
- version?: number | undefined;
8
- salt?: Buffer | undefined;
9
- associatedData?: Buffer | undefined;
10
- secret?: Buffer | undefined;
11
- };
12
- export const argon2d: 0;
13
- export const argon2i: 1;
14
- export const argon2id: 2;
15
- /**
16
- * Hashes a password with Argon2, producing a raw hash
17
- *
18
- * @overload
19
- * @param {Buffer | string} password The plaintext password to be hashed
20
- * @param {Options & { raw: true }} options The parameters for Argon2
21
- * @returns {Promise<Buffer>} The raw hash generated from `password`
22
- */
23
- export function hash(password: Buffer | string, options: Options & {
24
- raw: true;
25
- }): Promise<Buffer>;
26
- /**
27
- * Hashes a password with Argon2, producing an encoded hash
28
- *
29
- * @overload
30
- * @param {Buffer | string} password The plaintext password to be hashed
31
- * @param {Options & { raw?: boolean }} [options] The parameters for Argon2
32
- * @returns {Promise<string>} The encoded hash generated from `password`
33
- */
34
- export function hash(password: Buffer | string, options?: (Options & {
35
- raw?: boolean;
36
- }) | undefined): Promise<string>;
37
- /**
38
- * @param {string} digest The digest to be checked
39
- * @param {Object} [options] The current parameters for Argon2
40
- * @param {number} [options.timeCost=3]
41
- * @param {number} [options.memoryCost=65536]
42
- * @param {number} [options.parallelism=4]
43
- * @param {number} [options.version=0x13]
44
- * @returns {boolean} `true` if the digest parameters do not match the parameters in `options`, otherwise `false`
45
- */
46
- export function needsRehash(digest: string, options?: {
47
- timeCost?: number | undefined;
48
- memoryCost?: number | undefined;
49
- parallelism?: number | undefined;
50
- version?: number | undefined;
51
- } | undefined): boolean;
52
- /**
53
- * @param {string} digest The digest to be checked
54
- * @param {Buffer | string} password The plaintext password to be verified
55
- * @param {Object} [options] The current parameters for Argon2
56
- * @param {Buffer} [options.secret]
57
- * @returns {Promise<boolean>} `true` if the digest parameters matches the hash generated from `password`, otherwise `false`
58
- */
59
- export function verify(digest: string, password: Buffer | string, options?: {
60
- secret?: Buffer | undefined;
61
- } | undefined): Promise<boolean>;
62
- //# sourceMappingURL=argon2.d.cts.map
@@ -1 +0,0 @@
1
- {"name":"argon2","version":"0.44.0","main":"argon2.cjs"}