@spinajs/authn-keys 0.0.0-stage → 3.0.1
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":"assertion.js","sourceRoot":"","sources":["../../../src/strategies/assertion.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { SecretStore } from '@spinajs/authn/contracts';
|
|
2
|
+
import type { AuthnContext, Credentials, StrategyOutcome, ThrottleKey } from '@spinajs/authn/contracts';
|
|
3
|
+
import { KeyStrategy } from './keys.js';
|
|
4
|
+
import type { KeyStrategyDeps } from './keys.js';
|
|
5
|
+
export interface KeyChallengeStrategyDeps extends KeyStrategyDeps {
|
|
6
|
+
readonly secrets?: SecretStore;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Challenge-response login for CLIs that want a session (design §22.10): `POST /auth/keys/challenge` gives a
|
|
10
|
+
* challenge for a kid, the client signs `spinajs-key-login:<nonce>:<audience>` with that key, and `POST /auth/keys/login` sends
|
|
11
|
+
* `{ keyId, challengeId, signature }`. The signing input names this service (lane notes D6). The challenge is redeemed only after the signature holds, so a wrong signature
|
|
12
|
+
* burns nothing (the throttle counts it).
|
|
13
|
+
*/
|
|
14
|
+
export declare class KeyChallengeStrategy extends KeyStrategy<KeyChallengeStrategyDeps> {
|
|
15
|
+
readonly name = "keys-challenge";
|
|
16
|
+
readonly kinds: string[];
|
|
17
|
+
readonly interactive = true;
|
|
18
|
+
protected Secrets: SecretStore;
|
|
19
|
+
protected get secrets(): SecretStore;
|
|
20
|
+
protected get audience(): string;
|
|
21
|
+
resolve(): Promise<void>;
|
|
22
|
+
throttleKeys(c: Credentials, ctx: AuthnContext): readonly ThrottleKey[];
|
|
23
|
+
verify(c: Credentials, ctx: AuthnContext): Promise<StrategyOutcome>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=challenge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"challenge.d.ts","sourceRoot":"","sources":["../../../src/strategies/challenge.ts"],"names":[],"mappings":"AACA,OAAO,EAA0B,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAKxG,OAAO,EAAE,WAAW,EAA8D,MAAM,WAAW,CAAC;AACpG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEjD,MAAM,WAAW,wBAAyB,SAAQ,eAAe;IAC/D,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC;CAChC;AAED;;;;;GAKG;AACH,qBACa,oBAAqB,SAAQ,WAAW,CAAC,wBAAwB,CAAC;IAC7E,QAAQ,CAAC,IAAI,oBAAoB;IACjC,QAAQ,CAAC,KAAK,WAAqB;IACnC,QAAQ,CAAC,WAAW,QAAQ;IAG5B,SAAS,CAAC,OAAO,EAAE,WAAW,CAAC;IAE/B,SAAS,KAAK,OAAO,IAAI,WAAW,CAEnC;IAED,SAAS,KAAK,QAAQ,IAAI,MAAM,CAM/B;IAEY,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAGpC;IAED,YAAY,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,YAAY,GAAG,SAAS,WAAW,EAAE,CAEtE;IAEK,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,CAqBxE;CACF"}
|
|
@@ -0,0 +1,78 @@
|
|
|
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 { Autoinject, Injectable } from '@spinajs/di';
|
|
11
|
+
import { AuthenticationStrategy, SecretStore } from '@spinajs/authn/contracts';
|
|
12
|
+
import { InvalidOption } from '@spinajs/exceptions';
|
|
13
|
+
import { challengeSecretPurpose, challengeSigningInput, parseChallengeId, verifyChallengeSignature } from '../challenge/challenge.js';
|
|
14
|
+
import { decodeB64url } from '../jwk/base64url.js';
|
|
15
|
+
import { loginChallengeIdentity } from '../registry/registry.js';
|
|
16
|
+
import { KeyStrategy, MAX_CREDENTIAL_LENGTH, failure, keyThrottleKeys, usableKey } from './keys.js';
|
|
17
|
+
/**
|
|
18
|
+
* Challenge-response login for CLIs that want a session (design §22.10): `POST /auth/keys/challenge` gives a
|
|
19
|
+
* challenge for a kid, the client signs `spinajs-key-login:<nonce>:<audience>` with that key, and `POST /auth/keys/login` sends
|
|
20
|
+
* `{ keyId, challengeId, signature }`. The signing input names this service (lane notes D6). The challenge is redeemed only after the signature holds, so a wrong signature
|
|
21
|
+
* burns nothing (the throttle counts it).
|
|
22
|
+
*/
|
|
23
|
+
let KeyChallengeStrategy = class KeyChallengeStrategy extends KeyStrategy {
|
|
24
|
+
constructor() {
|
|
25
|
+
super(...arguments);
|
|
26
|
+
this.name = 'keys-challenge';
|
|
27
|
+
this.kinds = ['key-challenge'];
|
|
28
|
+
this.interactive = true;
|
|
29
|
+
}
|
|
30
|
+
get secrets() {
|
|
31
|
+
return this.Deps?.secrets ?? this.Secrets;
|
|
32
|
+
}
|
|
33
|
+
get audience() {
|
|
34
|
+
const audience = this.options.challenge.audience;
|
|
35
|
+
if (audience === null) {
|
|
36
|
+
throw new InvalidOption('authn.keys.challenge.audience (or authn.keys.assertion.audience) must be set for key challenge logins');
|
|
37
|
+
}
|
|
38
|
+
return audience;
|
|
39
|
+
}
|
|
40
|
+
async resolve() {
|
|
41
|
+
void this.audience;
|
|
42
|
+
await super.resolve();
|
|
43
|
+
}
|
|
44
|
+
throttleKeys(c, ctx) {
|
|
45
|
+
return keyThrottleKeys(c.kind === 'key-challenge' && typeof c.keyId === 'string' ? c.keyId : null, ctx);
|
|
46
|
+
}
|
|
47
|
+
async verify(c, ctx) {
|
|
48
|
+
if (c.kind !== 'key-challenge') {
|
|
49
|
+
return failure('unsupported_credentials');
|
|
50
|
+
}
|
|
51
|
+
const { keyId, challengeId, signature } = c;
|
|
52
|
+
if (typeof keyId !== 'string' || typeof signature !== 'string' || typeof challengeId !== 'string' || keyId.length + challengeId.length + signature.length > MAX_CREDENTIAL_LENGTH) {
|
|
53
|
+
return failure('invalid_credentials');
|
|
54
|
+
}
|
|
55
|
+
const parsed = parseChallengeId(challengeId);
|
|
56
|
+
const found = await usableKey(this.registry, keyId, ctx);
|
|
57
|
+
if (!found.key || !parsed) {
|
|
58
|
+
this.unknownKeyWork((found.key ? found.key.alg : found.alg) ?? 'EdDSA', challengeSigningInput({ nonce: parsed?.nonce ?? '' }, 'login', this.audience), decodeB64url(signature) ?? Buffer.alloc(0));
|
|
59
|
+
return failure(found.key ? 'invalid_credentials' : found.reason);
|
|
60
|
+
}
|
|
61
|
+
if (!verifyChallengeSignature(found.key, parsed.nonce, 'login', this.audience, signature)) {
|
|
62
|
+
return failure('invalid_credentials');
|
|
63
|
+
}
|
|
64
|
+
if (!(await this.secrets.redeem(loginChallengeIdentity(keyId), challengeSecretPurpose(parsed.rid), parsed.nonce))) {
|
|
65
|
+
return failure('invalid_credentials');
|
|
66
|
+
}
|
|
67
|
+
return this.success(found.key, 'key-challenge', ctx);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
__decorate([
|
|
71
|
+
Autoinject(SecretStore),
|
|
72
|
+
__metadata("design:type", SecretStore)
|
|
73
|
+
], KeyChallengeStrategy.prototype, "Secrets", void 0);
|
|
74
|
+
KeyChallengeStrategy = __decorate([
|
|
75
|
+
Injectable(AuthenticationStrategy)
|
|
76
|
+
], KeyChallengeStrategy);
|
|
77
|
+
export { KeyChallengeStrategy };
|
|
78
|
+
//# sourceMappingURL=challenge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"challenge.js","sourceRoot":"","sources":["../../../src/strategies/challenge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { AuthnContext, Credentials, KeyAlgorithm, SignedRequest, StrategyOutcome, ThrottleKey } from '@spinajs/authn/contracts';
|
|
2
|
+
import type { SignatureInput } from '../httpsig/fields.js';
|
|
3
|
+
import { KeyNonceStore } from '../nonce/store.js';
|
|
4
|
+
import { KeyStrategy } from './keys.js';
|
|
5
|
+
import type { KeyStrategyDeps } from './keys.js';
|
|
6
|
+
interface Checked {
|
|
7
|
+
readonly input: SignatureInput;
|
|
8
|
+
readonly signature: Buffer;
|
|
9
|
+
readonly kid: string;
|
|
10
|
+
readonly nonce: string;
|
|
11
|
+
readonly expires: number;
|
|
12
|
+
readonly alg?: KeyAlgorithm;
|
|
13
|
+
}
|
|
14
|
+
export interface HttpSignatureStrategyDeps extends KeyStrategyDeps {
|
|
15
|
+
readonly nonces?: KeyNonceStore;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Per-request HTTP message signatures, an RFC 9421 subset (design §22.10, A18): one signature; `@method`,
|
|
19
|
+
* `@target-uri` and, with a body, `content-digest` (RFC 9530, checked against the body) covered; `created`, `expires`
|
|
20
|
+
* at most `maxAgeSeconds` after it, a single-use `nonce` and `keyid`; `alg` optional. Any label is accepted.
|
|
21
|
+
*/
|
|
22
|
+
export declare class HttpSignatureStrategy extends KeyStrategy<HttpSignatureStrategyDeps> {
|
|
23
|
+
readonly name = "keys-httpsig";
|
|
24
|
+
readonly kinds: string[];
|
|
25
|
+
readonly interactive = false;
|
|
26
|
+
protected Nonces: KeyNonceStore;
|
|
27
|
+
protected get nonces(): KeyNonceStore;
|
|
28
|
+
throttleKeys(c: Credentials, ctx: AuthnContext): readonly ThrottleKey[];
|
|
29
|
+
/** Everything that needs no key: the headers' form, the parameters, coverage, the digest and the time window. */
|
|
30
|
+
protected check(req: SignedRequest, ctx: AuthnContext): Checked | null;
|
|
31
|
+
verify(c: Credentials, ctx: AuthnContext): Promise<StrategyOutcome>;
|
|
32
|
+
}
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=httpsig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpsig.d.ts","sourceRoot":"","sources":["../../../src/strategies/httpsig.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAIrI,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAY,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAA8D,MAAM,WAAW,CAAC;AACpG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAQjD,UAAU,OAAO;IACf,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,CAAC,EAAE,YAAY,CAAC;CAC7B;AAOD,MAAM,WAAW,yBAA0B,SAAQ,eAAe;IAChE,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;CACjC;AAED;;;;GAIG;AACH,qBACa,qBAAsB,SAAQ,WAAW,CAAC,yBAAyB,CAAC;IAC/E,QAAQ,CAAC,IAAI,kBAAkB;IAC/B,QAAQ,CAAC,KAAK,WAAsB;IACpC,QAAQ,CAAC,WAAW,SAAS;IAG7B,SAAS,CAAC,MAAM,EAAE,aAAa,CAAC;IAEhC,SAAS,KAAK,MAAM,IAAI,aAAa,CAEpC;IAED,YAAY,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,YAAY,GAAG,SAAS,WAAW,EAAE,CAKtE;IAED,iHAAiH;IACjH,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,GAAG,IAAI,CAuCrE;IAEK,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,CA4BxE;CACF"}
|
|
@@ -0,0 +1,124 @@
|
|
|
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 { Autoinject, Injectable } from '@spinajs/di';
|
|
11
|
+
import { AuthenticationStrategy } from '@spinajs/authn/contracts';
|
|
12
|
+
import { verifySignature } from '../jwk/signature.js';
|
|
13
|
+
import { digestMatches, lowerCaseHeaders, signatureBase } from '../httpsig/base.js';
|
|
14
|
+
import { parseByteSequenceDictionary, parseSignatureInput } from '../httpsig/fields.js';
|
|
15
|
+
import { KeyNonceStore, nonceKey } from '../nonce/store.js';
|
|
16
|
+
import { KeyStrategy, MAX_CREDENTIAL_LENGTH, failure, keyThrottleKeys, usableKey } from './keys.js';
|
|
17
|
+
/** RFC 9421 algorithm names; the `alg` parameter is optional and, when sent, must name the key's algorithm. */
|
|
18
|
+
const ALG_PARAM = { ed25519: 'EdDSA', 'ecdsa-p256-sha256': 'ES256' };
|
|
19
|
+
const PARAMS = ['created', 'expires', 'nonce', 'keyid', 'alg'];
|
|
20
|
+
const MAX_NONCE = 256;
|
|
21
|
+
const EMPTY = Buffer.alloc(0);
|
|
22
|
+
const isRequest = (r) => {
|
|
23
|
+
const o = r;
|
|
24
|
+
return typeof o === 'object' && o !== null && typeof o.method === 'string' && typeof o.targetUri === 'string' && typeof o.headers === 'object' && o.headers !== null && (o.body === undefined || o.body instanceof Uint8Array);
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Per-request HTTP message signatures, an RFC 9421 subset (design §22.10, A18): one signature; `@method`,
|
|
28
|
+
* `@target-uri` and, with a body, `content-digest` (RFC 9530, checked against the body) covered; `created`, `expires`
|
|
29
|
+
* at most `maxAgeSeconds` after it, a single-use `nonce` and `keyid`; `alg` optional. Any label is accepted.
|
|
30
|
+
*/
|
|
31
|
+
let HttpSignatureStrategy = class HttpSignatureStrategy extends KeyStrategy {
|
|
32
|
+
constructor() {
|
|
33
|
+
super(...arguments);
|
|
34
|
+
this.name = 'keys-httpsig';
|
|
35
|
+
this.kinds = ['http-signature'];
|
|
36
|
+
this.interactive = false;
|
|
37
|
+
}
|
|
38
|
+
get nonces() {
|
|
39
|
+
return this.Deps?.nonces ?? this.Nonces;
|
|
40
|
+
}
|
|
41
|
+
throttleKeys(c, ctx) {
|
|
42
|
+
const req = c.kind === 'http-signature' && isRequest(c.request) ? c.request : null;
|
|
43
|
+
const input = req ? lowerCaseHeaders(req.headers)['signature-input'] : undefined;
|
|
44
|
+
const keyid = typeof input === 'string' && input.length <= MAX_CREDENTIAL_LENGTH ? parseSignatureInput(input)?.params.get('keyid') : undefined;
|
|
45
|
+
return keyThrottleKeys(typeof keyid === 'string' ? keyid : null, ctx);
|
|
46
|
+
}
|
|
47
|
+
/** Everything that needs no key: the headers' form, the parameters, coverage, the digest and the time window. */
|
|
48
|
+
check(req, ctx) {
|
|
49
|
+
const headers = lowerCaseHeaders(req.headers);
|
|
50
|
+
if ([headers['signature-input'], headers.signature].some((v) => typeof v !== 'string' || v.length > MAX_CREDENTIAL_LENGTH)) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const input = parseSignatureInput(headers['signature-input']);
|
|
54
|
+
const signatures = parseByteSequenceDictionary(headers.signature);
|
|
55
|
+
if (!input || !signatures || signatures.size !== 1 || !signatures.has(input.label)) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
const p = input.params;
|
|
59
|
+
const created = p.get('created');
|
|
60
|
+
const expires = p.get('expires');
|
|
61
|
+
const nonce = p.get('nonce');
|
|
62
|
+
const kid = p.get('keyid');
|
|
63
|
+
const alg = p.get('alg');
|
|
64
|
+
if ([...p.keys()].some((k) => !PARAMS.includes(k)) || typeof created !== 'number' || typeof expires !== 'number' || typeof nonce !== 'string' || nonce.length === 0 || nonce.length > MAX_NONCE || typeof kid !== 'string') {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
if (alg !== undefined && (typeof alg !== 'string' || !Object.hasOwn(ALG_PARAM, alg))) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
const covered = new Set(input.components);
|
|
71
|
+
const hasBody = req.body !== undefined;
|
|
72
|
+
const required = this.options.httpSignature.requiredComponents.filter((c) => c !== 'content-digest' || hasBody);
|
|
73
|
+
if (!covered.has('@method') || !covered.has('@target-uri') || (hasBody && !covered.has('content-digest')) || required.some((c) => !covered.has(c))) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
if (covered.has('content-digest') && !digestMatches(headers['content-digest'], req.body ?? EMPTY)) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
const h = this.options.httpSignature;
|
|
80
|
+
const nowS = Math.floor(ctx.now.getTime() / 1000);
|
|
81
|
+
if (created > nowS + h.skewSeconds || expires <= created || expires - created > h.maxAgeSeconds || nowS >= expires) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
return { input, signature: signatures.get(input.label), kid, nonce, expires, ...(alg !== undefined ? { alg: ALG_PARAM[alg] } : {}) };
|
|
85
|
+
}
|
|
86
|
+
async verify(c, ctx) {
|
|
87
|
+
if (c.kind !== 'http-signature') {
|
|
88
|
+
return failure('unsupported_credentials');
|
|
89
|
+
}
|
|
90
|
+
if (!isRequest(c.request)) {
|
|
91
|
+
return failure('invalid_credentials');
|
|
92
|
+
}
|
|
93
|
+
const req = c.request;
|
|
94
|
+
const checked = this.check(req, ctx);
|
|
95
|
+
const base = checked ? signatureBase(req, checked.input) : null;
|
|
96
|
+
if (!checked || base === null) {
|
|
97
|
+
return failure('invalid_credentials');
|
|
98
|
+
}
|
|
99
|
+
const data = Buffer.from(base, 'utf8');
|
|
100
|
+
const found = await usableKey(this.registry, checked.kid, ctx);
|
|
101
|
+
if (!found.key) {
|
|
102
|
+
this.unknownKeyWork(found.alg ?? checked.alg ?? 'EdDSA', data, checked.signature);
|
|
103
|
+
return failure(found.reason);
|
|
104
|
+
}
|
|
105
|
+
const key = found.key;
|
|
106
|
+
if ((checked.alg !== undefined && checked.alg !== key.alg) || !verifySignature(key, data, checked.signature)) {
|
|
107
|
+
return failure('invalid_credentials');
|
|
108
|
+
}
|
|
109
|
+
const expiresAt = new Date((checked.expires + this.options.httpSignature.skewSeconds) * 1000);
|
|
110
|
+
if (!(await this.nonces.claim(nonceKey('sig', key.kid, checked.nonce), expiresAt, ctx.now))) {
|
|
111
|
+
return failure('invalid_credentials');
|
|
112
|
+
}
|
|
113
|
+
return this.success(key, 'http-signature', ctx);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
__decorate([
|
|
117
|
+
Autoinject(KeyNonceStore),
|
|
118
|
+
__metadata("design:type", KeyNonceStore)
|
|
119
|
+
], HttpSignatureStrategy.prototype, "Nonces", void 0);
|
|
120
|
+
HttpSignatureStrategy = __decorate([
|
|
121
|
+
Injectable(AuthenticationStrategy)
|
|
122
|
+
], HttpSignatureStrategy);
|
|
123
|
+
export { HttpSignatureStrategy };
|
|
124
|
+
//# sourceMappingURL=httpsig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpsig.js","sourceRoot":"","sources":["../../../src/strategies/httpsig.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/strategies/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/strategies/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Log } from '@spinajs/log';
|
|
2
|
+
import '../register-schema.js';
|
|
3
|
+
import { AuthenticationStrategy, KeyRegistry } from '@spinajs/authn/contracts';
|
|
4
|
+
import type { AuthnContext, AuthnFailure, KeyAlgorithm, IdentityRef, KeyOwner, KeyRecord, StrategyOutcome, ThrottleKey } from '@spinajs/authn/contracts';
|
|
5
|
+
import type { KeysConfig, KeysOptions } from '../options/options.js';
|
|
6
|
+
/** Credentials longer than this are refused before any parsing (a header is parsed before its signature is checked). */
|
|
7
|
+
export declare const MAX_CREDENTIAL_LENGTH = 8192;
|
|
8
|
+
/** An assertion's `iss`: the key owner as `<type>:<id>` (lane notes D8), e.g. `user:<uuid>` or `service:runner-1`. */
|
|
9
|
+
export declare const assertionIssuer: (owner: KeyOwner | IdentityRef) => string;
|
|
10
|
+
/** Credentials name a kid before anything is verified; one that cannot be read throttles under one shared key. */
|
|
11
|
+
export declare function keyThrottleKeys(kid: string | null, ctx: AuthnContext): readonly ThrottleKey[];
|
|
12
|
+
/** `alg`: the algorithm of a revoked or expired key, so the dummy verification costs what its real one would. */
|
|
13
|
+
export type KeyLookup = {
|
|
14
|
+
readonly key: KeyRecord;
|
|
15
|
+
} | {
|
|
16
|
+
readonly key: null;
|
|
17
|
+
readonly reason: AuthnFailure;
|
|
18
|
+
readonly alg?: KeyAlgorithm;
|
|
19
|
+
};
|
|
20
|
+
/** byId for verifiers: only a key that is neither revoked nor expired at ctx.now is usable; the reason goes to audit. */
|
|
21
|
+
export declare function usableKey(registry: KeyRegistry, kid: string, ctx: AuthnContext): Promise<KeyLookup>;
|
|
22
|
+
export declare const failure: (reason: AuthnFailure) => StrategyOutcome;
|
|
23
|
+
/** A test seam for building a key strategy with `new`: each field replaces what DI injects. */
|
|
24
|
+
export interface KeyStrategyDeps {
|
|
25
|
+
readonly registry?: KeyRegistry;
|
|
26
|
+
/** Complete options that bypass the configuration. */
|
|
27
|
+
readonly options?: KeysOptions;
|
|
28
|
+
}
|
|
29
|
+
/** What the key strategies share: the registry, `authn.keys`, the cost of an unusable key and the success outcome. */
|
|
30
|
+
export declare abstract class KeyStrategy<D extends KeyStrategyDeps = KeyStrategyDeps> extends AuthenticationStrategy {
|
|
31
|
+
protected readonly Deps?: D | undefined;
|
|
32
|
+
protected KeysConfig: KeysConfig;
|
|
33
|
+
protected Registry: KeyRegistry;
|
|
34
|
+
protected Log: Log;
|
|
35
|
+
constructor(Deps?: D | undefined);
|
|
36
|
+
protected get registry(): KeyRegistry;
|
|
37
|
+
protected get options(): KeysOptions;
|
|
38
|
+
/** The signature work an unknown, revoked or expired key costs, so it answers in the time a known key does (A02). */
|
|
39
|
+
protected unknownKeyWork(alg: KeyAlgorithm, data: Uint8Array, signature: Uint8Array): void;
|
|
40
|
+
/** Stamps the key's last use when the registry can; a failed stamp costs the stamp, never the login. */
|
|
41
|
+
protected success(key: KeyRecord, method: string, ctx: AuthnContext): Promise<StrategyOutcome>;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../../src/strategies/keys.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,uBAAuB,CAAC;AAC/B,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAIzJ,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGrE,wHAAwH;AACxH,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAE1C,sHAAsH;AACtH,eAAO,MAAM,eAAe,UAAW,QAAQ,GAAG,WAAW,KAAG,MAAqC,CAAC;AAEtG,kHAAkH;AAClH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,YAAY,GAAG,SAAS,WAAW,EAAE,CAM7F;AAED,iHAAiH;AACjH,MAAM,MAAM,SAAS,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,YAAY,CAAA;CAAE,CAAC;AAEzI,yHAAyH;AACzH,wBAAsB,SAAS,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CASzG;AAED,eAAO,MAAM,OAAO,WAAY,YAAY,KAAG,eAA0C,CAAC;AAE1F,+FAA+F;AAC/F,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAC;IAChC,sDAAsD;IACtD,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC;CAChC;AAED,sHAAsH;AACtH,8BAAsB,WAAW,CAAC,CAAC,SAAS,eAAe,GAAG,eAAe,CAAE,SAAQ,sBAAsB;IAU/F,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IARvC,SAAS,CAAC,UAAU,EAAE,UAAU,CAAC;IAGjC,SAAS,CAAC,QAAQ,EAAE,WAAW,CAAC;IAGhC,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAEnB,YAA+B,IAAI,CAAC,EAAE,CAAC,YAAA,EAEtC;IAED,SAAS,KAAK,QAAQ,IAAI,WAAW,CAEpC;IAED,SAAS,KAAK,OAAO,IAAI,WAAW,CAEnC;IAED,qHAAqH;IACrH,SAAS,CAAC,cAAc,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,GAAG,IAAI,CAEzF;IAED,wGAAwG;IACxG,UAAgB,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,CAUnG;CACF"}
|
|
@@ -0,0 +1,85 @@
|
|
|
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 { Autoinject } from '@spinajs/di';
|
|
11
|
+
import { Config } from '@spinajs/configuration';
|
|
12
|
+
import { Log, Logger } from '@spinajs/log';
|
|
13
|
+
import '../register-schema.js';
|
|
14
|
+
import { AuthenticationStrategy, KeyRegistry } from '@spinajs/authn/contracts';
|
|
15
|
+
import { isValidKid } from '../jwk/keys.js';
|
|
16
|
+
import { dummyVerify } from '../jwk/signature.js';
|
|
17
|
+
import { keysOptionsOf } from '../options/options.js';
|
|
18
|
+
import { isUsableKey } from '../registry/registry.js';
|
|
19
|
+
/** Credentials longer than this are refused before any parsing (a header is parsed before its signature is checked). */
|
|
20
|
+
export const MAX_CREDENTIAL_LENGTH = 8192;
|
|
21
|
+
/** An assertion's `iss`: the key owner as `<type>:<id>` (lane notes D8), e.g. `user:<uuid>` or `service:runner-1`. */
|
|
22
|
+
export const assertionIssuer = (owner) => `${owner.type}:${owner.id}`;
|
|
23
|
+
/** Credentials name a kid before anything is verified; one that cannot be read throttles under one shared key. */
|
|
24
|
+
export function keyThrottleKeys(kid, ctx) {
|
|
25
|
+
const id = kid !== null && isValidKid(kid) ? `key:${kid}` : 'key:?';
|
|
26
|
+
return [
|
|
27
|
+
{ kind: 'account', value: id },
|
|
28
|
+
{ kind: 'account-ip', value: `${id}|${ctx.ip ?? ''}` },
|
|
29
|
+
];
|
|
30
|
+
}
|
|
31
|
+
/** byId for verifiers: only a key that is neither revoked nor expired at ctx.now is usable; the reason goes to audit. */
|
|
32
|
+
export async function usableKey(registry, kid, ctx) {
|
|
33
|
+
const key = isValidKid(kid) ? await registry.byId(kid) : null;
|
|
34
|
+
if (!key) {
|
|
35
|
+
return { key: null, reason: 'invalid_credentials' };
|
|
36
|
+
}
|
|
37
|
+
if (!isUsableKey(key, ctx.now)) {
|
|
38
|
+
return { key: null, reason: key.revokedAt ? 'revoked' : 'expired', alg: key.alg };
|
|
39
|
+
}
|
|
40
|
+
return { key };
|
|
41
|
+
}
|
|
42
|
+
export const failure = (reason) => ({ ok: false, reason });
|
|
43
|
+
/** What the key strategies share: the registry, `authn.keys`, the cost of an unusable key and the success outcome. */
|
|
44
|
+
export class KeyStrategy extends AuthenticationStrategy {
|
|
45
|
+
constructor(Deps) {
|
|
46
|
+
super();
|
|
47
|
+
this.Deps = Deps;
|
|
48
|
+
}
|
|
49
|
+
get registry() {
|
|
50
|
+
return this.Deps?.registry ?? this.Registry;
|
|
51
|
+
}
|
|
52
|
+
get options() {
|
|
53
|
+
return keysOptionsOf(this.Deps?.options ?? this.KeysConfig);
|
|
54
|
+
}
|
|
55
|
+
/** The signature work an unknown, revoked or expired key costs, so it answers in the time a known key does (A02). */
|
|
56
|
+
unknownKeyWork(alg, data, signature) {
|
|
57
|
+
dummyVerify(alg, data, signature);
|
|
58
|
+
}
|
|
59
|
+
/** Stamps the key's last use when the registry can; a failed stamp costs the stamp, never the login. */
|
|
60
|
+
async success(key, method, ctx) {
|
|
61
|
+
const registry = this.registry;
|
|
62
|
+
if (registry.touch) {
|
|
63
|
+
try {
|
|
64
|
+
await registry.touch(key.kid, ctx.now);
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
this.Log.error({ error: err, kid: key.kid }, 'Could not stamp the last use of key ${kid}');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return { ok: true, identity: { type: key.owner.type, id: key.owner.id }, method, ...(key.scope ? { ceiling: key.scope } : {}) };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
__decorate([
|
|
74
|
+
Config('authn.keys'),
|
|
75
|
+
__metadata("design:type", Object)
|
|
76
|
+
], KeyStrategy.prototype, "KeysConfig", void 0);
|
|
77
|
+
__decorate([
|
|
78
|
+
Autoinject(KeyRegistry),
|
|
79
|
+
__metadata("design:type", KeyRegistry)
|
|
80
|
+
], KeyStrategy.prototype, "Registry", void 0);
|
|
81
|
+
__decorate([
|
|
82
|
+
Logger('authn-keys'),
|
|
83
|
+
__metadata("design:type", Log)
|
|
84
|
+
], KeyStrategy.prototype, "Log", void 0);
|
|
85
|
+
//# sourceMappingURL=keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../../src/strategies/keys.ts"],"names":[],"mappings":"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"}
|