@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
package/session/index.d.ts
CHANGED
|
@@ -3,10 +3,31 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Provides session management, credential storage, and encryption.
|
|
5
5
|
*/
|
|
6
|
-
export { InMemoryAuthorizationStore, RedisAuthorizationStore, verifyPkce, generatePkceChallenge, pkceChallengeSchema, authorizationCodeRecordSchema, } from './authorization.store';
|
|
7
|
-
export type { AuthorizationStore, PkceChallenge, AuthorizationCodeRecord, PendingAuthorizationRecord, RefreshTokenRecord, ConsentStateRecord, FederatedLoginStateRecord, } from './authorization.store';
|
|
6
|
+
export { InMemoryAuthorizationStore, RedisAuthorizationStore, verifyPkce, generatePkceChallenge, generateAuthorizationCode, generateRefreshTokenValue, buildCodeRecord, buildPendingRecord, buildRefreshTokenRecord, AUTH_CODE_TTL_MS, PENDING_AUTH_TTL_MS, REFRESH_TOKEN_TTL_MS, pkceChallengeSchema, authorizationCodeRecordSchema, } from './authorization.store';
|
|
7
|
+
export type { AuthorizationStore, PkceChallenge, AuthorizationCodeRecord, PendingAuthorizationRecord, RefreshTokenRecord, ConsentStateRecord, FederatedLoginStateRecord, CreateCodeRecordParams, CreatePendingRecordParams, CreateRefreshTokenRecordParams, } from './authorization.store';
|
|
8
|
+
export { StorageAuthorizationStore } from './storage-authorization.store';
|
|
9
|
+
export type { StorageAuthorizationStoreOptions } from './storage-authorization.store';
|
|
8
10
|
export { credentialTypeSchema, oauthCredentialSchema, apiKeyCredentialSchema, basicAuthCredentialSchema, bearerCredentialSchema, privateKeyCredentialSchema, mtlsCredentialSchema, customCredentialSchema, sshKeyCredentialSchema, serviceAccountCredentialSchema, pkceOAuthCredentialSchema, credentialSchema, appCredentialSchema, vaultConsentRecordSchema, vaultFederatedRecordSchema, pendingIncrementalAuthSchema, authorizationVaultEntrySchema, } from './authorization-vault';
|
|
9
11
|
export type { CredentialType, OAuthCredential, ApiKeyCredential, BasicAuthCredential, BearerCredential, PrivateKeyCredential, MtlsCredential, CustomCredential, SshKeyCredential, ServiceAccountCredential, PkceOAuthCredential, Credential, AppCredential, VaultConsentRecord, VaultFederatedRecord, PendingIncrementalAuth, AuthorizationVaultEntry, AuthorizationVault, } from './authorization-vault';
|
|
12
|
+
export { SessionCredentialVault } from './session-credential-vault';
|
|
13
|
+
export type { StoredCredential, SessionCredentialVaultOptions } from './session-credential-vault';
|
|
14
|
+
export { createSessionCredentialVault } from './session-credential-vault.factory';
|
|
15
|
+
export type { CreateSessionCredentialVaultOptions } from './session-credential-vault.factory';
|
|
16
|
+
export { signCredentialResumeToken, verifyCredentialResumeToken, buildCredentialResumeUrl, DEFAULT_RESUME_TTL_MS, } from './credential-resume-link';
|
|
17
|
+
export type { CredentialResumePayload } from './credential-resume-link';
|
|
18
|
+
export { CREDENTIALS_ACCESSOR } from './credentials-accessor';
|
|
19
|
+
export type { CredentialsAccessor, CredentialValue, CredentialNotConnected, CredentialConnected, RequireConnectResult, RequireConnectOptions, } from './credentials-accessor';
|
|
20
|
+
export { CredentialsAccessorImpl } from './credentials-accessor.impl';
|
|
21
|
+
export type { CredentialsAccessorDeps } from './credentials-accessor.impl';
|
|
22
|
+
export type { SecureStoreBackend, SecureStoreScope, SecureStoreScopeRef } from './secure-store';
|
|
23
|
+
export { EncryptedStorageSecureStoreBackend } from './secure-store-backends';
|
|
24
|
+
export type { EncryptedStorageSecureStoreBackendOptions } from './secure-store-backends';
|
|
25
|
+
export { SECURE_STORE_ACCESSOR } from './secure-store-accessor';
|
|
26
|
+
export type { SecureStoreAccessor, SecureStoreSetOptions } from './secure-store-accessor';
|
|
27
|
+
export { SecureStoreAccessorImpl } from './secure-store-accessor.impl';
|
|
28
|
+
export type { SecureStoreAccessorDeps } from './secure-store-accessor.impl';
|
|
29
|
+
export { createSecureStore } from './secure-store.factory';
|
|
30
|
+
export type { CreateSecureStoreOptions, ResolvedSecureStore, SecureStoreBackendKind } from './secure-store.factory';
|
|
10
31
|
export { encryptedDataSchema, encryptedVaultEntrySchema, VaultEncryption } from './vault-encryption';
|
|
11
32
|
export type { EncryptedData, VaultKeyDerivationClaims, VaultEncryptionConfig, EncryptedVaultEntry, VaultSensitiveData, } from './vault-encryption';
|
|
12
33
|
export { TokenVault } from './token.vault';
|
|
@@ -30,8 +51,17 @@ export { VercelKvSessionStore } from './vercel-kv-session.store';
|
|
|
30
51
|
export type { VercelKvSessionConfig } from './vercel-kv-session.store';
|
|
31
52
|
export { InMemoryOrchestratedTokenStore } from './orchestrated-token.store';
|
|
32
53
|
export type { InMemoryOrchestratedTokenStoreOptions } from './orchestrated-token.store';
|
|
54
|
+
export { StorageOrchestratedTokenStore } from './storage-orchestrated-token.store';
|
|
55
|
+
export type { StorageOrchestratedTokenStoreOptions } from './storage-orchestrated-token.store';
|
|
33
56
|
export { InMemoryFederatedAuthSessionStore, toSessionRecord, fromSessionRecord, createFederatedAuthSession, isSessionComplete, getNextProvider, completeCurrentProvider, startNextProvider, } from './federated-auth.session';
|
|
34
57
|
export type { ProviderPkce, ProviderTokens, ProviderUserInfo, CompletedProvider, FederatedAuthSession, FederatedAuthSessionRecord, FederatedAuthSessionStore, FederatedAuthSessionCreateParams, } from './federated-auth.session';
|
|
58
|
+
export { StorageFederatedAuthSessionStore } from './storage-federated-auth.session';
|
|
59
|
+
export type { StorageFederatedAuthSessionStoreOptions } from './storage-federated-auth.session';
|
|
60
|
+
export { InMemoryConsentStore, consentRecordKey } from './consent.store';
|
|
61
|
+
export type { ConsentStore, RememberedConsentRecord } from './consent.store';
|
|
62
|
+
export { StorageConsentStore } from './storage-consent.store';
|
|
63
|
+
export type { StorageConsentStoreOptions } from './storage-consent.store';
|
|
64
|
+
export { createTokenStorageAdapter, isRedisTokenStorage, isSqliteTokenStorage, isPersistentTokenStorage, } from './token-storage.factory';
|
|
35
65
|
export { redisVaultEntrySchema, EncryptedRedisVault, createEncryptedVault } from './encrypted-authorization-vault';
|
|
36
66
|
export type { RedisVaultEntry, EncryptionContext } from './encrypted-authorization-vault';
|
|
37
67
|
export { toEpochSeconds, isSoonExpiring, isSoonExpiringProvider, tryJwtExp } from './token.refresh';
|
package/session/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/session/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAEL,0BAA0B,EAC1B,uBAAuB,EAEvB,UAAU,EACV,qBAAqB,EAErB,mBAAmB,EACnB,6BAA6B,GAC9B,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAEV,kBAAkB,EAClB,aAAa,EACb,uBAAuB,EACvB,0BAA0B,EAC1B,kBAAkB,EAClB,kBAAkB,EAClB,yBAAyB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/session/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestrated token-record encryption helpers.
|
|
3
|
+
*
|
|
4
|
+
* Shared by {@link InMemoryOrchestratedTokenStore} and
|
|
5
|
+
* {@link StorageOrchestratedTokenStore} so both apply byte-for-byte identical
|
|
6
|
+
* AES-256-GCM encryption: a per-composite-key subkey is derived from the master
|
|
7
|
+
* `encryptionKey` via HKDF-SHA256, and the record JSON is sealed with a random
|
|
8
|
+
* 12-byte IV. The envelope is a base64url JSON `{ iv, tag, data }`.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Internal token record structure (upstream provider tokens).
|
|
12
|
+
*/
|
|
13
|
+
export interface ProviderTokenRecord {
|
|
14
|
+
accessToken: string;
|
|
15
|
+
refreshToken?: string;
|
|
16
|
+
expiresAt?: number;
|
|
17
|
+
createdAt: number;
|
|
18
|
+
updatedAt: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Derive a per-record AES key from the master key + composite key via HKDF.
|
|
22
|
+
* Results are cached in `cache` (keyed by composite key) to avoid recomputation.
|
|
23
|
+
*/
|
|
24
|
+
export declare function deriveKeyForRecord(masterKey: Uint8Array, compositeKey: string, cache: Map<string, Uint8Array>): Uint8Array;
|
|
25
|
+
/**
|
|
26
|
+
* Encrypt a token record into a base64url JSON envelope string.
|
|
27
|
+
*/
|
|
28
|
+
export declare function encryptRecord(key: Uint8Array, record: ProviderTokenRecord): string;
|
|
29
|
+
/**
|
|
30
|
+
* Decrypt a base64url JSON envelope string back into a token record.
|
|
31
|
+
*/
|
|
32
|
+
export declare function decryptRecord(key: Uint8Array, encrypted: string): ProviderTokenRecord;
|
|
33
|
+
//# sourceMappingURL=orchestrated-token.crypto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrated-token.crypto.d.ts","sourceRoot":"","sources":["../../src/session/orchestrated-token.crypto.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,UAAU,EACrB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAC7B,UAAU,CASZ;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,mBAAmB,GAAG,MAAM,CASlF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,mBAAmB,CAOrF"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SecureStoreAccessor — the `this.secureStore` ToolContext / auth-UI API (#470).
|
|
3
|
+
*
|
|
4
|
+
* A typed accessor over a {@link SecureStoreBackend} that tools (and the auth
|
|
5
|
+
* UI) read/write user-typed secrets through, scoped to the current
|
|
6
|
+
* session/subject. It owns scope resolution, JSON (de)serialization of typed
|
|
7
|
+
* values, and TTLs — so server authors never re-implement crypto, key
|
|
8
|
+
* derivation, scope, or persistence (the whole point of #470).
|
|
9
|
+
*
|
|
10
|
+
* This is the GENERAL secret store. It is distinct from `this.credentials`,
|
|
11
|
+
* which remains the OAuth-credential-centric vault (`requireConnect` resume
|
|
12
|
+
* URLs, per-authorize vault rotation). #464's `this.credentials` is unchanged.
|
|
13
|
+
*/
|
|
14
|
+
import { type Token } from '@frontmcp/di';
|
|
15
|
+
/**
|
|
16
|
+
* Runtime accessor for session-scoped secure secrets, available on tool
|
|
17
|
+
* contexts (and the auth UI) as `this.secureStore`:
|
|
18
|
+
*
|
|
19
|
+
* ```typescript
|
|
20
|
+
* @Tool({ name: 'call_api' })
|
|
21
|
+
* class CallApiTool extends ToolContext {
|
|
22
|
+
* async execute(input: Input): Promise<Output> {
|
|
23
|
+
* await this.secureStore.set('stg.api-key', input.apiKey);
|
|
24
|
+
* const key = await this.secureStore.get<string>('stg.api-key');
|
|
25
|
+
* const all = await this.secureStore.list();
|
|
26
|
+
* // …
|
|
27
|
+
* }
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* Values are JSON-serialized, so any JSON-safe type round-trips. The namespace
|
|
32
|
+
* is resolved from the configured `auth.secureStore.scope` (the authenticated
|
|
33
|
+
* `sub` for `user`, the transport `sessionId` for `session`, or a fixed
|
|
34
|
+
* server-wide namespace for `global`).
|
|
35
|
+
*/
|
|
36
|
+
export interface SecureStoreAccessor {
|
|
37
|
+
/**
|
|
38
|
+
* Read a secret by key for the current scope, JSON-parsed into `T`. Returns
|
|
39
|
+
* `undefined` when the key is absent, when the scope cannot be resolved (e.g.
|
|
40
|
+
* an anonymous request under `user` scope), or when decryption/parse fails.
|
|
41
|
+
*/
|
|
42
|
+
get<T = string>(key: string): Promise<T | undefined>;
|
|
43
|
+
/**
|
|
44
|
+
* Store a JSON-serializable `value` under `key` for the current scope.
|
|
45
|
+
* Optionally bounded by `ttlMs`. Resolves without writing (and logs at debug)
|
|
46
|
+
* when the scope cannot be resolved for the current request.
|
|
47
|
+
*/
|
|
48
|
+
set<T = string>(key: string, value: T, options?: SecureStoreSetOptions): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Delete a secret by key for the current scope. Returns `true` when a value
|
|
51
|
+
* existed and was removed; `false` otherwise (including when the scope cannot
|
|
52
|
+
* be resolved).
|
|
53
|
+
*/
|
|
54
|
+
delete(key: string): Promise<boolean>;
|
|
55
|
+
/**
|
|
56
|
+
* List the secret keys present for the current scope. Empty when the scope
|
|
57
|
+
* cannot be resolved or when no secrets are stored.
|
|
58
|
+
*/
|
|
59
|
+
list(): Promise<string[]>;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Options for {@link SecureStoreAccessor.set}.
|
|
63
|
+
*/
|
|
64
|
+
export interface SecureStoreSetOptions {
|
|
65
|
+
/**
|
|
66
|
+
* Time-to-live in milliseconds. Backends that cannot honor a TTL (e.g. an OS
|
|
67
|
+
* keychain) ignore it. Falls back to the configured `auth.secureStore.ttlMs`
|
|
68
|
+
* when omitted.
|
|
69
|
+
*/
|
|
70
|
+
ttlMs?: number;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* DI token for {@link SecureStoreAccessor}. Resolved by the `this.secureStore`
|
|
74
|
+
* context extension.
|
|
75
|
+
*/
|
|
76
|
+
export declare const SECURE_STORE_ACCESSOR: Token<SecureStoreAccessor>;
|
|
77
|
+
//# sourceMappingURL=secure-store-accessor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure-store-accessor.d.ts","sourceRoot":"","sources":["../../src/session/secure-store-accessor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,cAAc,CAAC;AAE1C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAErD;;;;OAIG;IACH,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvF;;;;OAIG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtC;;;OAGG;IACH,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAmD,KAAK,CAAC,mBAAmB,CAAC,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SecureStoreAccessorImpl — request-scoped implementation of the
|
|
3
|
+
* `this.secureStore` accessor (#470).
|
|
4
|
+
*
|
|
5
|
+
* Binds a {@link SecureStoreBackend} to the current request's resolved scope
|
|
6
|
+
* namespace and handles JSON (de)serialization of typed values. The namespace
|
|
7
|
+
* is derived from the configured {@link SecureStoreScope}:
|
|
8
|
+
* - `user`: the authenticated `sub` (resolved lazily via `resolveSub`),
|
|
9
|
+
* - `session`: the transport `sessionId` (resolved via `resolveSessionId`),
|
|
10
|
+
* - `global`: a single fixed server-wide namespace.
|
|
11
|
+
*
|
|
12
|
+
* Identities are hashed into the namespace (never stored raw) so storage keys
|
|
13
|
+
* carry no PII, and so the backend cannot correlate the raw subject/session.
|
|
14
|
+
*/
|
|
15
|
+
import { type AuthLogger } from '../common/auth-logger.interface';
|
|
16
|
+
import { type SecureStoreBackend, type SecureStoreScope } from './secure-store';
|
|
17
|
+
import { type SecureStoreAccessor, type SecureStoreSetOptions } from './secure-store-accessor';
|
|
18
|
+
/**
|
|
19
|
+
* Dependencies for {@link SecureStoreAccessorImpl}.
|
|
20
|
+
*/
|
|
21
|
+
export interface SecureStoreAccessorDeps {
|
|
22
|
+
/** The secure-store backing (built-in encrypted-storage, or a custom one). */
|
|
23
|
+
backend: SecureStoreBackend;
|
|
24
|
+
/** Configured scope strategy. @default 'user' */
|
|
25
|
+
scope?: SecureStoreScope;
|
|
26
|
+
/**
|
|
27
|
+
* Resolve the current request's authenticated subject. Returns undefined for
|
|
28
|
+
* anonymous/unauthenticated requests (so `user` scope is unavailable then).
|
|
29
|
+
*/
|
|
30
|
+
resolveSub: () => string | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Resolve the current request's transport session id. Returns undefined when
|
|
33
|
+
* there is no session (so `session` scope is unavailable then).
|
|
34
|
+
*/
|
|
35
|
+
resolveSessionId: () => string | undefined;
|
|
36
|
+
/** Default TTL (ms) applied to writes when `set` omits one. */
|
|
37
|
+
ttlMs?: number;
|
|
38
|
+
/** Scoped logger. */
|
|
39
|
+
logger?: AuthLogger;
|
|
40
|
+
}
|
|
41
|
+
export declare class SecureStoreAccessorImpl implements SecureStoreAccessor {
|
|
42
|
+
private readonly backend;
|
|
43
|
+
private readonly scope;
|
|
44
|
+
private readonly resolveSub;
|
|
45
|
+
private readonly resolveSessionId;
|
|
46
|
+
private readonly ttlMs?;
|
|
47
|
+
private readonly logger;
|
|
48
|
+
constructor(deps: SecureStoreAccessorDeps);
|
|
49
|
+
/**
|
|
50
|
+
* Resolve the namespace for the current request from the configured scope.
|
|
51
|
+
* Returns undefined when the scope's identity is unavailable (anonymous user
|
|
52
|
+
* under `user` scope, or no session under `session` scope), in which case
|
|
53
|
+
* reads return empty and writes are skipped.
|
|
54
|
+
*/
|
|
55
|
+
private resolveNamespace;
|
|
56
|
+
get<T = string>(key: string): Promise<T | undefined>;
|
|
57
|
+
set<T = string>(key: string, value: T, options?: SecureStoreSetOptions): Promise<void>;
|
|
58
|
+
delete(key: string): Promise<boolean>;
|
|
59
|
+
list(): Promise<string[]>;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=secure-store-accessor.impl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure-store-accessor.impl.d.ts","sourceRoot":"","sources":["../../src/session/secure-store-accessor.impl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClF,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAK/F;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,8EAA8E;IAC9E,OAAO,EAAE,kBAAkB,CAAC;IAC5B,iDAAiD;IACjD,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB;;;OAGG;IACH,UAAU,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACrC;;;OAGG;IACH,gBAAgB,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAC3C,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,qBAAa,uBAAwB,YAAW,mBAAmB;IACjE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA2B;IACtD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA2B;IAC5D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;gBAExB,IAAI,EAAE,uBAAuB;IASzC;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAgBlB,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAapD,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAUtF,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMrC,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAKhC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in {@link SecureStoreBackend} implementations for the session-scoped
|
|
3
|
+
* secure-secret store (#470).
|
|
4
|
+
*
|
|
5
|
+
* Both built-ins REUSE existing infra rather than re-implementing crypto:
|
|
6
|
+
* - {@link EncryptedStorageSecureStoreBackend} wraps any `StorageAdapter`
|
|
7
|
+
* (memory / sqlite / redis — built via {@link createTokenStorageAdapter}) and
|
|
8
|
+
* encrypts every value at rest with the shared {@link VaultEncryption}
|
|
9
|
+
* primitive (AES-256-GCM, HKDF-SHA256). The in-memory backing is simply this
|
|
10
|
+
* backend over a `MemoryStorageAdapter`, so even the `'memory'` backing keeps
|
|
11
|
+
* secrets encrypted in the process heap (closing the in-memory side of #464).
|
|
12
|
+
*
|
|
13
|
+
* A backend keys solely on the `(namespace, key)` pair it is handed; the
|
|
14
|
+
* accessor resolves `namespace` from the request scope before calling in.
|
|
15
|
+
*/
|
|
16
|
+
import { type StorageAdapter } from '@frontmcp/utils';
|
|
17
|
+
import { type AuthLogger } from '../common/auth-logger.interface';
|
|
18
|
+
import { type SecureStoreBackend } from './secure-store';
|
|
19
|
+
/**
|
|
20
|
+
* Options for {@link EncryptedStorageSecureStoreBackend}.
|
|
21
|
+
*/
|
|
22
|
+
export interface EncryptedStorageSecureStoreBackendOptions {
|
|
23
|
+
/** Connected storage adapter backing the store (memory / sqlite / redis). */
|
|
24
|
+
storage: StorageAdapter;
|
|
25
|
+
/**
|
|
26
|
+
* Master pepper for key derivation. Defense-in-depth: even with the stored
|
|
27
|
+
* ciphertext an attacker still needs this pepper to derive the AES key. When
|
|
28
|
+
* omitted, an empty pepper is used (the caller — LocalPrimaryAuth — passes the
|
|
29
|
+
* server JWT/VAULT secret).
|
|
30
|
+
*/
|
|
31
|
+
pepper?: string;
|
|
32
|
+
/** Key prefix for all stored keys. @default 'mcp:secret:' */
|
|
33
|
+
keyPrefix?: string;
|
|
34
|
+
/** Scoped logger. @default noop */
|
|
35
|
+
logger?: AuthLogger;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* `StorageAdapter`-backed secure-store backend with AES-256-GCM at-rest
|
|
39
|
+
* encryption via {@link VaultEncryption}.
|
|
40
|
+
*
|
|
41
|
+
* Storage key layout (no PII; the namespace is an opaque hash/identity handed in
|
|
42
|
+
* by the accessor):
|
|
43
|
+
* - `secret:keys:<namespace>` → JSON array of key names (the key SET).
|
|
44
|
+
* - `secret:data:<namespace>:<key>` → encrypted {@link EncryptedSecretRecord}.
|
|
45
|
+
*
|
|
46
|
+
* The per-namespace AES key is derived (and cached) from the namespace + pepper,
|
|
47
|
+
* so a value written under one namespace cannot be decrypted under another.
|
|
48
|
+
*/
|
|
49
|
+
export declare class EncryptedStorageSecureStoreBackend implements SecureStoreBackend {
|
|
50
|
+
private readonly storage;
|
|
51
|
+
private readonly encryption;
|
|
52
|
+
private readonly keyPrefix;
|
|
53
|
+
private readonly logger;
|
|
54
|
+
/** Cache of derived AES keys, keyed by namespace. */
|
|
55
|
+
private readonly keyCache;
|
|
56
|
+
constructor(options: EncryptedStorageSecureStoreBackendOptions);
|
|
57
|
+
/** `secret:keys:<namespace>` → JSON array of key names. */
|
|
58
|
+
private keysKey;
|
|
59
|
+
/** `secret:data:<namespace>:<key>` → encrypted record. */
|
|
60
|
+
private dataKey;
|
|
61
|
+
/**
|
|
62
|
+
* Derive (and cache) the AES-256 key for a namespace. The namespace acts as
|
|
63
|
+
* the HKDF salt material, so values are cryptographically isolated per scope.
|
|
64
|
+
*/
|
|
65
|
+
private deriveKey;
|
|
66
|
+
private setOpts;
|
|
67
|
+
get(namespace: string, key: string): Promise<string | null>;
|
|
68
|
+
set(namespace: string, key: string, value: string, ttlMs?: number): Promise<void>;
|
|
69
|
+
delete(namespace: string, key: string): Promise<boolean>;
|
|
70
|
+
list(namespace: string): Promise<string[]>;
|
|
71
|
+
private readKeySet;
|
|
72
|
+
private writeKeySet;
|
|
73
|
+
private addKeyToSet;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=secure-store-backends.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure-store-backends.d.ts","sourceRoot":"","sources":["../../src/session/secure-store-backends.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEvE,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClF,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAYzD;;GAEG;AACH,MAAM,WAAW,yCAAyC;IACxD,6EAA6E;IAC7E,OAAO,EAAE,cAAc,CAAC;IACxB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,kCAAmC,YAAW,kBAAkB;IAC3E,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,MAAM,CAAa;IACpC,qDAAqD;IACrD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0C;gBAEvD,OAAO,EAAE,yCAAyC;IAc9D,2DAA2D;IAC3D,OAAO,CAAC,OAAO;IAIf,0DAA0D;IAC1D,OAAO,CAAC,OAAO;IAIf;;;OAGG;IACH,OAAO,CAAC,SAAS;IAWjB,OAAO,CAAC,OAAO;IAQT,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAc3D,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASjF,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUxD,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YAQlC,UAAU;YAWV,WAAW;YAKX,WAAW;CAO1B"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SecureStoreBackend — the pluggable backing contract for the general
|
|
3
|
+
* session-scoped secure-secret store (#470).
|
|
4
|
+
*
|
|
5
|
+
* Unlike {@link SessionCredentialVault} (which is OAuth-credential-centric:
|
|
6
|
+
* `sub`-keyed, vault-rotation on every authorize, resume-URL `requireConnect`),
|
|
7
|
+
* this is a GENERAL key→secret store for arbitrary user-typed secrets that a
|
|
8
|
+
* tool or auth-UI reads/writes through `this.secureStore`. The backing is
|
|
9
|
+
* selectable per deployment (memory / sqlite / redis / a custom — e.g.
|
|
10
|
+
* OS-keychain — backend) WITHOUT the framework bundling any native dependency.
|
|
11
|
+
*
|
|
12
|
+
* Security model
|
|
13
|
+
* --------------
|
|
14
|
+
* - Every value is namespaced by a `ScopeRef` ({@link SecureStoreScopeRef}) so a
|
|
15
|
+
* `user`-scoped secret keys by the authenticated `sub`, a `session`-scoped one
|
|
16
|
+
* by the transport `sessionId`, and a `global`-scoped one by a fixed
|
|
17
|
+
* namespace. The accessor (`this.secureStore`) resolves the namespace from the
|
|
18
|
+
* request before calling a backend, so a backend NEVER sees raw identities it
|
|
19
|
+
* has not been handed.
|
|
20
|
+
* - Built-in backends encrypt values at rest with the shared
|
|
21
|
+
* {@link VaultEncryption} primitive (AES-256-GCM, HKDF-SHA256 keyed by the
|
|
22
|
+
* namespace + a server pepper). A CUSTOM backend (e.g. an OS keychain) owns
|
|
23
|
+
* its own at-rest protection — the OS keychain is encrypted by the OS, so the
|
|
24
|
+
* keychain backend stores the plaintext value and relies on the OS for
|
|
25
|
+
* confidentiality.
|
|
26
|
+
*
|
|
27
|
+
* A backend deals ONLY in `(namespace, key) → string` — JSON serialization of
|
|
28
|
+
* typed values is handled one layer up by the accessor.
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* The resolved namespace a {@link SecureStoreBackend} operates within. Produced
|
|
32
|
+
* by the accessor from the current request + configured scope, NEVER by the
|
|
33
|
+
* backend itself. Carries the scope kind purely for diagnostics/logging; a
|
|
34
|
+
* backend keys solely on {@link namespace}.
|
|
35
|
+
*/
|
|
36
|
+
export interface SecureStoreScopeRef {
|
|
37
|
+
/** The resolved namespace (already incorporates the scope + identity). */
|
|
38
|
+
namespace: string;
|
|
39
|
+
/** Which scope produced this namespace (for diagnostics only). */
|
|
40
|
+
scope: SecureStoreScope;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* How a secure-store namespace is derived from the current request:
|
|
44
|
+
* - `user` (default): keyed by the authenticated subject (`sub`). Survives a
|
|
45
|
+
* reconnect for the same user.
|
|
46
|
+
* - `session`: keyed by the transport `sessionId`. Disappears when the session
|
|
47
|
+
* ends.
|
|
48
|
+
* - `global`: a single shared namespace (server-wide). Use for operator-level
|
|
49
|
+
* secrets that are not tied to any one user/session.
|
|
50
|
+
*/
|
|
51
|
+
export type SecureStoreScope = 'user' | 'session' | 'global';
|
|
52
|
+
/**
|
|
53
|
+
* Pluggable backing for the session-scoped secure-secret store.
|
|
54
|
+
*
|
|
55
|
+
* Implement this to provide a custom backing (e.g. an OS keychain) and wire it
|
|
56
|
+
* via `auth.secureStore: { backend: myBackend }`. All four methods operate
|
|
57
|
+
* within an explicit, already-resolved `namespace` so the same backend instance
|
|
58
|
+
* can safely serve every scope/identity.
|
|
59
|
+
*/
|
|
60
|
+
export interface SecureStoreBackend {
|
|
61
|
+
/**
|
|
62
|
+
* Read a stored value by key within `namespace`. Returns `null` when the key
|
|
63
|
+
* is absent (mirrors `StorageAdapter.get`).
|
|
64
|
+
*/
|
|
65
|
+
get(namespace: string, key: string): Promise<string | null>;
|
|
66
|
+
/**
|
|
67
|
+
* Store `value` under `key` within `namespace`. `ttlMs` (when supported by
|
|
68
|
+
* the backend) bounds the lifetime; backends that cannot honor a TTL (e.g. an
|
|
69
|
+
* OS keychain) MUST ignore it rather than reject the write.
|
|
70
|
+
*/
|
|
71
|
+
set(namespace: string, key: string, value: string, ttlMs?: number): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Delete `key` within `namespace`. Returns `true` when a value existed and was
|
|
74
|
+
* removed, `false` otherwise. Idempotent.
|
|
75
|
+
*/
|
|
76
|
+
delete(namespace: string, key: string): Promise<boolean>;
|
|
77
|
+
/**
|
|
78
|
+
* List the keys present within `namespace`. Returns an empty array when the
|
|
79
|
+
* namespace is empty.
|
|
80
|
+
*/
|
|
81
|
+
list(namespace: string): Promise<string[]>;
|
|
82
|
+
/**
|
|
83
|
+
* Optional lifecycle hook. Backends that own a connection/handle (e.g. a
|
|
84
|
+
* keychain session) may close it here. The built-in adapter-backed backend
|
|
85
|
+
* does NOT dispose the shared adapter (it is owned by the auth layer).
|
|
86
|
+
*/
|
|
87
|
+
dispose?(): Promise<void>;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=secure-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure-store.d.ts","sourceRoot":"","sources":["../../src/session/secure-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,KAAK,EAAE,gBAAgB,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE7D;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAE5D;;;;OAIG;IACH,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElF;;;OAGG;IACH,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEzD;;;OAGG;IACH,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE3C;;;;OAIG;IACH,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secure-store backend factory (#470).
|
|
3
|
+
*
|
|
4
|
+
* Builds a {@link SecureStoreBackend} from an `auth.secureStore`
|
|
5
|
+
* {@link SecureStoreConfig}, mirroring {@link createTokenStorageAdapter}'s
|
|
6
|
+
* selection pattern:
|
|
7
|
+
*
|
|
8
|
+
* - `'memory'` / object-without-backing → in-memory `StorageAdapter` wrapped in
|
|
9
|
+
* the AES-256-GCM-encrypted {@link EncryptedStorageSecureStoreBackend}.
|
|
10
|
+
* - `{ sqlite }` / `{ redis }` → persistent `StorageAdapter` (via
|
|
11
|
+
* {@link createTokenStorageAdapter}) wrapped in the same encrypted backend.
|
|
12
|
+
* - `{ backend }` → the user-supplied custom backing is used AS-IS (e.g. an OS
|
|
13
|
+
* keychain). The framework bundles NO native dependency for this path.
|
|
14
|
+
*
|
|
15
|
+
* The dependency direction matches the CLAUDE.md storage-factory pattern: SQLite
|
|
16
|
+
* is reached lazily through `createTokenStorageAdapter`, so `better-sqlite3` /
|
|
17
|
+
* `ioredis` stay out of bundles that don't use them.
|
|
18
|
+
*/
|
|
19
|
+
import { type StorageAdapter } from '@frontmcp/utils';
|
|
20
|
+
import { type AuthLogger } from '../common/auth-logger.interface';
|
|
21
|
+
import { type SecureStoreConfig } from '../options/interfaces';
|
|
22
|
+
import { type SecureStoreBackend, type SecureStoreScope } from './secure-store';
|
|
23
|
+
/** The backing kind a {@link SecureStoreConfig} resolves to. */
|
|
24
|
+
export type SecureStoreBackendKind = 'memory' | 'sqlite' | 'redis' | 'custom';
|
|
25
|
+
/**
|
|
26
|
+
* Resolved view of a {@link SecureStoreConfig}: the constructed backend, the
|
|
27
|
+
* namespace scope, the default TTL, and the backing kind (for diagnostics).
|
|
28
|
+
*/
|
|
29
|
+
export interface ResolvedSecureStore {
|
|
30
|
+
backend: SecureStoreBackend;
|
|
31
|
+
scope: SecureStoreScope;
|
|
32
|
+
ttlMs?: number;
|
|
33
|
+
kind: SecureStoreBackendKind;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Options for {@link createSecureStore}.
|
|
37
|
+
*/
|
|
38
|
+
export interface CreateSecureStoreOptions {
|
|
39
|
+
/** The `auth.secureStore` config. `undefined` → in-memory default. */
|
|
40
|
+
config: SecureStoreConfig | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Master pepper for the built-in encrypted backings. Used when the config
|
|
43
|
+
* does not carry an explicit `encryption.pepper`. Typically the server
|
|
44
|
+
* JWT/VAULT secret.
|
|
45
|
+
*/
|
|
46
|
+
pepper?: string;
|
|
47
|
+
/**
|
|
48
|
+
* Optionally reuse an already-connected adapter for the built-in encrypted
|
|
49
|
+
* backing instead of building one from the config. When provided, the
|
|
50
|
+
* sqlite/redis selection is NOT used to build an adapter (it still informs the
|
|
51
|
+
* reported `kind`). Ignored for the `{ backend }` (custom) path.
|
|
52
|
+
*/
|
|
53
|
+
storage?: StorageAdapter;
|
|
54
|
+
/** Scoped logger. */
|
|
55
|
+
logger?: AuthLogger;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Create a {@link SecureStoreBackend} (plus resolved scope/ttl/kind) for the
|
|
59
|
+
* given `auth.secureStore` config.
|
|
60
|
+
*/
|
|
61
|
+
export declare function createSecureStore(options: CreateSecureStoreOptions): Promise<ResolvedSecureStore>;
|
|
62
|
+
//# sourceMappingURL=secure-store.factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure-store.factory.d.ts","sourceRoot":"","sources":["../../src/session/secure-store.factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE5E,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,KAAK,iBAAiB,EAA0D,MAAM,uBAAuB,CAAC;AACvH,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAKhF,gEAAgE;AAChE,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE9E;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,kBAAkB,CAAC;IAC5B,KAAK,EAAE,gBAAgB,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,sBAAsB,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,sEAAsE;IACtE,MAAM,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACtC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,qBAAqB;IACrB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AA8DD;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA8BvG"}
|