@stdiobus/workers-registry 1.4.14 → 1.5.0-beta.2

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.
Files changed (129) hide show
  1. package/README.md +181 -21
  2. package/out/dist/workers-registry/acp-registry/index.js +128 -2
  3. package/out/dist/workers-registry/acp-registry/index.js.map +4 -4
  4. package/out/dist/workers-registry/acp-worker/index.js +1 -3
  5. package/out/dist/workers-registry/acp-worker/index.js.map +4 -4
  6. package/out/dist/workers-registry/index.d.ts +1 -0
  7. package/out/dist/workers-registry/index.js +6 -0
  8. package/out/dist/workers-registry/openai-agent/index.js +1 -1
  9. package/out/dist/workers-registry/openai-agent/index.js.map +2 -2
  10. package/out/dist/workers-registry/registry-launcher/index.js +131 -0
  11. package/out/dist/workers-registry/registry-launcher/index.js.map +7 -0
  12. package/out/tsc/workers-registry/acp-worker/src/index.d.ts +0 -10
  13. package/out/tsc/workers-registry/registry-launcher/src/auth/auth-manager.d.ts +392 -0
  14. package/out/tsc/workers-registry/registry-launcher/src/auth/cli/cli.property.test.d.ts +22 -0
  15. package/out/tsc/workers-registry/registry-launcher/src/auth/cli/index.d.ts +9 -0
  16. package/out/tsc/workers-registry/registry-launcher/src/auth/cli/login-command.d.ts +32 -0
  17. package/out/tsc/workers-registry/registry-launcher/src/auth/cli/logout-command.d.ts +25 -0
  18. package/out/tsc/workers-registry/registry-launcher/src/auth/cli/setup-command.d.ts +25 -0
  19. package/out/tsc/workers-registry/registry-launcher/src/auth/cli/status-command.d.ts +21 -0
  20. package/out/tsc/workers-registry/registry-launcher/src/auth/errors.d.ts +190 -0
  21. package/out/tsc/workers-registry/registry-launcher/src/auth/flows/agent-auth-flow.d.ts +146 -0
  22. package/out/tsc/workers-registry/registry-launcher/src/auth/flows/callback-server.d.ts +131 -0
  23. package/out/tsc/workers-registry/registry-launcher/src/auth/flows/callback-server.test.d.ts +1 -0
  24. package/out/tsc/workers-registry/registry-launcher/src/auth/flows/index.d.ts +11 -0
  25. package/out/tsc/workers-registry/registry-launcher/src/auth/flows/terminal-auth-flow.d.ts +252 -0
  26. package/out/tsc/workers-registry/registry-launcher/src/auth/flows/terminal-auth-flow.test.d.ts +1 -0
  27. package/out/tsc/workers-registry/registry-launcher/src/auth/index.d.ts +33 -0
  28. package/out/tsc/workers-registry/registry-launcher/src/auth/integration.test.d.ts +1 -0
  29. package/out/tsc/workers-registry/registry-launcher/src/auth/model-credentials/anthropic-api-key.d.ts +154 -0
  30. package/out/tsc/workers-registry/registry-launcher/src/auth/model-credentials/index.d.ts +20 -0
  31. package/out/tsc/workers-registry/registry-launcher/src/auth/model-credentials/model-credentials.test.d.ts +1 -0
  32. package/out/tsc/workers-registry/registry-launcher/src/auth/model-credentials/openai-api-key.d.ts +182 -0
  33. package/out/tsc/workers-registry/registry-launcher/src/auth/model-credentials/types.d.ts +186 -0
  34. package/out/tsc/workers-registry/registry-launcher/src/auth/pkce.d.ts +61 -0
  35. package/out/tsc/workers-registry/registry-launcher/src/auth/pkce.property.test.d.ts +1 -0
  36. package/out/tsc/workers-registry/registry-launcher/src/auth/pkce.test.d.ts +1 -0
  37. package/out/tsc/workers-registry/registry-launcher/src/auth/providers/base-provider.d.ts +138 -0
  38. package/out/tsc/workers-registry/registry-launcher/src/auth/providers/base-provider.test.d.ts +1 -0
  39. package/out/tsc/workers-registry/registry-launcher/src/auth/providers/cognito-provider.d.ts +44 -0
  40. package/out/tsc/workers-registry/registry-launcher/src/auth/providers/concrete-providers.test.d.ts +1 -0
  41. package/out/tsc/workers-registry/registry-launcher/src/auth/providers/entra-provider.d.ts +54 -0
  42. package/out/tsc/workers-registry/registry-launcher/src/auth/providers/github-provider.d.ts +19 -0
  43. package/out/tsc/workers-registry/registry-launcher/src/auth/providers/google-provider.d.ts +19 -0
  44. package/out/tsc/workers-registry/registry-launcher/src/auth/providers/index.d.ts +107 -0
  45. package/out/tsc/workers-registry/registry-launcher/src/auth/providers/index.test.d.ts +1 -0
  46. package/out/tsc/workers-registry/registry-launcher/src/auth/providers/oidc-provider.d.ts +413 -0
  47. package/out/tsc/workers-registry/registry-launcher/src/auth/providers/oidc-provider.property.test.d.ts +1 -0
  48. package/out/tsc/workers-registry/registry-launcher/src/auth/providers/oidc-provider.test.d.ts +1 -0
  49. package/out/tsc/workers-registry/registry-launcher/src/auth/providers/providers.property.test.d.ts +1 -0
  50. package/out/tsc/workers-registry/registry-launcher/src/auth/providers/types.d.ts +28 -0
  51. package/out/tsc/workers-registry/registry-launcher/src/auth/session.d.ts +251 -0
  52. package/out/tsc/workers-registry/registry-launcher/src/auth/session.property.test.d.ts +1 -0
  53. package/out/tsc/workers-registry/registry-launcher/src/auth/session.test.d.ts +1 -0
  54. package/out/tsc/workers-registry/registry-launcher/src/auth/state.d.ts +26 -0
  55. package/out/tsc/workers-registry/registry-launcher/src/auth/state.property.test.d.ts +1 -0
  56. package/out/tsc/workers-registry/registry-launcher/src/auth/state.test.d.ts +1 -0
  57. package/out/tsc/workers-registry/registry-launcher/src/auth/storage/credential-store.d.ts +98 -0
  58. package/out/tsc/workers-registry/registry-launcher/src/auth/storage/credential-store.test.d.ts +1 -0
  59. package/out/tsc/workers-registry/registry-launcher/src/auth/storage/encrypted-file-backend.d.ts +101 -0
  60. package/out/tsc/workers-registry/registry-launcher/src/auth/storage/encrypted-file-backend.test.d.ts +1 -0
  61. package/out/tsc/workers-registry/registry-launcher/src/auth/storage/index.d.ts +12 -0
  62. package/out/tsc/workers-registry/registry-launcher/src/auth/storage/keychain-backend.d.ts +80 -0
  63. package/out/tsc/workers-registry/registry-launcher/src/auth/storage/keychain-backend.test.d.ts +1 -0
  64. package/out/tsc/workers-registry/registry-launcher/src/auth/storage/memory-backend.d.ts +54 -0
  65. package/out/tsc/workers-registry/registry-launcher/src/auth/storage/storage.property.test.d.ts +1 -0
  66. package/out/tsc/workers-registry/registry-launcher/src/auth/storage/types.d.ts +44 -0
  67. package/out/tsc/workers-registry/registry-launcher/src/auth/token-manager.d.ts +171 -0
  68. package/out/tsc/workers-registry/registry-launcher/src/auth/token-manager.property.test.d.ts +1 -0
  69. package/out/tsc/workers-registry/registry-launcher/src/auth/token-manager.test.d.ts +1 -0
  70. package/out/tsc/workers-registry/registry-launcher/src/auth/types.d.ts +369 -0
  71. package/out/tsc/workers-registry/registry-launcher/src/auth/types.test.d.ts +1 -0
  72. package/out/tsc/workers-registry/registry-launcher/src/config/config.property.test.d.ts +1 -0
  73. package/out/tsc/workers-registry/registry-launcher/src/config/config.test.d.ts +1 -0
  74. package/out/tsc/workers-registry/{acp-worker/src/registry-launcher → registry-launcher/src}/registry/index.d.ts +51 -2
  75. package/out/tsc/workers-registry/registry-launcher/src/registry/index.property.test.d.ts +1 -0
  76. package/out/tsc/workers-registry/registry-launcher/src/registry/index.test.d.ts +1 -0
  77. package/out/tsc/workers-registry/{acp-worker/src/registry-launcher → registry-launcher/src}/registry/types.d.ts +24 -0
  78. package/out/tsc/workers-registry/registry-launcher/src/router/message-router.d.ts +770 -0
  79. package/out/tsc/workers-registry/registry-launcher/src/router/message-router.property.test.d.ts +1 -0
  80. package/out/tsc/workers-registry/registry-launcher/src/router/message-router.test.d.ts +1 -0
  81. package/out/tsc/workers-registry/registry-launcher/src/runtime/manager.property.test.d.ts +1 -0
  82. package/out/tsc/workers-registry/registry-launcher/src/runtime/manager.test.d.ts +1 -0
  83. package/out/tsc/workers-registry/registry-launcher/src/stream/ndjson-handler.property.test.d.ts +1 -0
  84. package/out/tsc/workers-registry/registry-launcher/src/stream/ndjson-handler.test.d.ts +1 -0
  85. package/out/tsc/workers-registry/registry-launcher/tests/e2e/auth-flow.e2e.test.d.ts +1 -0
  86. package/out/tsc/workers-registry/registry-launcher/tests/e2e/auth-required-flow.e2e.test.d.ts +1 -0
  87. package/out/tsc/workers-registry/registry-launcher/tests/e2e/helpers/api-keys.d.ts +32 -0
  88. package/out/tsc/workers-registry/registry-launcher/tests/e2e/helpers/index.d.ts +17 -0
  89. package/out/tsc/workers-registry/registry-launcher/tests/e2e/helpers/launcher-harness.d.ts +101 -0
  90. package/out/tsc/workers-registry/registry-launcher/tests/e2e/helpers/registry-server.d.ts +46 -0
  91. package/out/tsc/workers-registry/registry-launcher/tests/e2e/production-agent-auth.e2e.test.d.ts +1 -0
  92. package/out/tsc/workers-registry/registry-launcher/tests/e2e/production-api-keys.e2e.test.d.ts +1 -0
  93. package/out/tsc/workers-registry/registry-launcher/tests/e2e/production-auth-required.e2e.test.d.ts +1 -0
  94. package/out/tsc/workers-registry/registry-launcher/tests/e2e/production-cli.e2e.test.d.ts +1 -0
  95. package/out/tsc/workers-registry/registry-launcher/tests/e2e/production-concurrent.e2e.test.d.ts +1 -0
  96. package/out/tsc/workers-registry/registry-launcher/tests/e2e/production-lifecycle.e2e.test.d.ts +1 -0
  97. package/out/tsc/workers-registry/registry-launcher/tests/e2e/production-terminal-auth.e2e.test.d.ts +1 -0
  98. package/out/tsc/workers-registry/registry-launcher/tests/integration/agent-auth.integration.test.d.ts +9 -0
  99. package/out/tsc/workers-registry/registry-launcher/tests/integration/registry-launcher.test.d.ts +1 -0
  100. package/out/tsc/workers-registry/registry-launcher/tests/integration/terminal-auth.integration.test.d.ts +12 -0
  101. package/package.json +16 -11
  102. package/out/tsc/workers-registry/acp-worker/src/registry-launcher/router/message-router.d.ts +0 -199
  103. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher/config/config.property.test.d.ts → registry-launcher/src/auth/auth-manager.property.test.d.ts} +0 -0
  104. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher/config/config.test.d.ts → registry-launcher/src/auth/auth-manager.test.d.ts} +0 -0
  105. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher/registry/index.property.test.d.ts → registry-launcher/src/auth/cli/cli.test.d.ts} +0 -0
  106. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher/registry/index.test.d.ts → registry-launcher/src/auth/cli/login-command.test.d.ts} +0 -0
  107. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher/router/message-router.property.test.d.ts → registry-launcher/src/auth/cli/provider-config.test.d.ts} +0 -0
  108. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher/router/message-router.test.d.ts → registry-launcher/src/auth/cli/setup-command.test.d.ts} +0 -0
  109. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher/runtime/manager.property.test.d.ts → registry-launcher/src/auth/cli/status-command.test.d.ts} +0 -0
  110. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher/runtime/manager.test.d.ts → registry-launcher/src/auth/errors.property.test.d.ts} +0 -0
  111. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher/stream/ndjson-handler.property.test.d.ts → registry-launcher/src/auth/errors.test.d.ts} +0 -0
  112. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher/stream/ndjson-handler.test.d.ts → registry-launcher/src/auth/flows/agent-auth-flow.test.d.ts} +0 -0
  113. /package/out/tsc/workers-registry/{acp-worker/tests/integration/registry-launcher.test.d.ts → registry-launcher/src/auth/flows/callback-server.property.test.d.ts} +0 -0
  114. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher → registry-launcher/src}/config/api-keys.d.ts +0 -0
  115. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher → registry-launcher/src}/config/config.d.ts +0 -0
  116. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher → registry-launcher/src}/config/index.d.ts +0 -0
  117. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher → registry-launcher/src}/config/types.d.ts +0 -0
  118. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher → registry-launcher/src}/index.d.ts +0 -0
  119. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher → registry-launcher/src}/log.d.ts +0 -0
  120. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher → registry-launcher/src}/log.test.d.ts +0 -0
  121. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher → registry-launcher/src}/registry/resolver.d.ts +0 -0
  122. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher → registry-launcher/src}/router/index.d.ts +0 -0
  123. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher → registry-launcher/src}/runtime/agent-runtime.d.ts +0 -0
  124. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher → registry-launcher/src}/runtime/index.d.ts +0 -0
  125. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher → registry-launcher/src}/runtime/manager.d.ts +0 -0
  126. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher → registry-launcher/src}/runtime/types.d.ts +0 -0
  127. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher → registry-launcher/src}/stream/index.d.ts +0 -0
  128. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher → registry-launcher/src}/stream/ndjson-handler.d.ts +0 -0
  129. /package/out/tsc/workers-registry/{acp-worker/src/registry-launcher → registry-launcher/src}/test-utils/index.d.ts +0 -0
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Minimum number of random bytes for state parameter.
3
+ * 32 bytes provides 256 bits of entropy for CSRF protection.
4
+ */
5
+ export declare const STATE_MIN_BYTES = 32;
6
+ /**
7
+ * Generate a cryptographically secure state parameter.
8
+ *
9
+ * Generates at least 32 bytes of cryptographic randomness using
10
+ * Node.js crypto.randomBytes, then encodes as base64url without padding.
11
+ *
12
+ * @returns Base64url-encoded random bytes (at least 32 bytes)
13
+ */
14
+ export declare function generateState(): string;
15
+ /**
16
+ * Validate a returned state parameter against the expected value.
17
+ *
18
+ * Uses constant-time comparison to prevent timing attacks.
19
+ * Returns false for missing, empty, or mismatched state parameters.
20
+ * Never throws exceptions - always returns boolean.
21
+ *
22
+ * @param expected - The original state parameter
23
+ * @param received - The state parameter from the callback
24
+ * @returns True if the states match exactly, false otherwise
25
+ */
26
+ export declare function validateState(expected: string | null | undefined, received: string | null | undefined): boolean;
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Main credential store facade.
3
+ *
4
+ * Selects the best available storage backend (keychain > encrypted file > memory).
5
+ * Provides a unified interface for credential storage regardless of the underlying backend.
6
+ *
7
+ * @module storage/credential-store
8
+ */
9
+ import type { AuthProviderId, StorageBackendType, StoredCredentials } from '../types.js';
10
+ import type { ICredentialStore } from './types.js';
11
+ /**
12
+ * Options for creating a credential store.
13
+ */
14
+ export interface CredentialStoreOptions {
15
+ /** Preferred storage backend (overrides automatic selection) */
16
+ preferredBackend?: StorageBackendType;
17
+ /** Custom path for encrypted file storage */
18
+ encryptedFilePath?: string;
19
+ }
20
+ /**
21
+ * Credential store implementation.
22
+ *
23
+ * Automatically selects the best available storage backend:
24
+ * 1. Keychain (most secure, OS-level protection)
25
+ * 2. Encrypted file (secure, portable)
26
+ * 3. Memory (testing only, not persistent)
27
+ *
28
+ * The backend selection happens lazily on first use.
29
+ */
30
+ export declare class CredentialStore implements ICredentialStore {
31
+ private backend;
32
+ private backendInitialized;
33
+ private readonly options;
34
+ /**
35
+ * Create a new credential store.
36
+ * @param options - Configuration options
37
+ */
38
+ constructor(options?: CredentialStoreOptions);
39
+ /**
40
+ * Initialize the storage backend.
41
+ * Selects the best available backend based on system capabilities.
42
+ */
43
+ private initializeBackend;
44
+ /**
45
+ * Create a specific backend by type.
46
+ */
47
+ private createBackend;
48
+ /**
49
+ * Get the initialized backend.
50
+ */
51
+ private getBackend;
52
+ /**
53
+ * Store credentials for a provider.
54
+ * @param providerId - The provider identifier
55
+ * @param credentials - The credentials to store
56
+ */
57
+ store(providerId: AuthProviderId, credentials: StoredCredentials): Promise<void>;
58
+ /**
59
+ * Retrieve credentials for a provider.
60
+ * @param providerId - The provider identifier
61
+ * @returns The stored credentials or null if not found
62
+ */
63
+ retrieve(providerId: AuthProviderId): Promise<StoredCredentials | null>;
64
+ /**
65
+ * Delete credentials for a provider.
66
+ * @param providerId - The provider identifier
67
+ */
68
+ delete(providerId: AuthProviderId): Promise<void>;
69
+ /**
70
+ * Delete all stored credentials.
71
+ */
72
+ deleteAll(): Promise<void>;
73
+ /**
74
+ * List all providers with stored credentials.
75
+ * @returns Array of provider identifiers
76
+ */
77
+ listProviders(): Promise<AuthProviderId[]>;
78
+ /**
79
+ * Get the active storage backend type.
80
+ * @returns The backend type currently in use
81
+ */
82
+ getBackendType(): StorageBackendType;
83
+ /**
84
+ * Check if the store has been initialized.
85
+ * @returns True if a backend has been selected
86
+ */
87
+ isInitialized(): boolean;
88
+ /**
89
+ * Force re-initialization of the backend.
90
+ * Useful for testing or when system capabilities change.
91
+ */
92
+ reinitialize(): Promise<void>;
93
+ }
94
+ /**
95
+ * Create a credential store with default options.
96
+ * @returns A new credential store instance
97
+ */
98
+ export declare function createCredentialStore(options?: CredentialStoreOptions): CredentialStore;
@@ -0,0 +1,101 @@
1
+ import type { AuthProviderId, StorageBackendType, StoredCredentials } from '../types.js';
2
+ import type { IStorageBackend } from './types.js';
3
+ /**
4
+ * Custom error for credential store corruption.
5
+ */
6
+ export declare class CredentialStoreCorruptedError extends Error {
7
+ readonly cause?: Error | undefined;
8
+ constructor(message: string, cause?: Error | undefined);
9
+ }
10
+ /**
11
+ * Encrypted file storage backend implementation.
12
+ *
13
+ * Uses AES-256-GCM encryption with a key derived from:
14
+ * - Random salt (stored with file, unique per file)
15
+ * - Machine-specific entropy (hostname, username)
16
+ *
17
+ * This provides both uniqueness (random salt) and machine binding (entropy).
18
+ *
19
+ * Requirements: 5.2, 5.3
20
+ */
21
+ export declare class EncryptedFileBackend implements IStorageBackend {
22
+ readonly type: StorageBackendType;
23
+ /** Cached encryption key (derived once per instance, per salt) */
24
+ private encryptionKey;
25
+ /** Cached salt from current file */
26
+ private currentSalt;
27
+ /** Path to the credentials file */
28
+ private readonly filePath;
29
+ /** Path to the config directory */
30
+ private readonly configDir;
31
+ /**
32
+ * Create a new EncryptedFileBackend instance.
33
+ * @param customPath - Optional custom path for the credentials file (for testing)
34
+ */
35
+ constructor(customPath?: string);
36
+ /**
37
+ * Check if the backend is available.
38
+ * Tests if the config directory is writable.
39
+ * @returns True if the file system is writable
40
+ */
41
+ isAvailable(): Promise<boolean>;
42
+ /**
43
+ * Store credentials for a provider.
44
+ * @param providerId - The provider identifier
45
+ * @param credentials - The credentials to store
46
+ */
47
+ store(providerId: AuthProviderId, credentials: StoredCredentials): Promise<void>;
48
+ /**
49
+ * Retrieve credentials for a provider.
50
+ * @param providerId - The provider identifier
51
+ * @returns The stored credentials or null if not found
52
+ */
53
+ retrieve(providerId: AuthProviderId): Promise<StoredCredentials | null>;
54
+ /**
55
+ * Delete credentials for a provider.
56
+ * @param providerId - The provider identifier
57
+ */
58
+ delete(providerId: AuthProviderId): Promise<void>;
59
+ /**
60
+ * Delete all stored credentials.
61
+ */
62
+ deleteAll(): Promise<void>;
63
+ /**
64
+ * List all providers with stored credentials.
65
+ * @returns Array of provider IDs that have stored credentials
66
+ */
67
+ listProviders(): Promise<AuthProviderId[]>;
68
+ /**
69
+ * Derive the encryption key from salt and machine-specific entropy.
70
+ * Uses PBKDF2 with random salt + hostname + username.
71
+ * @param salt - The random salt (32 bytes)
72
+ * @returns The derived 256-bit encryption key
73
+ */
74
+ private deriveKey;
75
+ /**
76
+ * Encrypt data using AES-256-GCM.
77
+ * @param plaintext - The data to encrypt
78
+ * @param salt - The salt to use for key derivation
79
+ * @returns Buffer containing Salt + IV + Auth Tag + Ciphertext
80
+ */
81
+ private encrypt;
82
+ /**
83
+ * Decrypt data using AES-256-GCM.
84
+ * @param data - Buffer containing Salt + IV + Auth Tag + Ciphertext
85
+ * @returns The decrypted plaintext
86
+ * @throws CredentialStoreCorruptedError if decryption fails
87
+ */
88
+ private decrypt;
89
+ /**
90
+ * Load the credentials store from the encrypted file.
91
+ * @returns The decrypted credentials store
92
+ * @throws CredentialStoreCorruptedError if the file exists but cannot be decrypted
93
+ */
94
+ private loadStore;
95
+ /**
96
+ * Save the credentials store to the encrypted file.
97
+ * Sets restrictive file permissions (0600 - owner read/write only).
98
+ * @param store - The credentials store to save
99
+ */
100
+ private saveStore;
101
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Storage module exports.
3
+ *
4
+ * @module storage
5
+ */
6
+ export type { ICredentialStore, IStorageBackend } from './types.js';
7
+ export { CredentialStore, createCredentialStore } from './credential-store.js';
8
+ export type { CredentialStoreOptions } from './credential-store.js';
9
+ export { MemoryBackend } from './memory-backend.js';
10
+ export { EncryptedFileBackend, CredentialStoreCorruptedError } from './encrypted-file-backend.js';
11
+ export { KeychainBackend } from './keychain-backend.js';
12
+ export type { KeytarModule } from './keychain-backend.js';
@@ -0,0 +1,80 @@
1
+ /**
2
+ * OS keychain storage backend.
3
+ *
4
+ * Uses macOS Keychain, Windows Credential Manager, or Linux Secret Service
5
+ * via the keytar package for secure credential storage.
6
+ *
7
+ * @module storage/keychain-backend
8
+ */
9
+ import type { AuthProviderId, StorageBackendType, StoredCredentials } from '../types.js';
10
+ import type { IStorageBackend } from './types.js';
11
+ /**
12
+ * Keytar module interface (subset of keytar API we use).
13
+ */
14
+ export interface KeytarModule {
15
+ setPassword(service: string, account: string, password: string): Promise<void>;
16
+ getPassword(service: string, account: string): Promise<string | null>;
17
+ deletePassword(service: string, account: string): Promise<boolean>;
18
+ findCredentials(service: string): Promise<Array<{
19
+ account: string;
20
+ password: string;
21
+ }>>;
22
+ }
23
+ /**
24
+ * Keychain storage backend implementation.
25
+ *
26
+ * Uses the system keychain for secure credential storage:
27
+ * - macOS: Keychain Access
28
+ * - Windows: Credential Manager
29
+ * - Linux: Secret Service (libsecret)
30
+ *
31
+ * Handles keychain unavailability gracefully by returning false from isAvailable().
32
+ */
33
+ export declare class KeychainBackend implements IStorageBackend {
34
+ readonly type: StorageBackendType;
35
+ private keytar;
36
+ private keytarLoadAttempted;
37
+ private keytarLoadError;
38
+ /**
39
+ * Lazily load keytar module.
40
+ * Uses dynamic import to handle cases where keytar is not installed.
41
+ */
42
+ private loadKeytar;
43
+ /**
44
+ * Get account name for a provider.
45
+ */
46
+ private getAccountName;
47
+ /**
48
+ * Check if the keychain backend is available on this system.
49
+ * Returns false if keytar is not installed or keychain access fails.
50
+ */
51
+ isAvailable(): Promise<boolean>;
52
+ /**
53
+ * Store credentials for a provider in the system keychain.
54
+ */
55
+ store(providerId: AuthProviderId, credentials: StoredCredentials): Promise<void>;
56
+ /**
57
+ * Retrieve credentials for a provider from the system keychain.
58
+ */
59
+ retrieve(providerId: AuthProviderId): Promise<StoredCredentials | null>;
60
+ /**
61
+ * Delete credentials for a provider from the system keychain.
62
+ */
63
+ delete(providerId: AuthProviderId): Promise<void>;
64
+ /**
65
+ * Delete all stored credentials from the system keychain.
66
+ */
67
+ deleteAll(): Promise<void>;
68
+ /**
69
+ * List all providers with stored credentials.
70
+ */
71
+ listProviders(): Promise<AuthProviderId[]>;
72
+ /**
73
+ * Add a provider to the internal providers list.
74
+ */
75
+ private addToProvidersList;
76
+ /**
77
+ * Remove a provider from the internal providers list.
78
+ */
79
+ private removeFromProvidersList;
80
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * In-memory storage backend for testing.
3
+ *
4
+ * This backend stores credentials in a Map and is primarily intended
5
+ * for testing purposes. All operations are synchronous but return
6
+ * Promises for interface compatibility with other backends.
7
+ *
8
+ * @module storage/memory-backend
9
+ */
10
+ import type { AuthProviderId, StorageBackendType, StoredCredentials } from '../types.js';
11
+ import type { IStorageBackend } from './types.js';
12
+ /**
13
+ * In-memory storage backend implementation.
14
+ *
15
+ * Uses a Map<AuthProviderId, StoredCredentials> for storage.
16
+ * This backend is always available and is primarily used for testing.
17
+ */
18
+ export declare class MemoryBackend implements IStorageBackend {
19
+ readonly type: StorageBackendType;
20
+ /** Internal storage map */
21
+ private readonly storage;
22
+ /**
23
+ * Check if the backend is available.
24
+ * Memory backend is always available.
25
+ * @returns Always resolves to true
26
+ */
27
+ isAvailable(): Promise<boolean>;
28
+ /**
29
+ * Store credentials for a provider.
30
+ * @param providerId - The provider identifier
31
+ * @param credentials - The credentials to store
32
+ */
33
+ store(providerId: AuthProviderId, credentials: StoredCredentials): Promise<void>;
34
+ /**
35
+ * Retrieve credentials for a provider.
36
+ * @param providerId - The provider identifier
37
+ * @returns The stored credentials or null if not found
38
+ */
39
+ retrieve(providerId: AuthProviderId): Promise<StoredCredentials | null>;
40
+ /**
41
+ * Delete credentials for a provider.
42
+ * @param providerId - The provider identifier
43
+ */
44
+ delete(providerId: AuthProviderId): Promise<void>;
45
+ /**
46
+ * Delete all stored credentials.
47
+ */
48
+ deleteAll(): Promise<void>;
49
+ /**
50
+ * List all providers with stored credentials.
51
+ * @returns Array of provider IDs that have stored credentials
52
+ */
53
+ listProviders(): Promise<AuthProviderId[]>;
54
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Storage interface definitions.
3
+ *
4
+ * @module storage/types
5
+ */
6
+ import type { AuthProviderId, StorageBackendType, StoredCredentials } from '../types.js';
7
+ /**
8
+ * Low-level storage backend interface.
9
+ * Implemented by keychain, encrypted file, and memory backends.
10
+ */
11
+ export interface IStorageBackend {
12
+ /** Backend type identifier */
13
+ readonly type: StorageBackendType;
14
+ /** Check if the backend is available on this system */
15
+ isAvailable(): Promise<boolean>;
16
+ /** Store credentials for a provider */
17
+ store(providerId: AuthProviderId, credentials: StoredCredentials): Promise<void>;
18
+ /** Retrieve credentials for a provider */
19
+ retrieve(providerId: AuthProviderId): Promise<StoredCredentials | null>;
20
+ /** Delete credentials for a provider */
21
+ delete(providerId: AuthProviderId): Promise<void>;
22
+ /** Delete all stored credentials */
23
+ deleteAll(): Promise<void>;
24
+ /** List all providers with stored credentials */
25
+ listProviders(): Promise<AuthProviderId[]>;
26
+ }
27
+ /**
28
+ * Secure credential storage interface.
29
+ * Facade that selects the best available backend.
30
+ */
31
+ export interface ICredentialStore {
32
+ /** Store credentials for a provider */
33
+ store(providerId: AuthProviderId, credentials: StoredCredentials): Promise<void>;
34
+ /** Retrieve credentials for a provider */
35
+ retrieve(providerId: AuthProviderId): Promise<StoredCredentials | null>;
36
+ /** Delete credentials for a provider */
37
+ delete(providerId: AuthProviderId): Promise<void>;
38
+ /** Delete all stored credentials */
39
+ deleteAll(): Promise<void>;
40
+ /** List all providers with stored credentials */
41
+ listProviders(): Promise<AuthProviderId[]>;
42
+ /** Get the active storage backend type */
43
+ getBackendType(): StorageBackendType;
44
+ }
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Token lifecycle management.
3
+ *
4
+ * Handles token storage, refresh, and expiration.
5
+ * Implements proactive token refresh and concurrent refresh serialization.
6
+ *
7
+ * @module token-manager
8
+ */
9
+ import type { AuthProviderId, TokenResponse, TokenStatus } from './types.js';
10
+ import type { ICredentialStore } from './storage/types.js';
11
+ import type { IAuthProvider } from './providers/types.js';
12
+ /**
13
+ * Default token refresh threshold in milliseconds (5 minutes).
14
+ * Tokens will be proactively refreshed when they expire within this threshold.
15
+ */
16
+ export declare const DEFAULT_REFRESH_THRESHOLD_MS: number;
17
+ /**
18
+ * Token lifecycle management interface.
19
+ */
20
+ export interface ITokenManager {
21
+ /** Get a valid access token, refreshing if necessary */
22
+ getAccessToken(providerId: AuthProviderId): Promise<string | null>;
23
+ /** Store new tokens from an OAuth response */
24
+ storeTokens(providerId: AuthProviderId, tokens: TokenResponse): Promise<void>;
25
+ /** Check if tokens exist and are valid for a provider */
26
+ hasValidTokens(providerId: AuthProviderId): Promise<boolean>;
27
+ /** Force refresh tokens for a provider */
28
+ forceRefresh(providerId: AuthProviderId): Promise<string | null>;
29
+ /** Clear tokens for a provider (triggers re-auth) */
30
+ clearTokens(providerId: AuthProviderId): Promise<void>;
31
+ /** Get token status for all providers */
32
+ getStatus(): Promise<Map<AuthProviderId, TokenStatus>>;
33
+ }
34
+ /**
35
+ * Provider resolver function type.
36
+ * Used to get provider instances for token refresh operations.
37
+ */
38
+ export type ProviderResolver = (providerId: AuthProviderId) => IAuthProvider | null;
39
+ /**
40
+ * Options for creating a token manager.
41
+ */
42
+ export interface TokenManagerOptions {
43
+ /** Credential store for persisting tokens */
44
+ credentialStore: ICredentialStore;
45
+ /** Function to resolve provider instances */
46
+ providerResolver: ProviderResolver;
47
+ /** Token refresh threshold in milliseconds (default: 5 minutes) */
48
+ refreshThresholdMs?: number;
49
+ }
50
+ /**
51
+ * Token manager implementation.
52
+ *
53
+ * Manages token lifecycle including:
54
+ * - Proactive token refresh when tokens are near expiration
55
+ * - Concurrent refresh serialization (only one refresh per provider at a time)
56
+ * - Automatic credential cleanup on refresh failure
57
+ * - Refresh token rotation handling
58
+ */
59
+ export declare class TokenManager implements ITokenManager {
60
+ private readonly credentialStore;
61
+ private readonly providerResolver;
62
+ private readonly refreshThresholdMs;
63
+ /**
64
+ * Map of provider IDs to pending refresh promises.
65
+ * Used to serialize concurrent refresh requests.
66
+ */
67
+ private readonly pendingRefreshes;
68
+ /**
69
+ * Create a new token manager.
70
+ * @param options - Configuration options
71
+ */
72
+ constructor(options: TokenManagerOptions);
73
+ /**
74
+ * Get a valid access token, refreshing if necessary.
75
+ *
76
+ * If the token is within the refresh threshold of expiration, it will be
77
+ * proactively refreshed before returning.
78
+ *
79
+ * @param providerId - The provider identifier
80
+ * @returns The access token or null if not available
81
+ */
82
+ getAccessToken(providerId: AuthProviderId): Promise<string | null>;
83
+ /**
84
+ * Store new tokens from an OAuth response.
85
+ *
86
+ * Converts the token response to stored credentials format and persists them.
87
+ * Preserves the existing refresh token if the new response doesn't include one
88
+ * (some providers only return refresh tokens on initial auth, not on refresh).
89
+ *
90
+ * @param providerId - The provider identifier
91
+ * @param tokens - The token response from the OAuth provider
92
+ */
93
+ storeTokens(providerId: AuthProviderId, tokens: TokenResponse): Promise<void>;
94
+ /**
95
+ * Check if tokens exist and are valid for a provider.
96
+ *
97
+ * A token is considered valid if:
98
+ * - Credentials exist for the provider
99
+ * - The access token is not expired
100
+ *
101
+ * @param providerId - The provider identifier
102
+ * @returns True if valid tokens exist
103
+ */
104
+ hasValidTokens(providerId: AuthProviderId): Promise<boolean>;
105
+ /**
106
+ * Force refresh tokens for a provider.
107
+ *
108
+ * Unlike getAccessToken, this always attempts a refresh regardless of
109
+ * the current token's expiration status.
110
+ *
111
+ * @param providerId - The provider identifier
112
+ * @returns The new access token or null if refresh failed
113
+ */
114
+ forceRefresh(providerId: AuthProviderId): Promise<string | null>;
115
+ /**
116
+ * Clear tokens for a provider.
117
+ *
118
+ * This triggers re-authentication on the next token request.
119
+ *
120
+ * @param providerId - The provider identifier
121
+ */
122
+ clearTokens(providerId: AuthProviderId): Promise<void>;
123
+ /**
124
+ * Get token status for all providers.
125
+ *
126
+ * @returns Map of provider IDs to their token status
127
+ */
128
+ getStatus(): Promise<Map<AuthProviderId, TokenStatus>>;
129
+ /**
130
+ * Check if credentials are expired.
131
+ *
132
+ * @param credentials - The stored credentials
133
+ * @returns True if the token is expired
134
+ */
135
+ private isExpired;
136
+ /**
137
+ * Check if credentials should be proactively refreshed.
138
+ *
139
+ * Returns true if the token will expire within the refresh threshold.
140
+ *
141
+ * @param credentials - The stored credentials
142
+ * @returns True if the token should be refreshed
143
+ */
144
+ private shouldRefresh;
145
+ /**
146
+ * Internal token refresh implementation with concurrent request serialization.
147
+ *
148
+ * Ensures only one refresh operation occurs at a time per provider.
149
+ * If a refresh is already in progress, returns the pending promise.
150
+ *
151
+ * @param providerId - The provider identifier
152
+ * @param credentials - The current stored credentials
153
+ * @returns The new access token or null if refresh failed
154
+ */
155
+ private refreshTokenInternal;
156
+ /**
157
+ * Execute the actual token refresh operation.
158
+ *
159
+ * @param providerId - The provider identifier
160
+ * @param refreshToken - The refresh token to use
161
+ * @returns The new access token or null if refresh failed
162
+ */
163
+ private executeRefresh;
164
+ }
165
+ /**
166
+ * Create a token manager with the given options.
167
+ *
168
+ * @param options - Configuration options
169
+ * @returns A new token manager instance
170
+ */
171
+ export declare function createTokenManager(options: TokenManagerOptions): TokenManager;