@doist/outline-cli 1.7.0 → 1.8.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/CHANGELOG.md +6 -0
- package/dist/commands/auth.js +10 -2
- package/dist/commands/auth.js.map +1 -1
- package/dist/lib/api.js +32 -4
- package/dist/lib/api.js.map +1 -1
- package/dist/lib/auth-provider.js +84 -88
- package/dist/lib/auth-provider.js.map +1 -1
- package/dist/lib/auth.d.ts +23 -0
- package/dist/lib/auth.js +85 -3
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/config.d.ts +7 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/user-records.js +29 -8
- package/dist/lib/user-records.js.map +1 -1
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## [1.8.0](https://github.com/Doist/outline-cli/compare/v1.7.0...v1.8.0) (2026-05-21)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* **auth:** silent OAuth token refresh ([#75](https://github.com/Doist/outline-cli/issues/75)) ([83996d5](https://github.com/Doist/outline-cli/commit/83996d56810e28e608d91a981fd3b313dcdeb4d3))
|
|
6
|
+
|
|
1
7
|
## [1.7.0](https://github.com/Doist/outline-cli/compare/v1.6.0...v1.7.0) (2026-05-17)
|
|
2
8
|
|
|
3
9
|
### Features
|
package/dist/commands/auth.js
CHANGED
|
@@ -3,6 +3,7 @@ import chalk from 'chalk';
|
|
|
3
3
|
import { apiRequest } from '../lib/api.js';
|
|
4
4
|
import { renderError, renderSuccess } from '../lib/auth-pages.js';
|
|
5
5
|
import { createOutlineAuthProvider, createOutlineTokenStore, getActiveTokenSource, } from '../lib/auth-provider.js';
|
|
6
|
+
import { refreshedTokenForStatus } from '../lib/auth.js';
|
|
6
7
|
import { CliError } from '../lib/errors.js';
|
|
7
8
|
const DEFAULT_OAUTH_CALLBACK_PORT = 54969;
|
|
8
9
|
function resolvePreferredCallbackPort() {
|
|
@@ -65,10 +66,17 @@ export function registerAuthCommand(program) {
|
|
|
65
66
|
attachStatusCommand(auth, {
|
|
66
67
|
store,
|
|
67
68
|
description: 'Show current authentication state',
|
|
68
|
-
async fetchLive({
|
|
69
|
+
async fetchLive({ account, token }) {
|
|
69
70
|
try {
|
|
71
|
+
// Refresh the *selected* account before the check (scoped via
|
|
72
|
+
// its id + base URL/client id), then probe with the rotated
|
|
73
|
+
// token. Outline access tokens last ~an hour; without this
|
|
74
|
+
// `auth status` can't self-heal even though normal commands
|
|
75
|
+
// do. Passing the resolved token keeps the check tied to the
|
|
76
|
+
// requested account rather than the default.
|
|
77
|
+
const liveToken = await refreshedTokenForStatus(account, token);
|
|
70
78
|
const [{ data: info }, source] = await Promise.all([
|
|
71
|
-
apiRequest('auth.info', {}, { token, baseUrl: account.baseUrl }),
|
|
79
|
+
apiRequest('auth.info', {}, { token: liveToken, baseUrl: account.baseUrl }),
|
|
72
80
|
getActiveTokenSource(),
|
|
73
81
|
]);
|
|
74
82
|
statusData = { email: info.user.email, source };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/api.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { fetchWithRetry } from '../transport/fetch-with-retry.js';
|
|
2
|
-
import {
|
|
2
|
+
import { TOKEN_ENV_VAR } from './auth-constants.js';
|
|
3
|
+
import { getApiToken, getBaseUrl, proactiveRefresh, reactiveRefresh } from './auth.js';
|
|
3
4
|
import { withSpinner } from './spinner.js';
|
|
4
5
|
/**
|
|
5
6
|
* Spinner configuration mapping API paths to spinner options.
|
|
@@ -22,25 +23,52 @@ const API_SPINNER_CONFIG = {
|
|
|
22
23
|
'collections.update': { text: 'Updating collection...', color: 'yellow' },
|
|
23
24
|
'collections.delete': { text: 'Deleting collection...', color: 'yellow' },
|
|
24
25
|
};
|
|
26
|
+
/**
|
|
27
|
+
* Resolve the token for a request. A caller-supplied override is used as-is.
|
|
28
|
+
* On the managed path, prefer the token `proactiveRefresh` resolved (rotated
|
|
29
|
+
* or current) so unrefreshable/access-only accounts stay on a single store
|
|
30
|
+
* read; only fall back to `getApiToken` when proactive refresh bows out.
|
|
31
|
+
*/
|
|
32
|
+
async function resolveRequestToken(managed, override) {
|
|
33
|
+
if (override)
|
|
34
|
+
return override;
|
|
35
|
+
if (managed) {
|
|
36
|
+
const refreshed = await proactiveRefresh();
|
|
37
|
+
if (refreshed)
|
|
38
|
+
return refreshed;
|
|
39
|
+
}
|
|
40
|
+
return getApiToken();
|
|
41
|
+
}
|
|
25
42
|
/**
|
|
26
43
|
* Core API request function without spinner wrapping.
|
|
27
44
|
*/
|
|
28
45
|
async function rawApiRequest(path, body = {}, overrides = {}) {
|
|
46
|
+
// Only stored credentials can be refreshed: a caller-supplied token
|
|
47
|
+
// override or the `OUTLINE_API_TOKEN` env var is taken as-is.
|
|
48
|
+
const managed = !overrides.token && !process.env[TOKEN_ENV_VAR]?.trim();
|
|
49
|
+
// Resolve the base URL and the (proactively refreshed) token in parallel.
|
|
29
50
|
const [resolvedBaseUrl, resolvedToken] = await Promise.all([
|
|
30
51
|
overrides.baseUrl ? Promise.resolve(overrides.baseUrl.replace(/\/$/, '')) : getBaseUrl(),
|
|
31
|
-
|
|
52
|
+
resolveRequestToken(managed, overrides.token),
|
|
32
53
|
]);
|
|
33
|
-
const
|
|
54
|
+
const performRequest = (token) => fetchWithRetry({
|
|
34
55
|
url: `${resolvedBaseUrl}/api/${path}`,
|
|
35
56
|
options: {
|
|
36
57
|
method: 'POST',
|
|
37
58
|
headers: {
|
|
38
59
|
'Content-Type': 'application/json',
|
|
39
|
-
Authorization: `Bearer ${
|
|
60
|
+
Authorization: `Bearer ${token}`,
|
|
40
61
|
},
|
|
41
62
|
body: JSON.stringify(body),
|
|
42
63
|
},
|
|
43
64
|
});
|
|
65
|
+
let res = await performRequest(resolvedToken);
|
|
66
|
+
// Reactive path: a 401 on a managed token triggers a forced rotation and
|
|
67
|
+
// a single retry. `reactiveRefresh` throws `NoTokenError` when the refresh
|
|
68
|
+
// token is gone, so an unrecoverable 401 surfaces the re-login hint.
|
|
69
|
+
if (res.status === 401 && managed && (await reactiveRefresh())) {
|
|
70
|
+
res = await performRequest(await getApiToken());
|
|
71
|
+
}
|
|
44
72
|
if (!res.ok) {
|
|
45
73
|
let message = `API error: ${res.status} ${res.statusText}`;
|
|
46
74
|
try {
|
package/dist/lib/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAA;AACjE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createInterface } from 'node:readline/promises';
|
|
2
|
-
import { createKeyringTokenStore,
|
|
2
|
+
import { createKeyringTokenStore, createPkceProvider, } from '@doist/cli-core/auth';
|
|
3
3
|
import { fetchWithRetry } from '../transport/fetch-with-retry.js';
|
|
4
4
|
import { apiRequest } from './api.js';
|
|
5
5
|
import { LEGACY_CLEAR_PAYLOAD, SECURE_STORE_SERVICE, TOKEN_ENV_VAR } from './auth-constants.js';
|
|
@@ -8,9 +8,6 @@ import { getConfig, getConfigPath, updateConfig } from './config.js';
|
|
|
8
8
|
import { runMigrateLegacyAuth } from './migrate-auth.js';
|
|
9
9
|
import { makeOutlineAccount } from './outline-account.js';
|
|
10
10
|
import { createOutlineUserRecordStore, getDefaultUserRecord } from './user-records.js';
|
|
11
|
-
function asHandshake(value) {
|
|
12
|
-
return value;
|
|
13
|
-
}
|
|
14
11
|
function stringFlag(flags, key) {
|
|
15
12
|
const value = flags[key];
|
|
16
13
|
return typeof value === 'string' && value.trim() ? value.trim() : undefined;
|
|
@@ -49,68 +46,54 @@ async function resolveClientId(flags) {
|
|
|
49
46
|
}
|
|
50
47
|
return answered;
|
|
51
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Routes cli-core's OAuth HTTP through outline's transport so the proxy /
|
|
51
|
+
* decompression dispatcher applies — to the token exchange AND the
|
|
52
|
+
* oauth4webapi refresh grant (cli-core threads this into oauth4webapi's
|
|
53
|
+
* `customFetch`), which would otherwise capture the bare global `fetch`.
|
|
54
|
+
*/
|
|
55
|
+
const outlineFetch = (input, init) => fetchWithRetry({ url: input, options: init ?? {} });
|
|
52
56
|
export function createOutlineAuthProvider() {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
url.searchParams.set('code_challenge_method', 'S256');
|
|
64
|
-
url.searchParams.set('redirect_uri', redirectUri);
|
|
65
|
-
url.searchParams.set('state', state);
|
|
66
|
-
const handshake = { baseUrl, clientId, codeVerifier };
|
|
67
|
-
return { authorizeUrl: url.toString(), handshake };
|
|
57
|
+
// Captured at `authorize` (which may prompt for it) and reused by
|
|
58
|
+
// `exchangeCode` / `validate` so a single login can't double-prompt. A
|
|
59
|
+
// provider built only for silent refresh never runs `authorize`, so this
|
|
60
|
+
// stays undefined there and `tokenUrl` falls back to stored config — the
|
|
61
|
+
// refresh path must never prompt.
|
|
62
|
+
let baseUrl;
|
|
63
|
+
return createPkceProvider({
|
|
64
|
+
authorizeUrl: async ({ flags }) => {
|
|
65
|
+
baseUrl = await resolveBaseUrl(flags);
|
|
66
|
+
return `${baseUrl}/oauth/authorize`;
|
|
68
67
|
},
|
|
69
|
-
async
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
grant_type: 'authorization_code',
|
|
76
|
-
client_id: hs.clientId,
|
|
77
|
-
redirect_uri: redirectUri,
|
|
78
|
-
code_verifier: hs.codeVerifier,
|
|
79
|
-
code,
|
|
80
|
-
});
|
|
81
|
-
const res = await fetchWithRetry({
|
|
82
|
-
url: `${hs.baseUrl}/oauth/token`,
|
|
83
|
-
options: {
|
|
84
|
-
method: 'POST',
|
|
85
|
-
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
86
|
-
body: params.toString(),
|
|
87
|
-
},
|
|
88
|
-
});
|
|
89
|
-
const json = (await res.json().catch(() => ({})));
|
|
90
|
-
if (!res.ok) {
|
|
91
|
-
const message = json.error_description || json.message || json.error || res.statusText;
|
|
92
|
-
throw new Error(`OAuth token exchange failed: ${message}`);
|
|
93
|
-
}
|
|
94
|
-
if (!json.access_token) {
|
|
95
|
-
throw new Error('OAuth token exchange did not return an access token.');
|
|
96
|
-
}
|
|
97
|
-
return { accessToken: json.access_token };
|
|
68
|
+
tokenUrl: async ({ handshake }) => {
|
|
69
|
+
// `handshake.baseUrl` lets a caller scope refresh to a specific
|
|
70
|
+
// account's instance (status --user); otherwise the authorize-time
|
|
71
|
+
// value, then the default config.
|
|
72
|
+
const base = baseUrl ?? handshake.baseUrl ?? (await getBaseUrl());
|
|
73
|
+
return `${base}/oauth/token`;
|
|
98
74
|
},
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
75
|
+
// Prefer a handshake-scoped client id (account-aware refresh); else
|
|
76
|
+
// resolve from flag/config (only prompts when neither is set, so it's
|
|
77
|
+
// safe on the refresh path — the logged-in record carries one).
|
|
78
|
+
clientId: ({ handshake, flags }) => {
|
|
79
|
+
const fromHandshake = handshake.clientId;
|
|
80
|
+
return typeof fromHandshake === 'string' && fromHandshake
|
|
81
|
+
? fromHandshake
|
|
82
|
+
: resolveClientId(flags);
|
|
83
|
+
},
|
|
84
|
+
validate: async ({ token, handshake }) => {
|
|
85
|
+
const base = baseUrl ?? (await getBaseUrl());
|
|
86
|
+
const { data } = await apiRequest('auth.info', {}, { token, baseUrl: base });
|
|
105
87
|
return makeOutlineAccount({
|
|
106
88
|
id: data.user.id,
|
|
107
89
|
label: data.user.name,
|
|
108
|
-
baseUrl:
|
|
109
|
-
oauthClientId:
|
|
90
|
+
baseUrl: base,
|
|
91
|
+
oauthClientId: handshake.clientId,
|
|
110
92
|
teamName: data.team.name,
|
|
111
93
|
});
|
|
112
94
|
},
|
|
113
|
-
|
|
95
|
+
fetchImpl: outlineFetch,
|
|
96
|
+
});
|
|
114
97
|
}
|
|
115
98
|
/**
|
|
116
99
|
* Accepts the Outline user UUID or display name. Id matches are
|
|
@@ -218,39 +201,52 @@ export function createOutlineTokenStore() {
|
|
|
218
201
|
const result = await ensureMigrated(); // memoised
|
|
219
202
|
return result === null || !migrationIsConclusive(result);
|
|
220
203
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
}),
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
await ensureMigrated();
|
|
237
|
-
const fromStore = await inner.active(ref);
|
|
238
|
-
if (fromStore)
|
|
239
|
-
return fromStore;
|
|
240
|
-
const legacy = await readLegacyTokenSnapshot();
|
|
241
|
-
if (legacy && (ref === undefined || matchOutlineAccount(legacy.account, ref))) {
|
|
242
|
-
return legacy;
|
|
204
|
+
/**
|
|
205
|
+
* Shared env → v2 → legacy resolution for `active` / `activeBundle`.
|
|
206
|
+
* `fromV2` reads the matching cli-core method; `fromEnvOrLegacy` maps an
|
|
207
|
+
* env/legacy token into the caller's shape (env + legacy carry no refresh
|
|
208
|
+
* material, so the bundle form surfaces as access-only).
|
|
209
|
+
*/
|
|
210
|
+
async function resolveAuth(ref, fromV2, fromEnvOrLegacy) {
|
|
211
|
+
if (ref === undefined) {
|
|
212
|
+
const envToken = process.env[TOKEN_ENV_VAR]?.trim();
|
|
213
|
+
if (envToken) {
|
|
214
|
+
return fromEnvOrLegacy(envToken, makeOutlineAccount({ id: '', label: '', baseUrl: await getBaseUrl() }));
|
|
243
215
|
}
|
|
244
|
-
|
|
216
|
+
}
|
|
217
|
+
await ensureMigrated();
|
|
218
|
+
const fromStore = await fromV2();
|
|
219
|
+
if (fromStore)
|
|
220
|
+
return fromStore;
|
|
221
|
+
const legacy = await readLegacyTokenSnapshot();
|
|
222
|
+
if (legacy && (ref === undefined || matchOutlineAccount(legacy.account, ref))) {
|
|
223
|
+
return fromEnvOrLegacy(legacy.token, legacy.account);
|
|
224
|
+
}
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
// `ensureMigrated` runs before the v2 write so the post-write discharge
|
|
228
|
+
// can't race a pending migration into re-grabbing the legacy token. The
|
|
229
|
+
// discharge is best-effort: a lingering `api_token` is dormant because
|
|
230
|
+
// reads hit v2 first. (`clear` needs the stricter propagating variant.)
|
|
231
|
+
async function writeThenDischargeLegacy(write) {
|
|
232
|
+
await ensureMigrated();
|
|
233
|
+
await write();
|
|
234
|
+
if (await migrationIsInconclusive()) {
|
|
235
|
+
await dischargeLegacyState().catch(() => undefined);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return {
|
|
239
|
+
active(ref) {
|
|
240
|
+
return resolveAuth(ref, () => inner.active(ref), (token, account) => ({ token, account }));
|
|
245
241
|
},
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
242
|
+
activeBundle(ref) {
|
|
243
|
+
return resolveAuth(ref, () => inner.activeBundle(ref), (token, account) => ({ account, bundle: { accessToken: token } }));
|
|
244
|
+
},
|
|
245
|
+
set(account, token) {
|
|
246
|
+
return writeThenDischargeLegacy(() => inner.set(account, token));
|
|
247
|
+
},
|
|
248
|
+
setBundle(account, bundle, options) {
|
|
249
|
+
return writeThenDischargeLegacy(() => inner.setBundle(account, bundle, options));
|
|
254
250
|
},
|
|
255
251
|
async clear(ref) {
|
|
256
252
|
await ensureMigrated();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-provider.js","sourceRoot":"","sources":["../../src/lib/auth-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAGH,uBAAuB,EACvB,
|
|
1
|
+
{"version":3,"file":"auth-provider.js","sourceRoot":"","sources":["../../src/lib/auth-provider.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/auth.d.ts
CHANGED
|
@@ -2,10 +2,33 @@ import { SecureStoreUnavailableError } from '@doist/cli-core/auth';
|
|
|
2
2
|
import { TOKEN_ENV_VAR } from './auth-constants.js';
|
|
3
3
|
import { getActiveTokenSource } from './auth-provider.js';
|
|
4
4
|
import { CliError } from './errors.js';
|
|
5
|
+
import { type OutlineAccount } from './outline-account.js';
|
|
5
6
|
export { SecureStoreUnavailableError, getActiveTokenSource, TOKEN_ENV_VAR };
|
|
6
7
|
export declare class NoTokenError extends CliError {
|
|
7
8
|
constructor();
|
|
8
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* Best-effort proactive rotation before a request. Returns the token to use
|
|
12
|
+
* (the rotated one, or the current one if no rotation was needed) so the
|
|
13
|
+
* caller doesn't re-read the store; `undefined` when the default account
|
|
14
|
+
* isn't refreshable (no refresh token / env / failure) — the caller then
|
|
15
|
+
* falls back to `getApiToken()` and the 401 path stays authoritative.
|
|
16
|
+
*/
|
|
17
|
+
export declare function proactiveRefresh(): Promise<string | undefined>;
|
|
18
|
+
/**
|
|
19
|
+
* Refresh the *selected* account (not the default) for `auth status`, returning
|
|
20
|
+
* its current-or-rotated token. Scoped via the account's id + base URL/client
|
|
21
|
+
* id through the refresh handshake, so `--user <other>` checks and rotates the
|
|
22
|
+
* right account at the right instance. Env / legacy / record-less accounts
|
|
23
|
+
* aren't refreshable — the snapshot `fallback` token is returned as-is.
|
|
24
|
+
*/
|
|
25
|
+
export declare function refreshedTokenForStatus(account: OutlineAccount, fallback: string): Promise<string>;
|
|
26
|
+
/**
|
|
27
|
+
* Reactive rotation after a 401. Returns `true` when the token rotated (the
|
|
28
|
+
* caller retries once). A rejected/absent refresh token surfaces as
|
|
29
|
+
* `NoTokenError` (re-login); a transient failure propagates unchanged.
|
|
30
|
+
*/
|
|
31
|
+
export declare function reactiveRefresh(): Promise<boolean>;
|
|
9
32
|
/**
|
|
10
33
|
* Read the active token. Hot path: when `OUTLINE_API_TOKEN` is set we
|
|
11
34
|
* return it directly without consulting the token store, since
|
package/dist/lib/auth.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { SecureStoreUnavailableError } from '@doist/cli-core/auth';
|
|
1
|
+
import { refreshAccessToken, SecureStoreUnavailableError } from '@doist/cli-core/auth';
|
|
2
2
|
import { TOKEN_ENV_VAR } from './auth-constants.js';
|
|
3
|
-
import { createOutlineTokenStore, getActiveTokenSource, } from './auth-provider.js';
|
|
4
|
-
import { getConfig } from './config.js';
|
|
3
|
+
import { createOutlineAuthProvider, createOutlineTokenStore, getActiveTokenSource, } from './auth-provider.js';
|
|
4
|
+
import { getConfig, getConfigPath } from './config.js';
|
|
5
5
|
import { CliError } from './errors.js';
|
|
6
6
|
import { DEFAULT_BASE_URL } from './outline-account.js';
|
|
7
7
|
import { getDefaultUserRecord } from './user-records.js';
|
|
@@ -23,6 +23,88 @@ function tokenStore() {
|
|
|
23
23
|
storeSingleton = createOutlineTokenStore();
|
|
24
24
|
return storeSingleton;
|
|
25
25
|
}
|
|
26
|
+
let providerSingleton;
|
|
27
|
+
function authProvider() {
|
|
28
|
+
if (!providerSingleton)
|
|
29
|
+
providerSingleton = createOutlineAuthProvider();
|
|
30
|
+
return providerSingleton;
|
|
31
|
+
}
|
|
32
|
+
// Caller-provided O_EXCL lock so concurrent `ol` invocations don't issue
|
|
33
|
+
// parallel refresh grants. Resolved per-call (not cached) to honour test
|
|
34
|
+
// config-path mocking, mirroring `getConfigPath`.
|
|
35
|
+
function refreshLockPath() {
|
|
36
|
+
return `${getConfigPath()}.refresh.lock`;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Best-effort proactive rotation before a request. Returns the token to use
|
|
40
|
+
* (the rotated one, or the current one if no rotation was needed) so the
|
|
41
|
+
* caller doesn't re-read the store; `undefined` when the default account
|
|
42
|
+
* isn't refreshable (no refresh token / env / failure) — the caller then
|
|
43
|
+
* falls back to `getApiToken()` and the 401 path stays authoritative.
|
|
44
|
+
*/
|
|
45
|
+
export async function proactiveRefresh() {
|
|
46
|
+
try {
|
|
47
|
+
const { bundle } = await refreshAccessToken({
|
|
48
|
+
store: tokenStore(),
|
|
49
|
+
provider: authProvider(),
|
|
50
|
+
lockPath: refreshLockPath(),
|
|
51
|
+
});
|
|
52
|
+
return bundle.accessToken;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Refresh the *selected* account (not the default) for `auth status`, returning
|
|
60
|
+
* its current-or-rotated token. Scoped via the account's id + base URL/client
|
|
61
|
+
* id through the refresh handshake, so `--user <other>` checks and rotates the
|
|
62
|
+
* right account at the right instance. Env / legacy / record-less accounts
|
|
63
|
+
* aren't refreshable — the snapshot `fallback` token is returned as-is.
|
|
64
|
+
*/
|
|
65
|
+
export async function refreshedTokenForStatus(account, fallback) {
|
|
66
|
+
if (process.env[TOKEN_ENV_VAR]?.trim() || !account.id)
|
|
67
|
+
return fallback;
|
|
68
|
+
try {
|
|
69
|
+
const { bundle } = await refreshAccessToken({
|
|
70
|
+
store: tokenStore(),
|
|
71
|
+
provider: authProvider(),
|
|
72
|
+
lockPath: refreshLockPath(),
|
|
73
|
+
ref: account.id,
|
|
74
|
+
handshake: { baseUrl: account.baseUrl, clientId: account.oauthClientId },
|
|
75
|
+
});
|
|
76
|
+
return bundle.accessToken;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return fallback;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Reactive rotation after a 401. Returns `true` when the token rotated (the
|
|
84
|
+
* caller retries once). A rejected/absent refresh token surfaces as
|
|
85
|
+
* `NoTokenError` (re-login); a transient failure propagates unchanged.
|
|
86
|
+
*/
|
|
87
|
+
export async function reactiveRefresh() {
|
|
88
|
+
try {
|
|
89
|
+
const result = await refreshAccessToken({
|
|
90
|
+
store: tokenStore(),
|
|
91
|
+
provider: authProvider(),
|
|
92
|
+
lockPath: refreshLockPath(),
|
|
93
|
+
force: true,
|
|
94
|
+
});
|
|
95
|
+
return result.rotated;
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
// Match on the structural `.code` rather than `instanceof`: cli-core
|
|
99
|
+
// throws its own CliError, and class identity isn't reliable across
|
|
100
|
+
// package boundaries (duplicate module instances under linking).
|
|
101
|
+
const code = err?.code;
|
|
102
|
+
if (code === 'AUTH_REFRESH_EXPIRED' || code === 'AUTH_REFRESH_UNAVAILABLE') {
|
|
103
|
+
throw new NoTokenError();
|
|
104
|
+
}
|
|
105
|
+
throw err;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
26
108
|
/**
|
|
27
109
|
* Read the active token. Hot path: when `OUTLINE_API_TOKEN` is set we
|
|
28
110
|
* return it directly without consulting the token store, since
|
package/dist/lib/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -10,7 +10,14 @@ export type StoredUser = {
|
|
|
10
10
|
base_url?: string;
|
|
11
11
|
oauth_client_id?: string;
|
|
12
12
|
team_name?: string;
|
|
13
|
+
/** Plaintext access-token fallback, present only when the keyring was unavailable at write time. */
|
|
13
14
|
token?: string;
|
|
15
|
+
/** Access-token expiry (unix-epoch ms); drives proactive refresh. */
|
|
16
|
+
access_token_expires_at?: number;
|
|
17
|
+
/** Refresh-token expiry (unix-epoch ms), when the server returns one. */
|
|
18
|
+
refresh_token_expires_at?: number;
|
|
19
|
+
/** Whether a refresh token is stored (keyring slot or `refresh_token`). */
|
|
20
|
+
has_refresh_token?: boolean;
|
|
14
21
|
};
|
|
15
22
|
export type Config = CoreConfig & {
|
|
16
23
|
config_version?: number;
|
package/dist/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,aAAa,IAAI,iBAAiB,EAClC,UAAU,IAAI,cAAc,EAC5B,YAAY,IAAI,gBAAgB,EAChC,WAAW,IAAI,eAAe,GACjC,MAAM,iBAAiB,CAAA;AAExB,MAAM,QAAQ,GAAG,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,aAAa,IAAI,iBAAiB,EAClC,UAAU,IAAI,cAAc,EAC5B,YAAY,IAAI,gBAAgB,EAChC,WAAW,IAAI,eAAe,GACjC,MAAM,iBAAiB,CAAA;AAExB,MAAM,QAAQ,GAAG,aAAa,CAAA;AAwC9B;;;;GAIG;AACH,MAAM,UAAU,aAAa;IACzB,OAAO,iBAAiB,CAAC,QAAQ,CAAC,CAAA;AACtC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS;IAC3B,OAAO,cAAc,CAAS,aAAa,EAAE,CAAC,CAAA;AAClD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAAc;IAC1C,OAAO,eAAe,CAAC,aAAa,EAAE,EAAE,MAAM,CAAC,CAAA;AACnD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAwB;IACvD,OAAO,gBAAgB,CAAS,aAAa,EAAE,EAAE,OAAO,CAAC,CAAA;AAC7D,CAAC"}
|
package/dist/lib/user-records.js
CHANGED
|
@@ -62,16 +62,23 @@ function toRecord(user) {
|
|
|
62
62
|
oauthClientId: user.oauth_client_id,
|
|
63
63
|
teamName: user.team_name,
|
|
64
64
|
});
|
|
65
|
-
const trimmed = user.token?.trim();
|
|
66
65
|
const record = { account };
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
const token = user.token?.trim();
|
|
67
|
+
if (token)
|
|
68
|
+
record.fallbackToken = token;
|
|
69
|
+
if (user.access_token_expires_at !== undefined) {
|
|
70
|
+
record.accessTokenExpiresAt = user.access_token_expires_at;
|
|
71
|
+
}
|
|
72
|
+
if (user.refresh_token_expires_at !== undefined) {
|
|
73
|
+
record.refreshTokenExpiresAt = user.refresh_token_expires_at;
|
|
74
|
+
}
|
|
75
|
+
if (user.has_refresh_token !== undefined)
|
|
76
|
+
record.hasRefreshToken = user.has_refresh_token;
|
|
69
77
|
return record;
|
|
70
78
|
}
|
|
71
79
|
function fromRecord(record) {
|
|
72
|
-
// Replace, don't merge:
|
|
73
|
-
//
|
|
74
|
-
const trimmed = record.fallbackToken?.trim();
|
|
80
|
+
// Replace, don't merge: absent fields strip the corresponding slots so a
|
|
81
|
+
// stale value can't shadow a fresh keyring-backed write. cli-core contract.
|
|
75
82
|
const next = {
|
|
76
83
|
id: record.account.id,
|
|
77
84
|
name: record.account.label,
|
|
@@ -82,8 +89,22 @@ function fromRecord(record) {
|
|
|
82
89
|
next.oauth_client_id = record.account.oauthClientId;
|
|
83
90
|
if (record.account.teamName)
|
|
84
91
|
next.team_name = record.account.teamName;
|
|
85
|
-
|
|
86
|
-
|
|
92
|
+
const token = record.fallbackToken?.trim();
|
|
93
|
+
if (token)
|
|
94
|
+
next.token = token;
|
|
95
|
+
// Deliberately NOT persisting `fallbackRefreshToken`: the refresh token is
|
|
96
|
+
// a long-lived credential and must stay in the secure store only. If the
|
|
97
|
+
// keyring is offline at write time, the refresh token isn't persisted, so
|
|
98
|
+
// that account fails closed (re-auth on next expiry) rather than leaving a
|
|
99
|
+
// long-lived secret in plaintext config. (Doist secrets-management standard.)
|
|
100
|
+
if (record.accessTokenExpiresAt !== undefined) {
|
|
101
|
+
next.access_token_expires_at = record.accessTokenExpiresAt;
|
|
102
|
+
}
|
|
103
|
+
if (record.refreshTokenExpiresAt !== undefined) {
|
|
104
|
+
next.refresh_token_expires_at = record.refreshTokenExpiresAt;
|
|
105
|
+
}
|
|
106
|
+
if (record.hasRefreshToken !== undefined)
|
|
107
|
+
next.has_refresh_token = record.hasRefreshToken;
|
|
87
108
|
return next;
|
|
88
109
|
}
|
|
89
110
|
//# sourceMappingURL=user-records.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-records.js","sourceRoot":"","sources":["../../src/lib/user-records.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"user-records.js","sourceRoot":"","sources":["../../src/lib/user-records.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@doist/outline-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "CLI for the Outline wiki/knowledge base API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -48,11 +48,12 @@
|
|
|
48
48
|
"node": ">=20.18.1"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@doist/cli-core": "0.
|
|
51
|
+
"@doist/cli-core": "0.19.0",
|
|
52
52
|
"chalk": "5.6.2",
|
|
53
53
|
"commander": "14.0.2",
|
|
54
54
|
"marked": "18.0.3",
|
|
55
55
|
"marked-terminal-renderer": "2.2.0",
|
|
56
|
+
"oauth4webapi": "3.8.6",
|
|
56
57
|
"open": "10.2.0",
|
|
57
58
|
"undici": "7.22.0"
|
|
58
59
|
},
|