asherah 4.0.41 → 4.0.42
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/index.d.ts +38 -2
- package/npm/index.js +22 -6
- package/package.json +13 -12
package/index.d.ts
CHANGED
|
@@ -230,11 +230,20 @@ export declare function setenv(env: string): void;
|
|
|
230
230
|
* const drr = asherah.encrypt('user-42', Buffer.from('secret'));
|
|
231
231
|
* // store drr in your database
|
|
232
232
|
* ```
|
|
233
|
+
*
|
|
234
|
+
* **Blocking the Node.js event loop**: this function runs on the JS
|
|
235
|
+
* thread and synchronously waits for the metastore (MySQL/Postgres/
|
|
236
|
+
* DynamoDB) and KMS round-trips. While it executes no other JavaScript
|
|
237
|
+
* — timers, network callbacks, GC scheduling — can run. For any
|
|
238
|
+
* production workload that touches the network on a cache miss, prefer
|
|
239
|
+
* {@link encryptAsync}, which offloads to the Rust tokio runtime and
|
|
240
|
+
* keeps the event loop responsive.
|
|
233
241
|
*/
|
|
234
242
|
export declare function encrypt(partitionId: string, data: Buffer): string;
|
|
235
243
|
|
|
236
244
|
/** Async variant of {@link encrypt}. The work runs on the Rust tokio
|
|
237
|
-
* runtime; the Node event loop is NOT blocked.
|
|
245
|
+
* runtime; the Node event loop is NOT blocked. Prefer this in any
|
|
246
|
+
* service that handles concurrent requests. */
|
|
238
247
|
export declare function encryptAsync(partitionId: string, data: Buffer): Promise<string>;
|
|
239
248
|
|
|
240
249
|
/**
|
|
@@ -248,10 +257,16 @@ export declare function encryptAsync(partitionId: string, data: Buffer): Promise
|
|
|
248
257
|
* @throws TypeError if either argument is null/undefined.
|
|
249
258
|
* @throws Error if the JSON is malformed, the partition doesn't match,
|
|
250
259
|
* the parent key has been revoked, or the AEAD tag fails.
|
|
260
|
+
*
|
|
261
|
+
* **Blocking the Node.js event loop**: like {@link encrypt}, this runs
|
|
262
|
+
* synchronously on the JS thread and waits for any metastore/KMS calls.
|
|
263
|
+
* Use {@link decryptAsync} in services that handle concurrent traffic.
|
|
251
264
|
*/
|
|
252
265
|
export declare function decrypt(partitionId: string, dataRowRecordJson: string): Buffer;
|
|
253
266
|
|
|
254
|
-
/** Async variant of {@link decrypt}.
|
|
267
|
+
/** Async variant of {@link decrypt}. The work runs on the Rust tokio
|
|
268
|
+
* runtime; the Node event loop stays responsive. Prefer this in any
|
|
269
|
+
* service that handles concurrent requests. */
|
|
255
270
|
export declare function decryptAsync(partitionId: string, dataRowRecordJson: string): Promise<Buffer>;
|
|
256
271
|
|
|
257
272
|
/** UTF-8 string-typed wrapper around {@link encrypt}. Empty `string`
|
|
@@ -267,6 +282,27 @@ export declare function decryptString(partitionId: string, dataRowRecordJson: st
|
|
|
267
282
|
/** Async variant of {@link decryptString}. */
|
|
268
283
|
export declare function decryptStringAsync(partitionId: string, dataRowRecordJson: string): Promise<string>;
|
|
269
284
|
|
|
285
|
+
/**
|
|
286
|
+
* Best-effort wipe of a plaintext `Buffer` returned by {@link decrypt}
|
|
287
|
+
* or {@link decryptAsync}.
|
|
288
|
+
*
|
|
289
|
+
* The native (Rust) buffer is volatile-wiped before the Buffer reaches
|
|
290
|
+
* JavaScript, but the V8 `Buffer` lives on the JS heap where the GC may
|
|
291
|
+
* have already copied the bytes during compaction. Pass the Buffer here
|
|
292
|
+
* to overwrite its current backing store with zeros via
|
|
293
|
+
* `buffer.fill(0)`. Mirrors `Zeroize([]byte)` in the Go binding,
|
|
294
|
+
* `AsherahSession.ZeroizePlaintext(byte[])` in .NET, and
|
|
295
|
+
* `Asherah.clearPlaintext(byte[])` in Java.
|
|
296
|
+
*
|
|
297
|
+
* **Caveat:** treat the plaintext as opaque within a tight scope and
|
|
298
|
+
* never copy or substring it before clearing — V8 may have aliased
|
|
299
|
+
* portions of the underlying ArrayBuffer that this call doesn't reach.
|
|
300
|
+
*
|
|
301
|
+
* T-finding "Node has no parallel `clearPlaintext`" in
|
|
302
|
+
* `docs/review-2026-05-05-findings.md`.
|
|
303
|
+
*/
|
|
304
|
+
export declare function clearPlaintext(plaintext: Buffer | null | undefined): void;
|
|
305
|
+
|
|
270
306
|
// ─── Factory / Session API (recommended) ────────────────────────────────────
|
|
271
307
|
|
|
272
308
|
/**
|
package/npm/index.js
CHANGED
|
@@ -154,12 +154,10 @@ const METASTORE_ALIASES = {
|
|
|
154
154
|
|
|
155
155
|
// Legacy/debug KMS aliases.
|
|
156
156
|
//
|
|
157
|
-
//
|
|
158
|
-
//
|
|
159
|
-
//
|
|
160
|
-
//
|
|
161
|
-
// validation (commit 9049fa4) and break every binding test that
|
|
162
|
-
// uses the debug fixture.
|
|
157
|
+
// The Rust core treats `static` and `test-debug-static` as synonyms
|
|
158
|
+
// — both fall back to the publicly known test key when no hex is
|
|
159
|
+
// supplied — so no JS-side normalization is needed. The map is kept
|
|
160
|
+
// as a hook for future aliases.
|
|
163
161
|
const KMS_ALIASES = {};
|
|
164
162
|
|
|
165
163
|
function normalizeConfig(config) {
|
|
@@ -269,6 +267,23 @@ function decryptAsync(partitionId, dataRowRecord) {
|
|
|
269
267
|
return native.decryptAsync(partitionId, toBuffer(dataRowRecord));
|
|
270
268
|
}
|
|
271
269
|
|
|
270
|
+
// Best-effort wipe of a plaintext Buffer. The native (Rust) buffer is
|
|
271
|
+
// volatile-wiped before reaching JS; this clears the JS-side copy.
|
|
272
|
+
// V8 may have aliased portions of the ArrayBuffer that this call
|
|
273
|
+
// doesn't reach, so the wipe is best-effort. Mirrors Go's `Zeroize`,
|
|
274
|
+
// .NET's `ZeroizePlaintext`, and Java's `clearPlaintext`. T-finding
|
|
275
|
+
// "Node has no parallel clearPlaintext" in
|
|
276
|
+
// docs/review-2026-05-05-findings.md.
|
|
277
|
+
function clearPlaintext(plaintext) {
|
|
278
|
+
if (plaintext == null) {
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
if (typeof plaintext.fill !== 'function') {
|
|
282
|
+
throw new TypeError('clearPlaintext: argument must be a Buffer or Uint8Array');
|
|
283
|
+
}
|
|
284
|
+
plaintext.fill(0);
|
|
285
|
+
}
|
|
286
|
+
|
|
272
287
|
// Export everything from native addon
|
|
273
288
|
Object.assign(module.exports, native);
|
|
274
289
|
|
|
@@ -277,6 +292,7 @@ module.exports.setup = setup;
|
|
|
277
292
|
module.exports.setupAsync = setupAsync;
|
|
278
293
|
module.exports.decrypt = decrypt;
|
|
279
294
|
module.exports.decryptAsync = decryptAsync;
|
|
295
|
+
module.exports.clearPlaintext = clearPlaintext;
|
|
280
296
|
|
|
281
297
|
// snake_case aliases for canonical API compatibility
|
|
282
298
|
module.exports.setup_async = setupAsync;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "asherah",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.42",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Asherah application-layer encryption for Node.js with automatic key rotation, powered by the native Rust implementation.",
|
|
6
6
|
"author": "Jay Gowdy",
|
|
@@ -57,11 +57,12 @@
|
|
|
57
57
|
"scripts": {
|
|
58
58
|
"build": "napi build",
|
|
59
59
|
"build:release": "napi build --release",
|
|
60
|
-
"test": "node test/roundtrip.js && node test/e2e-consumer.js",
|
|
61
|
-
"test:unit": "node test/roundtrip.js",
|
|
60
|
+
"test": "node test/roundtrip.js && node test/rotation.js && node test/e2e-consumer.js",
|
|
61
|
+
"test:unit": "node test/roundtrip.js && node test/rotation.js",
|
|
62
|
+
"test:rotation": "node test/rotation.js",
|
|
62
63
|
"test:e2e": "node test/e2e-consumer.js",
|
|
63
64
|
"test:e2e-aws": "node test/e2e-aws.js",
|
|
64
|
-
"test:bun": "bun test/roundtrip.js && bun test/e2e-consumer.js && bun test/bun-compat.js"
|
|
65
|
+
"test:bun": "bun test/roundtrip.js && bun test/rotation.js && bun test/e2e-consumer.js && bun test/bun-compat.js"
|
|
65
66
|
},
|
|
66
67
|
"devDependencies": {
|
|
67
68
|
"@napi-rs/cli": "^2.18.0"
|
|
@@ -70,13 +71,13 @@
|
|
|
70
71
|
"node": ">= 18"
|
|
71
72
|
},
|
|
72
73
|
"optionalDependencies": {
|
|
73
|
-
"asherah-darwin-arm64": "4.0.
|
|
74
|
-
"asherah-darwin-x64": "4.0.
|
|
75
|
-
"asherah-linux-x64-gnu": "4.0.
|
|
76
|
-
"asherah-linux-arm64-gnu": "4.0.
|
|
77
|
-
"asherah-linux-x64-musl": "4.0.
|
|
78
|
-
"asherah-linux-arm64-musl": "4.0.
|
|
79
|
-
"asherah-windows-x64": "4.0.
|
|
80
|
-
"asherah-windows-arm64": "4.0.
|
|
74
|
+
"asherah-darwin-arm64": "4.0.42",
|
|
75
|
+
"asherah-darwin-x64": "4.0.42",
|
|
76
|
+
"asherah-linux-x64-gnu": "4.0.42",
|
|
77
|
+
"asherah-linux-arm64-gnu": "4.0.42",
|
|
78
|
+
"asherah-linux-x64-musl": "4.0.42",
|
|
79
|
+
"asherah-linux-arm64-musl": "4.0.42",
|
|
80
|
+
"asherah-windows-x64": "4.0.42",
|
|
81
|
+
"asherah-windows-arm64": "4.0.42"
|
|
81
82
|
}
|
|
82
83
|
}
|