@vercel/cli-auth 0.2.0 → 0.3.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.
@@ -1,29 +1,32 @@
1
- import { z } from 'zod/mini';
2
- declare const Credentials: z.ZodMiniObject<{
3
- /** An `access_token` obtained using the OAuth Device Authorization flow. */
4
- token: z.ZodMiniOptional<z.ZodMiniString<string>>;
5
- /** A `refresh_token` obtained using the OAuth Device Authorization flow. */
6
- refreshToken: z.ZodMiniOptional<z.ZodMiniString<string>>;
7
- /**
8
- * The absolute time (seconds) when the {@link Credentials.token} expires.
9
- * Used to optimistically check if the token is still valid.
10
- */
11
- expiresAt: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
12
- /** Whether to skip writing the credentials to disk during {@link CredentialsStore.update} */
13
- skipWrite: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
14
- '// Note': z.ZodMiniOptional<z.ZodMiniString<string>>;
15
- '// Docs': z.ZodMiniOptional<z.ZodMiniString<string>>;
16
- }, z.core.$strip>;
17
- export type Credentials = z.infer<typeof Credentials>;
18
- /**
19
- * Returns in which directory the config should be present
20
- * @internal Should only be used in {@link CredentialsStore} or tests.
21
- */
22
- export declare function getGlobalPathConfig(dir: string): string;
23
- export declare function CredentialsStore(dir: string): {
1
+ import * as cliConfig from '@vercel/cli-config';
2
+ import type { AuthConfig as SharedAuthConfig, CredStorage, CredentialsStorageLocation, GlobalConfig as SharedGlobalConfig } from '@vercel/cli-config';
3
+ type KeyringEntry = {
4
+ getPassword(): string | null;
5
+ setPassword(password: string): void;
6
+ deleteCredential(): boolean;
7
+ };
8
+ type KeyringEntryConstructor = new (service: string, account: string) => KeyringEntry;
9
+ type LoadKeyringModule = () => {
10
+ Entry: KeyringEntryConstructor;
11
+ };
12
+ export type GlobalConfig = Pick<SharedGlobalConfig, 'credStorage'>;
13
+ export type Credentials = Omit<SharedAuthConfig, 'tokenSource'>;
14
+ type PersistableAuthConfig = SharedAuthConfig;
15
+ export declare function resolveCredStorage(value: unknown): CredStorage;
16
+ export declare function readGlobalConfig(dir: string): GlobalConfig;
17
+ export declare function getCredStorage(dir: string, config?: GlobalConfig): CredStorage;
18
+ export declare function setLoadKeyringModuleForTesting(nextLoadKeyringModule?: LoadKeyringModule): void;
19
+ export declare function CredentialsStore(dir: string, config?: GlobalConfig): {
24
20
  configPath: string;
25
21
  get(): Credentials;
26
- /** Update the credentials store. If `skipWrite` is set, the update will be skipped. */
27
- update(config: Partial<Credentials>): void;
22
+ update(config: Partial<Credentials>): CredentialsStorageLocation | void;
23
+ delete(): void;
28
24
  };
25
+ export declare function readCredentials(dir: string, config?: GlobalConfig): Credentials;
26
+ export declare function readCliAuthConfig(dir: string, config?: GlobalConfig): Credentials;
27
+ export declare function writeCredentials(dir: string, credentials: Partial<Credentials>, config?: GlobalConfig): void | cliConfig.CredentialsStorageLocation;
28
+ export declare function persistCliAuthConfig(dir: string, authConfig: PersistableAuthConfig, config?: GlobalConfig): void | cliConfig.CredentialsStorageLocation;
29
+ export declare function clearCredentials(dir: string, config?: GlobalConfig): void;
30
+ export declare function clearAllCredentials(dir: string): void;
31
+ export declare function clearAllCredentialsStrict(dir: string): void;
29
32
  export {};
@@ -36,73 +36,393 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.getGlobalPathConfig = getGlobalPathConfig;
39
+ exports.resolveCredStorage = resolveCredStorage;
40
+ exports.readGlobalConfig = readGlobalConfig;
41
+ exports.getCredStorage = getCredStorage;
42
+ exports.setLoadKeyringModuleForTesting = setLoadKeyringModuleForTesting;
40
43
  exports.CredentialsStore = CredentialsStore;
41
- const node_path_1 = __importDefault(require("node:path"));
42
- const fs = __importStar(require("node:fs"));
43
- const node_os_1 = require("node:os");
44
- // NOTE: We are pinned on v5 because newer versions behave differently
45
- // when there are dots in the application name, eg. `com.vercel.cli` becomes `com.vercel`
46
- const xdg_app_paths_1 = __importDefault(require("xdg-app-paths"));
47
- const mini_1 = require("zod/mini");
48
- const Credentials = mini_1.z.object({
49
- /** An `access_token` obtained using the OAuth Device Authorization flow. */
50
- token: mini_1.z.optional(mini_1.z.string()),
51
- /** A `refresh_token` obtained using the OAuth Device Authorization flow. */
52
- refreshToken: mini_1.z.optional(mini_1.z.string()),
53
- /**
54
- * The absolute time (seconds) when the {@link Credentials.token} expires.
55
- * Used to optimistically check if the token is still valid.
56
- */
57
- expiresAt: mini_1.z.optional(mini_1.z.number()),
58
- /** Whether to skip writing the credentials to disk during {@link CredentialsStore.update} */
59
- skipWrite: mini_1.z.optional(mini_1.z.boolean()),
60
- '// Note': mini_1.z.optional(mini_1.z.string()),
61
- '// Docs': mini_1.z.optional(mini_1.z.string()),
62
- });
63
- /** Returns whether a directory exists */
64
- function isDirectory(path) {
44
+ exports.readCredentials = readCredentials;
45
+ exports.readCliAuthConfig = readCliAuthConfig;
46
+ exports.writeCredentials = writeCredentials;
47
+ exports.persistCliAuthConfig = persistCliAuthConfig;
48
+ exports.clearCredentials = clearCredentials;
49
+ exports.clearAllCredentials = clearAllCredentials;
50
+ exports.clearAllCredentialsStrict = clearAllCredentialsStrict;
51
+ const node_crypto_1 = require("node:crypto");
52
+ const node_assert_1 = __importDefault(require("node:assert"));
53
+ const cliConfig = __importStar(require("@vercel/cli-config"));
54
+ const KEYRING_SERVICE = 'com.vercel.vercel-cli';
55
+ const TOKEN_STORAGE_ENV = 'VERCEL_TOKEN_STORAGE';
56
+ const KEYRING_UNAVAILABLE_ENV = 'VERCEL_TEST_KEYRING_UNAVAILABLE';
57
+ const KEYRING_UNAVAILABLE_ERROR = 'OS keyring support is unavailable. Set `credStorage` to `auto` or `file` to store credentials in auth.json instead.';
58
+ const defaultLoadKeyringModule = () => require('@napi-rs/keyring');
59
+ let loadKeyringModule = defaultLoadKeyringModule;
60
+ function parseCredentials(value) {
61
+ const { tokenSource, ...credentials } = cliConfig.parseAuthConfig(value);
62
+ return credentials;
63
+ }
64
+ function formatCredStorageError(value, source) {
65
+ try {
66
+ cliConfig.parseGlobalConfig({ credStorage: value });
67
+ }
68
+ catch (error) {
69
+ if (error instanceof Error) {
70
+ return error.message.replace('`credStorage`', `\`${source}\``);
71
+ }
72
+ }
73
+ return `Invalid value for \`${source}\`: ${JSON.stringify(value)}. Expected one of: ${cliConfig.CRED_STORAGE_CONFIG_VALUES.map(storage => JSON.stringify(storage)).join(', ')}.`;
74
+ }
75
+ function parseCredStorage(value, source) {
76
+ if (typeof value === 'undefined') {
77
+ return cliConfig.DEFAULT_CRED_STORAGE;
78
+ }
79
+ try {
80
+ const config = cliConfig.parseGlobalConfig({ credStorage: value });
81
+ (0, node_assert_1.default)(config.credStorage !== undefined, 'expected credStorage value to be non-empty');
82
+ return config.credStorage;
83
+ }
84
+ catch {
85
+ throw new Error(formatCredStorageError(value, source));
86
+ }
87
+ }
88
+ function resolveCredStorage(value) {
89
+ return parseCredStorage(value, 'credStorage');
90
+ }
91
+ function readRuntimeFlags() {
92
+ return {
93
+ keyringUnavailableForTesting: process.env[KEYRING_UNAVAILABLE_ENV] === '1',
94
+ };
95
+ }
96
+ function resolveCliAuthConfig(dir, config) {
97
+ const runtimeFlags = readRuntimeFlags();
98
+ if (config?.credStorage) {
99
+ return {
100
+ ...runtimeFlags,
101
+ credStorage: resolveCredStorage(config.credStorage),
102
+ };
103
+ }
104
+ const credStorageOverride = process.env[TOKEN_STORAGE_ENV];
105
+ if (typeof credStorageOverride !== 'undefined') {
106
+ return {
107
+ ...runtimeFlags,
108
+ credStorage: parseCredStorage(credStorageOverride, TOKEN_STORAGE_ENV),
109
+ };
110
+ }
111
+ return {
112
+ ...runtimeFlags,
113
+ credStorage: resolveCredStorage(readGlobalConfig(dir).credStorage),
114
+ };
115
+ }
116
+ function readGlobalConfig(dir) {
117
+ const configPath = cliConfig.getConfigFilePath(dir);
65
118
  try {
66
- return fs.lstatSync(path).isDirectory();
119
+ const config = cliConfig.readGlobalConfigFile(configPath);
120
+ return {
121
+ credStorage: typeof config.credStorage === 'undefined'
122
+ ? undefined
123
+ : resolveCredStorage(config.credStorage),
124
+ };
67
125
  }
68
- catch (_) {
69
- // We don't care which kind of error occured, it isn't a directory anyway.
70
- return false;
126
+ catch (error) {
127
+ if (isENOENTError(error)) {
128
+ return {};
129
+ }
130
+ throw error;
71
131
  }
72
132
  }
73
- /**
74
- * Returns in which directory the config should be present
75
- * @internal Should only be used in {@link CredentialsStore} or tests.
133
+ function getCredStorage(dir, config) {
134
+ return resolveCliAuthConfig(dir, config).credStorage;
135
+ }
136
+ /** Return an account key suitable for use in keyrings for a given configPath.
137
+ *
138
+ * `auth.json` and the keychain are supposed to be equivalent and exchangeable.
139
+ * Since file-based credentials storage is configurable (via config path),
140
+ * we must ensure that keyring entries are keyed by config path also. We cannot
141
+ * use the full path as the key, so use a 16-byte prefix of sha256 hash of
142
+ * the path.
76
143
  */
77
- function getGlobalPathConfig(dir) {
78
- const vercelDirectories = (0, xdg_app_paths_1.default)(dir).dataDirs();
79
- const possibleConfigPaths = [
80
- ...vercelDirectories, // latest vercel directory
81
- node_path_1.default.join((0, node_os_1.homedir)(), '.now'), // legacy config in user's home directory
82
- ...(0, xdg_app_paths_1.default)('now').dataDirs(), // legacy XDG directory
83
- ];
84
- // The customPath flag is the preferred location,
85
- // followed by the vercel directory,
86
- // followed by the now directory.
87
- // If none of those exist, use the vercel directory.
88
- return (possibleConfigPaths.find(configPath => isDirectory(configPath)) ||
89
- vercelDirectories[0]);
90
- }
91
- function CredentialsStore(dir) {
92
- const configPath = node_path_1.default.join(getGlobalPathConfig(dir), 'auth.json');
144
+ function getKeyringAccount(configPath) {
145
+ const digest = (0, node_crypto_1.createHash)('sha256').update(configPath).digest('hex');
146
+ return `cli:${digest.slice(0, 16)}`;
147
+ }
148
+ function setLoadKeyringModuleForTesting(nextLoadKeyringModule) {
149
+ loadKeyringModule = nextLoadKeyringModule ?? defaultLoadKeyringModule;
150
+ }
151
+ function createKeyringEntry(configPath, runtimeFlags) {
152
+ try {
153
+ if (runtimeFlags.keyringUnavailableForTesting) {
154
+ throw new Error(`${KEYRING_UNAVAILABLE_ENV} is set`);
155
+ }
156
+ const { Entry } = loadKeyringModule();
157
+ return new Entry(KEYRING_SERVICE, getKeyringAccount(configPath));
158
+ }
159
+ catch (error) {
160
+ const wrappedError = new Error(KEYRING_UNAVAILABLE_ERROR);
161
+ wrappedError.cause = error;
162
+ throw wrappedError;
163
+ }
164
+ }
165
+ function isKeyringUnavailableError(error) {
166
+ return error instanceof Error && error.message === KEYRING_UNAVAILABLE_ERROR;
167
+ }
168
+ function readCredentialsFromFile(configPath) {
169
+ return cliConfig.readAuthFileConfig(configPath);
170
+ }
171
+ function isENOENTError(error) {
172
+ return (typeof error === 'object' &&
173
+ error !== null &&
174
+ 'code' in error &&
175
+ error.code === 'ENOENT');
176
+ }
177
+ function createMissingCredentialsError(configPath) {
178
+ const error = new Error(`ENOENT: no such file or directory, open '${configPath}'`);
179
+ Object.assign(error, { code: 'ENOENT' });
180
+ return error;
181
+ }
182
+ function writeCredentialsToFile(configPath, config) {
183
+ cliConfig.writeAuthConfigFile(configPath, config);
184
+ }
185
+ function readCredentialsFromKeyring(configPath, runtimeFlags) {
186
+ const entry = createKeyringEntry(configPath, runtimeFlags);
187
+ const value = entry.getPassword();
188
+ if (value === null) {
189
+ return null;
190
+ }
191
+ return parseCredentials(JSON.parse(value));
192
+ }
193
+ function writeCredentialsToKeyring(configPath, config, runtimeFlags) {
194
+ const entry = createKeyringEntry(configPath, runtimeFlags);
195
+ entry.setPassword(JSON.stringify(config));
196
+ }
197
+ function deleteCredentialsFromKeyring(configPath, runtimeFlags) {
198
+ const entry = createKeyringEntry(configPath, runtimeFlags);
199
+ return entry.deleteCredential();
200
+ }
201
+ function deleteCredentialsFile(configPath) {
202
+ cliConfig.deleteAuthConfigFile(configPath);
203
+ }
204
+ function tryDeleteCredentialsFromKeyring(configPath, runtimeFlags) {
205
+ try {
206
+ deleteCredentialsFromKeyring(configPath, runtimeFlags);
207
+ }
208
+ catch { }
209
+ }
210
+ function deleteCredentialsFromKeyringIfAvailable(configPath, runtimeFlags) {
211
+ try {
212
+ deleteCredentialsFromKeyring(configPath, runtimeFlags);
213
+ }
214
+ catch (error) {
215
+ if (!isKeyringUnavailableError(error)) {
216
+ throw error;
217
+ }
218
+ }
219
+ }
220
+ function migrateCredentialsToFile(configPath, credentials, runtimeFlags) {
221
+ writeCredentialsToFile(configPath, credentials);
222
+ tryDeleteCredentialsFromKeyring(configPath, runtimeFlags);
223
+ return credentials;
224
+ }
225
+ function tryReadKeyringCredentialsIntoFile(configPath, runtimeFlags) {
226
+ try {
227
+ const credentials = readCredentialsFromKeyring(configPath, runtimeFlags);
228
+ if (credentials === null) {
229
+ return null;
230
+ }
231
+ return migrateCredentialsToFile(configPath, credentials, runtimeFlags);
232
+ }
233
+ catch {
234
+ return null;
235
+ }
236
+ }
237
+ function readFileStorageCredentials(configPath, runtimeFlags) {
238
+ try {
239
+ const credentials = readCredentialsFromFile(configPath);
240
+ if (cliConfig.authConfigHasUsableTokenData(credentials)) {
241
+ return credentials;
242
+ }
243
+ return (tryReadKeyringCredentialsIntoFile(configPath, runtimeFlags) ?? credentials);
244
+ }
245
+ catch (error) {
246
+ if (!isENOENTError(error)) {
247
+ throw error;
248
+ }
249
+ const credentials = tryReadKeyringCredentialsIntoFile(configPath, runtimeFlags);
250
+ if (credentials !== null) {
251
+ return credentials;
252
+ }
253
+ throw error;
254
+ }
255
+ }
256
+ function migrateCredentialsToKeyring(configPath, credentials, runtimeFlags) {
257
+ writeCredentialsToKeyring(configPath, credentials, runtimeFlags);
258
+ deleteCredentialsFile(configPath);
259
+ return credentials;
260
+ }
261
+ function readKeyringStorageCredentials(configPath, runtimeFlags) {
262
+ const credentials = readCredentialsFromKeyring(configPath, runtimeFlags);
263
+ if (credentials !== null) {
264
+ return credentials;
265
+ }
266
+ try {
267
+ const fileCredentials = readCredentialsFromFile(configPath);
268
+ return migrateCredentialsToKeyring(configPath, fileCredentials, runtimeFlags);
269
+ }
270
+ catch (error) {
271
+ if (isENOENTError(error)) {
272
+ throw createMissingCredentialsError(configPath);
273
+ }
274
+ throw error;
275
+ }
276
+ }
277
+ function readAutoStorageCredentials(configPath, runtimeFlags) {
278
+ try {
279
+ const credentials = readCredentialsFromKeyring(configPath, runtimeFlags);
280
+ if (credentials !== null) {
281
+ return credentials;
282
+ }
283
+ }
284
+ catch { }
285
+ return readCredentialsFromFile(configPath);
286
+ }
287
+ function writeFileStorageCredentials(configPath, credentials, runtimeFlags) {
288
+ writeCredentialsToFile(configPath, credentials);
289
+ tryDeleteCredentialsFromKeyring(configPath, runtimeFlags);
290
+ return 'file';
291
+ }
292
+ function writeKeyringStorageCredentials(configPath, credentials, runtimeFlags) {
293
+ writeCredentialsToKeyring(configPath, credentials, runtimeFlags);
294
+ deleteCredentialsFile(configPath);
295
+ return 'keyring';
296
+ }
297
+ function writeAutoStorageCredentials(configPath, credentials, runtimeFlags) {
298
+ try {
299
+ return writeKeyringStorageCredentials(configPath, credentials, runtimeFlags);
300
+ }
301
+ catch {
302
+ deleteCredentialsFromKeyringIfAvailable(configPath, runtimeFlags);
303
+ return writeFileStorageCredentials(configPath, credentials, runtimeFlags);
304
+ }
305
+ }
306
+ function deleteFileStorageCredentials(configPath, runtimeFlags) {
307
+ deleteCredentialsFile(configPath);
308
+ deleteCredentialsFromKeyringIfAvailable(configPath, runtimeFlags);
309
+ }
310
+ function deleteKeyringStorageCredentials(configPath, runtimeFlags) {
311
+ deleteCredentialsFromKeyring(configPath, runtimeFlags);
312
+ deleteCredentialsFile(configPath);
313
+ }
314
+ function deleteAutoStorageCredentials(configPath, runtimeFlags) {
315
+ try {
316
+ deleteCredentialsFromKeyring(configPath, runtimeFlags);
317
+ }
318
+ catch { }
319
+ deleteCredentialsFile(configPath);
320
+ }
321
+ function CredentialsStore(dir, config = {}) {
322
+ const configPath = cliConfig.getAuthConfigFilePath(dir);
323
+ const cliAuthConfig = resolveCliAuthConfig(dir, config);
324
+ const tokenStorage = cliAuthConfig.credStorage;
93
325
  return {
94
326
  configPath,
95
327
  get() {
96
- return Credentials.parse(JSON.parse(fs.readFileSync(configPath, 'utf8')));
328
+ switch (tokenStorage) {
329
+ case 'file':
330
+ return readFileStorageCredentials(configPath, cliAuthConfig);
331
+ case 'keyring':
332
+ return readKeyringStorageCredentials(configPath, cliAuthConfig);
333
+ case 'auto':
334
+ return readAutoStorageCredentials(configPath, cliAuthConfig);
335
+ }
336
+ throw new Error(`Unsupported credStorage: ${tokenStorage}`);
97
337
  },
98
- /** Update the credentials store. If `skipWrite` is set, the update will be skipped. */
99
338
  update(config) {
100
339
  if (config.skipWrite)
101
340
  return;
102
- const parsedConfig = Credentials.parse(config);
103
- fs.mkdirSync(node_path_1.default.dirname(configPath), { recursive: true });
104
- fs.writeFileSync(configPath, JSON.stringify(parsedConfig, null, 2) + '\n', { mode: 0o600 });
341
+ const parsedConfig = parseCredentials(config);
342
+ switch (tokenStorage) {
343
+ case 'file':
344
+ return writeFileStorageCredentials(configPath, parsedConfig, cliAuthConfig);
345
+ case 'keyring':
346
+ return writeKeyringStorageCredentials(configPath, parsedConfig, cliAuthConfig);
347
+ case 'auto':
348
+ return writeAutoStorageCredentials(configPath, parsedConfig, cliAuthConfig);
349
+ }
350
+ throw new Error(`Unsupported credStorage: ${tokenStorage}`);
351
+ },
352
+ delete() {
353
+ switch (tokenStorage) {
354
+ case 'file':
355
+ deleteFileStorageCredentials(configPath, cliAuthConfig);
356
+ break;
357
+ case 'keyring':
358
+ deleteKeyringStorageCredentials(configPath, cliAuthConfig);
359
+ break;
360
+ case 'auto':
361
+ deleteAutoStorageCredentials(configPath, cliAuthConfig);
362
+ break;
363
+ }
105
364
  },
106
365
  };
107
366
  }
367
+ function readCredentials(dir, config = {}) {
368
+ return CredentialsStore(dir, config).get();
369
+ }
370
+ function readCliAuthConfig(dir, config = {}) {
371
+ return readCredentials(dir, config);
372
+ }
373
+ function writeCredentials(dir, credentials, config = {}) {
374
+ return CredentialsStore(dir, config).update(credentials);
375
+ }
376
+ function toPersistedAuthConfig(authConfig) {
377
+ const { skipWrite, tokenSource, ...persistedAuthConfig } = authConfig;
378
+ return persistedAuthConfig;
379
+ }
380
+ function persistCliAuthConfig(dir, authConfig, config = {}) {
381
+ if (authConfig.skipWrite) {
382
+ return;
383
+ }
384
+ const persistedAuthConfig = toPersistedAuthConfig(authConfig);
385
+ if (!cliConfig.authConfigHasUsableTokenData(persistedAuthConfig)) {
386
+ clearAllCredentialsStrict(dir);
387
+ return;
388
+ }
389
+ return writeCredentials(dir, persistedAuthConfig, config);
390
+ }
391
+ function clearCredentials(dir, config = {}) {
392
+ CredentialsStore(dir, config).delete();
393
+ }
394
+ function clearAllCredentials(dir) {
395
+ for (const credStorage of cliConfig.CRED_STORAGE_VALUES) {
396
+ try {
397
+ clearCredentials(dir, { credStorage });
398
+ }
399
+ catch { }
400
+ }
401
+ }
402
+ function clearAllCredentialsStrict(dir) {
403
+ const configPath = cliConfig.getAuthConfigFilePath(dir);
404
+ const runtimeFlags = readRuntimeFlags();
405
+ let fileError;
406
+ let keyringError;
407
+ try {
408
+ deleteCredentialsFile(configPath);
409
+ }
410
+ catch (error) {
411
+ fileError = error;
412
+ }
413
+ try {
414
+ deleteCredentialsFromKeyring(configPath, runtimeFlags);
415
+ }
416
+ catch (error) {
417
+ if (!isKeyringUnavailableError(error)) {
418
+ keyringError = error;
419
+ }
420
+ }
421
+ if (keyringError) {
422
+ throw keyringError;
423
+ }
424
+ if (fileError) {
425
+ throw fileError;
426
+ }
427
+ }
108
428
  //# sourceMappingURL=credentials-store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"credentials-store.js","sourceRoot":"","sources":["credentials-store.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,kDAiBC;AAED,4CAmBC;AA9ED,0DAA6B;AAC7B,4CAA8B;AAC9B,qCAAkC;AAClC,sEAAsE;AACtE,yFAAyF;AACzF,kEAAwC;AACxC,mCAA6B;AAE7B,MAAM,WAAW,GAAG,QAAC,CAAC,MAAM,CAAC;IAC3B,4EAA4E;IAC5E,KAAK,EAAE,QAAC,CAAC,QAAQ,CAAC,QAAC,CAAC,MAAM,EAAE,CAAC;IAC7B,4EAA4E;IAC5E,YAAY,EAAE,QAAC,CAAC,QAAQ,CAAC,QAAC,CAAC,MAAM,EAAE,CAAC;IACpC;;;OAGG;IACH,SAAS,EAAE,QAAC,CAAC,QAAQ,CAAC,QAAC,CAAC,MAAM,EAAE,CAAC;IACjC,6FAA6F;IAC7F,SAAS,EAAE,QAAC,CAAC,QAAQ,CAAC,QAAC,CAAC,OAAO,EAAE,CAAC;IAClC,SAAS,EAAE,QAAC,CAAC,QAAQ,CAAC,QAAC,CAAC,MAAM,EAAE,CAAC;IACjC,SAAS,EAAE,QAAC,CAAC,QAAQ,CAAC,QAAC,CAAC,MAAM,EAAE,CAAC;CAClC,CAAC,CAAC;AAIH,yCAAyC;AACzC,SAAS,WAAW,CAAC,IAAY;IAC/B,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IAC1C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,0EAA0E;QAC1E,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAgB,mBAAmB,CAAC,GAAW;IAC7C,MAAM,iBAAiB,GAAG,IAAA,uBAAW,EAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;IAEtD,MAAM,mBAAmB,GAAG;QAC1B,GAAG,iBAAiB,EAAE,0BAA0B;QAChD,mBAAI,CAAC,IAAI,CAAC,IAAA,iBAAO,GAAE,EAAE,MAAM,CAAC,EAAE,yCAAyC;QACvE,GAAG,IAAA,uBAAW,EAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,EAAE,uBAAuB;KAC1D,CAAC;IAEF,iDAAiD;IACjD,oCAAoC;IACpC,iCAAiC;IACjC,oDAAoD;IACpD,OAAO,CACL,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QAC/D,iBAAiB,CAAC,CAAC,CAAC,CACrB,CAAC;AACJ,CAAC;AAED,SAAgB,gBAAgB,CAAC,GAAW;IAC1C,MAAM,UAAU,GAAG,mBAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,CAAC;IACpE,OAAO;QACL,UAAU;QACV,GAAG;YACD,OAAO,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QAC5E,CAAC;QACD,uFAAuF;QACvF,MAAM,CAAC,MAA4B;YACjC,IAAI,MAAM,CAAC,SAAS;gBAAE,OAAO;YAC7B,MAAM,YAAY,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC/C,EAAE,CAAC,SAAS,CAAC,mBAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5D,EAAE,CAAC,aAAa,CACd,UAAU,EACV,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAC5C,EAAE,IAAI,EAAE,KAAK,EAAE,CAChB,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"credentials-store.js","sourceRoot":"","sources":["credentials-store.ts"],"names":[],"mappings":"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"}
@@ -1,79 +1,594 @@
1
- import path from 'node:path';
2
- import * as fs from 'node:fs';
3
- import { homedir } from 'node:os';
4
- // NOTE: We are pinned on v5 because newer versions behave differently
5
- // when there are dots in the application name, eg. `com.vercel.cli` becomes `com.vercel`
6
- import XDGAppPaths from 'xdg-app-paths';
7
- import { z } from 'zod/mini';
8
-
9
- const Credentials = z.object({
10
- /** An `access_token` obtained using the OAuth Device Authorization flow. */
11
- token: z.optional(z.string()),
12
- /** A `refresh_token` obtained using the OAuth Device Authorization flow. */
13
- refreshToken: z.optional(z.string()),
14
- /**
15
- * The absolute time (seconds) when the {@link Credentials.token} expires.
16
- * Used to optimistically check if the token is still valid.
17
- */
18
- expiresAt: z.optional(z.number()),
19
- /** Whether to skip writing the credentials to disk during {@link CredentialsStore.update} */
20
- skipWrite: z.optional(z.boolean()),
21
- '// Note': z.optional(z.string()),
22
- '// Docs': z.optional(z.string()),
23
- });
24
-
25
- export type Credentials = z.infer<typeof Credentials>;
26
-
27
- /** Returns whether a directory exists */
28
- function isDirectory(path: string): boolean {
1
+ import { createHash } from 'node:crypto';
2
+ import assert from 'node:assert';
3
+ import * as cliConfig from '@vercel/cli-config';
4
+ import type {
5
+ AuthConfig as SharedAuthConfig,
6
+ CredStorage,
7
+ CredentialsStorageLocation,
8
+ GlobalConfig as SharedGlobalConfig,
9
+ } from '@vercel/cli-config';
10
+
11
+ const KEYRING_SERVICE = 'com.vercel.vercel-cli';
12
+ const TOKEN_STORAGE_ENV = 'VERCEL_TOKEN_STORAGE';
13
+ const KEYRING_UNAVAILABLE_ENV = 'VERCEL_TEST_KEYRING_UNAVAILABLE';
14
+ const KEYRING_UNAVAILABLE_ERROR =
15
+ 'OS keyring support is unavailable. Set `credStorage` to `auto` or `file` to store credentials in auth.json instead.';
16
+
17
+ type KeyringEntry = {
18
+ getPassword(): string | null;
19
+ setPassword(password: string): void;
20
+ deleteCredential(): boolean;
21
+ };
22
+
23
+ type KeyringEntryConstructor = new (
24
+ service: string,
25
+ account: string
26
+ ) => KeyringEntry;
27
+
28
+ type LoadKeyringModule = () => {
29
+ Entry: KeyringEntryConstructor;
30
+ };
31
+
32
+ const defaultLoadKeyringModule: LoadKeyringModule = () =>
33
+ require('@napi-rs/keyring') as {
34
+ Entry: KeyringEntryConstructor;
35
+ };
36
+
37
+ let loadKeyringModule = defaultLoadKeyringModule;
38
+
39
+ type RuntimeFlags = {
40
+ keyringUnavailableForTesting: boolean;
41
+ };
42
+
43
+ type ResolvedCliAuthConfig = RuntimeFlags & {
44
+ credStorage: CredStorage;
45
+ };
46
+
47
+ export type GlobalConfig = Pick<SharedGlobalConfig, 'credStorage'>;
48
+
49
+ export type Credentials = Omit<SharedAuthConfig, 'tokenSource'>;
50
+
51
+ type PersistableAuthConfig = SharedAuthConfig;
52
+
53
+ function parseCredentials(value: unknown): Credentials {
54
+ const { tokenSource, ...credentials } = cliConfig.parseAuthConfig(value);
55
+ return credentials;
56
+ }
57
+
58
+ function formatCredStorageError(value: unknown, source: string): string {
59
+ try {
60
+ cliConfig.parseGlobalConfig({ credStorage: value });
61
+ } catch (error) {
62
+ if (error instanceof Error) {
63
+ return error.message.replace('`credStorage`', `\`${source}\``);
64
+ }
65
+ }
66
+
67
+ return `Invalid value for \`${source}\`: ${JSON.stringify(
68
+ value
69
+ )}. Expected one of: ${cliConfig.CRED_STORAGE_CONFIG_VALUES.map(storage => JSON.stringify(storage)).join(', ')}.`;
70
+ }
71
+
72
+ function parseCredStorage(value: unknown, source: string): CredStorage {
73
+ if (typeof value === 'undefined') {
74
+ return cliConfig.DEFAULT_CRED_STORAGE;
75
+ }
76
+
29
77
  try {
30
- return fs.lstatSync(path).isDirectory();
31
- } catch (_) {
32
- // We don't care which kind of error occured, it isn't a directory anyway.
33
- return false;
78
+ const config = cliConfig.parseGlobalConfig({ credStorage: value });
79
+ assert(
80
+ config.credStorage !== undefined,
81
+ 'expected credStorage value to be non-empty'
82
+ );
83
+ return config.credStorage;
84
+ } catch {
85
+ throw new Error(formatCredStorageError(value, source));
34
86
  }
35
87
  }
36
88
 
37
- /**
38
- * Returns in which directory the config should be present
39
- * @internal Should only be used in {@link CredentialsStore} or tests.
89
+ export function resolveCredStorage(value: unknown): CredStorage {
90
+ return parseCredStorage(value, 'credStorage');
91
+ }
92
+
93
+ function readRuntimeFlags(): RuntimeFlags {
94
+ return {
95
+ keyringUnavailableForTesting: process.env[KEYRING_UNAVAILABLE_ENV] === '1',
96
+ };
97
+ }
98
+
99
+ function resolveCliAuthConfig(
100
+ dir: string,
101
+ config?: GlobalConfig
102
+ ): ResolvedCliAuthConfig {
103
+ const runtimeFlags = readRuntimeFlags();
104
+
105
+ if (config?.credStorage) {
106
+ return {
107
+ ...runtimeFlags,
108
+ credStorage: resolveCredStorage(config.credStorage),
109
+ };
110
+ }
111
+
112
+ const credStorageOverride = process.env[TOKEN_STORAGE_ENV];
113
+
114
+ if (typeof credStorageOverride !== 'undefined') {
115
+ return {
116
+ ...runtimeFlags,
117
+ credStorage: parseCredStorage(credStorageOverride, TOKEN_STORAGE_ENV),
118
+ };
119
+ }
120
+
121
+ return {
122
+ ...runtimeFlags,
123
+ credStorage: resolveCredStorage(readGlobalConfig(dir).credStorage),
124
+ };
125
+ }
126
+
127
+ export function readGlobalConfig(dir: string): GlobalConfig {
128
+ const configPath = cliConfig.getConfigFilePath(dir);
129
+
130
+ try {
131
+ const config = cliConfig.readGlobalConfigFile(configPath);
132
+
133
+ return {
134
+ credStorage:
135
+ typeof config.credStorage === 'undefined'
136
+ ? undefined
137
+ : resolveCredStorage(config.credStorage),
138
+ };
139
+ } catch (error) {
140
+ if (isENOENTError(error)) {
141
+ return {};
142
+ }
143
+
144
+ throw error;
145
+ }
146
+ }
147
+
148
+ export function getCredStorage(
149
+ dir: string,
150
+ config?: GlobalConfig
151
+ ): CredStorage {
152
+ return resolveCliAuthConfig(dir, config).credStorage;
153
+ }
154
+
155
+ /** Return an account key suitable for use in keyrings for a given configPath.
156
+ *
157
+ * `auth.json` and the keychain are supposed to be equivalent and exchangeable.
158
+ * Since file-based credentials storage is configurable (via config path),
159
+ * we must ensure that keyring entries are keyed by config path also. We cannot
160
+ * use the full path as the key, so use a 16-byte prefix of sha256 hash of
161
+ * the path.
40
162
  */
41
- export function getGlobalPathConfig(dir: string): string {
42
- const vercelDirectories = XDGAppPaths(dir).dataDirs();
43
-
44
- const possibleConfigPaths = [
45
- ...vercelDirectories, // latest vercel directory
46
- path.join(homedir(), '.now'), // legacy config in user's home directory
47
- ...XDGAppPaths('now').dataDirs(), // legacy XDG directory
48
- ];
49
-
50
- // The customPath flag is the preferred location,
51
- // followed by the vercel directory,
52
- // followed by the now directory.
53
- // If none of those exist, use the vercel directory.
163
+ function getKeyringAccount(configPath: string): string {
164
+ const digest = createHash('sha256').update(configPath).digest('hex');
165
+ return `cli:${digest.slice(0, 16)}`;
166
+ }
167
+
168
+ export function setLoadKeyringModuleForTesting(
169
+ nextLoadKeyringModule?: LoadKeyringModule
170
+ ) {
171
+ loadKeyringModule = nextLoadKeyringModule ?? defaultLoadKeyringModule;
172
+ }
173
+
174
+ function createKeyringEntry(
175
+ configPath: string,
176
+ runtimeFlags: RuntimeFlags
177
+ ): KeyringEntry {
178
+ try {
179
+ if (runtimeFlags.keyringUnavailableForTesting) {
180
+ throw new Error(`${KEYRING_UNAVAILABLE_ENV} is set`);
181
+ }
182
+
183
+ const { Entry } = loadKeyringModule();
184
+
185
+ return new Entry(KEYRING_SERVICE, getKeyringAccount(configPath));
186
+ } catch (error) {
187
+ const wrappedError = new Error(KEYRING_UNAVAILABLE_ERROR);
188
+ (wrappedError as Error & { cause?: unknown }).cause = error;
189
+ throw wrappedError;
190
+ }
191
+ }
192
+
193
+ function isKeyringUnavailableError(error: unknown): boolean {
194
+ return error instanceof Error && error.message === KEYRING_UNAVAILABLE_ERROR;
195
+ }
196
+
197
+ function readCredentialsFromFile(configPath: string): Credentials {
198
+ return cliConfig.readAuthFileConfig(configPath);
199
+ }
200
+
201
+ function isENOENTError(error: unknown): boolean {
54
202
  return (
55
- possibleConfigPaths.find(configPath => isDirectory(configPath)) ||
56
- vercelDirectories[0]
203
+ typeof error === 'object' &&
204
+ error !== null &&
205
+ 'code' in error &&
206
+ error.code === 'ENOENT'
207
+ );
208
+ }
209
+
210
+ function createMissingCredentialsError(configPath: string): Error {
211
+ const error = new Error(
212
+ `ENOENT: no such file or directory, open '${configPath}'`
57
213
  );
214
+ Object.assign(error, { code: 'ENOENT' });
215
+ return error;
58
216
  }
59
217
 
60
- export function CredentialsStore(dir: string) {
61
- const configPath = path.join(getGlobalPathConfig(dir), 'auth.json');
218
+ function writeCredentialsToFile(configPath: string, config: Credentials): void {
219
+ cliConfig.writeAuthConfigFile(configPath, config);
220
+ }
221
+
222
+ function readCredentialsFromKeyring(
223
+ configPath: string,
224
+ runtimeFlags: RuntimeFlags
225
+ ): Credentials | null {
226
+ const entry = createKeyringEntry(configPath, runtimeFlags);
227
+ const value = entry.getPassword();
228
+
229
+ if (value === null) {
230
+ return null;
231
+ }
232
+
233
+ return parseCredentials(JSON.parse(value));
234
+ }
235
+
236
+ function writeCredentialsToKeyring(
237
+ configPath: string,
238
+ config: Credentials,
239
+ runtimeFlags: RuntimeFlags
240
+ ): void {
241
+ const entry = createKeyringEntry(configPath, runtimeFlags);
242
+ entry.setPassword(JSON.stringify(config));
243
+ }
244
+
245
+ function deleteCredentialsFromKeyring(
246
+ configPath: string,
247
+ runtimeFlags: RuntimeFlags
248
+ ): boolean {
249
+ const entry = createKeyringEntry(configPath, runtimeFlags);
250
+ return entry.deleteCredential();
251
+ }
252
+
253
+ function deleteCredentialsFile(configPath: string): void {
254
+ cliConfig.deleteAuthConfigFile(configPath);
255
+ }
256
+
257
+ function tryDeleteCredentialsFromKeyring(
258
+ configPath: string,
259
+ runtimeFlags: RuntimeFlags
260
+ ): void {
261
+ try {
262
+ deleteCredentialsFromKeyring(configPath, runtimeFlags);
263
+ } catch {}
264
+ }
265
+
266
+ function deleteCredentialsFromKeyringIfAvailable(
267
+ configPath: string,
268
+ runtimeFlags: RuntimeFlags
269
+ ): void {
270
+ try {
271
+ deleteCredentialsFromKeyring(configPath, runtimeFlags);
272
+ } catch (error) {
273
+ if (!isKeyringUnavailableError(error)) {
274
+ throw error;
275
+ }
276
+ }
277
+ }
278
+
279
+ function migrateCredentialsToFile(
280
+ configPath: string,
281
+ credentials: Credentials,
282
+ runtimeFlags: RuntimeFlags
283
+ ): Credentials {
284
+ writeCredentialsToFile(configPath, credentials);
285
+ tryDeleteCredentialsFromKeyring(configPath, runtimeFlags);
286
+ return credentials;
287
+ }
288
+
289
+ function tryReadKeyringCredentialsIntoFile(
290
+ configPath: string,
291
+ runtimeFlags: RuntimeFlags
292
+ ): Credentials | null {
293
+ try {
294
+ const credentials = readCredentialsFromKeyring(configPath, runtimeFlags);
295
+
296
+ if (credentials === null) {
297
+ return null;
298
+ }
299
+
300
+ return migrateCredentialsToFile(configPath, credentials, runtimeFlags);
301
+ } catch {
302
+ return null;
303
+ }
304
+ }
305
+
306
+ function readFileStorageCredentials(
307
+ configPath: string,
308
+ runtimeFlags: RuntimeFlags
309
+ ): Credentials {
310
+ try {
311
+ const credentials = readCredentialsFromFile(configPath);
312
+
313
+ if (cliConfig.authConfigHasUsableTokenData(credentials)) {
314
+ return credentials;
315
+ }
316
+
317
+ return (
318
+ tryReadKeyringCredentialsIntoFile(configPath, runtimeFlags) ?? credentials
319
+ );
320
+ } catch (error) {
321
+ if (!isENOENTError(error)) {
322
+ throw error;
323
+ }
324
+
325
+ const credentials = tryReadKeyringCredentialsIntoFile(
326
+ configPath,
327
+ runtimeFlags
328
+ );
329
+
330
+ if (credentials !== null) {
331
+ return credentials;
332
+ }
333
+
334
+ throw error;
335
+ }
336
+ }
337
+
338
+ function migrateCredentialsToKeyring(
339
+ configPath: string,
340
+ credentials: Credentials,
341
+ runtimeFlags: RuntimeFlags
342
+ ): Credentials {
343
+ writeCredentialsToKeyring(configPath, credentials, runtimeFlags);
344
+ deleteCredentialsFile(configPath);
345
+ return credentials;
346
+ }
347
+
348
+ function readKeyringStorageCredentials(
349
+ configPath: string,
350
+ runtimeFlags: RuntimeFlags
351
+ ): Credentials {
352
+ const credentials = readCredentialsFromKeyring(configPath, runtimeFlags);
353
+
354
+ if (credentials !== null) {
355
+ return credentials;
356
+ }
357
+
358
+ try {
359
+ const fileCredentials = readCredentialsFromFile(configPath);
360
+
361
+ return migrateCredentialsToKeyring(
362
+ configPath,
363
+ fileCredentials,
364
+ runtimeFlags
365
+ );
366
+ } catch (error) {
367
+ if (isENOENTError(error)) {
368
+ throw createMissingCredentialsError(configPath);
369
+ }
370
+
371
+ throw error;
372
+ }
373
+ }
374
+
375
+ function readAutoStorageCredentials(
376
+ configPath: string,
377
+ runtimeFlags: RuntimeFlags
378
+ ): Credentials {
379
+ try {
380
+ const credentials = readCredentialsFromKeyring(configPath, runtimeFlags);
381
+
382
+ if (credentials !== null) {
383
+ return credentials;
384
+ }
385
+ } catch {}
386
+
387
+ return readCredentialsFromFile(configPath);
388
+ }
389
+
390
+ function writeFileStorageCredentials(
391
+ configPath: string,
392
+ credentials: Credentials,
393
+ runtimeFlags: RuntimeFlags
394
+ ): CredentialsStorageLocation {
395
+ writeCredentialsToFile(configPath, credentials);
396
+ tryDeleteCredentialsFromKeyring(configPath, runtimeFlags);
397
+ return 'file';
398
+ }
399
+
400
+ function writeKeyringStorageCredentials(
401
+ configPath: string,
402
+ credentials: Credentials,
403
+ runtimeFlags: RuntimeFlags
404
+ ): CredentialsStorageLocation {
405
+ writeCredentialsToKeyring(configPath, credentials, runtimeFlags);
406
+ deleteCredentialsFile(configPath);
407
+ return 'keyring';
408
+ }
409
+
410
+ function writeAutoStorageCredentials(
411
+ configPath: string,
412
+ credentials: Credentials,
413
+ runtimeFlags: RuntimeFlags
414
+ ): CredentialsStorageLocation {
415
+ try {
416
+ return writeKeyringStorageCredentials(
417
+ configPath,
418
+ credentials,
419
+ runtimeFlags
420
+ );
421
+ } catch {
422
+ deleteCredentialsFromKeyringIfAvailable(configPath, runtimeFlags);
423
+ return writeFileStorageCredentials(configPath, credentials, runtimeFlags);
424
+ }
425
+ }
426
+
427
+ function deleteFileStorageCredentials(
428
+ configPath: string,
429
+ runtimeFlags: RuntimeFlags
430
+ ): void {
431
+ deleteCredentialsFile(configPath);
432
+ deleteCredentialsFromKeyringIfAvailable(configPath, runtimeFlags);
433
+ }
434
+
435
+ function deleteKeyringStorageCredentials(
436
+ configPath: string,
437
+ runtimeFlags: RuntimeFlags
438
+ ): void {
439
+ deleteCredentialsFromKeyring(configPath, runtimeFlags);
440
+ deleteCredentialsFile(configPath);
441
+ }
442
+
443
+ function deleteAutoStorageCredentials(
444
+ configPath: string,
445
+ runtimeFlags: RuntimeFlags
446
+ ): void {
447
+ try {
448
+ deleteCredentialsFromKeyring(configPath, runtimeFlags);
449
+ } catch {}
450
+ deleteCredentialsFile(configPath);
451
+ }
452
+
453
+ export function CredentialsStore(dir: string, config: GlobalConfig = {}) {
454
+ const configPath = cliConfig.getAuthConfigFilePath(dir);
455
+ const cliAuthConfig = resolveCliAuthConfig(dir, config);
456
+ const tokenStorage = cliAuthConfig.credStorage;
457
+
62
458
  return {
63
459
  configPath,
64
460
  get(): Credentials {
65
- return Credentials.parse(JSON.parse(fs.readFileSync(configPath, 'utf8')));
461
+ switch (tokenStorage) {
462
+ case 'file':
463
+ return readFileStorageCredentials(configPath, cliAuthConfig);
464
+ case 'keyring':
465
+ return readKeyringStorageCredentials(configPath, cliAuthConfig);
466
+ case 'auto':
467
+ return readAutoStorageCredentials(configPath, cliAuthConfig);
468
+ }
469
+
470
+ throw new Error(`Unsupported credStorage: ${tokenStorage}`);
66
471
  },
67
- /** Update the credentials store. If `skipWrite` is set, the update will be skipped. */
68
- update(config: Partial<Credentials>): void {
472
+ update(config: Partial<Credentials>): CredentialsStorageLocation | void {
69
473
  if (config.skipWrite) return;
70
- const parsedConfig = Credentials.parse(config);
71
- fs.mkdirSync(path.dirname(configPath), { recursive: true });
72
- fs.writeFileSync(
73
- configPath,
74
- JSON.stringify(parsedConfig, null, 2) + '\n',
75
- { mode: 0o600 }
76
- );
474
+ const parsedConfig = parseCredentials(config);
475
+ switch (tokenStorage) {
476
+ case 'file':
477
+ return writeFileStorageCredentials(
478
+ configPath,
479
+ parsedConfig,
480
+ cliAuthConfig
481
+ );
482
+ case 'keyring':
483
+ return writeKeyringStorageCredentials(
484
+ configPath,
485
+ parsedConfig,
486
+ cliAuthConfig
487
+ );
488
+ case 'auto':
489
+ return writeAutoStorageCredentials(
490
+ configPath,
491
+ parsedConfig,
492
+ cliAuthConfig
493
+ );
494
+ }
495
+
496
+ throw new Error(`Unsupported credStorage: ${tokenStorage}`);
497
+ },
498
+ delete(): void {
499
+ switch (tokenStorage) {
500
+ case 'file':
501
+ deleteFileStorageCredentials(configPath, cliAuthConfig);
502
+ break;
503
+ case 'keyring':
504
+ deleteKeyringStorageCredentials(configPath, cliAuthConfig);
505
+ break;
506
+ case 'auto':
507
+ deleteAutoStorageCredentials(configPath, cliAuthConfig);
508
+ break;
509
+ }
77
510
  },
78
511
  };
79
512
  }
513
+
514
+ export function readCredentials(dir: string, config: GlobalConfig = {}) {
515
+ return CredentialsStore(dir, config).get();
516
+ }
517
+
518
+ export function readCliAuthConfig(dir: string, config: GlobalConfig = {}) {
519
+ return readCredentials(dir, config);
520
+ }
521
+
522
+ export function writeCredentials(
523
+ dir: string,
524
+ credentials: Partial<Credentials>,
525
+ config: GlobalConfig = {}
526
+ ) {
527
+ return CredentialsStore(dir, config).update(credentials);
528
+ }
529
+
530
+ function toPersistedAuthConfig(authConfig: PersistableAuthConfig): Credentials {
531
+ const { skipWrite, tokenSource, ...persistedAuthConfig } = authConfig;
532
+ return persistedAuthConfig;
533
+ }
534
+
535
+ export function persistCliAuthConfig(
536
+ dir: string,
537
+ authConfig: PersistableAuthConfig,
538
+ config: GlobalConfig = {}
539
+ ) {
540
+ if (authConfig.skipWrite) {
541
+ return;
542
+ }
543
+
544
+ const persistedAuthConfig = toPersistedAuthConfig(authConfig);
545
+
546
+ if (!cliConfig.authConfigHasUsableTokenData(persistedAuthConfig)) {
547
+ clearAllCredentialsStrict(dir);
548
+ return;
549
+ }
550
+
551
+ return writeCredentials(dir, persistedAuthConfig, config);
552
+ }
553
+
554
+ export function clearCredentials(dir: string, config: GlobalConfig = {}) {
555
+ CredentialsStore(dir, config).delete();
556
+ }
557
+
558
+ export function clearAllCredentials(dir: string) {
559
+ for (const credStorage of cliConfig.CRED_STORAGE_VALUES) {
560
+ try {
561
+ clearCredentials(dir, { credStorage });
562
+ } catch {}
563
+ }
564
+ }
565
+
566
+ export function clearAllCredentialsStrict(dir: string) {
567
+ const configPath = cliConfig.getAuthConfigFilePath(dir);
568
+ const runtimeFlags = readRuntimeFlags();
569
+
570
+ let fileError: unknown;
571
+ let keyringError: unknown;
572
+
573
+ try {
574
+ deleteCredentialsFile(configPath);
575
+ } catch (error) {
576
+ fileError = error;
577
+ }
578
+
579
+ try {
580
+ deleteCredentialsFromKeyring(configPath, runtimeFlags);
581
+ } catch (error) {
582
+ if (!isKeyringUnavailableError(error)) {
583
+ keyringError = error;
584
+ }
585
+ }
586
+
587
+ if (keyringError) {
588
+ throw keyringError;
589
+ }
590
+
591
+ if (fileError) {
592
+ throw fileError;
593
+ }
594
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vercel/cli-auth",
3
3
  "description": "Used by Vercel's CLIs to handle authentication",
4
- "version": "0.2.0",
4
+ "version": "0.3.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -19,10 +19,11 @@
19
19
  "!**/*.test.ts"
20
20
  ],
21
21
  "dependencies": {
22
+ "@napi-rs/keyring": "1.2.0",
22
23
  "async-listen": "3.0.0",
23
24
  "open": "8.4.0",
24
- "xdg-app-paths": "5",
25
- "zod": "4.1.11"
25
+ "zod": "4.1.11",
26
+ "@vercel/cli-config": "0.2.1"
26
27
  },
27
28
  "devDependencies": {
28
29
  "@types/node": "20.11.0",