@doist/cli-core 0.16.1 → 0.18.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.
Files changed (35) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +22 -14
  3. package/dist/auth/index.d.ts +3 -1
  4. package/dist/auth/index.d.ts.map +1 -1
  5. package/dist/auth/index.js +1 -0
  6. package/dist/auth/index.js.map +1 -1
  7. package/dist/auth/keyring/internal.d.ts +25 -0
  8. package/dist/auth/keyring/internal.d.ts.map +1 -0
  9. package/dist/auth/keyring/internal.js +31 -0
  10. package/dist/auth/keyring/internal.js.map +1 -0
  11. package/dist/auth/keyring/migrate.d.ts +19 -17
  12. package/dist/auth/keyring/migrate.d.ts.map +1 -1
  13. package/dist/auth/keyring/migrate.js +111 -49
  14. package/dist/auth/keyring/migrate.js.map +1 -1
  15. package/dist/auth/keyring/record-write.d.ts +70 -16
  16. package/dist/auth/keyring/record-write.d.ts.map +1 -1
  17. package/dist/auth/keyring/record-write.js +139 -30
  18. package/dist/auth/keyring/record-write.js.map +1 -1
  19. package/dist/auth/keyring/slot-naming.d.ts +6 -0
  20. package/dist/auth/keyring/slot-naming.d.ts.map +1 -0
  21. package/dist/auth/keyring/slot-naming.js +8 -0
  22. package/dist/auth/keyring/slot-naming.js.map +1 -0
  23. package/dist/auth/keyring/token-store.d.ts +10 -2
  24. package/dist/auth/keyring/token-store.d.ts.map +1 -1
  25. package/dist/auth/keyring/token-store.js +93 -64
  26. package/dist/auth/keyring/token-store.js.map +1 -1
  27. package/dist/auth/keyring/types.d.ts +20 -0
  28. package/dist/auth/keyring/types.d.ts.map +1 -1
  29. package/dist/auth/persist.d.ts +23 -0
  30. package/dist/auth/persist.d.ts.map +1 -0
  31. package/dist/auth/persist.js +38 -0
  32. package/dist/auth/persist.js.map +1 -0
  33. package/dist/auth/types.d.ts +27 -1
  34. package/dist/auth/types.d.ts.map +1 -1
  35. package/package.json +5 -5
@@ -1,9 +1,16 @@
1
- import type { AuthAccount } from '../types.js';
1
+ import type { AuthAccount, TokenBundle } from '../types.js';
2
2
  import { type SecureStore } from './secure-store.js';
