@polyjose/node 0.1.1 → 0.2.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/README.md +80 -137
- package/THIRD-PARTY-NOTICES.txt +15966 -40
- package/addon-sha256.json +8 -8
- package/backend.d.ts +71 -75
- package/backend.js +124 -249
- package/package.json +9 -13
- package/polyjose.darwin-arm64.node +0 -0
- package/polyjose.darwin-x64.node +0 -0
- package/polyjose.linux-arm64-gnu.node +0 -0
- package/polyjose.linux-arm64-musl.node +0 -0
- package/polyjose.linux-x64-gnu.node +0 -0
- package/polyjose.linux-x64-musl.node +0 -0
- package/polyjose.win32-arm64-msvc.node +0 -0
- package/polyjose.win32-x64-msvc.node +0 -0
- package/binding.cjs +0 -869
- package/binding.d.ts +0 -469
package/addon-sha256.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"darwin-arm64": "
|
|
3
|
-
"darwin-x64": "
|
|
4
|
-
"linux-arm64-gnu": "
|
|
5
|
-
"linux-arm64-musl": "
|
|
6
|
-
"linux-x64-gnu": "
|
|
7
|
-
"linux-x64-musl": "
|
|
8
|
-
"win32-arm64-msvc": "
|
|
9
|
-
"win32-x64-msvc": "
|
|
2
|
+
"darwin-arm64": "6d6c3958cd6f927b2e12f53c24d9c1902f3f2ffb979b3b4044994cffebcebbba",
|
|
3
|
+
"darwin-x64": "a418f5f08575bd9d2fb9fa4cbcf84a8710c7c6d312132f9bb7819db473f32cc6",
|
|
4
|
+
"linux-arm64-gnu": "cc8e8488d9350fe3b2d957eb45a6a9955b14f88b4fd0ac445e4934858c0c59be",
|
|
5
|
+
"linux-arm64-musl": "dbadc50f85953f80a869f7f223681963faefcac1c27ec27471be802a8819f402",
|
|
6
|
+
"linux-x64-gnu": "05a2a461d1e8f70743c1aedeeb07b57be6a601b3cce56b6e64fc1e93a29da594",
|
|
7
|
+
"linux-x64-musl": "4228de8d078831836078a16ebd1511d3583cb58646c308ac9e4acf7c3639834e",
|
|
8
|
+
"win32-arm64-msvc": "44dba875cf64e02bf85844a1b5a42de26b541d33ed6d2e45b69a39060577f3df",
|
|
9
|
+
"win32-x64-msvc": "a9d80de28164779bba224cab505035a2d711309583e9c763dfd0b102c8fe8ffa"
|
|
10
10
|
}
|
package/backend.d.ts
CHANGED
|
@@ -1,90 +1,86 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The napi-rs backend of `@polyjose/node` (ADR 0031 §1-§2, `bindings/js/BACKEND.md
|
|
2
|
+
* The napi-rs backend of `@polyjose/node` (ADR 0031 §1-§2, `bindings/js/BACKEND.md`; packaging as
|
|
3
|
+
* superseded by the feature 0017 ADR: one package that ships the addon of all eight targets).
|
|
3
4
|
*
|
|
4
|
-
* The
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* The native addon `polyjose.<platform>.node` already is the backend contract: one function per
|
|
6
|
+
* ADR 0030 §4 operation, camelCase, in the ADR's argument order, rejecting with an `Error` whose
|
|
7
|
+
* `code` is one of `errorCodes()` (ADR 0030 §5). Its types are the `binding.d.ts` that
|
|
8
|
+
* `napi build --dts` generates. So this module only picks the addon for this host, authenticates
|
|
9
|
+
* it, loads it and gives it the facade's `Backend` type; it adds no JOSE logic and renames nothing
|
|
10
|
+
* (ADR 0030 §1: loading and integrity checks are entry idiom).
|
|
9
11
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* `
|
|
12
|
+
* **No resolving loader (feature 0017; review-security.md M1, feature 0007 F02).** napi-rs's
|
|
13
|
+
* generated loader picks the first module that loads from an override variable, the package
|
|
14
|
+
* directory, every ancestor `node_modules`, `NODE_PATH` and a WASI chain, so a JavaScript or native
|
|
15
|
+
* file planted in any of them could become the crypto backend and "verify" any token. polyjose
|
|
16
|
+
* builds no such loader (`napi build --no-js`) and resolves no module name at all: this file reads
|
|
17
|
+
* only files of its own package directory, `dirname(import.meta.url)`, by absolute path. It never
|
|
18
|
+
* reads `process.env`, so neither `NODE_PATH` nor any `NAPI_RS_*` variable changes what loads.
|
|
13
19
|
*
|
|
14
|
-
* **
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* It
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* it and accepts nothing else.
|
|
28
|
-
*
|
|
29
|
-
* **Before loading,** nothing runs unless every module the loader could pick is a native addon:
|
|
30
|
-
* 1. Neither WASI variable is set, whatever its value.
|
|
31
|
-
* 2. No WASI candidate resolves.
|
|
32
|
-
* 3. Every native candidate that resolves is a `.node` file: the override path, and for every
|
|
33
|
-
* platform the loader probes, `./polyjose.<platform>.node` and `@polyjose/node-<platform>`.
|
|
34
|
-
* `@polyjose/node-<platform>/package.json`, which the loader also reads, must be a
|
|
35
|
-
* `package.json`.
|
|
36
|
-
* Resolution is the loader's own: `backend.js` sits next to `binding.cjs`, and `require.resolve`
|
|
37
|
-
* uses the same directory, `node_modules` walk, `NODE_PATH` and symlink handling as the loader's
|
|
38
|
-
* `require`, and runs no code. Node loads a `.node` file only as a native addon, never as
|
|
39
|
-
* JavaScript.
|
|
40
|
-
*
|
|
41
|
-
* **The hash pin (feature 0007 F07; bindings security audit N-M1, the JVM's 0008 F05 bar).** Steps
|
|
42
|
-
* 1-6 make sure the package loads a native addon at this version, but `version()` is what the
|
|
43
|
-
* addon itself says, and a native addon is as easy to plant as a JavaScript file. So before the
|
|
44
|
-
* loader runs, this module also *authenticates* the addon:
|
|
45
|
-
* a. `addon-sha256.json`, next to this file, maps each platform polyjose built this package for
|
|
46
|
-
* to its addon's SHA-256 (FIPS 180-4). It is generated, never hand-edited:
|
|
47
|
-
* `scripts/addon-hashes.sh`, run by `scripts/build.sh` for a local build and by the release
|
|
48
|
-
* assembly of the main package for every published platform. No map, a malformed one, or no
|
|
49
|
-
* entry for this host refuses the load: nothing is trusted by default.
|
|
50
|
-
* b. It picks the one file the loader would load on this host (the platform name of
|
|
51
|
-
* `hostPlatform`, the loader's own): `NAPI_RS_NATIVE_LIBRARY_PATH` when set, else
|
|
52
|
-
* `./polyjose.<platform>.node`, else `@polyjose/node-<platform>`, resolved as above. A
|
|
53
|
-
* caller's override is not refused; it is held to the same pin.
|
|
54
|
-
* c. It reads that file once, hashes those bytes with `node:crypto` and refuses on a mismatch,
|
|
55
|
-
* naming the platform, the source and both hashes. There is no fallback to another candidate.
|
|
56
|
-
* d. It writes the same bytes, with `O_EXCL`, into a new directory from `fs.mkdtempSync` under
|
|
20
|
+
* **The steps (the F07 hash-pin model, bindings security audit N-M1, the JVM's 0008 F05 bar):**
|
|
21
|
+
* 1. The platform name (`detectPlatform`): `darwin-<arch>`, `win32-<arch>-msvc`, or
|
|
22
|
+
* `linux-<arch>-gnu|musl` for x64 and arm64, with napi-rs's names. Any other host is refused
|
|
23
|
+
* by name, pointing at `@polyjose/wasm`, which runs everywhere.
|
|
24
|
+
* 2. `addon-sha256.json`, in the package directory, maps each shipped platform to its addon's
|
|
25
|
+
* SHA-256 (FIPS 180-4). It is generated, never hand-edited: `scripts/addon-hashes.sh`, run by
|
|
26
|
+
* `scripts/build.sh` for a local build and by `scripts/pack-main.sh` over the eight addons the
|
|
27
|
+
* package ships. No map, a malformed one, or no entry for this host refuses the load: nothing
|
|
28
|
+
* is trusted by default.
|
|
29
|
+
* 3. It reads `polyjose.<platform>.node` from the package directory once, hashes those bytes with
|
|
30
|
+
* `node:crypto` and refuses on a mismatch, naming the platform, the file and both hashes.
|
|
31
|
+
* There is no fallback to another file.
|
|
32
|
+
* 4. It writes the same bytes, with `O_EXCL`, into a new directory from `fs.mkdtempSync` under
|
|
57
33
|
* `os.tmpdir()` (mode 0700 on POSIX; on Windows the per-user `%TEMP%` ACL), under a random
|
|
58
34
|
* leaf name (macOS looks a leaf name up in `DYLD_LIBRARY_PATH` before the path), checks the
|
|
59
|
-
* copy's SHA-256 again, and
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* d, shared only with a loader (`binding.cjs`), so no JavaScript module wraps or re-exports
|
|
70
|
-
* it, and a `binding.cjs` that other code required first (with its own addon) is refused;
|
|
71
|
-
* 5. stamped `__napiBindingTarget === "native"`;
|
|
72
|
-
* 6. at this package's version: `version()` must equal `package.json`'s version. That is the
|
|
73
|
-
* workspace version, which every release keeps in step (feature 0007 T04). So an addon from
|
|
74
|
-
* another release is refused, whatever `NAPI_RS_ENFORCE_VERSION_CHECK` says (SF-4 item 3).
|
|
35
|
+
* copy's SHA-256 again, and `require`s that absolute path, which Node's `.node` handler hands
|
|
36
|
+
* to `dlopen`. So between the check and `dlopen` only this user (who can already change
|
|
37
|
+
* anything they run) could swap the file; whoever can write the installed package can't. The
|
|
38
|
+
* copy is deleted right after (a loaded library stays mapped; Windows can't delete a loaded
|
|
39
|
+
* DLL, so there the copy stays in the temporary directory).
|
|
40
|
+
* 5. What loaded must be the exports of exactly that one module in the CommonJS cache, the
|
|
41
|
+
* private copy, so no JavaScript module wraps or re-exports it.
|
|
42
|
+
* 6. It must be this package's version: `version()` equals `package.json`'s version, the
|
|
43
|
+
* workspace version every release keeps in step (feature 0007 T04), so an addon of another
|
|
44
|
+
* release is refused.
|
|
75
45
|
* Every refusal is an `Error` with `code` `ERR_POLYJOSE_ADDON_REFUSED`. This doesn't defend against
|
|
76
46
|
* code already running in the process, which can patch anything. It makes sure the package never
|
|
77
47
|
* selects a substitute.
|
|
78
48
|
*
|
|
79
|
-
* `test/loader.test.ts` pins
|
|
80
|
-
*
|
|
49
|
+
* `test/loader.test.ts` pins what this module loads (its built-ins and its one `require`), the
|
|
50
|
+
* platform detection, and each refusal.
|
|
81
51
|
*/
|
|
82
52
|
import type { Backend } from "./facade/backend.js";
|
|
53
|
+
/** The one `fs` call platform detection makes (so tests can fake it). */
|
|
54
|
+
interface TextReader {
|
|
55
|
+
readFileSync(path: string, encoding: "utf8"): string;
|
|
56
|
+
}
|
|
57
|
+
interface ProcessReport {
|
|
58
|
+
excludeNetwork: boolean;
|
|
59
|
+
getReport(): {
|
|
60
|
+
readonly header?: {
|
|
61
|
+
readonly glibcVersionRuntime?: unknown;
|
|
62
|
+
};
|
|
63
|
+
readonly sharedObjects?: unknown;
|
|
64
|
+
} | null;
|
|
65
|
+
}
|
|
66
|
+
/** What `detectPlatform` reads of `process`. */
|
|
67
|
+
interface PlatformHost {
|
|
68
|
+
readonly platform: string;
|
|
69
|
+
readonly arch: string;
|
|
70
|
+
readonly report?: ProcessReport;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* The eight platforms whose addon this package ships (ADR 0031 §2's targets): the only keys a map
|
|
74
|
+
* may have. `test/loader.test.ts` checks them against package.json's `napi.targets` and `files`.
|
|
75
|
+
*/
|
|
76
|
+
export declare const PLATFORMS: readonly ["darwin-x64", "darwin-arm64", "linux-x64-gnu", "linux-arm64-gnu", "linux-x64-musl", "linux-arm64-musl", "win32-x64-msvc", "win32-arm64-msvc"];
|
|
83
77
|
/**
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* is
|
|
78
|
+
* Step 1: this host's platform name, napi-rs's (`napi build --platform` names the addon after it):
|
|
79
|
+
* `darwin-x64|arm64`, `win32-x64|arm64-msvc`, `linux-x64|arm64-gnu|musl`. Any other platform or
|
|
80
|
+
* architecture is `<platform>-<arch>`, which `PLATFORMS` does not list. On Linux it reads
|
|
81
|
+
* /usr/bin/ldd and may take a process report (`isMusl`); it refuses when it cannot tell the libc.
|
|
87
82
|
*/
|
|
88
|
-
export declare
|
|
89
|
-
/** The
|
|
83
|
+
export declare function detectPlatform(host: PlatformHost, fs: TextReader): string;
|
|
84
|
+
/** The native addon, typed as the facade's backend. */
|
|
90
85
|
export declare const backend: Backend;
|
|
86
|
+
export {};
|