@spinajs/authn-keys 0.0.0-stage → 3.0.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 +165 -2
- package/lib/cjs/bootstrap.d.ts +6 -0
- package/lib/cjs/bootstrap.d.ts.map +1 -0
- package/lib/cjs/bootstrap.js +23 -0
- package/lib/cjs/bootstrap.js.map +1 -0
- package/lib/cjs/challenge/challenge.d.ts +27 -0
- package/lib/cjs/challenge/challenge.d.ts.map +1 -0
- package/lib/cjs/challenge/challenge.js +56 -0
- package/lib/cjs/challenge/challenge.js.map +1 -0
- package/lib/cjs/challenge/index.d.ts +2 -0
- package/lib/cjs/challenge/index.d.ts.map +1 -0
- package/lib/cjs/challenge/index.js +18 -0
- package/lib/cjs/challenge/index.js.map +1 -0
- package/lib/cjs/cli/AddKey.d.ts +18 -0
- package/lib/cjs/cli/AddKey.d.ts.map +1 -0
- package/lib/cjs/cli/AddKey.js +65 -0
- package/lib/cjs/cli/AddKey.js.map +1 -0
- package/lib/cjs/cli/ListKeys.d.ts +11 -0
- package/lib/cjs/cli/ListKeys.d.ts.map +1 -0
- package/lib/cjs/cli/ListKeys.js +48 -0
- package/lib/cjs/cli/ListKeys.js.map +1 -0
- package/lib/cjs/cli/RevokeKey.d.ts +9 -0
- package/lib/cjs/cli/RevokeKey.d.ts.map +1 -0
- package/lib/cjs/cli/RevokeKey.js +42 -0
- package/lib/cjs/cli/RevokeKey.js.map +1 -0
- package/lib/cjs/cli/common.d.ts +9 -0
- package/lib/cjs/cli/common.d.ts.map +1 -0
- package/lib/cjs/cli/common.js +35 -0
- package/lib/cjs/cli/common.js.map +1 -0
- package/lib/cjs/cli/index.d.ts +5 -0
- package/lib/cjs/cli/index.d.ts.map +1 -0
- package/lib/cjs/cli/index.js +21 -0
- package/lib/cjs/cli/index.js.map +1 -0
- package/lib/cjs/config/authn-keys.d.ts +9 -0
- package/lib/cjs/config/authn-keys.d.ts.map +1 -0
- package/lib/cjs/config/authn-keys.js +23 -0
- package/lib/cjs/config/authn-keys.js.map +1 -0
- package/lib/cjs/httpsig/base.d.ts +8 -0
- package/lib/cjs/httpsig/base.d.ts.map +1 -0
- package/lib/cjs/httpsig/base.js +73 -0
- package/lib/cjs/httpsig/base.js.map +1 -0
- package/lib/cjs/httpsig/fields.d.ts +17 -0
- package/lib/cjs/httpsig/fields.d.ts.map +1 -0
- package/lib/cjs/httpsig/fields.js +137 -0
- package/lib/cjs/httpsig/fields.js.map +1 -0
- package/lib/cjs/httpsig/index.d.ts +3 -0
- package/lib/cjs/httpsig/index.d.ts.map +1 -0
- package/lib/cjs/httpsig/index.js +19 -0
- package/lib/cjs/httpsig/index.js.map +1 -0
- package/lib/cjs/index.d.ts +13 -0
- package/lib/cjs/index.d.ts.map +1 -0
- package/lib/cjs/index.js +29 -0
- package/lib/cjs/index.js.map +1 -0
- package/lib/cjs/jwk/base64url.d.ts +7 -0
- package/lib/cjs/jwk/base64url.d.ts.map +1 -0
- package/lib/cjs/jwk/base64url.js +22 -0
- package/lib/cjs/jwk/base64url.js.map +1 -0
- package/lib/cjs/jwk/ed25519.d.ts +9 -0
- package/lib/cjs/jwk/ed25519.d.ts.map +1 -0
- package/lib/cjs/jwk/ed25519.js +47 -0
- package/lib/cjs/jwk/ed25519.js.map +1 -0
- package/lib/cjs/jwk/index.d.ts +5 -0
- package/lib/cjs/jwk/index.d.ts.map +1 -0
- package/lib/cjs/jwk/index.js +21 -0
- package/lib/cjs/jwk/index.js.map +1 -0
- package/lib/cjs/jwk/keys.d.ts +18 -0
- package/lib/cjs/jwk/keys.d.ts.map +1 -0
- package/lib/cjs/jwk/keys.js +102 -0
- package/lib/cjs/jwk/keys.js.map +1 -0
- package/lib/cjs/jwk/signature.d.ts +11 -0
- package/lib/cjs/jwk/signature.d.ts.map +1 -0
- package/lib/cjs/jwk/signature.js +45 -0
- package/lib/cjs/jwk/signature.js.map +1 -0
- package/lib/cjs/jws/index.d.ts +4 -0
- package/lib/cjs/jws/index.d.ts.map +1 -0
- package/lib/cjs/jws/index.js +20 -0
- package/lib/cjs/jws/index.js.map +1 -0
- package/lib/cjs/jws/json.d.ts +11 -0
- package/lib/cjs/jws/json.d.ts.map +1 -0
- package/lib/cjs/jws/json.js +76 -0
- package/lib/cjs/jws/json.js.map +1 -0
- package/lib/cjs/jws/signer.d.ts +25 -0
- package/lib/cjs/jws/signer.d.ts.map +1 -0
- package/lib/cjs/jws/signer.js +83 -0
- package/lib/cjs/jws/signer.js.map +1 -0
- package/lib/cjs/jws/verifier.d.ts +10 -0
- package/lib/cjs/jws/verifier.d.ts.map +1 -0
- package/lib/cjs/jws/verifier.js +86 -0
- package/lib/cjs/jws/verifier.js.map +1 -0
- package/lib/cjs/migrations/AuthnKeys_2026_10_02_00_00_00.d.ts +7 -0
- package/lib/cjs/migrations/AuthnKeys_2026_10_02_00_00_00.d.ts.map +1 -0
- package/lib/cjs/migrations/AuthnKeys_2026_10_02_00_00_00.js +40 -0
- package/lib/cjs/migrations/AuthnKeys_2026_10_02_00_00_00.js.map +1 -0
- package/lib/cjs/migrations/index.d.ts +2 -0
- package/lib/cjs/migrations/index.d.ts.map +1 -0
- package/lib/cjs/migrations/index.js +18 -0
- package/lib/cjs/migrations/index.js.map +1 -0
- package/lib/cjs/models/AuthnKey.d.ts +22 -0
- package/lib/cjs/models/AuthnKey.d.ts.map +1 -0
- package/lib/cjs/models/AuthnKey.js +43 -0
- package/lib/cjs/models/AuthnKey.js.map +1 -0
- package/lib/cjs/models/AuthnNonce.d.ts +8 -0
- package/lib/cjs/models/AuthnNonce.d.ts.map +1 -0
- package/lib/cjs/models/AuthnNonce.js +31 -0
- package/lib/cjs/models/AuthnNonce.js.map +1 -0
- package/lib/cjs/models/index.d.ts +3 -0
- package/lib/cjs/models/index.d.ts.map +1 -0
- package/lib/cjs/models/index.js +19 -0
- package/lib/cjs/models/index.js.map +1 -0
- package/lib/cjs/nonce/index.d.ts +2 -0
- package/lib/cjs/nonce/index.d.ts.map +1 -0
- package/lib/cjs/nonce/index.js +18 -0
- package/lib/cjs/nonce/index.js.map +1 -0
- package/lib/cjs/nonce/store.d.ts +22 -0
- package/lib/cjs/nonce/store.d.ts.map +1 -0
- package/lib/cjs/nonce/store.js +98 -0
- package/lib/cjs/nonce/store.js.map +1 -0
- package/lib/cjs/options/index.d.ts +2 -0
- package/lib/cjs/options/index.d.ts.map +1 -0
- package/lib/cjs/options/index.js +18 -0
- package/lib/cjs/options/index.js.map +1 -0
- package/lib/cjs/options/options.d.ts +47 -0
- package/lib/cjs/options/options.d.ts.map +1 -0
- package/lib/cjs/options/options.js +42 -0
- package/lib/cjs/options/options.js.map +1 -0
- package/lib/cjs/package.json +1 -0
- package/lib/cjs/register-schema.d.ts +2 -0
- package/lib/cjs/register-schema.d.ts.map +1 -0
- package/lib/cjs/register-schema.js +9 -0
- package/lib/cjs/register-schema.js.map +1 -0
- package/lib/cjs/registry/index.d.ts +4 -0
- package/lib/cjs/registry/index.d.ts.map +1 -0
- package/lib/cjs/registry/index.js +20 -0
- package/lib/cjs/registry/index.js.map +1 -0
- package/lib/cjs/registry/orm-store.d.ts +15 -0
- package/lib/cjs/registry/orm-store.d.ts.map +1 -0
- package/lib/cjs/registry/orm-store.js +109 -0
- package/lib/cjs/registry/orm-store.js.map +1 -0
- package/lib/cjs/registry/registry.d.ts +54 -0
- package/lib/cjs/registry/registry.d.ts.map +1 -0
- package/lib/cjs/registry/registry.js +244 -0
- package/lib/cjs/registry/registry.js.map +1 -0
- package/lib/cjs/registry/store.d.ts +25 -0
- package/lib/cjs/registry/store.d.ts.map +1 -0
- package/lib/cjs/registry/store.js +66 -0
- package/lib/cjs/registry/store.js.map +1 -0
- package/lib/cjs/schema.d.ts +88 -0
- package/lib/cjs/schema.d.ts.map +1 -0
- package/lib/cjs/schema.js +41 -0
- package/lib/cjs/schema.js.map +1 -0
- package/lib/cjs/strategies/assertion.d.ts +29 -0
- package/lib/cjs/strategies/assertion.d.ts.map +1 -0
- package/lib/cjs/strategies/assertion.js +118 -0
- package/lib/cjs/strategies/assertion.js.map +1 -0
- package/lib/cjs/strategies/challenge.d.ts +25 -0
- package/lib/cjs/strategies/challenge.d.ts.map +1 -0
- package/lib/cjs/strategies/challenge.js +81 -0
- package/lib/cjs/strategies/challenge.js.map +1 -0
- package/lib/cjs/strategies/httpsig.d.ts +34 -0
- package/lib/cjs/strategies/httpsig.d.ts.map +1 -0
- package/lib/cjs/strategies/httpsig.js +127 -0
- package/lib/cjs/strategies/httpsig.js.map +1 -0
- package/lib/cjs/strategies/index.d.ts +5 -0
- package/lib/cjs/strategies/index.d.ts.map +1 -0
- package/lib/cjs/strategies/index.js +21 -0
- package/lib/cjs/strategies/index.js.map +1 -0
- package/lib/cjs/strategies/keys.d.ts +43 -0
- package/lib/cjs/strategies/keys.d.ts.map +1 -0
- package/lib/cjs/strategies/keys.js +93 -0
- package/lib/cjs/strategies/keys.js.map +1 -0
- package/lib/mjs/bootstrap.d.ts +6 -0
- package/lib/mjs/bootstrap.d.ts.map +1 -0
- package/lib/mjs/bootstrap.js +20 -0
- package/lib/mjs/bootstrap.js.map +1 -0
- package/lib/mjs/challenge/challenge.d.ts +27 -0
- package/lib/mjs/challenge/challenge.d.ts.map +1 -0
- package/lib/mjs/challenge/challenge.js +45 -0
- package/lib/mjs/challenge/challenge.js.map +1 -0
- package/lib/mjs/challenge/index.d.ts +2 -0
- package/lib/mjs/challenge/index.d.ts.map +1 -0
- package/lib/mjs/challenge/index.js +2 -0
- package/lib/mjs/challenge/index.js.map +1 -0
- package/lib/mjs/cli/AddKey.d.ts +18 -0
- package/lib/mjs/cli/AddKey.d.ts.map +1 -0
- package/lib/mjs/cli/AddKey.js +62 -0
- package/lib/mjs/cli/AddKey.js.map +1 -0
- package/lib/mjs/cli/ListKeys.d.ts +11 -0
- package/lib/mjs/cli/ListKeys.d.ts.map +1 -0
- package/lib/mjs/cli/ListKeys.js +44 -0
- package/lib/mjs/cli/ListKeys.js.map +1 -0
- package/lib/mjs/cli/RevokeKey.d.ts +9 -0
- package/lib/mjs/cli/RevokeKey.d.ts.map +1 -0
- package/lib/mjs/cli/RevokeKey.js +39 -0
- package/lib/mjs/cli/RevokeKey.js.map +1 -0
- package/lib/mjs/cli/common.d.ts +9 -0
- package/lib/mjs/cli/common.d.ts.map +1 -0
- package/lib/mjs/cli/common.js +30 -0
- package/lib/mjs/cli/common.js.map +1 -0
- package/lib/mjs/cli/index.d.ts +5 -0
- package/lib/mjs/cli/index.d.ts.map +1 -0
- package/lib/mjs/cli/index.js +5 -0
- package/lib/mjs/cli/index.js.map +1 -0
- package/lib/mjs/config/authn-keys.d.ts +9 -0
- package/lib/mjs/config/authn-keys.d.ts.map +1 -0
- package/lib/mjs/config/authn-keys.js +21 -0
- package/lib/mjs/config/authn-keys.js.map +1 -0
- package/lib/mjs/httpsig/base.d.ts +8 -0
- package/lib/mjs/httpsig/base.d.ts.map +1 -0
- package/lib/mjs/httpsig/base.js +67 -0
- package/lib/mjs/httpsig/base.js.map +1 -0
- package/lib/mjs/httpsig/fields.d.ts +17 -0
- package/lib/mjs/httpsig/fields.d.ts.map +1 -0
- package/lib/mjs/httpsig/fields.js +133 -0
- package/lib/mjs/httpsig/fields.js.map +1 -0
- package/lib/mjs/httpsig/index.d.ts +3 -0
- package/lib/mjs/httpsig/index.d.ts.map +1 -0
- package/lib/mjs/httpsig/index.js +3 -0
- package/lib/mjs/httpsig/index.js.map +1 -0
- package/lib/mjs/index.d.ts +13 -0
- package/lib/mjs/index.d.ts.map +1 -0
- package/lib/mjs/index.js +13 -0
- package/lib/mjs/index.js.map +1 -0
- package/lib/mjs/jwk/base64url.d.ts +7 -0
- package/lib/mjs/jwk/base64url.d.ts.map +1 -0
- package/lib/mjs/jwk/base64url.js +18 -0
- package/lib/mjs/jwk/base64url.js.map +1 -0
- package/lib/mjs/jwk/ed25519.d.ts +9 -0
- package/lib/mjs/jwk/ed25519.d.ts.map +1 -0
- package/lib/mjs/jwk/ed25519.js +42 -0
- package/lib/mjs/jwk/ed25519.js.map +1 -0
- package/lib/mjs/jwk/index.d.ts +5 -0
- package/lib/mjs/jwk/index.d.ts.map +1 -0
- package/lib/mjs/jwk/index.js +5 -0
- package/lib/mjs/jwk/index.js.map +1 -0
- package/lib/mjs/jwk/keys.d.ts +18 -0
- package/lib/mjs/jwk/keys.d.ts.map +1 -0
- package/lib/mjs/jwk/keys.js +95 -0
- package/lib/mjs/jwk/keys.js.map +1 -0
- package/lib/mjs/jwk/signature.d.ts +11 -0
- package/lib/mjs/jwk/signature.d.ts.map +1 -0
- package/lib/mjs/jwk/signature.js +39 -0
- package/lib/mjs/jwk/signature.js.map +1 -0
- package/lib/mjs/jws/index.d.ts +4 -0
- package/lib/mjs/jws/index.d.ts.map +1 -0
- package/lib/mjs/jws/index.js +4 -0
- package/lib/mjs/jws/index.js.map +1 -0
- package/lib/mjs/jws/json.d.ts +11 -0
- package/lib/mjs/jws/json.d.ts.map +1 -0
- package/lib/mjs/jws/json.js +72 -0
- package/lib/mjs/jws/json.js.map +1 -0
- package/lib/mjs/jws/signer.d.ts +25 -0
- package/lib/mjs/jws/signer.d.ts.map +1 -0
- package/lib/mjs/jws/signer.js +79 -0
- package/lib/mjs/jws/signer.js.map +1 -0
- package/lib/mjs/jws/verifier.d.ts +10 -0
- package/lib/mjs/jws/verifier.d.ts.map +1 -0
- package/lib/mjs/jws/verifier.js +83 -0
- package/lib/mjs/jws/verifier.js.map +1 -0
- package/lib/mjs/migrations/AuthnKeys_2026_10_02_00_00_00.d.ts +7 -0
- package/lib/mjs/migrations/AuthnKeys_2026_10_02_00_00_00.d.ts.map +1 -0
- package/lib/mjs/migrations/AuthnKeys_2026_10_02_00_00_00.js +37 -0
- package/lib/mjs/migrations/AuthnKeys_2026_10_02_00_00_00.js.map +1 -0
- package/lib/mjs/migrations/index.d.ts +2 -0
- package/lib/mjs/migrations/index.d.ts.map +1 -0
- package/lib/mjs/migrations/index.js +2 -0
- package/lib/mjs/migrations/index.js.map +1 -0
- package/lib/mjs/models/AuthnKey.d.ts +22 -0
- package/lib/mjs/models/AuthnKey.d.ts.map +1 -0
- package/lib/mjs/models/AuthnKey.js +40 -0
- package/lib/mjs/models/AuthnKey.js.map +1 -0
- package/lib/mjs/models/AuthnNonce.d.ts +8 -0
- package/lib/mjs/models/AuthnNonce.d.ts.map +1 -0
- package/lib/mjs/models/AuthnNonce.js +28 -0
- package/lib/mjs/models/AuthnNonce.js.map +1 -0
- package/lib/mjs/models/index.d.ts +3 -0
- package/lib/mjs/models/index.d.ts.map +1 -0
- package/lib/mjs/models/index.js +3 -0
- package/lib/mjs/models/index.js.map +1 -0
- package/lib/mjs/nonce/index.d.ts +2 -0
- package/lib/mjs/nonce/index.d.ts.map +1 -0
- package/lib/mjs/nonce/index.js +2 -0
- package/lib/mjs/nonce/index.js.map +1 -0
- package/lib/mjs/nonce/store.d.ts +22 -0
- package/lib/mjs/nonce/store.d.ts.map +1 -0
- package/lib/mjs/nonce/store.js +92 -0
- package/lib/mjs/nonce/store.js.map +1 -0
- package/lib/mjs/options/index.d.ts +2 -0
- package/lib/mjs/options/index.d.ts.map +1 -0
- package/lib/mjs/options/index.js +2 -0
- package/lib/mjs/options/index.js.map +1 -0
- package/lib/mjs/options/options.d.ts +47 -0
- package/lib/mjs/options/options.d.ts.map +1 -0
- package/lib/mjs/options/options.js +39 -0
- package/lib/mjs/options/options.js.map +1 -0
- package/lib/mjs/package.json +1 -0
- package/lib/mjs/register-schema.d.ts +2 -0
- package/lib/mjs/register-schema.d.ts.map +1 -0
- package/lib/mjs/register-schema.js +7 -0
- package/lib/mjs/register-schema.js.map +1 -0
- package/lib/mjs/registry/index.d.ts +4 -0
- package/lib/mjs/registry/index.d.ts.map +1 -0
- package/lib/mjs/registry/index.js +4 -0
- package/lib/mjs/registry/index.js.map +1 -0
- package/lib/mjs/registry/orm-store.d.ts +15 -0
- package/lib/mjs/registry/orm-store.d.ts.map +1 -0
- package/lib/mjs/registry/orm-store.js +106 -0
- package/lib/mjs/registry/orm-store.js.map +1 -0
- package/lib/mjs/registry/registry.d.ts +54 -0
- package/lib/mjs/registry/registry.d.ts.map +1 -0
- package/lib/mjs/registry/registry.js +239 -0
- package/lib/mjs/registry/registry.js.map +1 -0
- package/lib/mjs/registry/store.d.ts +25 -0
- package/lib/mjs/registry/store.d.ts.map +1 -0
- package/lib/mjs/registry/store.js +57 -0
- package/lib/mjs/registry/store.js.map +1 -0
- package/lib/mjs/schema.d.ts +88 -0
- package/lib/mjs/schema.d.ts.map +1 -0
- package/lib/mjs/schema.js +38 -0
- package/lib/mjs/schema.js.map +1 -0
- package/lib/mjs/strategies/assertion.d.ts +29 -0
- package/lib/mjs/strategies/assertion.d.ts.map +1 -0
- package/lib/mjs/strategies/assertion.js +115 -0
- package/lib/mjs/strategies/assertion.js.map +1 -0
- package/lib/mjs/strategies/challenge.d.ts +25 -0
- package/lib/mjs/strategies/challenge.d.ts.map +1 -0
- package/lib/mjs/strategies/challenge.js +78 -0
- package/lib/mjs/strategies/challenge.js.map +1 -0
- package/lib/mjs/strategies/httpsig.d.ts +34 -0
- package/lib/mjs/strategies/httpsig.d.ts.map +1 -0
- package/lib/mjs/strategies/httpsig.js +124 -0
- package/lib/mjs/strategies/httpsig.js.map +1 -0
- package/lib/mjs/strategies/index.d.ts +5 -0
- package/lib/mjs/strategies/index.d.ts.map +1 -0
- package/lib/mjs/strategies/index.js +5 -0
- package/lib/mjs/strategies/index.js.map +1 -0
- package/lib/mjs/strategies/keys.d.ts +43 -0
- package/lib/mjs/strategies/keys.d.ts.map +1 -0
- package/lib/mjs/strategies/keys.js +85 -0
- package/lib/mjs/strategies/keys.js.map +1 -0
- package/lib/tsconfig.cjs.tsbuildinfo +1 -0
- package/lib/tsconfig.mjs.tsbuildinfo +1 -0
- package/package.json +79 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/jws/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { isPlainObject } from '@spinajs/util';
|
|
2
|
+
/**
|
|
3
|
+
* JSON as serde_json reads it, so this verifier agrees with the canvas C8 Rust one: refuses invalid UTF-8, lone
|
|
4
|
+
* surrogates (escaped or not, keys included, also under a duplicate key), nesting deeper than 127, numbers beyond f64,
|
|
5
|
+
* and top-level `uintKeys` whose number is not written as a plain integer. A duplicate key keeps its last value
|
|
6
|
+
* (RFC 7515 §4 allows that, and both C8 verifiers do it). Undefined when refused; never throws.
|
|
7
|
+
*/
|
|
8
|
+
export declare function parseStrictJson(bytes: Uint8Array, uintKeys?: readonly string[]): unknown;
|
|
9
|
+
/** @deprecated Use `isPlainObject` from `@spinajs/util`. */
|
|
10
|
+
export declare const isJsonObject: typeof isPlainObject;
|
|
11
|
+
//# sourceMappingURL=json.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../../src/jws/json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAY9C;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,GAAE,SAAS,MAAM,EAAO,GAAG,OAAO,CAgD5F;AAED,4DAA4D;AAC5D,eAAO,MAAM,YAAY,sBAAgB,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { isPlainObject } from '@spinajs/util';
|
|
2
|
+
const LONE_SURROGATE = /\p{Surrogate}/u;
|
|
3
|
+
// serde_json refuses the 128th nested array or object (its recursion limit); canvas C8 refuses it on both sides.
|
|
4
|
+
const MAX_DEPTH = 127;
|
|
5
|
+
// On text JSON.parse accepted, these are exactly its strings, brackets and numbers (literals are skipped).
|
|
6
|
+
const TOKENS = /"[^"\\]*(?:\\.[^"\\]*)*"|[[\]{}]|-?[0-9][0-9.eE+-]*/g;
|
|
7
|
+
const KEY_FOLLOWS = /\s*:/y;
|
|
8
|
+
const UINT_TEXT = /^(0|[1-9][0-9]*)$/;
|
|
9
|
+
const decoder = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true });
|
|
10
|
+
/**
|
|
11
|
+
* JSON as serde_json reads it, so this verifier agrees with the canvas C8 Rust one: refuses invalid UTF-8, lone
|
|
12
|
+
* surrogates (escaped or not, keys included, also under a duplicate key), nesting deeper than 127, numbers beyond f64,
|
|
13
|
+
* and top-level `uintKeys` whose number is not written as a plain integer. A duplicate key keeps its last value
|
|
14
|
+
* (RFC 7515 §4 allows that, and both C8 verifiers do it). Undefined when refused; never throws.
|
|
15
|
+
*/
|
|
16
|
+
export function parseStrictJson(bytes, uintKeys = []) {
|
|
17
|
+
try {
|
|
18
|
+
const text = decoder.decode(bytes);
|
|
19
|
+
const value = JSON.parse(text);
|
|
20
|
+
// The number text of each top-level key, the last occurrence winning as in JSON.parse; read from the tokens
|
|
21
|
+
// because the reviver's source text needs Node 21+.
|
|
22
|
+
const numberText = new Map();
|
|
23
|
+
const topLevelObject = text.trimStart().startsWith('{');
|
|
24
|
+
let depth = 0;
|
|
25
|
+
let key = null;
|
|
26
|
+
for (const m of text.matchAll(TOKENS)) {
|
|
27
|
+
const token = m[0];
|
|
28
|
+
const pending = key;
|
|
29
|
+
key = null;
|
|
30
|
+
if (token === '[' || token === '{') {
|
|
31
|
+
depth += 1;
|
|
32
|
+
if (depth > MAX_DEPTH) {
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else if (token === ']' || token === '}') {
|
|
37
|
+
depth -= 1;
|
|
38
|
+
}
|
|
39
|
+
else if (token.startsWith('"')) {
|
|
40
|
+
const s = JSON.parse(token);
|
|
41
|
+
if (LONE_SURROGATE.test(s)) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
if (topLevelObject && depth === 1) {
|
|
45
|
+
KEY_FOLLOWS.lastIndex = m.index + token.length;
|
|
46
|
+
if (KEY_FOLLOWS.test(text)) {
|
|
47
|
+
key = s;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else if (!Number.isFinite(Number(token))) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
else if (pending !== null) {
|
|
55
|
+
numberText.set(pending, token);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
for (const k of uintKeys) {
|
|
59
|
+
const t = numberText.get(k);
|
|
60
|
+
if (t !== undefined && !UINT_TEXT.test(t)) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return value;
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/** @deprecated Use `isPlainObject` from `@spinajs/util`. */
|
|
71
|
+
export const isJsonObject = isPlainObject;
|
|
72
|
+
//# sourceMappingURL=json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../../src/jws/json.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { JwsSigner } from '@spinajs/authn/contracts';
|
|
2
|
+
import type { JwsClaims, JwsKey, JwsSignOptions } from '@spinajs/authn/contracts';
|
|
3
|
+
/** A private signing JWK: Ed25519 (RFC 8037) or P-256, with its `kid`. */
|
|
4
|
+
export interface PrivateJwk {
|
|
5
|
+
readonly kty: string;
|
|
6
|
+
readonly crv: string;
|
|
7
|
+
readonly kid: string;
|
|
8
|
+
readonly x: string;
|
|
9
|
+
readonly y?: string;
|
|
10
|
+
readonly d: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* JwsSigner over private JWKs the app loads (from a secret reference) and passes in; the first key, or `current`,
|
|
14
|
+
* signs by default. Header and claims are written exactly as canvas C8 does, so EdDSA tickets come out byte for byte.
|
|
15
|
+
*/
|
|
16
|
+
export declare class LocalJwsSigner extends JwsSigner {
|
|
17
|
+
private readonly keys;
|
|
18
|
+
private readonly current;
|
|
19
|
+
constructor(privateJwks: readonly PrivateJwk[], opts?: {
|
|
20
|
+
readonly current?: string;
|
|
21
|
+
});
|
|
22
|
+
sign<C extends JwsClaims>(claims: C, opts: JwsSignOptions): Promise<string>;
|
|
23
|
+
publicKeys(): Promise<readonly JwsKey[]>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=signer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../../../src/jws/signer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAQlF,0EAA0E;AAC1E,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;CACpB;AAgCD;;;GAGG;AACH,qBAAa,cAAe,SAAQ,SAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiC;IACtD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC,YAAY,WAAW,EAAE,SAAS,UAAU,EAAE,EAAE,IAAI,GAAE;QAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAO,EAavF;IAEK,IAAI,CAAC,CAAC,SAAS,SAAS,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBhF;IAEK,UAAU,IAAI,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAE7C;CACF"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { createPrivateKey, createPublicKey } from 'node:crypto';
|
|
2
|
+
import { JwsSigner } from '@spinajs/authn/contracts';
|
|
3
|
+
import { _is_string, _non_empty, _try_check_arg, isNonNegativeInt } from '@spinajs/util';
|
|
4
|
+
import { InvalidArgument } from '@spinajs/exceptions';
|
|
5
|
+
import { decodeB64url, encodeB64url } from '../jwk/base64url.js';
|
|
6
|
+
import { checkPublicJwk, isValidKid } from '../jwk/keys.js';
|
|
7
|
+
import { signRaw } from '../jwk/signature.js';
|
|
8
|
+
import { parseStrictJson } from './json.js';
|
|
9
|
+
function signingKey(jwk) {
|
|
10
|
+
const where = `signing key ${JSON.stringify(jwk?.kid)}`;
|
|
11
|
+
if (!isValidKid(jwk?.kid)) {
|
|
12
|
+
throw new InvalidArgument(`${where}: kid must be 1-64 of [A-Za-z0-9._-]`);
|
|
13
|
+
}
|
|
14
|
+
const material = checkPublicJwk(jwk.kty === 'EC' ? { kty: jwk.kty, crv: jwk.crv, x: jwk.x, y: jwk.y } : { kty: jwk.kty, crv: jwk.crv, x: jwk.x });
|
|
15
|
+
if (!material) {
|
|
16
|
+
throw new InvalidArgument(`${where}: not a valid Ed25519 or P-256 key`);
|
|
17
|
+
}
|
|
18
|
+
if (decodeB64url(jwk.d)?.length !== 32) {
|
|
19
|
+
throw new InvalidArgument(`${where}: d must be 32 bytes of base64url`);
|
|
20
|
+
}
|
|
21
|
+
let privateKey;
|
|
22
|
+
try {
|
|
23
|
+
privateKey = createPrivateKey({ key: { ...material.jwk, d: jwk.d }, format: 'jwk' });
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
throw new InvalidArgument(`${where}: the private key does not load`);
|
|
27
|
+
}
|
|
28
|
+
const derived = createPublicKey(privateKey).export({ format: 'jwk' });
|
|
29
|
+
if (derived.x !== material.jwk.x || (material.jwk.kty === 'EC' && derived.y !== material.jwk.y)) {
|
|
30
|
+
throw new InvalidArgument(`${where}: the public part does not match d`);
|
|
31
|
+
}
|
|
32
|
+
return { publicKey: Object.freeze({ ...material, kid: jwk.kid }), privateKey };
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* JwsSigner over private JWKs the app loads (from a secret reference) and passes in; the first key, or `current`,
|
|
36
|
+
* signs by default. Header and claims are written exactly as canvas C8 does, so EdDSA tickets come out byte for byte.
|
|
37
|
+
*/
|
|
38
|
+
export class LocalJwsSigner extends JwsSigner {
|
|
39
|
+
constructor(privateJwks, opts = {}) {
|
|
40
|
+
super();
|
|
41
|
+
this.keys = new Map();
|
|
42
|
+
for (const jwk of privateJwks) {
|
|
43
|
+
if (this.keys.has(jwk.kid)) {
|
|
44
|
+
throw new InvalidArgument(`signing key ${JSON.stringify(jwk.kid)} appears twice`);
|
|
45
|
+
}
|
|
46
|
+
this.keys.set(jwk.kid, signingKey(jwk));
|
|
47
|
+
}
|
|
48
|
+
const current = opts.current ?? privateJwks[0]?.kid;
|
|
49
|
+
if (current === undefined || !this.keys.has(current)) {
|
|
50
|
+
throw new InvalidArgument(`no signing key ${JSON.stringify(current)}`);
|
|
51
|
+
}
|
|
52
|
+
this.current = current;
|
|
53
|
+
}
|
|
54
|
+
async sign(claims, opts) {
|
|
55
|
+
const kid = opts.kid ?? this.current;
|
|
56
|
+
const key = this.keys.get(kid);
|
|
57
|
+
if (!key) {
|
|
58
|
+
throw new InvalidArgument(`no signing key ${JSON.stringify(kid)}`);
|
|
59
|
+
}
|
|
60
|
+
const [hasTyp] = _try_check_arg(_is_string(_non_empty()))(opts.typ, 'opts.typ');
|
|
61
|
+
if (!hasTyp) {
|
|
62
|
+
throw new InvalidArgument('a JWS needs a typ');
|
|
63
|
+
}
|
|
64
|
+
if (typeof claims.iss !== 'string' || typeof claims.aud !== 'string' || !isNonNegativeInt(claims.iat) || !isNonNegativeInt(claims.exp) || claims.exp <= claims.iat) {
|
|
65
|
+
throw new InvalidArgument('claims need string iss and aud, and integer iat < exp in Unix seconds');
|
|
66
|
+
}
|
|
67
|
+
const header = JSON.stringify({ alg: key.publicKey.alg, kid, typ: opts.typ });
|
|
68
|
+
const payload = JSON.stringify(claims);
|
|
69
|
+
if (parseStrictJson(Buffer.from(payload, 'utf8'), ['iat', 'exp']) === undefined) {
|
|
70
|
+
throw new InvalidArgument('claims must be JSON a strict verifier reads (no lone surrogates, no nesting deeper than 127)');
|
|
71
|
+
}
|
|
72
|
+
const input = `${encodeB64url(header)}.${encodeB64url(payload)}`;
|
|
73
|
+
return `${input}.${encodeB64url(signRaw(key.publicKey.alg, key.privateKey, Buffer.from(input, 'ascii')))}`;
|
|
74
|
+
}
|
|
75
|
+
async publicKeys() {
|
|
76
|
+
return Object.freeze([...this.keys.values()].map((k) => k.publicKey));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=signer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signer.js","sourceRoot":"","sources":["../../../src/jws/signer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { JwsVerifier } from '@spinajs/authn/contracts';
|
|
2
|
+
import type { JwsClaims, JwsKey, JwsVerification, JwsVerifyOptions } from '@spinajs/authn/contracts';
|
|
3
|
+
/**
|
|
4
|
+
* Compact JWS under the canvas C8 D4 rules (lane notes D3): the first failing check gives the code. The signature is
|
|
5
|
+
* checked with the key's own algorithm; a key that fails the key checks counts as unknown.
|
|
6
|
+
*/
|
|
7
|
+
export declare class StrictJwsVerifier extends JwsVerifier {
|
|
8
|
+
verify<C extends JwsClaims, K extends JwsKey = JwsKey>(token: string, opts: JwsVerifyOptions<C, K>): Promise<JwsVerification<C, K>>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=verifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifier.d.ts","sourceRoot":"","sources":["../../../src/jws/verifier.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,KAAK,EAAE,SAAS,EAA2B,MAAM,EAAE,eAAe,EAAE,gBAAgB,EAAgB,MAAM,0BAA0B,CAAC;AAW5I;;;GAGG;AACH,qBACa,iBAAkB,SAAQ,WAAW;IAC1C,MAAM,CAAC,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CA2DxI;CACF"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { Injectable } from '@spinajs/di';
|
|
8
|
+
import { JwsVerifier } from '@spinajs/authn/contracts';
|
|
9
|
+
import { isNonNegativeInt, isPlainObject } from '@spinajs/util';
|
|
10
|
+
import { decodeB64url } from '../jwk/base64url.js';
|
|
11
|
+
import { publicKeyObject } from '../jwk/keys.js';
|
|
12
|
+
import { SIGNATURE_BYTES, verifySignature } from '../jwk/signature.js';
|
|
13
|
+
import { parseStrictJson } from './json.js';
|
|
14
|
+
const HEADER_MEMBERS = ['alg', 'kid', 'typ'];
|
|
15
|
+
const fail = (code) => ({ ok: false, code });
|
|
16
|
+
/**
|
|
17
|
+
* Compact JWS under the canvas C8 D4 rules (lane notes D3): the first failing check gives the code. The signature is
|
|
18
|
+
* checked with the key's own algorithm; a key that fails the key checks counts as unknown.
|
|
19
|
+
*/
|
|
20
|
+
let StrictJwsVerifier = class StrictJwsVerifier extends JwsVerifier {
|
|
21
|
+
async verify(token, opts) {
|
|
22
|
+
if (typeof token !== 'string') {
|
|
23
|
+
return fail('malformed');
|
|
24
|
+
}
|
|
25
|
+
const parts = token.split('.');
|
|
26
|
+
if (parts.length !== 3) {
|
|
27
|
+
return fail('malformed');
|
|
28
|
+
}
|
|
29
|
+
const [headerText, payloadText, signatureText] = parts;
|
|
30
|
+
const headerBytes = decodeB64url(headerText);
|
|
31
|
+
const payloadBytes = decodeB64url(payloadText);
|
|
32
|
+
const signature = decodeB64url(signatureText);
|
|
33
|
+
if (!headerBytes || !payloadBytes || signature?.length !== SIGNATURE_BYTES) {
|
|
34
|
+
return fail('malformed');
|
|
35
|
+
}
|
|
36
|
+
const h = parseStrictJson(headerBytes);
|
|
37
|
+
if (!isPlainObject(h) || Object.keys(h).length !== HEADER_MEMBERS.length || !HEADER_MEMBERS.every((m) => typeof h[m] === 'string')) {
|
|
38
|
+
return fail('bad_header');
|
|
39
|
+
}
|
|
40
|
+
const header = Object.freeze({ alg: h.alg, kid: h.kid, typ: h.typ });
|
|
41
|
+
if (!opts.algorithms.includes(header.alg) || header.typ !== opts.typ) {
|
|
42
|
+
return fail('bad_header');
|
|
43
|
+
}
|
|
44
|
+
const key = await opts.keys(header.kid);
|
|
45
|
+
if (!key || key.alg !== header.alg || publicKeyObject(key) === null) {
|
|
46
|
+
return fail('unknown_key');
|
|
47
|
+
}
|
|
48
|
+
if (!verifySignature(key, Buffer.from(`${headerText}.${payloadText}`, 'ascii'), signature)) {
|
|
49
|
+
return fail('bad_signature');
|
|
50
|
+
}
|
|
51
|
+
const payload = parseStrictJson(payloadBytes, ['iat', 'exp']);
|
|
52
|
+
if (!isPlainObject(payload)) {
|
|
53
|
+
return fail('invalid_claims');
|
|
54
|
+
}
|
|
55
|
+
const { iss, aud, iat, exp } = payload;
|
|
56
|
+
if (typeof iss !== 'string' || typeof aud !== 'string' || !isNonNegativeInt(iat) || !isNonNegativeInt(exp) || exp <= iat || exp - iat > opts.maxLifetimeSeconds) {
|
|
57
|
+
return fail('invalid_claims');
|
|
58
|
+
}
|
|
59
|
+
const claims = opts.claims(payload);
|
|
60
|
+
if (claims === null) {
|
|
61
|
+
return fail('invalid_claims');
|
|
62
|
+
}
|
|
63
|
+
if (typeof opts.issuer === 'function' ? !opts.issuer(iss, key) : iss !== opts.issuer) {
|
|
64
|
+
return fail('wrong_issuer');
|
|
65
|
+
}
|
|
66
|
+
if (aud !== opts.audience) {
|
|
67
|
+
return fail('wrong_audience');
|
|
68
|
+
}
|
|
69
|
+
const nowS = Math.floor(opts.now.getTime() / 1000);
|
|
70
|
+
if (nowS >= exp + opts.skewSeconds) {
|
|
71
|
+
return fail('expired');
|
|
72
|
+
}
|
|
73
|
+
if (iat > nowS + opts.skewSeconds) {
|
|
74
|
+
return fail('not_yet_valid');
|
|
75
|
+
}
|
|
76
|
+
return { ok: true, header, claims, key };
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
StrictJwsVerifier = __decorate([
|
|
80
|
+
Injectable(JwsVerifier)
|
|
81
|
+
], StrictJwsVerifier);
|
|
82
|
+
export { StrictJwsVerifier };
|
|
83
|
+
//# sourceMappingURL=verifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifier.js","sourceRoot":"","sources":["../../../src/jws/verifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { OrmDriver, OrmMigration } from '@spinajs/orm';
|
|
2
|
+
/** Design §22.16 `authn_key`, plus an owner index for GET /user/keys. */
|
|
3
|
+
export declare class AuthnKeys_2026_10_02_00_00_00 extends OrmMigration {
|
|
4
|
+
up(connection: OrmDriver): Promise<void>;
|
|
5
|
+
down(connection: OrmDriver): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=AuthnKeys_2026_10_02_00_00_00.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthnKeys_2026_10_02_00_00_00.d.ts","sourceRoot":"","sources":["../../../src/migrations/AuthnKeys_2026_10_02_00_00_00.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAElE,yEAAyE;AACzE,qBACa,6BAA8B,SAAQ,YAAY;IAChD,EAAE,CAAC,UAAU,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBpD;IAEY,IAAI,CAAC,UAAU,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtD;CACF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { Migration, OrmMigration } from '@spinajs/orm';
|
|
8
|
+
/** Design §22.16 `authn_key`, plus an owner index for GET /user/keys. */
|
|
9
|
+
let AuthnKeys_2026_10_02_00_00_00 = class AuthnKeys_2026_10_02_00_00_00 extends OrmMigration {
|
|
10
|
+
async up(connection) {
|
|
11
|
+
await connection.schema().createTable('authn_key', (table) => {
|
|
12
|
+
table.string('kid', 64).primaryKey();
|
|
13
|
+
table.string('owner_type', 16).notNull();
|
|
14
|
+
table.string('owner_id', 64).notNull();
|
|
15
|
+
table.string('alg', 16).notNull();
|
|
16
|
+
table.text('jwk').notNull();
|
|
17
|
+
table.string('thumbprint', 64).notNull();
|
|
18
|
+
table.text('scope');
|
|
19
|
+
table.string('name', 128);
|
|
20
|
+
table.dateTime('expires_at');
|
|
21
|
+
table.dateTime('revoked_at');
|
|
22
|
+
table.dateTime('last_used_at');
|
|
23
|
+
table.string('created_by', 100);
|
|
24
|
+
table.dateTime('created_at').notNull();
|
|
25
|
+
});
|
|
26
|
+
await connection.index().unique().table('authn_key').name('authn_key_thumb').columns(['thumbprint']);
|
|
27
|
+
await connection.index().table('authn_key').name('authn_key_owner').columns(['owner_type', 'owner_id']);
|
|
28
|
+
}
|
|
29
|
+
async down(connection) {
|
|
30
|
+
await connection.schema().dropTable('authn_key');
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
AuthnKeys_2026_10_02_00_00_00 = __decorate([
|
|
34
|
+
Migration('default')
|
|
35
|
+
], AuthnKeys_2026_10_02_00_00_00);
|
|
36
|
+
export { AuthnKeys_2026_10_02_00_00_00 };
|
|
37
|
+
//# sourceMappingURL=AuthnKeys_2026_10_02_00_00_00.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthnKeys_2026_10_02_00_00_00.js","sourceRoot":"","sources":["../../../src/migrations/AuthnKeys_2026_10_02_00_00_00.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,SAAS,EAAa,YAAY,EAAE,MAAM,cAAc,CAAC;AAElE,yEAAyE;AAElE,IAAM,6BAA6B,GAAnC,MAAM,6BAA8B,SAAQ,YAAY;IACtD,KAAK,CAAC,EAAE,CAAC,UAAqB;QACnC,MAAM,UAAU,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE;YAC3D,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC;YACrC,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;YACzC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;YACvC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;YAClC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;YAC5B,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;YACzC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACpB,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YAC1B,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;YAC7B,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;YAC7B,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;YAC/B,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;YAChC,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;QACzC,CAAC,CAAC,CAAC;QACH,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;QACrG,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC;IAC1G,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,UAAqB;QACrC,MAAM,UAAU,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACnD,CAAC;CACF,CAAA;AAxBY,6BAA6B;IADzC,SAAS,CAAC,SAAS,CAAC;GACR,6BAA6B,CAwBzC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/migrations/index.ts"],"names":[],"mappings":"AAAA,cAAc,oCAAoC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/migrations/index.ts"],"names":[],"mappings":"AAAA,cAAc,oCAAoC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ModelBase } from '@spinajs/orm';
|
|
2
|
+
import { DateTime } from 'luxon';
|
|
3
|
+
/** A row of authn_key; OrmKeyStore maps it to the contract's KeyRecord. */
|
|
4
|
+
export declare class AuthnKey extends ModelBase<AuthnKey> {
|
|
5
|
+
kid: string;
|
|
6
|
+
owner_type: string;
|
|
7
|
+
owner_id: string;
|
|
8
|
+
alg: string;
|
|
9
|
+
/** The public JWK as JSON text, required members only. */
|
|
10
|
+
jwk: string;
|
|
11
|
+
thumbprint: string;
|
|
12
|
+
/** The Ceiling as JSON text. */
|
|
13
|
+
scope?: string | null;
|
|
14
|
+
name?: string | null;
|
|
15
|
+
expires_at?: DateTime;
|
|
16
|
+
revoked_at?: DateTime;
|
|
17
|
+
last_used_at?: DateTime;
|
|
18
|
+
/** PrincipalRef as `<type>:<id>`. */
|
|
19
|
+
created_by?: string | null;
|
|
20
|
+
created_at: DateTime;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=AuthnKey.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthnKey.d.ts","sourceRoot":"","sources":["../../../src/models/AuthnKey.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqC,SAAS,EAAW,MAAM,cAAc,CAAC;AACrF,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC,2EAA2E;AAC3E,qBAEa,QAAS,SAAQ,SAAS,CAAC,QAAQ,CAAC;IAExC,GAAG,EAAE,MAAM,CAAC;IAEZ,UAAU,EAAE,MAAM,CAAC;IAEnB,QAAQ,EAAE,MAAM,CAAC;IAEjB,GAAG,EAAE,MAAM,CAAC;IAEnB,0DAA0D;IACnD,GAAG,EAAE,MAAM,CAAC;IAEZ,UAAU,EAAE,MAAM,CAAC;IAE1B,gCAAgC;IACzB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEtB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGrB,UAAU,CAAC,EAAE,QAAQ,CAAC;IAGtB,UAAU,CAAC,EAAE,QAAQ,CAAC;IAGtB,YAAY,CAAC,EAAE,QAAQ,CAAC;IAE/B,qCAAqC;IAC9B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAG3B,UAAU,EAAE,QAAQ,CAAC;CAC7B"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { Connection, DateTime as DT, Model, ModelBase, Primary } from '@spinajs/orm';
|
|
11
|
+
import { DateTime } from 'luxon';
|
|
12
|
+
/** A row of authn_key; OrmKeyStore maps it to the contract's KeyRecord. */
|
|
13
|
+
let AuthnKey = class AuthnKey extends ModelBase {
|
|
14
|
+
};
|
|
15
|
+
__decorate([
|
|
16
|
+
Primary(),
|
|
17
|
+
__metadata("design:type", String)
|
|
18
|
+
], AuthnKey.prototype, "kid", void 0);
|
|
19
|
+
__decorate([
|
|
20
|
+
DT(),
|
|
21
|
+
__metadata("design:type", DateTime)
|
|
22
|
+
], AuthnKey.prototype, "expires_at", void 0);
|
|
23
|
+
__decorate([
|
|
24
|
+
DT(),
|
|
25
|
+
__metadata("design:type", DateTime)
|
|
26
|
+
], AuthnKey.prototype, "revoked_at", void 0);
|
|
27
|
+
__decorate([
|
|
28
|
+
DT(),
|
|
29
|
+
__metadata("design:type", DateTime)
|
|
30
|
+
], AuthnKey.prototype, "last_used_at", void 0);
|
|
31
|
+
__decorate([
|
|
32
|
+
DT(),
|
|
33
|
+
__metadata("design:type", DateTime)
|
|
34
|
+
], AuthnKey.prototype, "created_at", void 0);
|
|
35
|
+
AuthnKey = __decorate([
|
|
36
|
+
Connection('default'),
|
|
37
|
+
Model('authn_key')
|
|
38
|
+
], AuthnKey);
|
|
39
|
+
export { AuthnKey };
|
|
40
|
+
//# sourceMappingURL=AuthnKey.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthnKey.js","sourceRoot":"","sources":["../../../src/models/AuthnKey.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACrF,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC,2EAA2E;AAGpE,IAAM,QAAQ,GAAd,MAAM,QAAS,SAAQ,SAAmB;CAkChD,CAAA;AAhCQ;IADN,OAAO,EAAE;;qCACS;AAmBZ;IADN,EAAE,EAAE;8BACe,QAAQ;4CAAC;AAGtB;IADN,EAAE,EAAE;8BACe,QAAQ;4CAAC;AAGtB;IADN,EAAE,EAAE;8BACiB,QAAQ;8CAAC;AAMxB;IADN,EAAE,EAAE;8BACc,QAAQ;4CAAC;AAjCjB,QAAQ;IAFpB,UAAU,CAAC,SAAS,CAAC;IACrB,KAAK,CAAC,WAAW,CAAC;GACN,QAAQ,CAkCpB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ModelBase } from '@spinajs/orm';
|
|
2
|
+
import { DateTime } from 'luxon';
|
|
3
|
+
/** A row of authn_nonce (design §22.16; the table comes with authn-orm's AuthnInitial migration). */
|
|
4
|
+
export declare class AuthnNonce extends ModelBase<AuthnNonce> {
|
|
5
|
+
k: string;
|
|
6
|
+
expires_at: DateTime;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=AuthnNonce.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthnNonce.d.ts","sourceRoot":"","sources":["../../../src/models/AuthnNonce.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqC,SAAS,EAAW,MAAM,cAAc,CAAC;AACrF,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC,qGAAqG;AACrG,qBAEa,UAAW,SAAQ,SAAS,CAAC,UAAU,CAAC;IAE5C,CAAC,EAAE,MAAM,CAAC;IAGV,UAAU,EAAE,QAAQ,CAAC;CAC7B"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { Connection, DateTime as DT, Model, ModelBase, Primary } from '@spinajs/orm';
|
|
11
|
+
import { DateTime } from 'luxon';
|
|
12
|
+
/** A row of authn_nonce (design §22.16; the table comes with authn-orm's AuthnInitial migration). */
|
|
13
|
+
let AuthnNonce = class AuthnNonce extends ModelBase {
|
|
14
|
+
};
|
|
15
|
+
__decorate([
|
|
16
|
+
Primary(),
|
|
17
|
+
__metadata("design:type", String)
|
|
18
|
+
], AuthnNonce.prototype, "k", void 0);
|
|
19
|
+
__decorate([
|
|
20
|
+
DT(),
|
|
21
|
+
__metadata("design:type", DateTime)
|
|
22
|
+
], AuthnNonce.prototype, "expires_at", void 0);
|
|
23
|
+
AuthnNonce = __decorate([
|
|
24
|
+
Connection('default'),
|
|
25
|
+
Model('authn_nonce')
|
|
26
|
+
], AuthnNonce);
|
|
27
|
+
export { AuthnNonce };
|
|
28
|
+
//# sourceMappingURL=AuthnNonce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthnNonce.js","sourceRoot":"","sources":["../../../src/models/AuthnNonce.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACrF,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC,qGAAqG;AAG9F,IAAM,UAAU,GAAhB,MAAM,UAAW,SAAQ,SAAqB;CAMpD,CAAA;AAJQ;IADN,OAAO,EAAE;;qCACO;AAGV;IADN,EAAE,EAAE;8BACc,QAAQ;8CAAC;AALjB,UAAU;IAFtB,UAAU,CAAC,SAAS,CAAC;IACrB,KAAK,CAAC,aAAa,CAAC;GACR,UAAU,CAMtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/models/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/models/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/nonce/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/nonce/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Orm } from '@spinajs/orm';
|
|
2
|
+
/** Single-use values (assertion jti, HTTP signature nonces) until they expire. */
|
|
3
|
+
export declare abstract class KeyNonceStore {
|
|
4
|
+
/** True exactly once while `key` is live: the first claim keeps it until `expiresAt`; an expired key may be claimed again. */
|
|
5
|
+
abstract claim(key: string, expiresAt: Date, now: Date): Promise<boolean>;
|
|
6
|
+
}
|
|
7
|
+
/** A fixed-length store key for a value a client chose, scoped to the key that signed it. */
|
|
8
|
+
export declare const nonceKey: (scope: 'jti' | 'sig', kid: string, value: string) => string;
|
|
9
|
+
export declare class MemoryKeyNonceStore extends KeyNonceStore {
|
|
10
|
+
private readonly live;
|
|
11
|
+
private claims;
|
|
12
|
+
claim(key: string, expiresAt: Date, now: Date): Promise<boolean>;
|
|
13
|
+
}
|
|
14
|
+
/** authn_nonce through the ORM: the primary key makes a claim atomic across processes. */
|
|
15
|
+
export declare class DbKeyNonceStore extends KeyNonceStore {
|
|
16
|
+
/** Binds the models when nothing else brought the Orm up. */
|
|
17
|
+
protected Orm: Orm;
|
|
18
|
+
private claims;
|
|
19
|
+
claim(key: string, expiresAt: Date, now: Date): Promise<boolean>;
|
|
20
|
+
private purge;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/nonce/store.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAInC,kFAAkF;AAClF,8BAAsB,aAAa;IACjC,8HAA8H;IAC9H,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3E;AAED,6FAA6F;AAC7F,eAAO,MAAM,QAAQ,UAAW,KAAK,GAAG,KAAK,OAAO,MAAM,SAAS,MAAM,KAAG,MAAmG,CAAC;AAIhL,qBAAa,mBAAoB,SAAQ,aAAa;IACpD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA6B;IAClD,OAAO,CAAC,MAAM,CAAK;IAEb,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAgBrE;CACF;AAKD,0FAA0F;AAC1F,qBACa,eAAgB,SAAQ,aAAa;IAChD,6DAA6D;IAE7D,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAEnB,OAAO,CAAC,MAAM,CAAK;IAEb,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAsBrE;YAEa,KAAK;CAMpB"}
|