@frontmcp/auth 1.3.0 → 1.4.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/authorities/authorities.profiles.d.ts +14 -1
- package/authorities/authorities.profiles.d.ts.map +1 -1
- package/authorization/dcr-client.registry.d.ts +83 -0
- package/authorization/dcr-client.registry.d.ts.map +1 -0
- package/authorization/index.d.ts +2 -0
- package/authorization/index.d.ts.map +1 -1
- package/cimd/cimd.service.d.ts +2 -9
- package/cimd/cimd.service.d.ts.map +1 -1
- package/common/session.types.d.ts +4 -4
- package/esm/index.mjs +1821 -214
- package/esm/package.json +8 -8
- package/index.d.ts +5 -5
- package/index.d.ts.map +1 -1
- package/index.js +2030 -383
- package/jwks/jwks.service.d.ts +2 -4
- package/jwks/jwks.service.d.ts.map +1 -1
- package/options/app-auth.schema.d.ts +226 -0
- package/options/app-auth.schema.d.ts.map +1 -1
- package/options/index.d.ts +4 -4
- package/options/index.d.ts.map +1 -1
- package/options/interfaces.d.ts +580 -4
- package/options/interfaces.d.ts.map +1 -1
- package/options/orchestrated.schema.d.ts +492 -1
- package/options/orchestrated.schema.d.ts.map +1 -1
- package/options/schema.d.ts +226 -0
- package/options/schema.d.ts.map +1 -1
- package/options/shared.schemas.d.ts +237 -2
- package/options/shared.schemas.d.ts.map +1 -1
- package/package.json +8 -8
- package/session/authorization.store.d.ts +117 -47
- package/session/authorization.store.d.ts.map +1 -1
- package/session/consent.store.d.ts +86 -0
- package/session/consent.store.d.ts.map +1 -0
- package/session/credential-resume-link.d.ts +64 -0
- package/session/credential-resume-link.d.ts.map +1 -0
- package/session/credentials-accessor.d.ts +102 -0
- package/session/credentials-accessor.d.ts.map +1 -0
- package/session/credentials-accessor.impl.d.ts +46 -0
- package/session/credentials-accessor.impl.d.ts.map +1 -0
- package/session/index.d.ts +32 -2
- package/session/index.d.ts.map +1 -1
- package/session/orchestrated-token.crypto.d.ts +33 -0
- package/session/orchestrated-token.crypto.d.ts.map +1 -0
- package/session/secure-store-accessor.d.ts +77 -0
- package/session/secure-store-accessor.d.ts.map +1 -0
- package/session/secure-store-accessor.impl.d.ts +61 -0
- package/session/secure-store-accessor.impl.d.ts.map +1 -0
- package/session/secure-store-backends.d.ts +75 -0
- package/session/secure-store-backends.d.ts.map +1 -0
- package/session/secure-store.d.ts +89 -0
- package/session/secure-store.d.ts.map +1 -0
- package/session/secure-store.factory.d.ts +62 -0
- package/session/secure-store.factory.d.ts.map +1 -0
- package/session/session-credential-vault.d.ts +153 -0
- package/session/session-credential-vault.d.ts.map +1 -0
- package/session/session-credential-vault.factory.d.ts +50 -0
- package/session/session-credential-vault.factory.d.ts.map +1 -0
- package/session/storage-authorization.store.d.ts +51 -0
- package/session/storage-authorization.store.d.ts.map +1 -0
- package/session/storage-consent.store.d.ts +33 -0
- package/session/storage-consent.store.d.ts.map +1 -0
- package/session/storage-federated-auth.session.d.ts +36 -0
- package/session/storage-federated-auth.session.d.ts.map +1 -0
- package/session/storage-orchestrated-token.store.d.ts +72 -0
- package/session/storage-orchestrated-token.store.d.ts.map +1 -0
- package/session/token-storage.factory.d.ts +46 -0
- package/session/token-storage.factory.d.ts.map +1 -0
- package/ui/index.d.ts +3 -2
- package/ui/index.d.ts.map +1 -1
- package/ui/local-login.helper.d.ts +31 -0
- package/ui/local-login.helper.d.ts.map +1 -0
- package/ui/templates.d.ts +118 -2
- package/ui/templates.d.ts.map +1 -1
- package/vault/auth-providers.types.d.ts +3 -3
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SessionCredentialVault — per-session, AES-256-GCM-encrypted credential store
|
|
3
|
+
* (Checkpoint 3b).
|
|
4
|
+
*
|
|
5
|
+
* Persists the `credentials` a local `authenticate()` verifier returns
|
|
6
|
+
* (Checkpoint 3a accepted-and-ignored them) and exposes them to tools via the
|
|
7
|
+
* `this.credentials` ToolContext accessor.
|
|
8
|
+
*
|
|
9
|
+
* Security model
|
|
10
|
+
* --------------
|
|
11
|
+
* - Credentials are keyed by the authenticated subject (`sub`) behind a
|
|
12
|
+
* `sub → vaultId` indirection. Every fresh authorize mints a NEW random
|
|
13
|
+
* `vaultId` ({@link SessionCredentialVault.rotateVault}); the per-record
|
|
14
|
+
* encryption key is derived (HKDF salt) from that `vaultId`, so when a user
|
|
15
|
+
* disconnects and reconnects the old ciphertext becomes undecryptable and the
|
|
16
|
+
* reconnected session sees an EMPTY vault (per-session rotation).
|
|
17
|
+
* - At-rest encryption is AES-256-GCM via the shared {@link VaultEncryption}
|
|
18
|
+
* primitive. The master pepper comes from `VAULT_SECRET ?? JWT_SECRET`; when
|
|
19
|
+
* neither is set a random per-process pepper is used and a warning is logged
|
|
20
|
+
* (credentials then do not survive a restart — fail-safe, never plaintext).
|
|
21
|
+
* - The plaintext `secret` and `metadata` are NEVER written unencrypted. Only
|
|
22
|
+
* the unencrypted index (key names, vaultId pointer) is stored in the clear,
|
|
23
|
+
* and it carries no PII.
|
|
24
|
+
*
|
|
25
|
+
* Construct via {@link createSessionCredentialVault} (CLAUDE.md storage-factory
|
|
26
|
+
* pattern) so the same `auth.tokenStorage` config backs both the token stores
|
|
27
|
+
* and this vault.
|
|
28
|
+
*/
|
|
29
|
+
import { type StorageAdapter } from '@frontmcp/utils';
|
|
30
|
+
import { type AuthLogger } from '../common/auth-logger.interface';
|
|
31
|
+
/**
|
|
32
|
+
* A stored credential value: the secret plus optional non-secret metadata.
|
|
33
|
+
*/
|
|
34
|
+
export interface StoredCredential {
|
|
35
|
+
/** The secret value (token, api key, …). Encrypted at rest. */
|
|
36
|
+
secret: string;
|
|
37
|
+
/** Optional non-secret metadata stored alongside the credential (encrypted). */
|
|
38
|
+
metadata?: Record<string, unknown>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Options for {@link SessionCredentialVault}.
|
|
42
|
+
*/
|
|
43
|
+
export interface SessionCredentialVaultOptions {
|
|
44
|
+
/** Connected storage adapter backing the vault (memory / Redis / SQLite). */
|
|
45
|
+
storage: StorageAdapter;
|
|
46
|
+
/**
|
|
47
|
+
* Master pepper for key derivation. When omitted, falls back to
|
|
48
|
+
* `VAULT_SECRET ?? JWT_SECRET`, and finally a random per-process value (with a
|
|
49
|
+
* warning). Defense-in-depth: even with a stolen vaultId an attacker still
|
|
50
|
+
* needs this pepper to derive the AES key.
|
|
51
|
+
*/
|
|
52
|
+
pepper?: string;
|
|
53
|
+
/** Key prefix for all stored keys. @default 'mcp:cred:' */
|
|
54
|
+
keyPrefix?: string;
|
|
55
|
+
/** TTL (ms) for credential entries. @default undefined (no expiry) */
|
|
56
|
+
ttlMs?: number;
|
|
57
|
+
/** TTL (ms) for the pending-authorize accumulator. @default 600000 (10 min) */
|
|
58
|
+
pendingTtlMs?: number;
|
|
59
|
+
/** Scoped logger. @default noop */
|
|
60
|
+
logger?: AuthLogger;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Per-session encrypted credential vault.
|
|
64
|
+
*
|
|
65
|
+
* @see createSessionCredentialVault for the factory entry point.
|
|
66
|
+
*/
|
|
67
|
+
export declare class SessionCredentialVault {
|
|
68
|
+
private readonly storage;
|
|
69
|
+
private readonly encryption;
|
|
70
|
+
private readonly keyPrefix;
|
|
71
|
+
private readonly ttlMs?;
|
|
72
|
+
private readonly pendingTtlMs;
|
|
73
|
+
private readonly logger;
|
|
74
|
+
/** Cache of derived AES keys, keyed by `${sub}:${vaultId}`. */
|
|
75
|
+
private readonly keyCache;
|
|
76
|
+
constructor(options: SessionCredentialVaultOptions);
|
|
77
|
+
/** `cred:idx:<sub>` → current vaultId (the sub → vaultId indirection). */
|
|
78
|
+
private indexKey;
|
|
79
|
+
/** `cred:keys:<sub>:<vaultId>` → JSON array of credential key names (the SET). */
|
|
80
|
+
private keysKey;
|
|
81
|
+
/** `cred:data:<sub>:<vaultId>:<key>` → encrypted credential record. */
|
|
82
|
+
private dataKey;
|
|
83
|
+
/** `cred:pending:<pendingId>` → encrypted pending-authorize accumulator. */
|
|
84
|
+
private pendingKey;
|
|
85
|
+
/** Convert the configured `ttlMs` into `SetOptions` (storage uses `ttlSeconds`). */
|
|
86
|
+
private get credentialSetOpts();
|
|
87
|
+
/**
|
|
88
|
+
* Derive (and cache) the AES-256 key for a `(sub, vaultId)` pair. The vaultId
|
|
89
|
+
* acts as the HKDF salt, so rotating it makes prior ciphertext undecryptable.
|
|
90
|
+
*/
|
|
91
|
+
private deriveKey;
|
|
92
|
+
/**
|
|
93
|
+
* Read the current vaultId for a subject, or undefined when the subject has no
|
|
94
|
+
* live vault (never authorized, or rotated away).
|
|
95
|
+
*/
|
|
96
|
+
getVaultId(sub: string): Promise<string | undefined>;
|
|
97
|
+
/**
|
|
98
|
+
* Mint a FRESH vaultId for a subject and point the indirection at it. Called
|
|
99
|
+
* at the start of each authorize so reconnect = empty vault. Returns the new
|
|
100
|
+
* vaultId. The old vaultId's ciphertext is left in storage but is
|
|
101
|
+
* unreachable (no index pointer) and undecryptable (different derived key);
|
|
102
|
+
* it expires via TTL when configured.
|
|
103
|
+
*/
|
|
104
|
+
rotateVault(sub: string): Promise<string>;
|
|
105
|
+
/**
|
|
106
|
+
* Encrypt + store a single credential into the vault identified by
|
|
107
|
+
* `(sub, vaultId)` and add its key to the key set. Used both to commit
|
|
108
|
+
* authorize-time credentials and to additively add a credential mid-session.
|
|
109
|
+
*/
|
|
110
|
+
store(sub: string, vaultId: string, key: string, value: StoredCredential): Promise<void>;
|
|
111
|
+
/**
|
|
112
|
+
* Decrypt and return a credential by key for a subject's CURRENT vault.
|
|
113
|
+
* Returns undefined when there is no live vault or no such key, or when
|
|
114
|
+
* decryption fails (e.g. a stale pointer to rotated-away ciphertext).
|
|
115
|
+
*/
|
|
116
|
+
get(sub: string, key: string): Promise<StoredCredential | undefined>;
|
|
117
|
+
/**
|
|
118
|
+
* List the credential keys available in a subject's current vault. Returns an
|
|
119
|
+
* empty array when there is no live vault (e.g. after rotation on reconnect).
|
|
120
|
+
*/
|
|
121
|
+
list(sub: string): Promise<string[]>;
|
|
122
|
+
/**
|
|
123
|
+
* Remove a credential by key from a subject's current vault (deletes the
|
|
124
|
+
* ciphertext and drops the key from the set). No-op when absent.
|
|
125
|
+
*/
|
|
126
|
+
remove(sub: string, key: string): Promise<void>;
|
|
127
|
+
/**
|
|
128
|
+
* Stage credentials returned by `authenticate()` under a pending id, encrypted
|
|
129
|
+
* against a freshly-rotated vaultId for `sub`. They are NOT visible to tools
|
|
130
|
+
* until {@link commit} flushes them — this lets the authorize flow accumulate
|
|
131
|
+
* credentials before the subject's identity is final.
|
|
132
|
+
*
|
|
133
|
+
* @returns the vaultId the credentials were staged against.
|
|
134
|
+
*/
|
|
135
|
+
stage(pendingId: string, sub: string, credentials: Array<{
|
|
136
|
+
key: string;
|
|
137
|
+
} & StoredCredential>): Promise<string>;
|
|
138
|
+
/**
|
|
139
|
+
* Flush a staged batch into the live vault, binding it to `sub`. The staged
|
|
140
|
+
* batch's `sub` must equal the supplied `sub` (the one baked into the minted
|
|
141
|
+
* token) — a mismatch is refused so credentials can never be committed under a
|
|
142
|
+
* different identity than the one that will read them.
|
|
143
|
+
*
|
|
144
|
+
* @returns true when a batch was committed, false when none was staged.
|
|
145
|
+
*/
|
|
146
|
+
commit(pendingId: string, sub: string): Promise<boolean>;
|
|
147
|
+
private readKeySet;
|
|
148
|
+
private writeKeySet;
|
|
149
|
+
private addKeyToSet;
|
|
150
|
+
/** Strip undefined metadata so the encrypted JSON stays minimal. */
|
|
151
|
+
private normalize;
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=session-credential-vault.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-credential-vault.d.ts","sourceRoot":"","sources":["../../src/session/session-credential-vault.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAuC,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE3F,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAGlF;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC5C,6EAA6E;IAC7E,OAAO,EAAE,cAAc,CAAC;IACxB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mCAAmC;IACnC,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAmBD;;;;GAIG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,+DAA+D;IAC/D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0C;gBAEvD,OAAO,EAAE,6BAA6B;IAelD,0EAA0E;IAC1E,OAAO,CAAC,QAAQ;IAIhB,kFAAkF;IAClF,OAAO,CAAC,OAAO;IAIf,uEAAuE;IACvE,OAAO,CAAC,OAAO;IAIf,4EAA4E;IAC5E,OAAO,CAAC,UAAU;IAIlB,oFAAoF;IACpF,OAAO,KAAK,iBAAiB,GAE5B;IAMD;;;OAGG;IACH,OAAO,CAAC,SAAS;IAiBjB;;;OAGG;IACG,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAK1D;;;;;;OAMG;IACG,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAU/C;;;;OAIG;IACG,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ9F;;;;OAIG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;IAgB1E;;;OAGG;IACG,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAM1C;;;OAGG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAerD;;;;;;;OAOG;IACG,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,gBAAgB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAepH;;;;;;;OAOG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;YAiChD,UAAU;YAWV,WAAW;YAMX,WAAW;IAQzB,oEAAoE;IACpE,OAAO,CAAC,SAAS;CAGlB"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SessionCredentialVault factory.
|
|
3
|
+
*
|
|
4
|
+
* Follows the CLAUDE.md storage-factory pattern: builds a connected
|
|
5
|
+
* {@link StorageAdapter} from the SAME `auth.tokenStorage` config that backs the
|
|
6
|
+
* authorization-code / token stores, then wraps it in a
|
|
7
|
+
* {@link SessionCredentialVault}. Keeping one config source means a credential
|
|
8
|
+
* vault is automatically persistent (Redis/SQLite) whenever the rest of the auth
|
|
9
|
+
* layer is, and in-memory by default otherwise.
|
|
10
|
+
*/
|
|
11
|
+
import { type StorageAdapter } from '@frontmcp/utils';
|
|
12
|
+
import { type AuthLogger } from '../common/auth-logger.interface';
|
|
13
|
+
import { type TokenStorageConfig } from '../options/interfaces';
|
|
14
|
+
import { SessionCredentialVault } from './session-credential-vault';
|
|
15
|
+
/**
|
|
16
|
+
* Options for {@link createSessionCredentialVault}.
|
|
17
|
+
*/
|
|
18
|
+
export interface CreateSessionCredentialVaultOptions {
|
|
19
|
+
/**
|
|
20
|
+
* Token-storage config — the SAME `auth.tokenStorage` selection used by the
|
|
21
|
+
* token stores. `'memory'` (or undefined) yields an in-memory vault;
|
|
22
|
+
* `{ redis }` / `{ sqlite }` a persistent one.
|
|
23
|
+
*/
|
|
24
|
+
tokenStorage?: TokenStorageConfig;
|
|
25
|
+
/**
|
|
26
|
+
* Optionally reuse an already-connected adapter instead of creating one from
|
|
27
|
+
* `tokenStorage`. When provided, `tokenStorage` is ignored for adapter
|
|
28
|
+
* construction (used to share the LocalPrimaryAuth adapter).
|
|
29
|
+
*/
|
|
30
|
+
storage?: StorageAdapter;
|
|
31
|
+
/** Master pepper override (defaults to `VAULT_SECRET ?? JWT_SECRET`). */
|
|
32
|
+
pepper?: string;
|
|
33
|
+
/** Key prefix for all stored keys. @default 'mcp:cred:' */
|
|
34
|
+
keyPrefix?: string;
|
|
35
|
+
/** TTL (ms) for credential entries. @default undefined (no expiry) */
|
|
36
|
+
ttlMs?: number;
|
|
37
|
+
/** Scoped logger. */
|
|
38
|
+
logger?: AuthLogger;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Create a {@link SessionCredentialVault} backed by the configured token storage.
|
|
42
|
+
*
|
|
43
|
+
* @returns the vault plus the backing adapter type, mirroring the SDK store
|
|
44
|
+
* factories (`{ store, type }`).
|
|
45
|
+
*/
|
|
46
|
+
export declare function createSessionCredentialVault(options: CreateSessionCredentialVaultOptions): Promise<{
|
|
47
|
+
vault: SessionCredentialVault;
|
|
48
|
+
type: 'memory' | 'redis' | 'sqlite';
|
|
49
|
+
}>;
|
|
50
|
+
//# sourceMappingURL=session-credential-vault.factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-credential-vault.factory.d.ts","sourceRoot":"","sources":["../../src/session/session-credential-vault.factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAGpE;;GAEG;AACH,MAAM,WAAW,mCAAmC;IAClD;;;;OAIG;IACH,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC;;;;OAIG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,mCAAmC,GAC3C,OAAO,CAAC;IAAE,KAAK,EAAE,sBAAsB,CAAC;IAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAA;CAAE,CAAC,CAmBjF"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StorageAuthorizationStore
|
|
3
|
+
*
|
|
4
|
+
* `AuthorizationStore` backed by a `@frontmcp/utils` `StorageAdapter`
|
|
5
|
+
* (memory / Redis / SQLite). This is the adapter-backed counterpart to
|
|
6
|
+
* {@link InMemoryAuthorizationStore}, giving local-mode auth persistent
|
|
7
|
+
* authorization codes, pending authorizations, and refresh tokens.
|
|
8
|
+
*
|
|
9
|
+
* Records are stored as JSON blobs keyed by type, with TTL derived from each
|
|
10
|
+
* record's `expiresAt`. The pure record-builder helpers (`createCodeRecord`,
|
|
11
|
+
* etc.) are inherited from the shared `authorization.store` functions, so the
|
|
12
|
+
* minted records are byte-for-byte identical to the in-memory store's.
|
|
13
|
+
*/
|
|
14
|
+
import { type NamespacedStorage, type StorageAdapter } from '@frontmcp/utils';
|
|
15
|
+
import { type AuthorizationCodeRecord, type AuthorizationStore, type CreateCodeRecordParams, type CreatePendingRecordParams, type CreateRefreshTokenRecordParams, type PendingAuthorizationRecord, type RefreshTokenRecord } from './authorization.store';
|
|
16
|
+
export interface StorageAuthorizationStoreOptions {
|
|
17
|
+
/**
|
|
18
|
+
* Namespace prefix for all keys.
|
|
19
|
+
* @default 'oauth'
|
|
20
|
+
*/
|
|
21
|
+
namespace?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare class StorageAuthorizationStore implements AuthorizationStore {
|
|
24
|
+
private readonly codeStore;
|
|
25
|
+
private readonly pendingStore;
|
|
26
|
+
private readonly refreshStore;
|
|
27
|
+
private readonly namespace;
|
|
28
|
+
private readonly storageIsNamespaced;
|
|
29
|
+
constructor(storage: StorageAdapter | NamespacedStorage, options?: StorageAuthorizationStoreOptions);
|
|
30
|
+
generateCode(): string;
|
|
31
|
+
generateRefreshToken(): string;
|
|
32
|
+
createCodeRecord(params: CreateCodeRecordParams): AuthorizationCodeRecord;
|
|
33
|
+
createPendingRecord(params: CreatePendingRecordParams): PendingAuthorizationRecord;
|
|
34
|
+
createRefreshTokenRecord(params: CreateRefreshTokenRecordParams): RefreshTokenRecord;
|
|
35
|
+
storeAuthorizationCode(record: AuthorizationCodeRecord): Promise<void>;
|
|
36
|
+
getAuthorizationCode(code: string): Promise<AuthorizationCodeRecord | null>;
|
|
37
|
+
markCodeUsed(code: string): Promise<void>;
|
|
38
|
+
deleteAuthorizationCode(code: string): Promise<void>;
|
|
39
|
+
storePendingAuthorization(record: PendingAuthorizationRecord): Promise<void>;
|
|
40
|
+
getPendingAuthorization(id: string): Promise<PendingAuthorizationRecord | null>;
|
|
41
|
+
deletePendingAuthorization(id: string): Promise<void>;
|
|
42
|
+
storeRefreshToken(record: RefreshTokenRecord): Promise<void>;
|
|
43
|
+
getRefreshToken(token: string): Promise<RefreshTokenRecord | null>;
|
|
44
|
+
revokeRefreshToken(token: string): Promise<void>;
|
|
45
|
+
rotateRefreshToken(oldToken: string, newRecord: RefreshTokenRecord): Promise<void>;
|
|
46
|
+
cleanup(): Promise<void>;
|
|
47
|
+
private ttl;
|
|
48
|
+
private key;
|
|
49
|
+
private isNamespacedStorage;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=storage-authorization.store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-authorization.store.d.ts","sourceRoot":"","sources":["../../src/session/storage-authorization.store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAgB,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE5F,OAAO,EAML,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,EAC9B,KAAK,8BAA8B,EACnC,KAAK,0BAA0B,EAC/B,KAAK,kBAAkB,EACxB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,WAAW,gCAAgC;IAC/C;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,qBAAa,yBAA0B,YAAW,kBAAkB;IAClE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwC;IAClE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA2C;IACxE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmC;IAChE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAU;gBAElC,OAAO,EAAE,cAAc,GAAG,iBAAiB,EAAE,OAAO,GAAE,gCAAqC;IAevG,YAAY,IAAI,MAAM;IAItB,oBAAoB,IAAI,MAAM;IAI9B,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,GAAG,uBAAuB;IAIzE,mBAAmB,CAAC,MAAM,EAAE,yBAAyB,GAAG,0BAA0B;IAIlF,wBAAwB,CAAC,MAAM,EAAE,8BAA8B,GAAG,kBAAkB;IAQ9E,sBAAsB,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAItE,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC;IAU3E,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQzC,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQpD,yBAAyB,CAAC,MAAM,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5E,uBAAuB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,0BAA0B,GAAG,IAAI,CAAC;IAU/E,0BAA0B,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQrD,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5D,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IASlE,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQhD,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAUlF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAS9B,OAAO,CAAC,GAAG;IAKX,OAAO,CAAC,GAAG;IAKX,OAAO,CAAC,mBAAmB;CAG5B"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StorageConsentStore
|
|
3
|
+
*
|
|
4
|
+
* {@link ConsentStore} backed by a `@frontmcp/utils` `StorageAdapter`
|
|
5
|
+
* (memory / Redis / SQLite). Parallel to {@link StorageFederatedAuthSessionStore}:
|
|
6
|
+
* it stores the {@link RememberedConsentRecord} as a JSON blob keyed by
|
|
7
|
+
* `consent:{userSub}:{clientId}`.
|
|
8
|
+
*
|
|
9
|
+
* Unlike federated sessions (short-lived flow state), a remembered consent
|
|
10
|
+
* selection is intentionally long-lived — it survives restarts so a returning
|
|
11
|
+
* user keeps their prior tool selection — so no TTL is applied here.
|
|
12
|
+
*/
|
|
13
|
+
import { type NamespacedStorage, type StorageAdapter } from '@frontmcp/utils';
|
|
14
|
+
import { type ConsentStore, type RememberedConsentRecord } from './consent.store';
|
|
15
|
+
export interface StorageConsentStoreOptions {
|
|
16
|
+
/**
|
|
17
|
+
* Namespace prefix for all keys.
|
|
18
|
+
* @default 'remembered-consent'
|
|
19
|
+
*/
|
|
20
|
+
namespace?: string;
|
|
21
|
+
}
|
|
22
|
+
export declare class StorageConsentStore implements ConsentStore {
|
|
23
|
+
private readonly storage;
|
|
24
|
+
private readonly namespace;
|
|
25
|
+
private readonly storageIsNamespaced;
|
|
26
|
+
constructor(storage: StorageAdapter | NamespacedStorage, options?: StorageConsentStoreOptions);
|
|
27
|
+
get(userSub: string, clientId: string): Promise<RememberedConsentRecord | null>;
|
|
28
|
+
set(record: RememberedConsentRecord): Promise<void>;
|
|
29
|
+
delete(userSub: string, clientId: string): Promise<void>;
|
|
30
|
+
private key;
|
|
31
|
+
private isNamespacedStorage;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=storage-consent.store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-consent.store.d.ts","sourceRoot":"","sources":["../../src/session/storage-consent.store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAgB,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE5F,OAAO,EAAoB,KAAK,YAAY,EAAE,KAAK,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAEpG,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,mBAAoB,YAAW,YAAY;IACtD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwC;IAChE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAU;gBAElC,OAAO,EAAE,cAAc,GAAG,iBAAiB,EAAE,OAAO,GAAE,0BAA+B;IAW3F,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC;IAI/E,GAAG,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAInD,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9D,OAAO,CAAC,GAAG;IAKX,OAAO,CAAC,mBAAmB;CAG5B"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StorageFederatedAuthSessionStore
|
|
3
|
+
*
|
|
4
|
+
* `FederatedAuthSessionStore` backed by a `@frontmcp/utils` `StorageAdapter`
|
|
5
|
+
* (memory / Redis / SQLite). Parallel to {@link StorageTokenStore}: it stores
|
|
6
|
+
* the serializable {@link FederatedAuthSessionRecord} as a JSON blob keyed by
|
|
7
|
+
* session id, with a TTL derived from the session's `expiresAt`.
|
|
8
|
+
*
|
|
9
|
+
* Federated sessions are short-lived multi-provider OAuth flow state. Persisting
|
|
10
|
+
* them (Redis/SQLite) lets an in-progress federated login survive a server
|
|
11
|
+
* restart instead of being silently dropped.
|
|
12
|
+
*/
|
|
13
|
+
import { type NamespacedStorage, type StorageAdapter } from '@frontmcp/utils';
|
|
14
|
+
import { type FederatedAuthSession, type FederatedAuthSessionStore } from './federated-auth.session';
|
|
15
|
+
export interface StorageFederatedAuthSessionStoreOptions {
|
|
16
|
+
/**
|
|
17
|
+
* Namespace prefix for all keys.
|
|
18
|
+
* @default 'fed'
|
|
19
|
+
*/
|
|
20
|
+
namespace?: string;
|
|
21
|
+
}
|
|
22
|
+
export declare class StorageFederatedAuthSessionStore implements FederatedAuthSessionStore {
|
|
23
|
+
private readonly storage;
|
|
24
|
+
private readonly namespace;
|
|
25
|
+
private readonly storageIsNamespaced;
|
|
26
|
+
constructor(storage: StorageAdapter | NamespacedStorage, options?: StorageFederatedAuthSessionStoreOptions);
|
|
27
|
+
store(session: FederatedAuthSession): Promise<void>;
|
|
28
|
+
update(session: FederatedAuthSession): Promise<void>;
|
|
29
|
+
get(id: string): Promise<FederatedAuthSession | null>;
|
|
30
|
+
delete(id: string): Promise<void>;
|
|
31
|
+
private put;
|
|
32
|
+
private calculateTtl;
|
|
33
|
+
private key;
|
|
34
|
+
private isNamespacedStorage;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=storage-federated-auth.session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-federated-auth.session.d.ts","sourceRoot":"","sources":["../../src/session/storage-federated-auth.session.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAgB,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE5F,OAAO,EAGL,KAAK,oBAAoB,EAEzB,KAAK,yBAAyB,EAC/B,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,uCAAuC;IACtD;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,gCAAiC,YAAW,yBAAyB;IAChF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2C;IACnE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAU;gBAElC,OAAO,EAAE,cAAc,GAAG,iBAAiB,EAAE,OAAO,GAAE,uCAA4C;IAWxG,KAAK,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAInD,MAAM,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpD,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAgBrD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAIzB,GAAG;IAMjB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,GAAG;IAIX,OAAO,CAAC,mBAAmB;CAG5B"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StorageOrchestratedTokenStore
|
|
3
|
+
*
|
|
4
|
+
* Orchestrated-mode `TokenStore` backed by a `@frontmcp/utils` `StorageAdapter`
|
|
5
|
+
* (memory / Redis / SQLite). Parallel to {@link InMemoryOrchestratedTokenStore}:
|
|
6
|
+
* stores upstream provider access/refresh tokens keyed by
|
|
7
|
+
* `authorizationId:providerId`, with the SAME AES-256-GCM + HKDF encryption at
|
|
8
|
+
* rest (see `orchestrated-token.crypto.ts`).
|
|
9
|
+
*
|
|
10
|
+
* Persisting these (Redis/SQLite) means a user's connected upstream providers
|
|
11
|
+
* survive a server restart instead of forcing re-authorization.
|
|
12
|
+
*
|
|
13
|
+
* Values are stored as raw strings on the adapter so we can choose, per record,
|
|
14
|
+
* between an encrypted envelope (when `encryptionKey` is set) and plaintext JSON
|
|
15
|
+
* (dev only) — matching the in-memory store's behavior exactly.
|
|
16
|
+
*/
|
|
17
|
+
import type { NamespacedStorage, StorageAdapter } from '@frontmcp/utils';
|
|
18
|
+
import type { TokenStore } from '../authorization/orchestrated.authorization';
|
|
19
|
+
export interface StorageOrchestratedTokenStoreOptions {
|
|
20
|
+
/**
|
|
21
|
+
* Encryption key for token storage. If not provided, tokens are stored in
|
|
22
|
+
* plain text (dev only). For production always provide a key.
|
|
23
|
+
*/
|
|
24
|
+
encryptionKey?: Uint8Array;
|
|
25
|
+
/**
|
|
26
|
+
* Default TTL in milliseconds applied when a stored token has no `expiresAt`.
|
|
27
|
+
* @default undefined (no automatic expiration)
|
|
28
|
+
*/
|
|
29
|
+
defaultTtlMs?: number;
|
|
30
|
+
/**
|
|
31
|
+
* Namespace prefix for all keys.
|
|
32
|
+
* @default 'otok'
|
|
33
|
+
*/
|
|
34
|
+
namespace?: string;
|
|
35
|
+
}
|
|
36
|
+
export declare class StorageOrchestratedTokenStore implements TokenStore {
|
|
37
|
+
private readonly storage;
|
|
38
|
+
private readonly encryptionKey?;
|
|
39
|
+
private readonly defaultTtlMs?;
|
|
40
|
+
private readonly namespace;
|
|
41
|
+
private readonly storageIsNamespaced;
|
|
42
|
+
/** HKDF-derived subkey cache, keyed by composite key. */
|
|
43
|
+
private readonly derivedKeys;
|
|
44
|
+
constructor(storage: StorageAdapter | NamespacedStorage, options?: StorageOrchestratedTokenStoreOptions);
|
|
45
|
+
getAccessToken(authorizationId: string, providerId: string): Promise<string | null>;
|
|
46
|
+
getRefreshToken(authorizationId: string, providerId: string): Promise<string | null>;
|
|
47
|
+
storeTokens(authorizationId: string, providerId: string, tokens: {
|
|
48
|
+
accessToken: string;
|
|
49
|
+
refreshToken?: string;
|
|
50
|
+
expiresAt?: number;
|
|
51
|
+
}): Promise<void>;
|
|
52
|
+
deleteTokens(authorizationId: string, providerId: string): Promise<void>;
|
|
53
|
+
hasTokens(authorizationId: string, providerId: string): Promise<boolean>;
|
|
54
|
+
getProviderIds(authorizationId: string): Promise<string[]>;
|
|
55
|
+
migrateTokens(fromAuthId: string, toAuthId: string): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Delete all tokens for an authorization id.
|
|
58
|
+
*/
|
|
59
|
+
deleteAllForAuthorization(authorizationId: string): Promise<void>;
|
|
60
|
+
private getRecord;
|
|
61
|
+
private keyFor;
|
|
62
|
+
private compositeKey;
|
|
63
|
+
private storageKey;
|
|
64
|
+
/**
|
|
65
|
+
* List composite keys (authorizationId:providerId) matching a glob over the
|
|
66
|
+
* composite-key space, stripping any non-namespaced prefix we added.
|
|
67
|
+
*/
|
|
68
|
+
private listCompositeKeys;
|
|
69
|
+
private ttlOptions;
|
|
70
|
+
private isNamespacedStorage;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=storage-orchestrated-token.store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-orchestrated-token.store.d.ts","sourceRoot":"","sources":["../../src/session/storage-orchestrated-token.store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6CAA6C,CAAC;AAS9E,MAAM,WAAW,oCAAoC;IACnD;;;OAGG;IACH,aAAa,CAAC,EAAE,UAAU,CAAC;IAE3B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,6BAA8B,YAAW,UAAU;IAC9D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAC7D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAa;IAC5C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAU;IAE9C,yDAAyD;IACzD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiC;gBAEjD,OAAO,EAAE,cAAc,GAAG,iBAAiB,EAAE,OAAO,GAAE,oCAAyC;IAYrG,cAAc,CAAC,eAAe,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAKnF,eAAe,CAAC,eAAe,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAKpF,WAAW,CACf,eAAe,EAAE,MAAM,EACvB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GACzE,OAAO,CAAC,IAAI,CAAC;IAgBV,YAAY,CAAC,eAAe,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMxE,SAAS,CAAC,eAAe,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKxE,cAAc,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAkB1D,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuCxE;;OAEG;IACG,yBAAyB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAczD,SAAS;IAkCvB,OAAO,CAAC,MAAM;IAOd,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,UAAU;IAIlB;;;OAGG;YACW,iBAAiB;IAU/B,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,mBAAmB;CAG5B"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token-storage adapter factory
|
|
3
|
+
*
|
|
4
|
+
* Builds a `StorageAdapter` (from `@frontmcp/utils`) from an auth
|
|
5
|
+
* {@link TokenStorageConfig}, so the local-mode auth stores (authorization
|
|
6
|
+
* codes/tokens, federated-auth sessions, orchestrated provider tokens) can be
|
|
7
|
+
* backed by memory, Redis, or local SQLite using one consistent adapter.
|
|
8
|
+
*
|
|
9
|
+
* Dependency direction (per CLAUDE.md):
|
|
10
|
+
* - `@frontmcp/utils` stays storage-backend-agnostic and MUST NOT depend on
|
|
11
|
+
* `@frontmcp/storage-sqlite`.
|
|
12
|
+
* - The SQLite knowledge lives here, in the auth layer, via a lazy
|
|
13
|
+
* `require('@frontmcp/storage-sqlite')` — mirroring how the SDK's
|
|
14
|
+
* `session-store.factory.ts` lazy-loads the SQLite session store. This keeps
|
|
15
|
+
* `ioredis`/`better-sqlite3` out of bundles that don't use them.
|
|
16
|
+
*/
|
|
17
|
+
import { type StorageAdapter } from '@frontmcp/utils';
|
|
18
|
+
import { type TokenStorageConfig, type TokenStorageSqliteConfig } from '../options/interfaces';
|
|
19
|
+
import { type RedisConfig } from './transport-session.types';
|
|
20
|
+
/**
|
|
21
|
+
* Narrow a {@link TokenStorageConfig} to its Redis variant.
|
|
22
|
+
*/
|
|
23
|
+
export declare function isRedisTokenStorage(config: TokenStorageConfig | undefined): config is {
|
|
24
|
+
redis: RedisConfig;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Narrow a {@link TokenStorageConfig} to its SQLite variant.
|
|
28
|
+
*/
|
|
29
|
+
export declare function isSqliteTokenStorage(config: TokenStorageConfig | undefined): config is {
|
|
30
|
+
sqlite: TokenStorageSqliteConfig;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Whether a token-storage config persists across process restarts.
|
|
34
|
+
* `'memory'` (and the undefined default) do not; Redis and SQLite do.
|
|
35
|
+
*/
|
|
36
|
+
export declare function isPersistentTokenStorage(config: TokenStorageConfig | undefined): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Create and connect a `StorageAdapter` for the given token-storage config.
|
|
39
|
+
*
|
|
40
|
+
* @param config - Token storage configuration. `'memory'` (or `undefined`)
|
|
41
|
+
* yields an in-memory adapter; `{ redis }` a Redis adapter; `{ sqlite }` a
|
|
42
|
+
* SQLite-file adapter.
|
|
43
|
+
* @returns A connected `StorageAdapter`.
|
|
44
|
+
*/
|
|
45
|
+
export declare function createTokenStorageAdapter(config: TokenStorageConfig | undefined): Promise<StorageAdapter>;
|
|
46
|
+
//# sourceMappingURL=token-storage.factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-storage.factory.d.ts","sourceRoot":"","sources":["../../src/session/token-storage.factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAA6C,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjG,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAC/F,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAE7D;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,kBAAkB,GAAG,SAAS,GAAG,MAAM,IAAI;IAAE,KAAK,EAAE,WAAW,CAAA;CAAE,CAE5G;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,kBAAkB,GAAG,SAAS,GACrC,MAAM,IAAI;IAAE,MAAM,EAAE,wBAAwB,CAAA;CAAE,CAEhD;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,kBAAkB,GAAG,SAAS,GAAG,OAAO,CAExF;AAED;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAAC,MAAM,EAAE,kBAAkB,GAAG,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC,CAoC/G"}
|
package/ui/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export { CDN, DEFAULT_THEME, baseLayout, createLayout, authLayout, centeredCardLayout, wideLayout, extraWideLayout, escapeHtml, } from './base-layout';
|
|
7
7
|
export type { ThemeColors, ThemeFonts, ThemeConfig, BaseLayoutOptions } from './base-layout';
|
|
8
|
-
export { buildConsentPage, buildIncrementalAuthPage, buildFederatedLoginPage, buildToolConsentPage, buildLoginPage, buildErrorPage, renderToHtml, } from './templates';
|
|
9
|
-
export type { AppAuthCard, ProviderCard, ToolCard } from './templates';
|
|
8
|
+
export { buildConsentPage, buildIncrementalAuthPage, buildFederatedLoginPage, buildToolConsentPage, buildLoginPage, buildConnectPage, buildConnectSuccessPage, buildErrorPage, renderToHtml, } from './templates';
|
|
9
|
+
export type { AppAuthCard, ProviderCard, ToolCard, LoginExtraField, ConsentHiddenField } from './templates';
|
|
10
|
+
export { renderLocalLoginPage, toLoginExtraFields } from './local-login.helper';
|
|
10
11
|
//# sourceMappingURL=index.d.ts.map
|
package/ui/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,GAAG,EACH,aAAa,EACb,UAAU,EACV,YAAY,EACZ,UAAU,EACV,kBAAkB,EAClB,UAAU,EACV,eAAe,EACf,UAAU,GACX,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAG7F,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,uBAAuB,EACvB,oBAAoB,EACpB,cAAc,EACd,cAAc,EACd,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,GAAG,EACH,aAAa,EACb,UAAU,EACV,YAAY,EACZ,UAAU,EACV,kBAAkB,EAClB,UAAU,EACV,eAAe,EACf,UAAU,GACX,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAG7F,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,uBAAuB,EACvB,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EAChB,uBAAuB,EACvB,cAAc,EACd,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAG5G,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local-login page rendering helper (Checkpoint 3a).
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for turning a {@link LoginConfig} + {@link LoginRenderContext}
|
|
5
|
+
* into HTML, shared by the authorize flow (initial render) and the callback flow
|
|
6
|
+
* (error re-render). Keeps the flows lean and the precedence rules in one place:
|
|
7
|
+
*
|
|
8
|
+
* 1. `login.render` → full HTML override (caller owns the markup).
|
|
9
|
+
* 2. `login.fields` → built-in page with the custom fields REPLACING email/name.
|
|
10
|
+
* 3. otherwise → the unchanged default email/name login page.
|
|
11
|
+
*/
|
|
12
|
+
import type { LoginConfig, LoginRenderContext } from '../options/interfaces';
|
|
13
|
+
import { type LoginExtraField } from './templates';
|
|
14
|
+
/**
|
|
15
|
+
* Map a {@link LoginConfig.fields} record (+ optional pre-filled values) into the
|
|
16
|
+
* ordered {@link LoginExtraField} array consumed by {@link buildLoginPage}.
|
|
17
|
+
*/
|
|
18
|
+
export declare function toLoginExtraFields(fields: LoginConfig['fields'] | undefined, values?: Record<string, string>): LoginExtraField[];
|
|
19
|
+
/**
|
|
20
|
+
* Render the local login page for the given config + context.
|
|
21
|
+
*
|
|
22
|
+
* When `login` is undefined (and no values/error to pre-fill) this returns the
|
|
23
|
+
* byte-for-byte default login page via {@link buildLoginPage}, preserving the
|
|
24
|
+
* zero-config behavior.
|
|
25
|
+
*
|
|
26
|
+
* @param login The `auth.login` config (may be undefined).
|
|
27
|
+
* @param ctx Render context (client identity, scopes, pendingAuthId, callbackPath, error).
|
|
28
|
+
* @param values Optional submitted values to pre-fill on re-render (after a failed authenticate()).
|
|
29
|
+
*/
|
|
30
|
+
export declare function renderLocalLoginPage(login: LoginConfig | undefined, ctx: LoginRenderContext, values?: Record<string, string>): string;
|
|
31
|
+
//# sourceMappingURL=local-login.helper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-login.helper.d.ts","sourceRoot":"","sources":["../../src/ui/local-login.helper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC7E,OAAO,EAAkB,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnE;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,GAAG,SAAS,EACzC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,eAAe,EAAE,CAWnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,WAAW,GAAG,SAAS,EAC9B,GAAG,EAAE,kBAAkB,EACvB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,MAAM,CAsBR"}
|