3
- import type { UserRecordStore } from './types.js';
3
+ import type { UserRecord, UserRecordStore } from './types.js';
4
4
  type WriteRecordOptions<TAccount extends AuthAccount> = {
5
5
  /** Per-account keyring slot, already configured by the caller (e.g. via `createSecureStore`). */
6
6
  secureStore: SecureStore;
7
+ /**
8
+ * Optional refresh-token keyring slot. When supplied, any orphan refresh
9
+ * material from a prior `setBundle` is wiped best-effort AFTER the user
10
+ * record is upserted (see the deferred-cleanup contract on
11
+ * `writeBundleWithKeyringFallback`).
12
+ */
13
+ refreshStore?: SecureStore;
7
14
  userRecords: UserRecordStore<TAccount>;
8
15
  account: TAccount;
9
16
  token: string;
@@ -12,23 +19,70 @@ type WriteRecordResult = {
12
19
  /** `true` when the secret landed in the OS keyring; `false` when the keyring was unavailable and the token was written to `fallbackToken` on the user record. */
13
20
  storedSecurely: boolean;
14
21
  };
22
+ type WriteBundleOptions<TAccount extends AuthAccount> = {
23
+ /** Per-account access-token keyring slot. */
24
+ accessStore: SecureStore;
25
+ /** Per-account refresh-token keyring slot. */
26
+ refreshStore: SecureStore;
27
+ userRecords: UserRecordStore<TAccount>;
28
+ account: TAccount;
29
+ bundle: TokenBundle;
30
+ };
31
+ type WriteBundleResult = {
32
+ /** `true` when the access token landed in the OS keyring; `false` when it fell back to `fallbackToken`. */
33
+ accessStoredSecurely: boolean;
34
+ /**
35
+ * `true` when a refresh token landed in the OS keyring. `false` when it
36
+ * fell back to `fallbackRefreshToken`. `undefined` when the bundle
37
+ * carried no refresh token (nothing to store).
38
+ */
39
+ refreshStoredSecurely: boolean | undefined;
40
+ };
15
41
  /**
16
- * Shared keyring-then-record write used by `createKeyringTokenStore.set` and
17
- * `migrateLegacyAuth`. Encapsulates the order-of-operations contract that
18
- * matters for credential safety:
19
- *
20
- * 1. Keyring `setSecret` first. On `SecureStoreUnavailableError`, swallow
21
- * the failure and record a `fallbackToken` on the user record instead.
22
- * Any other error rethrows.
23
- * 2. `userRecords.upsert(record)`. On failure, best-effort rollback the
24
- * keyring write so we don't leave an orphan credential for an account
25
- * cli-core never managed to register. Original error rethrows.
42
+ * Single-token write. Thin wrapper over `writeBundleWithKeyringFallback`
43
+ * passing a refresh-less bundle, so trim/validate, access-slot fallback,
44
+ * upsert rollback, and the deferred refresh-slot wipe all share one
45
+ * implementation.
26
46
  *
27
- * Default promotion (`setDefaultId`) is intentionally **not** in here both
28
- * call sites do it best-effort outside the critical section because it is a
29
- * preference, not a correctness requirement, and an error there must not
30
- * dirty up a successful credential write.
47
+ * `refreshStore` is optional purely for legacy callers (`migrateLegacyAuth`)
48
+ * that don't have one wired; the migrate path never had refresh state so
49
+ * skipping the wipe is correct there.
31
50
  */
32
51
  export declare function writeRecordWithKeyringFallback<TAccount extends AuthAccount>(options: WriteRecordOptions<TAccount>): Promise<WriteRecordResult>;
52
+ /**
53
+ * Two-slot write. Order: access slot → refresh slot → upsert → deferred
54
+ * refresh wipe.
55
+ *
56
+ * 1. Validate `bundle.accessToken` (non-empty after trim).
57
+ * 2. `accessStore.setSecret`. `SecureStoreUnavailableError` degrades to
58
+ * `fallbackToken` on the record; any other error rethrows.
59
+ * 3. `refreshStore.setSecret` when `bundle.refreshToken` is present.
60
+ * `SecureStoreUnavailableError` degrades to `fallbackRefreshToken`. A
61
+ * non-keyring failure rolls back the access slot before rethrowing
62
+ * (no partial credentials left behind for an unregistered user).
63
+ * 4. `userRecords.upsert(record)`. On failure, best-effort
64
+ * `Promise.allSettled` rollback of any slot writes that succeeded.
65
+ * 5. Only after a successful upsert: if the bundle has no refresh token,
66
+ * wipe any orphan slot from a prior `setBundle` (best-effort). Doing
67
+ * this BEFORE the upsert would lose refresh state if the upsert then
68
+ * rejected — the new record's `hasRefreshToken` would still claim
69
+ * false but the old slot would be gone with no rollback path.
70
+ *
71
+ * Default promotion is external — preference, not correctness, and an
72
+ * error there must not dirty up a successful credential write.
73
+ */
74
+ export declare function writeBundleWithKeyringFallback<TAccount extends AuthAccount>(options: WriteBundleOptions<TAccount>): Promise<WriteBundleResult>;
75
+ /**
76
+ * Build a `UserRecord` for an access-only credential (no refresh state).
77
+ * Used by `migrateLegacyAuth`'s Phase 1 / Phase 2 record writes; both call
78
+ * sites then agree on the explicit `hasRefreshToken: false` that lets
79
+ * future bundle-aware readers skip the refresh-slot IPC.
80
+ *
81
+ * `writeBundleWithKeyringFallback` builds its own record shape inline
82
+ * because the bundle path also carries expiry fields; the structural
83
+ * overlap is the `hasRefreshToken: false` + optional `fallbackToken`
84
+ * pair, which is what this helper isolates.
85
+ */
86
+ export declare function buildSingleTokenRecord<TAccount extends AuthAccount>(account: TAccount, fallbackToken?: string): UserRecord<TAccount>;
33
87
  export {};
34
88
  //# sourceMappingURL=record-write.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"record-write.d.ts","sourceRoot":"","sources":["../../../src/auth/keyring/record-write.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,KAAK,WAAW,EAA+B,MAAM,mBAAmB,CAAA;AACjF,OAAO,KAAK,EAAc,eAAe,EAAE,MAAM,YAAY,CAAA;AAE7D,KAAK,kBAAkB,CAAC,QAAQ,SAAS,WAAW,IAAI;IACpD,iGAAiG;IACjG,WAAW,EAAE,WAAW,CAAA;IACxB,WAAW,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAA;IACtC,OAAO,EAAE,QAAQ,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,KAAK,iBAAiB,GAAG;IACrB,iKAAiK;IACjK,cAAc,EAAE,OAAO,CAAA;CAC1B,CAAA;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,8BAA8B,CAAC,QAAQ,SAAS,WAAW,EAC7E,OAAO,EAAE,kBAAkB,CAAC,QAAQ,CAAC,GACtC,OAAO,CAAC,iBAAiB,CAAC,CA8B5B"}
1
+ {"version":3,"file":"record-write.d.ts","sourceRoot":"","sources":["../../../src/auth/keyring/record-write.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAC3D,OAAO,EAAE,KAAK,WAAW,EAA+B,MAAM,mBAAmB,CAAA;AACjF,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAE7D,KAAK,kBAAkB,CAAC,QAAQ,SAAS,WAAW,IAAI;IACpD,iGAAiG;IACjG,WAAW,EAAE,WAAW,CAAA;IACxB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,WAAW,CAAA;IAC1B,WAAW,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAA;IACtC,OAAO,EAAE,QAAQ,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,KAAK,iBAAiB,GAAG;IACrB,iKAAiK;IACjK,cAAc,EAAE,OAAO,CAAA;CAC1B,CAAA;AAED,KAAK,kBAAkB,CAAC,QAAQ,SAAS,WAAW,IAAI;IACpD,6CAA6C;IAC7C,WAAW,EAAE,WAAW,CAAA;IACxB,8CAA8C;IAC9C,YAAY,EAAE,WAAW,CAAA;IACzB,WAAW,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAA;IACtC,OAAO,EAAE,QAAQ,CAAA;IACjB,MAAM,EAAE,WAAW,CAAA;CACtB,CAAA;AAED,KAAK,iBAAiB,GAAG;IACrB,2GAA2G;IAC3G,oBAAoB,EAAE,OAAO,CAAA;IAC7B;;;;OAIG;IACH,qBAAqB,EAAE,OAAO,GAAG,SAAS,CAAA;CAC7C,CAAA;AAED;;;;;;;;;GASG;AACH,wBAAsB,8BAA8B,CAAC,QAAQ,SAAS,WAAW,EAC7E,OAAO,EAAE,kBAAkB,CAAC,QAAQ,CAAC,GACtC,OAAO,CAAC,iBAAiB,CAAC,CAe5B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,8BAA8B,CAAC,QAAQ,SAAS,WAAW,EAC7E,OAAO,EAAE,kBAAkB,CAAC,QAAQ,CAAC,GACtC,OAAO,CAAC,iBAAiB,CAAC,CAgF5B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,SAAS,WAAW,EAC/D,OAAO,EAAE,QAAQ,EACjB,aAAa,CAAC,EAAE,MAAM,GACvB,UAAU,CAAC,QAAQ,CAAC,CAMtB"}
@@ -1,50 +1,159 @@
1
+ import { CliError } from '../../errors.js';
1
2
  import { SecureStoreUnavailableError } from './secure-store.js';
2
3
  /**
3
- * Shared keyring-then-record write used by `createKeyringTokenStore.set` and
4
- * `migrateLegacyAuth`. Encapsulates the order-of-operations contract that
5
- * matters for credential safety:
4
+ * Single-token write. Thin wrapper over `writeBundleWithKeyringFallback`
5
+ * passing a refresh-less bundle, so trim/validate, access-slot fallback,
6
+ * upsert rollback, and the deferred refresh-slot wipe all share one
7
+ * implementation.
6
8
  *
7
- * 1. Keyring `setSecret` first. On `SecureStoreUnavailableError`, swallow
8
- * the failure and record a `fallbackToken` on the user record instead.
9
- * Any other error rethrows.
10
- * 2. `userRecords.upsert(record)`. On failure, best-effort rollback the
11
- * keyring write so we don't leave an orphan credential for an account
12
- * cli-core never managed to register. Original error rethrows.
13
- *
14
- * Default promotion (`setDefaultId`) is intentionally **not** in here — both
15
- * call sites do it best-effort outside the critical section because it is a
16
- * preference, not a correctness requirement, and an error there must not
17
- * dirty up a successful credential write.
9
+ * `refreshStore` is optional purely for legacy callers (`migrateLegacyAuth`)
10
+ * that don't have one wired; the migrate path never had refresh state so
11
+ * skipping the wipe is correct there.
18
12
  */
19
13
  export async function writeRecordWithKeyringFallback(options) {
20
- const { secureStore, userRecords, account, token } = options;
21
- const trimmed = token.trim();
22
- let storedSecurely = false;
14
+ const { secureStore, refreshStore, userRecords, account, token } = options;
15
+ const { accessStoredSecurely } = await writeBundleWithKeyringFallback({
16
+ accessStore: secureStore,
17
+ // No-op store when the caller didn't wire one — the deferred wipe
18
+ // becomes inert and we don't accidentally create a refresh slot
19
+ // for legacy/migrate paths.
20
+ refreshStore: refreshStore ?? NOOP_SECURE_STORE,
21
+ userRecords,
22
+ account,
23
+ bundle: { accessToken: token },
24
+ });
25
+ return { storedSecurely: accessStoredSecurely };
26
+ }
27
+ /**
28
+ * Two-slot write. Order: access slot → refresh slot → upsert → deferred
29
+ * refresh wipe.
30
+ *
31
+ * 1. Validate `bundle.accessToken` (non-empty after trim).
32
+ * 2. `accessStore.setSecret`. `SecureStoreUnavailableError` degrades to
33
+ * `fallbackToken` on the record; any other error rethrows.
34
+ * 3. `refreshStore.setSecret` when `bundle.refreshToken` is present.
35
+ * `SecureStoreUnavailableError` degrades to `fallbackRefreshToken`. A
36
+ * non-keyring failure rolls back the access slot before rethrowing
37
+ * (no partial credentials left behind for an unregistered user).
38
+ * 4. `userRecords.upsert(record)`. On failure, best-effort
39
+ * `Promise.allSettled` rollback of any slot writes that succeeded.
40
+ * 5. Only after a successful upsert: if the bundle has no refresh token,
41
+ * wipe any orphan slot from a prior `setBundle` (best-effort). Doing
42
+ * this BEFORE the upsert would lose refresh state if the upsert then
43
+ * rejected — the new record's `hasRefreshToken` would still claim
44
+ * false but the old slot would be gone with no rollback path.
45
+ *
46
+ * Default promotion is external — preference, not correctness, and an
47
+ * error there must not dirty up a successful credential write.
48
+ */
49
+ export async function writeBundleWithKeyringFallback(options) {
50
+ const { accessStore, refreshStore, userRecords, account, bundle } = options;
51
+ const accessToken = bundle.accessToken.trim();
52
+ if (!accessToken) {
53
+ throw new CliError('AUTH_STORE_WRITE_FAILED', 'Refusing to persist a bundle with an empty access token.');
54
+ }
55
+ const refreshToken = bundle.refreshToken?.trim();
56
+ let accessStoredSecurely = false;
23
57
  try {
24
- await secureStore.setSecret(trimmed);
25
- storedSecurely = true;
58
+ await accessStore.setSecret(accessToken);
59
+ accessStoredSecurely = true;
26
60
  }
27
61
  catch (error) {
28
62
  if (!(error instanceof SecureStoreUnavailableError))
29
63
  throw error;
30
64
  }
31
- const record = storedSecurely
32
- ? { account }
33
- : { account, fallbackToken: trimmed };
65
+ let refreshStoredSecurely;
66
+ if (refreshToken) {
67
+ try {
68
+ await refreshStore.setSecret(refreshToken);
69
+ refreshStoredSecurely = true;
70
+ }
71
+ catch (error) {
72
+ if (error instanceof SecureStoreUnavailableError) {
73
+ refreshStoredSecurely = false;
74
+ }
75
+ else {
76
+ if (accessStoredSecurely) {
77
+ try {
78
+ await accessStore.deleteSecret();
79
+ }
80
+ catch {
81
+ // best-effort
82
+ }
83
+ }
84
+ throw error;
85
+ }
86
+ }
87
+ }
88
+ const record = {
89
+ account,
90
+ ...(accessStoredSecurely ? {} : { fallbackToken: accessToken }),
91
+ ...(refreshToken && refreshStoredSecurely === false
92
+ ? { fallbackRefreshToken: refreshToken }
93
+ : {}),
94
+ ...(bundle.accessTokenExpiresAt !== undefined
95
+ ? { accessTokenExpiresAt: bundle.accessTokenExpiresAt }
96
+ : {}),
97
+ ...(bundle.refreshTokenExpiresAt !== undefined
98
+ ? { refreshTokenExpiresAt: bundle.refreshTokenExpiresAt }
99
+ : {}),
100
+ hasRefreshToken: Boolean(refreshToken),
101
+ };
34
102
  try {
35
103
  await userRecords.upsert(record);
36
104
  }
37
105
  catch (error) {
38
- if (storedSecurely) {
39
- try {
40
- await secureStore.deleteSecret();
41
- }
42
- catch {
43
- // best-effort the user record failure is the real cause
44
- }
106
+ const rollbacks = [];
107
+ if (accessStoredSecurely)
108
+ rollbacks.push(accessStore.deleteSecret());
109
+ if (refreshStoredSecurely === true)
110
+ rollbacks.push(refreshStore.deleteSecret());
111
+ if (rollbacks.length > 0) {
112
+ await Promise.allSettled(rollbacks);
45
113
  }
46
114
  throw error;
47
115
  }
48
- return { storedSecurely };
116
+ // Deferred: wipe any orphan refresh slot from a prior setBundle now
117
+ // that the new record (with `hasRefreshToken: false`) is durable. If
118
+ // this fails the gate already prevents readers from consulting it; the
119
+ // worst case is a stale keyring entry that `clear()` will pick up.
120
+ if (!refreshToken) {
121
+ try {
122
+ await refreshStore.deleteSecret();
123
+ }
124
+ catch {
125
+ // best-effort
126
+ }
127
+ }
128
+ return { accessStoredSecurely, refreshStoredSecurely };
129
+ }
130
+ /**
131
+ * Build a `UserRecord` for an access-only credential (no refresh state).
132
+ * Used by `migrateLegacyAuth`'s Phase 1 / Phase 2 record writes; both call
133
+ * sites then agree on the explicit `hasRefreshToken: false` that lets
134
+ * future bundle-aware readers skip the refresh-slot IPC.
135
+ *
136
+ * `writeBundleWithKeyringFallback` builds its own record shape inline
137
+ * because the bundle path also carries expiry fields; the structural
138
+ * overlap is the `hasRefreshToken: false` + optional `fallbackToken`
139
+ * pair, which is what this helper isolates.
140
+ */
141
+ export function buildSingleTokenRecord(account, fallbackToken) {
142
+ return {
143
+ account,
144
+ ...(fallbackToken ? { fallbackToken } : {}),
145
+ hasRefreshToken: false,
146
+ };
49
147
  }
148
+ const NOOP_SECURE_STORE = {
149
+ async getSecret() {
150
+ return null;
151
+ },
152
+ async setSecret() {
153
+ // no-op
154
+ },
155
+ async deleteSecret() {
156
+ return false;
157
+ },
158
+ };
50
159
  //# sourceMappingURL=record-write.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"record-write.js","sourceRoot":"","sources":["../../../src/auth/keyring/record-write.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,2BAA2B,EAAE,MAAM,mBAAmB,CAAA;AAgBjF;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAChD,OAAqC;IAErC,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,OAAO,CAAA;IAC5D,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAA;IAE5B,IAAI,cAAc,GAAG,KAAK,CAAA;IAC1B,IAAI,CAAC;QACD,MAAM,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;QACpC,cAAc,GAAG,IAAI,CAAA;IACzB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,IAAI,CAAC,CAAC,KAAK,YAAY,2BAA2B,CAAC;YAAE,MAAM,KAAK,CAAA;IACpE,CAAC;IAED,MAAM,MAAM,GAAyB,cAAc;QAC/C,CAAC,CAAC,EAAE,OAAO,EAAE;QACb,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,CAAA;IAEzC,IAAI,CAAC;QACD,MAAM,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACpC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,IAAI,cAAc,EAAE,CAAC;YACjB,IAAI,CAAC;gBACD,MAAM,WAAW,CAAC,YAAY,EAAE,CAAA;YACpC,CAAC;YAAC,MAAM,CAAC;gBACL,0DAA0D;YAC9D,CAAC;QACL,CAAC;QACD,MAAM,KAAK,CAAA;IACf,CAAC;IAED,OAAO,EAAE,cAAc,EAAE,CAAA;AAC7B,CAAC"}
1
+ {"version":3,"file":"record-write.js","sourceRoot":"","sources":["../../../src/auth/keyring/record-write.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Derives the refresh slot name from the access slug. Single-sourced so the
3
+ * write and read paths can't drift onto different suffixes. Internal.
4
+ */
5
+ export declare function refreshAccountSlot(accountSlug: string): string;
6
+ //# sourceMappingURL=slot-naming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slot-naming.d.ts","sourceRoot":"","sources":["../../../src/auth/keyring/slot-naming.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE9D"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Derives the refresh slot name from the access slug. Single-sourced so the
3
+ * write and read paths can't drift onto different suffixes. Internal.
4
+ */
5
+ export function refreshAccountSlot(accountSlug) {
6
+ return `${accountSlug}/refresh`;
7
+ }
8
+ //# sourceMappingURL=slot-naming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slot-naming.js","sourceRoot":"","sources":["../../../src/auth/keyring/slot-naming.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAAmB;IAClD,OAAO,GAAG,WAAW,UAAU,CAAA;AACnC,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { AccountRef, AuthAccount, TokenStore } from '../types.js';
1
+ import type { AccountRef, AuthAccount, TokenBundle, TokenStore } from '../types.js';
2
2
  import type { TokenStorageResult, UserRecordStore } from './types.js';
3
3
  export type CreateKeyringTokenStoreOptions<TAccount extends AuthAccount> = {
4
4
  /** Application identifier used for every keyring entry (e.g. `'todoist-cli'`). */
@@ -24,7 +24,15 @@ export type CreateKeyringTokenStoreOptions<TAccount extends AuthAccount> = {
24
24
  matchAccount?: (account: TAccount, ref: AccountRef) => boolean;
25
25
  };
26
26
  export type KeyringTokenStore<TAccount extends AuthAccount> = TokenStore<TAccount> & {
27
- /** Storage result from the most recent `set()` call, or `undefined` before any (and reset to `undefined` when the most recent `set()` threw). */
27
+ /**
28
+ * Override `setBundle` as required (not optional) — the keyring store
29
+ * always knows how to persist refresh state. Lets cli-core helpers
30
+ * (`persistBundle`) call it without a non-null assertion.
31
+ */
32
+ setBundle(account: TAccount, bundle: TokenBundle, options?: {
33
+ promoteDefault?: boolean;
34
+ }): Promise<void>;
35
+ /** Storage result from the most recent `set()` / `setBundle()` call, or `undefined` before any (and reset to `undefined` when the most recent write threw). */
28
36
  getLastStorageResult(): TokenStorageResult | undefined;
29
37
  /** Storage result from the most recent `clear()` call, or `undefined` before any (and reset to `undefined` when the most recent `clear()` threw or was a no-op). */
30
38
  getLastClearResult(): TokenStorageResult | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"token-store.d.ts","sourceRoot":"","sources":["../../../src/auth/keyring/token-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAUtE,OAAO,KAAK,EAAE,kBAAkB,EAAc,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjF,MAAM,MAAM,8BAA8B,CAAC,QAAQ,SAAS,WAAW,IAAI;IACvE,kFAAkF;IAClF,WAAW,EAAE,MAAM,CAAA;IACnB,oFAAoF;IACpF,WAAW,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAA;IACtC;;;;OAIG;IACH,eAAe,EAAE,MAAM,CAAA;IACvB;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAA;IACvC;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,UAAU,KAAK,OAAO,CAAA;CACjE,CAAA;AAED,MAAM,MAAM,iBAAiB,CAAC,QAAQ,SAAS,WAAW,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG;IACjF,iJAAiJ;IACjJ,oBAAoB,IAAI,kBAAkB,GAAG,SAAS,CAAA;IACtD,oKAAoK;IACpK,kBAAkB,IAAI,kBAAkB,GAAG,SAAS,CAAA;CACvD,CAAA;AAOD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,SAAS,WAAW,EAChE,OAAO,EAAE,8BAA8B,CAAC,QAAQ,CAAC,GAClD,iBAAiB,CAAC,QAAQ,CAAC,CAgP7B"}
1
+ {"version":3,"file":"token-store.d.ts","sourceRoot":"","sources":["../../../src/auth/keyring/token-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAWnF,OAAO,KAAK,EAAE,kBAAkB,EAAc,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjF,MAAM,MAAM,8BAA8B,CAAC,QAAQ,SAAS,WAAW,IAAI;IACvE,kFAAkF;IAClF,WAAW,EAAE,MAAM,CAAA;IACnB,oFAAoF;IACpF,WAAW,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAA;IACtC;;;;OAIG;IACH,eAAe,EAAE,MAAM,CAAA;IACvB;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAA;IACvC;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,UAAU,KAAK,OAAO,CAAA;CACjE,CAAA;AAED,MAAM,MAAM,iBAAiB,CAAC,QAAQ,SAAS,WAAW,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG;IACjF;;;;OAIG;IACH,SAAS,CACL,OAAO,EAAE,QAAQ,EACjB,MAAM,EAAE,WAAW,EACnB,OAAO,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,OAAO,CAAA;KAAE,GACvC,OAAO,CAAC,IAAI,CAAC,CAAA;IAChB,+JAA+J;IAC/J,oBAAoB,IAAI,kBAAkB,GAAG,SAAS,CAAA;IACtD,oKAAoK;IACpK,kBAAkB,IAAI,kBAAkB,GAAG,SAAS,CAAA;CACvD,CAAA;AAOD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,SAAS,WAAW,EAChE,OAAO,EAAE,8BAA8B,CAAC,QAAQ,CAAC,GAClD,iBAAiB,CAAC,QAAQ,CAAC,CAgR7B"}
@@ -1,7 +1,9 @@
1
1
  import { CliError } from '../../errors.js';
2
2
  import { accountNotFoundError } from '../user-flag.js';
3
- import { writeRecordWithKeyringFallback } from './record-write.js';
4
- import { createSecureStore, DEFAULT_ACCOUNT_FOR_USER, SECURE_STORE_DESCRIPTION, SecureStoreUnavailableError, } from './secure-store.js';
3
+ import { readAccessTokenForRecord } from './internal.js';
4
+ import { writeBundleWithKeyringFallback, writeRecordWithKeyringFallback } from './record-write.js';
5
+ import { createSecureStore, DEFAULT_ACCOUNT_FOR_USER, SECURE_STORE_DESCRIPTION, } from './secure-store.js';
6
+ import { refreshAccountSlot } from './slot-naming.js';
5
7
  const DEFAULT_MATCH_ACCOUNT = (account, ref) => account.id === ref || account.label === ref;
6
8
  /**
7
9
  * Multi-account `TokenStore` that keeps secrets in the OS credential manager
@@ -37,6 +39,12 @@ export function createKeyringTokenStore(options) {
37
39
  function secureStoreFor(account) {
38
40
  return createSecureStore({ serviceName, account: accountForUser(account.id) });
39
41
  }
42
+ function refreshSecureStoreFor(account) {
43
+ return createSecureStore({
44
+ serviceName,
45
+ account: refreshAccountSlot(accountForUser(account.id)),
46
+ });
47
+ }
40
48
  /**
41
49
  * Read both `list()` and `getDefaultId()` concurrently. Used by paths
42
50
  * that need the pinned default (no-ref `active`/`clear`, `list`, and
@@ -87,6 +95,43 @@ export function createKeyringTokenStore(options) {
87
95
  warning: `${SECURE_STORE_DESCRIPTION} unavailable; ${action} ${recordsLocation}`,
88
96
  };
89
97
  }
98
+ /**
99
+ * Compose a storage result for a write that may have fallen back on
100
+ * either slot. `accessStored === false` indicates the access token went
101
+ * to `fallbackToken`; `refreshStored === false` indicates the refresh
102
+ * token went to `fallbackRefreshToken`. Either falsy slot downgrades
103
+ * the result to `config-file` so consumers see the warning — refresh
104
+ * plaintext is just as security-relevant as access plaintext.
105
+ */
106
+ function bundleStorageResult(accessStored, refreshStored) {
107
+ const accessFallback = !accessStored;
108
+ const refreshFallback = refreshStored === false;
109
+ if (!accessFallback && !refreshFallback)
110
+ return { storage: 'secure-store' };
111
+ const subject = accessFallback && refreshFallback
112
+ ? 'access + refresh tokens'
113
+ : accessFallback
114
+ ? 'access token'
115
+ : 'refresh token';
116
+ return fallbackResult(`${subject} saved as plaintext in`);
117
+ }
118
+ /**
119
+ * Best-effort default promotion shared by `set` and `setBundle`. The
120
+ * record is already persisted, so a failure here must not surface as
121
+ * `AUTH_STORE_WRITE_FAILED` — the user can recover by setting a
122
+ * default later.
123
+ */
124
+ async function promoteDefaultIfNeeded(accountId) {
125
+ try {
126
+ const existingDefault = await userRecords.getDefaultId();
127
+ if (!existingDefault) {
128
+ await userRecords.setDefaultId(accountId);
129
+ }
130
+ }
131
+ catch {
132
+ // best-effort
133
+ }
134
+ }
90
135
  return {
91
136
  async active(ref) {
92
137
  // Ref-only path skips `getDefaultId()` — `resolveTarget` never
@@ -98,38 +143,21 @@ export function createKeyringTokenStore(options) {
98
143
  const record = resolveTarget(snapshot, ref);
99
144
  if (!record)
100
145
  return null;
101
- const fallback = record.fallbackToken?.trim();
102
- if (fallback) {
103
- return { token: fallback, account: record.account };
104
- }
105
- let raw;
106
- try {
107
- raw = await secureStoreFor(record.account).getSecret();
108
- }
109
- catch (error) {
110
- // A matching record exists but the keyring can't be read.
111
- // Surface a typed failure instead of returning `null`, which
112
- // would otherwise be indistinguishable from "no stored
113
- // account" and trigger `ACCOUNT_NOT_FOUND` on `--user <ref>`.
114
- // `attachLogoutCommand` catches this specific code so an
115
- // explicit `logout --user <ref>` can still clear the matching
116
- // record without needing the unreadable token.
117
- if (error instanceof SecureStoreUnavailableError) {
118
- throw new CliError('AUTH_STORE_READ_FAILED', `${SECURE_STORE_DESCRIPTION} unavailable; could not read stored token (${error.message})`);
119
- }
120
- throw error;
121
- }
122
- const token = raw?.trim();
123
- if (token) {
124
- return { token, account: record.account };
125
- }
126
- // Record exists, no `fallbackToken`, and the keyring slot is
127
- // empty — the credential was deleted out-of-band (user ran
128
- // `security delete-generic-password`, `secret-tool clear`, …).
129
- // This is corrupted state, not a miss; collapsing it to `null`
130
- // would make `--user <ref>` surface as `ACCOUNT_NOT_FOUND` and
131
- // hide the real problem.
132
- throw new CliError('AUTH_STORE_READ_FAILED', `${SECURE_STORE_DESCRIPTION} returned no credential for the stored account; the keyring entry may have been removed externally.`);
146
+ // Reads the access slot only. Refresh-state material lives in
147
+ // the keyring and on the record, but `active()` stays cheap and
148
+ // returns the pre-PR1 snapshot shape — a future bundle-aware
149
+ // read path lights up the refresh slot only when callers
150
+ // actually need it (silent refresh).
151
+ const outcome = await readAccessTokenForRecord(record, secureStoreFor(record.account));
152
+ if (outcome.ok)
153
+ return { token: outcome.token, account: record.account };
154
+ // Map structured outcomes to the typed error contract.
155
+ const message = outcome.reason === 'slot-empty'
156
+ ? `${SECURE_STORE_DESCRIPTION} returned no credential for the stored account; the keyring entry may have been removed externally.`
157
+ : outcome.reason === 'slot-unavailable'
158
+ ? `${SECURE_STORE_DESCRIPTION} unavailable; could not read stored token (${outcome.detail})`
159
+ : `Access-slot read failed (${outcome.detail})`;
160
+ throw new CliError('AUTH_STORE_READ_FAILED', message);
133
161
  },
134
162
  async set(account, token) {
135
163
  // Reset the cached storage result up front so a caller that
@@ -138,25 +166,29 @@ export function createKeyringTokenStore(options) {
138
166
  lastStorageResult = undefined;
139
167
  const { storedSecurely } = await writeRecordWithKeyringFallback({
140
168
  secureStore: secureStoreFor(account),
169
+ refreshStore: refreshSecureStoreFor(account),
141
170
  userRecords,
142
171
  account,
143
172
  token,
144
173
  });
145
- // Best-effort default promotion: the record is already persisted,
146
- // so a failure here must not turn into `AUTH_STORE_WRITE_FAILED`
147
- // (the user can recover by setting a default later).
148
- try {
149
- const existingDefault = await userRecords.getDefaultId();
150
- if (!existingDefault) {
151
- await userRecords.setDefaultId(account.id);
152
- }
153
- }
154
- catch {
155
- // best-effort
174
+ await promoteDefaultIfNeeded(account.id);
175
+ lastStorageResult = bundleStorageResult(storedSecurely, undefined);
176
+ },
177
+ async setBundle(account, bundle, options) {
178
+ lastStorageResult = undefined;
179
+ const { accessStoredSecurely, refreshStoredSecurely } = await writeBundleWithKeyringFallback({
180
+ accessStore: secureStoreFor(account),
181
+ refreshStore: refreshSecureStoreFor(account),
182
+ userRecords,
183
+ account,
184
+ bundle,
185
+ });
186
+ // Opt-in: silent refresh omits `promoteDefault` so it can't
187
+ // re-pin selection; login passes `true` to match `set()`.
188
+ if (options?.promoteDefault) {
189
+ await promoteDefaultIfNeeded(account.id);
156
190
  }
157
- lastStorageResult = storedSecurely
158
- ? { storage: 'secure-store' }
159
- : fallbackResult('token saved as plaintext in');
191
+ lastStorageResult = bundleStorageResult(accessStoredSecurely, refreshStoredSecurely);
160
192
  },
161
193
  async clear(ref) {
162
194
  // Reset up front for the same reason as `set` — and so a no-op
@@ -183,22 +215,19 @@ export function createKeyringTokenStore(options) {
183
215
  }
184
216
  }
185
217
  const fallbackClear = fallbackResult('local auth state cleared in');
186
- // Always attempt the keyring delete. Even when the record carried
187
- // a `fallbackToken`, an older keyring entry may still be parked
188
- // there from a prior keyring-online write that was later replaced
189
- // by an offline-fallback write skipping the delete would leak
190
- // that orphan. Downgrade *any* failure to a warning: the record
191
- // is already gone, so re-throwing would corrupt local state
192
- // (caller sees an exception and assumes nothing was cleared,
193
- // even though the next `account list` will show the user gone).
194
- try {
195
- await secureStoreFor(record.account).deleteSecret();
196
- lastClearResult =
197
- record.fallbackToken !== undefined ? fallbackClear : { storage: 'secure-store' };
198
- }
199
- catch {
200
- lastClearResult = fallbackClear;
201
- }
218
+ // Always attempt both deletes a record's `fallbackToken`
219
+ // doesn't rule out an orphan keyring entry from a prior online
220
+ // write. Failures downgrade to a warning: the record is already
221
+ // gone, re-throwing would corrupt the caller's state.
222
+ const [accessOutcome, refreshOutcome] = await Promise.allSettled([
223
+ secureStoreFor(record.account).deleteSecret(),
224
+ refreshSecureStoreFor(record.account).deleteSecret(),
225
+ ]);
226
+ const fellBack = accessOutcome.status === 'rejected' ||
227
+ refreshOutcome.status === 'rejected' ||
228
+ record.fallbackToken !== undefined ||
229
+ record.fallbackRefreshToken !== undefined;
230
+ lastClearResult = fellBack ? fallbackClear : { storage: 'secure-store' };
202
231
  },
203
232
  async list() {
204
233
  const snapshot = await readFullSnapshot();
@@ -1 +1 @@
1
- {"version":3,"file":"token-store.js","sourceRoot":"","sources":["../../../src/auth/keyring/token-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"token-store.js","sourceRoot":"","sources":["../../../src/auth/keyring/token-store.ts"],"names":[],"mappings":"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"}