@iterable/cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMMANDS.md +1574 -0
- package/LICENSE.md +21 -0
- package/README.md +194 -0
- package/dist/commands/campaigns.d.ts +3 -0
- package/dist/commands/campaigns.d.ts.map +1 -0
- package/dist/commands/campaigns.js +106 -0
- package/dist/commands/campaigns.js.map +1 -0
- package/dist/commands/catalogs.d.ts +3 -0
- package/dist/commands/catalogs.d.ts.map +1 -0
- package/dist/commands/catalogs.js +99 -0
- package/dist/commands/catalogs.js.map +1 -0
- package/dist/commands/events.d.ts +3 -0
- package/dist/commands/events.d.ts.map +1 -0
- package/dist/commands/events.js +33 -0
- package/dist/commands/events.js.map +1 -0
- package/dist/commands/experiments.d.ts +3 -0
- package/dist/commands/experiments.d.ts.map +1 -0
- package/dist/commands/experiments.js +33 -0
- package/dist/commands/experiments.js.map +1 -0
- package/dist/commands/export.d.ts +3 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +33 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/journeys.d.ts +3 -0
- package/dist/commands/journeys.d.ts.map +1 -0
- package/dist/commands/journeys.js +21 -0
- package/dist/commands/journeys.js.map +1 -0
- package/dist/commands/lists.d.ts +3 -0
- package/dist/commands/lists.d.ts.map +1 -0
- package/dist/commands/lists.js +64 -0
- package/dist/commands/lists.js.map +1 -0
- package/dist/commands/messaging.d.ts +3 -0
- package/dist/commands/messaging.d.ts.map +1 -0
- package/dist/commands/messaging.js +120 -0
- package/dist/commands/messaging.js.map +1 -0
- package/dist/commands/registry.d.ts +46 -0
- package/dist/commands/registry.d.ts.map +1 -0
- package/dist/commands/registry.js +42 -0
- package/dist/commands/registry.js.map +1 -0
- package/dist/commands/snippets.d.ts +3 -0
- package/dist/commands/snippets.d.ts.map +1 -0
- package/dist/commands/snippets.js +42 -0
- package/dist/commands/snippets.js.map +1 -0
- package/dist/commands/subscriptions.d.ts +3 -0
- package/dist/commands/subscriptions.d.ts.map +1 -0
- package/dist/commands/subscriptions.js +40 -0
- package/dist/commands/subscriptions.js.map +1 -0
- package/dist/commands/templates.d.ts +3 -0
- package/dist/commands/templates.d.ts.map +1 -0
- package/dist/commands/templates.js +160 -0
- package/dist/commands/templates.js.map +1 -0
- package/dist/commands/transforms.d.ts +3 -0
- package/dist/commands/transforms.d.ts.map +1 -0
- package/dist/commands/transforms.js +24 -0
- package/dist/commands/transforms.js.map +1 -0
- package/dist/commands/types.d.ts +40 -0
- package/dist/commands/types.d.ts.map +1 -0
- package/dist/commands/types.js +15 -0
- package/dist/commands/types.js.map +1 -0
- package/dist/commands/users.d.ts +3 -0
- package/dist/commands/users.d.ts.map +1 -0
- package/dist/commands/users.js +103 -0
- package/dist/commands/users.js.map +1 -0
- package/dist/commands/webhooks.d.ts +3 -0
- package/dist/commands/webhooks.d.ts.map +1 -0
- package/dist/commands/webhooks.js +21 -0
- package/dist/commands/webhooks.js.map +1 -0
- package/dist/config.d.ts +14 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +60 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +11 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +21 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +107 -0
- package/dist/index.js.map +1 -0
- package/dist/key-manager.d.ts +280 -0
- package/dist/key-manager.d.ts.map +1 -0
- package/dist/key-manager.js +989 -0
- package/dist/key-manager.js.map +1 -0
- package/dist/keys-cli.d.ts +3 -0
- package/dist/keys-cli.d.ts.map +1 -0
- package/dist/keys-cli.js +396 -0
- package/dist/keys-cli.js.map +1 -0
- package/dist/output.d.ts +5 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +104 -0
- package/dist/output.js.map +1 -0
- package/dist/parser.d.ts +26 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +281 -0
- package/dist/parser.js.map +1 -0
- package/dist/router.d.ts +20 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +137 -0
- package/dist/router.js.map +1 -0
- package/dist/utils/cli-env.d.ts +10 -0
- package/dist/utils/cli-env.d.ts.map +1 -0
- package/dist/utils/cli-env.js +21 -0
- package/dist/utils/cli-env.js.map +1 -0
- package/dist/utils/command-info.d.ts +7 -0
- package/dist/utils/command-info.d.ts.map +1 -0
- package/dist/utils/command-info.js +36 -0
- package/dist/utils/command-info.js.map +1 -0
- package/dist/utils/detect-background.d.ts +3 -0
- package/dist/utils/detect-background.d.ts.map +1 -0
- package/dist/utils/detect-background.js +33 -0
- package/dist/utils/detect-background.js.map +1 -0
- package/dist/utils/endpoint-prompt.d.ts +5 -0
- package/dist/utils/endpoint-prompt.d.ts.map +1 -0
- package/dist/utils/endpoint-prompt.js +98 -0
- package/dist/utils/endpoint-prompt.js.map +1 -0
- package/dist/utils/formatting.d.ts +3 -0
- package/dist/utils/formatting.d.ts.map +1 -0
- package/dist/utils/formatting.js +5 -0
- package/dist/utils/formatting.js.map +1 -0
- package/dist/utils/password-prompt.d.ts +3 -0
- package/dist/utils/password-prompt.d.ts.map +1 -0
- package/dist/utils/password-prompt.js +21 -0
- package/dist/utils/password-prompt.js.map +1 -0
- package/dist/utils/sanitize.d.ts +13 -0
- package/dist/utils/sanitize.d.ts.map +1 -0
- package/dist/utils/sanitize.js +23 -0
- package/dist/utils/sanitize.js.map +1 -0
- package/dist/utils/theme.d.ts +11 -0
- package/dist/utils/theme.d.ts.map +1 -0
- package/dist/utils/theme.js +14 -0
- package/dist/utils/theme.js.map +1 -0
- package/dist/utils/ui.d.ts +22 -0
- package/dist/utils/ui.d.ts.map +1 -0
- package/dist/utils/ui.js +107 -0
- package/dist/utils/ui.js.map +1 -0
- package/dist/utils/url.d.ts +13 -0
- package/dist/utils/url.d.ts.map +1 -0
- package/dist/utils/url.js +20 -0
- package/dist/utils/url.js.map +1 -0
- package/package.json +90 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secure API Key Management with cross-platform support
|
|
3
|
+
*
|
|
4
|
+
* This module provides secure storage and management of multiple Iterable API keys.
|
|
5
|
+
*
|
|
6
|
+
* Storage Strategy:
|
|
7
|
+
* - macOS: API keys in Keychain, metadata in ~/.iterable/keys.json
|
|
8
|
+
* - Windows: API keys encrypted with DPAPI in ~/.iterable/keys.json
|
|
9
|
+
* - Linux: API keys and metadata in ~/.iterable/keys.json (mode 0o600)
|
|
10
|
+
* - Lock file: ~/.iterable/keys.lock prevents concurrent modifications
|
|
11
|
+
*
|
|
12
|
+
* Security Features:
|
|
13
|
+
* - API key format validation (32-char lowercase hex)
|
|
14
|
+
* - HTTPS-only URL validation (except localhost)
|
|
15
|
+
* - Duplicate key detection (both names and values)
|
|
16
|
+
* - File-based locking for concurrent access protection
|
|
17
|
+
* - Restrictive file permissions where supported (Linux/macOS)
|
|
18
|
+
*/
|
|
19
|
+
export type SecurityExecutor = (args: string[]) => Promise<string>;
|
|
20
|
+
export interface ApiKeyMetadata {
|
|
21
|
+
/** Unique identifier for this key */
|
|
22
|
+
id: string;
|
|
23
|
+
/** User-friendly name for this key */
|
|
24
|
+
name: string;
|
|
25
|
+
/** Iterable API base URL (e.g., https://api.iterable.com or https://api.eu.iterable.com) */
|
|
26
|
+
baseUrl: string;
|
|
27
|
+
/** ISO timestamp when key was created */
|
|
28
|
+
created: string;
|
|
29
|
+
/** ISO timestamp when key was last updated */
|
|
30
|
+
updated?: string;
|
|
31
|
+
/** Whether this is the currently active key */
|
|
32
|
+
isActive: boolean;
|
|
33
|
+
/** Optional per-key environment overrides (extensible for future vars) */
|
|
34
|
+
env?: Record<string, string>;
|
|
35
|
+
/** API key value (only present when not using Keychain storage) */
|
|
36
|
+
apiKey?: string;
|
|
37
|
+
/** Encrypted API key (Windows DPAPI) */
|
|
38
|
+
encryptedApiKey?: string;
|
|
39
|
+
}
|
|
40
|
+
export declare class KeyManager {
|
|
41
|
+
private readonly configDir;
|
|
42
|
+
private readonly metadataFile;
|
|
43
|
+
private readonly lockFile;
|
|
44
|
+
private store;
|
|
45
|
+
private saveLock;
|
|
46
|
+
private readonly execSecurity;
|
|
47
|
+
private readonly storageMethod;
|
|
48
|
+
/**
|
|
49
|
+
* Create a new KeyManager instance
|
|
50
|
+
*
|
|
51
|
+
* @param configDir - Optional custom config directory (defaults to ~/.iterable)
|
|
52
|
+
* @param execSecurity - Optional security command executor (for dependency injection in tests)
|
|
53
|
+
*/
|
|
54
|
+
constructor(configDir?: string, execSecurity?: SecurityExecutor);
|
|
55
|
+
/**
|
|
56
|
+
* Validate metadata against keychain and clean up orphaned entries (macOS only)
|
|
57
|
+
*
|
|
58
|
+
* Checks if each key in metadata still exists in the keychain.
|
|
59
|
+
* Removes any metadata entries that no longer have corresponding keychain entries.
|
|
60
|
+
* This prevents sync issues when keychain entries are manually deleted.
|
|
61
|
+
*
|
|
62
|
+
* @returns Array of cleaned up key names (if any)
|
|
63
|
+
*/
|
|
64
|
+
private validateAndCleanup;
|
|
65
|
+
/**
|
|
66
|
+
* Acquire an exclusive lock for metadata operations
|
|
67
|
+
*
|
|
68
|
+
* Uses atomic file creation (wx flag = O_CREAT | O_EXCL) to prevent concurrent
|
|
69
|
+
* modifications. Retries up to 20 times with 50ms delays (1 second total).
|
|
70
|
+
* Fails safely if lock cannot be acquired rather than forcefully stealing it.
|
|
71
|
+
*
|
|
72
|
+
* Lock contention is rare since writes only happen during explicit user operations
|
|
73
|
+
* (add, delete, activate keys) - no automatic updates.
|
|
74
|
+
*
|
|
75
|
+
* @returns An async unlock function that should be called in a finally block
|
|
76
|
+
* @throws {Error} If lock cannot be acquired after 1 second timeout
|
|
77
|
+
*/
|
|
78
|
+
private acquireLock;
|
|
79
|
+
/**
|
|
80
|
+
* Initialize the key manager
|
|
81
|
+
*
|
|
82
|
+
* Creates the configuration directory (mode 0o700) and loads existing metadata.
|
|
83
|
+
* If the metadata file doesn't exist, creates a new empty store.
|
|
84
|
+
* Uses idiomatic Node.js approach: try to read, handle ENOENT if file missing.
|
|
85
|
+
* This method must be called before any other key management operations.
|
|
86
|
+
*
|
|
87
|
+
* @throws {Error} If the configuration directory cannot be created or metadata is corrupt
|
|
88
|
+
*/
|
|
89
|
+
initialize(): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Load metadata from disk (with locking)
|
|
92
|
+
*/
|
|
93
|
+
private loadMetadata;
|
|
94
|
+
/**
|
|
95
|
+
* Create a backup of the metadata file before destructive operations
|
|
96
|
+
*/
|
|
97
|
+
private backupMetadata;
|
|
98
|
+
/**
|
|
99
|
+
* Save metadata to disk (with locking to prevent concurrent modifications)
|
|
100
|
+
*/
|
|
101
|
+
private saveMetadata;
|
|
102
|
+
/**
|
|
103
|
+
* Generate a unique ID for a key
|
|
104
|
+
* Uses UUID v4 for guaranteed uniqueness and no collision risk
|
|
105
|
+
*/
|
|
106
|
+
private generateId;
|
|
107
|
+
/**
|
|
108
|
+
* Validate API key format
|
|
109
|
+
*/
|
|
110
|
+
private validateApiKey;
|
|
111
|
+
/**
|
|
112
|
+
* Validate and normalize base URL
|
|
113
|
+
*/
|
|
114
|
+
private validateBaseUrl;
|
|
115
|
+
/**
|
|
116
|
+
* Encrypt data using Windows DPAPI
|
|
117
|
+
*
|
|
118
|
+
* Security: Uses native C++ bindings to Windows DPAPI (Data Protection API).
|
|
119
|
+
* - No shell execution or code evaluation
|
|
120
|
+
* - Encrypted data can only be decrypted by the same user on the same machine
|
|
121
|
+
* - Uses CurrentUser scope for user-level protection
|
|
122
|
+
* - No optional entropy parameter (null) for simplicity
|
|
123
|
+
*
|
|
124
|
+
* @param text - Plain text to encrypt (validated as 32-char hex by caller)
|
|
125
|
+
* @returns Base64-encoded encrypted blob
|
|
126
|
+
* @throws {Error} If DPAPI encryption fails or platform is not Windows
|
|
127
|
+
*/
|
|
128
|
+
private encryptWindows;
|
|
129
|
+
/**
|
|
130
|
+
* Decrypt data using Windows DPAPI
|
|
131
|
+
*
|
|
132
|
+
* Security: Uses native C++ bindings to Windows DPAPI.
|
|
133
|
+
* - No shell execution or code evaluation
|
|
134
|
+
* - Only the user who encrypted the data can decrypt it
|
|
135
|
+
* - Validates base64 input before decryption
|
|
136
|
+
*
|
|
137
|
+
* @param encryptedBase64 - Base64-encoded encrypted blob
|
|
138
|
+
* @returns Decrypted plain text
|
|
139
|
+
* @throws {Error} If DPAPI decryption fails, data is corrupt, or platform is not Windows
|
|
140
|
+
*/
|
|
141
|
+
private decryptWindows;
|
|
142
|
+
/**
|
|
143
|
+
* Save (add or update) an API key
|
|
144
|
+
*
|
|
145
|
+
* Private implementation that handles both add and update operations.
|
|
146
|
+
* If idOrName is provided, updates an existing key. Otherwise, adds a new key.
|
|
147
|
+
*
|
|
148
|
+
* @param name - User-friendly name for the key
|
|
149
|
+
* @param apiKey - The Iterable API key value
|
|
150
|
+
* @param baseUrl - Iterable API base URL
|
|
151
|
+
* @param envOverrides - Environment variable overrides. If undefined, keeps existing env (update) or no env (add). If provided (even empty {}), replaces/clears env.
|
|
152
|
+
* @param idOrName - If provided, updates the existing key with this ID or name
|
|
153
|
+
* @returns The ID of the saved key
|
|
154
|
+
*/
|
|
155
|
+
private saveKey;
|
|
156
|
+
/**
|
|
157
|
+
* Add a new API key
|
|
158
|
+
*
|
|
159
|
+
* Stores an API key securely (Keychain on macOS, encrypted on Windows, file on Linux).
|
|
160
|
+
*
|
|
161
|
+
* @param name - User-friendly name for the key (must be unique)
|
|
162
|
+
* @param apiKey - 32-character lowercase hexadecimal Iterable API key
|
|
163
|
+
* @param baseUrl - Iterable API base URL (must be HTTPS)
|
|
164
|
+
* @param envOverrides - Optional environment variable overrides for this key
|
|
165
|
+
* @returns The unique ID generated for this key
|
|
166
|
+
* @throws {Error} If the key name already exists, validation fails, or storage fails
|
|
167
|
+
*/
|
|
168
|
+
addKey(name: string, apiKey: string, baseUrl: string, envOverrides?: Record<string, string>): Promise<string>;
|
|
169
|
+
/**
|
|
170
|
+
* Update an existing API key
|
|
171
|
+
*
|
|
172
|
+
* Updates all properties of an existing key including name, API key value, base URL, and environment overrides.
|
|
173
|
+
*
|
|
174
|
+
* @param idOrName - The unique ID or name of the key to update
|
|
175
|
+
* @param name - New name for the key (must be unique unless unchanged)
|
|
176
|
+
* @param apiKey - New API key value (can be the same as existing)
|
|
177
|
+
* @param baseUrl - New Iterable API base URL
|
|
178
|
+
* @param envOverrides - New environment variable overrides (undefined = keep existing, {} = clear)
|
|
179
|
+
* @returns The ID of the updated key
|
|
180
|
+
* @throws {Error} If the key is not found, name conflict, validation fails, or storage fails
|
|
181
|
+
*/
|
|
182
|
+
updateKey(idOrName: string, name: string, apiKey: string, baseUrl: string, envOverrides?: Record<string, string>): Promise<string>;
|
|
183
|
+
/**
|
|
184
|
+
* List all keys (metadata only, not the actual keys)
|
|
185
|
+
*
|
|
186
|
+
* Returns metadata for all stored API keys including names, IDs, base URLs,
|
|
187
|
+
* timestamps, and active status. Does NOT return the actual API key values.
|
|
188
|
+
*
|
|
189
|
+
* @returns Array of API key metadata
|
|
190
|
+
* @throws {Error} If the key store is not initialized
|
|
191
|
+
*/
|
|
192
|
+
listKeys(): Promise<ApiKeyMetadata[]>;
|
|
193
|
+
/**
|
|
194
|
+
* Get key metadata by ID
|
|
195
|
+
*
|
|
196
|
+
* @param idOrName - The unique ID or user-friendly name of the key
|
|
197
|
+
* @returns The key metadata, or null if not found
|
|
198
|
+
*/
|
|
199
|
+
getKeyMetadata(idOrName: string): Promise<ApiKeyMetadata | null>;
|
|
200
|
+
/**
|
|
201
|
+
* Get a key by ID or name
|
|
202
|
+
*
|
|
203
|
+
* Retrieves the actual API key value from storage.
|
|
204
|
+
*
|
|
205
|
+
* @param idOrName - The unique ID or user-friendly name of the key
|
|
206
|
+
* @returns The API key value, or null if not found
|
|
207
|
+
* @throws {Error} If storage access fails
|
|
208
|
+
*/
|
|
209
|
+
getKey(idOrName: string): Promise<string | null>;
|
|
210
|
+
/**
|
|
211
|
+
* Get the currently active key
|
|
212
|
+
*
|
|
213
|
+
* Retrieves the API key value for whichever key is currently marked as active.
|
|
214
|
+
* Only one key can be active at a time.
|
|
215
|
+
*
|
|
216
|
+
* @returns The active API key value, or null if no key is active
|
|
217
|
+
* @throws {Error} If storage access fails
|
|
218
|
+
*/
|
|
219
|
+
getActiveKey(): Promise<string | null>;
|
|
220
|
+
/**
|
|
221
|
+
* Get the active key metadata
|
|
222
|
+
*
|
|
223
|
+
* Returns metadata for the currently active key without retrieving the
|
|
224
|
+
* actual API key value.
|
|
225
|
+
*
|
|
226
|
+
* @returns The active key metadata, or null if no key is active
|
|
227
|
+
* @throws {Error} If the key store is not initialized
|
|
228
|
+
*/
|
|
229
|
+
getActiveKeyMetadata(): Promise<ApiKeyMetadata | null>;
|
|
230
|
+
/**
|
|
231
|
+
* Set a key as active by ID or name
|
|
232
|
+
*
|
|
233
|
+
* Marks the specified key as active and deactivates all other keys.
|
|
234
|
+
* The active key's base URL and API key will be used by the CLI.
|
|
235
|
+
* Only one key can be active at a time.
|
|
236
|
+
*
|
|
237
|
+
* @param idOrName - The unique ID or user-friendly name of the key to activate
|
|
238
|
+
* @throws {Error} If the key is not found or the store is not initialized
|
|
239
|
+
*/
|
|
240
|
+
setActiveKey(idOrName: string): Promise<void>;
|
|
241
|
+
/**
|
|
242
|
+
* Delete a key by ID
|
|
243
|
+
*
|
|
244
|
+
* Removes a key from storage and the metadata store.
|
|
245
|
+
* Note: Only accepts key ID (not name) since IDs are guaranteed unique.
|
|
246
|
+
*
|
|
247
|
+
* @param id - The unique ID of the key to delete
|
|
248
|
+
* @throws {Error} If the key is not found or the store is not initialized
|
|
249
|
+
*/
|
|
250
|
+
deleteKey(id: string): Promise<void>;
|
|
251
|
+
/**
|
|
252
|
+
* Check if any keys exist
|
|
253
|
+
*
|
|
254
|
+
* Returns true if at least one API key has been stored in the key manager.
|
|
255
|
+
*
|
|
256
|
+
* @returns True if keys exist, false otherwise
|
|
257
|
+
* @throws {Error} If the key store is not initialized
|
|
258
|
+
*/
|
|
259
|
+
hasKeys(): Promise<boolean>;
|
|
260
|
+
/** Check if any key is currently marked as active (metadata only, no keychain call). */
|
|
261
|
+
hasActiveKey(): Promise<boolean>;
|
|
262
|
+
/** Deactivate all keys (no key will be active). */
|
|
263
|
+
deactivateAllKeys(): Promise<void>;
|
|
264
|
+
/**
|
|
265
|
+
* Find a key by its actual API key value
|
|
266
|
+
*
|
|
267
|
+
* Checks all stored keys to see if the given API key value already exists.
|
|
268
|
+
* Useful for preventing duplicate key values.
|
|
269
|
+
*
|
|
270
|
+
* @param apiKeyValue - The API key value to search for
|
|
271
|
+
* @returns The metadata of the matching key, or null if not found
|
|
272
|
+
* @throws {Error} If storage access fails
|
|
273
|
+
*/
|
|
274
|
+
findKeyByValue(apiKeyValue: string): Promise<ApiKeyMetadata | null>;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Get the singleton KeyManager instance
|
|
278
|
+
*/
|
|
279
|
+
export declare function getKeyManager(): KeyManager;
|
|
280
|
+
//# sourceMappingURL=key-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-manager.d.ts","sourceRoot":"","sources":["../src/key-manager.ts"],"names":[],"mappings":"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"}
|