@tiangong-lca/cli 0.1.6 → 0.1.7
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/README.md +3 -13
- package/dist/src/cli.js +20 -36
- package/dist/src/cli.js.map +1 -1
- package/dist/src/lib/auth-identity-receipt.d.ts +1 -2
- package/dist/src/lib/auth-identity-receipt.js +3 -20
- package/dist/src/lib/auth-identity-receipt.js.map +1 -1
- package/dist/src/lib/credential-safety.d.ts +7 -0
- package/dist/src/lib/credential-safety.js +28 -0
- package/dist/src/lib/credential-safety.js.map +1 -0
- package/dist/src/lib/dataset-save-draft-run.js +3 -1
- package/dist/src/lib/dataset-save-draft-run.js.map +1 -1
- package/dist/src/lib/env.d.ts +0 -2
- package/dist/src/lib/env.js +11 -19
- package/dist/src/lib/env.js.map +1 -1
- package/dist/src/lib/flow-publish-reviewed-data.js +1 -1
- package/dist/src/lib/flow-publish-reviewed-data.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-resulting-process.js +2 -6
- package/dist/src/lib/lifecyclemodel-resulting-process.js.map +1 -1
- package/dist/src/lib/process-refresh-references.js +1 -1
- package/dist/src/lib/process-refresh-references.js.map +1 -1
- package/dist/src/lib/process-scope-statistics.js +1 -1
- package/dist/src/lib/process-scope-statistics.js.map +1 -1
- package/dist/src/lib/supabase-client.d.ts +1 -3
- package/dist/src/lib/supabase-client.js +5 -15
- package/dist/src/lib/supabase-client.js.map +1 -1
- package/dist/src/lib/supabase-session.d.ts +5 -14
- package/dist/src/lib/supabase-session.js +34 -113
- package/dist/src/lib/supabase-session.js.map +1 -1
- package/package.json +1 -2
- package/dist/src/lib/user-api-key.d.ts +0 -16
- package/dist/src/lib/user-api-key.js +0 -75
- package/dist/src/lib/user-api-key.js.map +0 -1
|
@@ -5,7 +5,7 @@ import { exchangeOAuthAuthorizationCode, fetchOAuthUserInfo, type OAuthPkceValue
|
|
|
5
5
|
import { type SupabaseDataRuntime, type SupabaseRestRuntime } from './supabase-client.js';
|
|
6
6
|
export type CachedSupabaseSessionRecord = {
|
|
7
7
|
schema_version: 2;
|
|
8
|
-
auth_method: 'oauth'
|
|
8
|
+
auth_method: 'oauth';
|
|
9
9
|
supabase_url: string;
|
|
10
10
|
publishable_key_fingerprint: string;
|
|
11
11
|
auth_binding_fingerprint: string;
|
|
@@ -23,13 +23,13 @@ export type ResolvedSupabaseUserSession = {
|
|
|
23
23
|
userEmail: string;
|
|
24
24
|
projectBaseUrl: string;
|
|
25
25
|
sessionFile: string | null;
|
|
26
|
-
authMethod: 'oauth' | 'access_token'
|
|
27
|
-
source: 'memory' | 'cache' | 'refresh' | 'oauth_login' | '
|
|
26
|
+
authMethod: 'oauth' | 'access_token';
|
|
27
|
+
source: 'memory' | 'cache' | 'refresh' | 'oauth_login' | 'access_token';
|
|
28
28
|
};
|
|
29
29
|
type RuntimeIdentity = {
|
|
30
30
|
projectBaseUrl: string;
|
|
31
31
|
publishableKeyFingerprint: string;
|
|
32
|
-
authMethod: 'oauth' | 'access_token'
|
|
32
|
+
authMethod: 'oauth' | 'access_token';
|
|
33
33
|
authBindingFingerprint: string;
|
|
34
34
|
sessionFilePath: string | null;
|
|
35
35
|
memoKey: string;
|
|
@@ -61,18 +61,10 @@ declare function memoizeRecord(runtime: RuntimeIdentity, record: CachedSupabaseS
|
|
|
61
61
|
declare function dropMemoizedRecord(runtime: RuntimeIdentity): void;
|
|
62
62
|
declare function withSessionOperationLock<T>(memoKey: string, task: () => Promise<T>): Promise<T>;
|
|
63
63
|
declare function createSupabaseAuthClient(runtime: RuntimeIdentity, publishableKey: string, fetchImpl: FetchLike, timeoutMs: number): import("@supabase/supabase-js").SupabaseClient<any, "public", "public", any, any>;
|
|
64
|
-
declare function signInWithUserApiKey(options: {
|
|
65
|
-
runtime: SupabaseRestRuntime;
|
|
66
|
-
runtimeIdentity: RuntimeIdentity;
|
|
67
|
-
fetchImpl: FetchLike;
|
|
68
|
-
timeoutMs: number;
|
|
69
|
-
now: Date;
|
|
70
|
-
}): Promise<CachedSupabaseSessionRecord>;
|
|
71
64
|
declare function refreshWithRefreshToken(options: {
|
|
72
65
|
runtime: SupabaseRestRuntime;
|
|
73
66
|
runtimeIdentity: RuntimeIdentity;
|
|
74
67
|
refreshToken: string;
|
|
75
|
-
userEmail: string;
|
|
76
68
|
fetchImpl: FetchLike;
|
|
77
69
|
timeoutMs: number;
|
|
78
70
|
now: Date;
|
|
@@ -109,7 +101,7 @@ export type AuthStatusReceipt = {
|
|
|
109
101
|
schemaVersion: 'tiangong.cli-auth-status.v1';
|
|
110
102
|
status: 'ready' | 'login-required';
|
|
111
103
|
authMethod: ResolvedSupabaseUserSession['authMethod'];
|
|
112
|
-
sessionState: 'fresh' | 'refresh-required' | 'memory-only' | '
|
|
104
|
+
sessionState: 'fresh' | 'refresh-required' | 'memory-only' | 'missing';
|
|
113
105
|
sessionCache: 'private-file' | 'disabled' | 'memory-only';
|
|
114
106
|
expiresAt: number | null;
|
|
115
107
|
grantedScopes: string[];
|
|
@@ -163,7 +155,6 @@ export declare const __testInternals: {
|
|
|
163
155
|
resolveDefaultSessionFilePath: typeof resolveDefaultSessionFilePath;
|
|
164
156
|
resolveAndPersistSession: typeof resolveAndPersistSession;
|
|
165
157
|
resolveSessionFilePath: typeof resolveSessionFilePath;
|
|
166
|
-
signInWithUserApiKey: typeof signInWithUserApiKey;
|
|
167
158
|
withSessionOperationLock: typeof withSessionOperationLock;
|
|
168
159
|
writeCachedSessionRecord: typeof writeCachedSessionRecord;
|
|
169
160
|
};
|
|
@@ -7,7 +7,7 @@ import { openSystemBrowser, receiveOAuthLoopbackCallback, SYSTEM_BROWSER_OPTIONS
|
|
|
7
7
|
import { buildOAuthAuthorizationUrl, createOAuthPkceValues, DEFAULT_OAUTH_SCOPES, exchangeOAuthAuthorizationCode, fetchOAuthUserInfo, refreshOAuthTokens, } from './oauth-pkce.js';
|
|
8
8
|
import { withStateFileLock } from './state-lock.js';
|
|
9
9
|
import { createSupabaseFetch, deriveSupabaseProjectBaseUrl, } from './supabase-client.js';
|
|
10
|
-
import { fingerprintSecret
|
|
10
|
+
import { fingerprintSecret } from './credential-safety.js';
|
|
11
11
|
const DEFAULT_TIMEOUT_MS = 10_000;
|
|
12
12
|
const SESSION_REFRESH_WINDOW_SECONDS = 300;
|
|
13
13
|
const SESSION_MEMORY_CACHE = new Map();
|
|
@@ -35,19 +35,13 @@ function parseCachedSessionRecord(value) {
|
|
|
35
35
|
if (!isRecord(value)) {
|
|
36
36
|
return null;
|
|
37
37
|
}
|
|
38
|
-
if (value.schema_version !==
|
|
38
|
+
if (value.schema_version !== 2) {
|
|
39
39
|
return null;
|
|
40
40
|
}
|
|
41
41
|
const supabaseUrl = trimToken(value.supabase_url);
|
|
42
42
|
const publishableKeyFingerprint = trimToken(value.publishable_key_fingerprint);
|
|
43
|
-
const authMethod = value.
|
|
44
|
-
|
|
45
|
-
: value.auth_method === 'oauth' || value.auth_method === 'legacy_user_api_key'
|
|
46
|
-
? value.auth_method
|
|
47
|
-
: null;
|
|
48
|
-
const authBindingFingerprint = value.schema_version === 1
|
|
49
|
-
? trimToken(value.user_api_key_fingerprint)
|
|
50
|
-
: trimToken(value.auth_binding_fingerprint);
|
|
43
|
+
const authMethod = value.auth_method === 'oauth' ? 'oauth' : null;
|
|
44
|
+
const authBindingFingerprint = trimToken(value.auth_binding_fingerprint);
|
|
51
45
|
const userEmail = trimToken(value.user_email);
|
|
52
46
|
const accessToken = trimToken(value.access_token);
|
|
53
47
|
const refreshToken = trimToken(value.refresh_token);
|
|
@@ -57,12 +51,10 @@ function parseCachedSessionRecord(value) {
|
|
|
57
51
|
: value.expires_at === null
|
|
58
52
|
? null
|
|
59
53
|
: NaN;
|
|
60
|
-
const grantedScopes = value.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
? [...new Set(value.granted_scopes.map((scope) => scope.trim()))].sort((left, right) => left.localeCompare(right))
|
|
65
|
-
: null;
|
|
54
|
+
const grantedScopes = Array.isArray(value.granted_scopes) &&
|
|
55
|
+
value.granted_scopes.every((scope) => typeof scope === 'string' && scope.trim())
|
|
56
|
+
? [...new Set(value.granted_scopes.map((scope) => scope.trim()))].sort((left, right) => left.localeCompare(right))
|
|
57
|
+
: null;
|
|
66
58
|
if (!supabaseUrl ||
|
|
67
59
|
!publishableKeyFingerprint ||
|
|
68
60
|
!authMethod ||
|
|
@@ -123,9 +115,7 @@ function buildRuntimeIdentity(runtime) {
|
|
|
123
115
|
const publishableKeyFingerprint = fingerprintSecret(runtime.publishableKey);
|
|
124
116
|
const authBindingFingerprint = runtime.authMode === 'oauth'
|
|
125
117
|
? fingerprintSecret(`oauth-client:${runtime.oauthClientId}`)
|
|
126
|
-
: runtime.
|
|
127
|
-
? fingerprintSecret(runtime.accessToken)
|
|
128
|
-
: fingerprintUserApiKey(runtime.userApiKey);
|
|
118
|
+
: fingerprintSecret(runtime.accessToken);
|
|
129
119
|
const sessionFilePath = resolveSessionFilePath(runtime);
|
|
130
120
|
return {
|
|
131
121
|
projectBaseUrl,
|
|
@@ -164,7 +154,7 @@ function buildCachedSessionRecord(options) {
|
|
|
164
154
|
}
|
|
165
155
|
return {
|
|
166
156
|
schema_version: 2,
|
|
167
|
-
auth_method:
|
|
157
|
+
auth_method: 'oauth',
|
|
168
158
|
supabase_url: options.runtime.projectBaseUrl,
|
|
169
159
|
publishable_key_fingerprint: options.runtime.publishableKeyFingerprint,
|
|
170
160
|
auth_binding_fingerprint: options.runtime.authBindingFingerprint,
|
|
@@ -267,76 +257,35 @@ function createSupabaseAuthClient(runtime, publishableKey, fetchImpl, timeoutMs)
|
|
|
267
257
|
},
|
|
268
258
|
});
|
|
269
259
|
}
|
|
270
|
-
async function signInWithUserApiKey(options) {
|
|
271
|
-
const credentials = requireUserApiKeyCredentials(options.runtime.userApiKey);
|
|
272
|
-
const authClient = createSupabaseAuthClient(options.runtimeIdentity, options.runtime.publishableKey, options.fetchImpl, options.timeoutMs);
|
|
273
|
-
const { data, error } = await authClient.auth.signInWithPassword({
|
|
274
|
-
email: credentials.email,
|
|
275
|
-
password: credentials.password,
|
|
276
|
-
});
|
|
277
|
-
if (error || !data.session) {
|
|
278
|
-
throw new CliError('Failed to sign in with TIANGONG_LCA_API_KEY.', {
|
|
279
|
-
code: 'SUPABASE_AUTH_SIGN_IN_FAILED',
|
|
280
|
-
exitCode: 1,
|
|
281
|
-
details: error?.message ?? 'Supabase auth session missing from sign-in response.',
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
return buildCachedSessionRecord({
|
|
285
|
-
runtime: options.runtimeIdentity,
|
|
286
|
-
session: data.session,
|
|
287
|
-
userEmail: trimToken(data.user?.email) || credentials.email,
|
|
288
|
-
grantedScopes: [],
|
|
289
|
-
now: options.now,
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
260
|
async function refreshWithRefreshToken(options) {
|
|
293
261
|
const normalizedRefreshToken = trimToken(options.refreshToken);
|
|
294
262
|
if (!normalizedRefreshToken) {
|
|
295
263
|
return null;
|
|
296
264
|
}
|
|
297
265
|
try {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
timeoutMs: options.timeoutMs,
|
|
311
|
-
});
|
|
312
|
-
return buildCachedSessionRecord({
|
|
313
|
-
runtime: options.runtimeIdentity,
|
|
314
|
-
session: {
|
|
315
|
-
access_token: tokens.accessToken,
|
|
316
|
-
refresh_token: tokens.refreshToken,
|
|
317
|
-
expires_at: undefined,
|
|
318
|
-
expires_in: tokens.expiresIn,
|
|
319
|
-
},
|
|
320
|
-
userEmail: userInfo.email,
|
|
321
|
-
grantedScopes: tokens.scope,
|
|
322
|
-
now: options.now,
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
if (options.runtime.authMode !== 'legacy_user_api_key') {
|
|
326
|
-
return null;
|
|
327
|
-
}
|
|
328
|
-
const authClient = createSupabaseAuthClient(options.runtimeIdentity, options.runtime.publishableKey, options.fetchImpl, options.timeoutMs);
|
|
329
|
-
const { data, error } = await authClient.auth.refreshSession({
|
|
330
|
-
refresh_token: normalizedRefreshToken,
|
|
266
|
+
const tokens = await refreshOAuthTokens({
|
|
267
|
+
projectBaseUrl: options.runtimeIdentity.projectBaseUrl,
|
|
268
|
+
clientId: options.runtime.oauthClientId,
|
|
269
|
+
refreshToken: normalizedRefreshToken,
|
|
270
|
+
fetchImpl: options.fetchImpl,
|
|
271
|
+
timeoutMs: options.timeoutMs,
|
|
272
|
+
});
|
|
273
|
+
const userInfo = await fetchOAuthUserInfo({
|
|
274
|
+
projectBaseUrl: options.runtimeIdentity.projectBaseUrl,
|
|
275
|
+
accessToken: tokens.accessToken,
|
|
276
|
+
fetchImpl: options.fetchImpl,
|
|
277
|
+
timeoutMs: options.timeoutMs,
|
|
331
278
|
});
|
|
332
|
-
if (error || !data.session) {
|
|
333
|
-
return null;
|
|
334
|
-
}
|
|
335
279
|
return buildCachedSessionRecord({
|
|
336
280
|
runtime: options.runtimeIdentity,
|
|
337
|
-
session:
|
|
338
|
-
|
|
339
|
-
|
|
281
|
+
session: {
|
|
282
|
+
access_token: tokens.accessToken,
|
|
283
|
+
refresh_token: tokens.refreshToken,
|
|
284
|
+
expires_at: undefined,
|
|
285
|
+
expires_in: tokens.expiresIn,
|
|
286
|
+
},
|
|
287
|
+
userEmail: userInfo.email,
|
|
288
|
+
grantedScopes: tokens.scope,
|
|
340
289
|
now: options.now,
|
|
341
290
|
});
|
|
342
291
|
}
|
|
@@ -417,7 +366,6 @@ async function resolveAndPersistSession(options) {
|
|
|
417
366
|
runtime,
|
|
418
367
|
runtimeIdentity,
|
|
419
368
|
refreshToken: refreshCandidate.refresh_token,
|
|
420
|
-
userEmail: refreshCandidate.user_email,
|
|
421
369
|
fetchImpl: options.fetchImpl,
|
|
422
370
|
timeoutMs: options.timeoutMs,
|
|
423
371
|
now: options.now,
|
|
@@ -431,25 +379,11 @@ async function resolveAndPersistSession(options) {
|
|
|
431
379
|
}
|
|
432
380
|
}
|
|
433
381
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
exitCode: 1,
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
const signedIn = await signInWithUserApiKey({
|
|
442
|
-
runtime,
|
|
443
|
-
runtimeIdentity,
|
|
444
|
-
fetchImpl: options.fetchImpl,
|
|
445
|
-
timeoutMs: options.timeoutMs,
|
|
446
|
-
now: options.now,
|
|
382
|
+
dropMemoizedRecord(runtimeIdentity);
|
|
383
|
+
throw new CliError('No usable OAuth session is available. Run `tiangong-lca auth login` in a trusted terminal.', {
|
|
384
|
+
code: 'SUPABASE_OAUTH_LOGIN_REQUIRED',
|
|
385
|
+
exitCode: 1,
|
|
447
386
|
});
|
|
448
|
-
if (runtimeIdentity.sessionFilePath) {
|
|
449
|
-
writeCachedSessionRecord(runtimeIdentity.sessionFilePath, signedIn);
|
|
450
|
-
}
|
|
451
|
-
memoizeRecord(runtimeIdentity, signedIn);
|
|
452
|
-
return toResolvedSession(signedIn, runtimeIdentity, 'legacy_signin');
|
|
453
387
|
}
|
|
454
388
|
export async function resolveSupabaseUserSession(options) {
|
|
455
389
|
const runtimeIdentity = buildRuntimeIdentity(options.runtime);
|
|
@@ -517,18 +451,6 @@ export function inspectSupabaseAuthStatus(options) {
|
|
|
517
451
|
onlineVerified: false,
|
|
518
452
|
};
|
|
519
453
|
}
|
|
520
|
-
if (options.runtime.authMode === 'legacy_user_api_key') {
|
|
521
|
-
return {
|
|
522
|
-
schemaVersion: 'tiangong.cli-auth-status.v1',
|
|
523
|
-
status: 'ready',
|
|
524
|
-
authMethod: 'legacy_user_api_key',
|
|
525
|
-
sessionState: 'transition-only',
|
|
526
|
-
sessionCache: runtimeIdentity.sessionFilePath ? 'private-file' : 'disabled',
|
|
527
|
-
expiresAt: null,
|
|
528
|
-
grantedScopes: [],
|
|
529
|
-
onlineVerified: false,
|
|
530
|
-
};
|
|
531
|
-
}
|
|
532
454
|
const memoized = getMemoizedRecord(runtimeIdentity);
|
|
533
455
|
const cached = memoized && recordMatchesRuntime(memoized, runtimeIdentity)
|
|
534
456
|
? memoized
|
|
@@ -711,7 +633,6 @@ export const __testInternals = {
|
|
|
711
633
|
resolveDefaultSessionFilePath,
|
|
712
634
|
resolveAndPersistSession,
|
|
713
635
|
resolveSessionFilePath,
|
|
714
|
-
signInWithUserApiKey,
|
|
715
636
|
withSessionOperationLock,
|
|
716
637
|
writeCachedSessionRecord,
|
|
717
638
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supabase-session.js","sourceRoot":"","sources":["../../../src/lib/supabase-session.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n chmodSync,\n mkdirSync,\n readFileSync,\n renameSync,\n rmSync,\n statSync,\n writeFileSync,\n} from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { createClient, type Session } from '@supabase/supabase-js';\nimport { CliError } from './errors.js';\nimport type { FetchLike } from './http.js';\nimport {\n openSystemBrowser,\n receiveOAuthLoopbackCallback,\n SYSTEM_BROWSER_OPTIONS,\n type BrowserSpawn,\n} from './oauth-loopback.js';\nimport {\n buildOAuthAuthorizationUrl,\n createOAuthPkceValues,\n DEFAULT_OAUTH_SCOPES,\n exchangeOAuthAuthorizationCode,\n fetchOAuthUserInfo,\n refreshOAuthTokens,\n type OAuthPkceValues,\n} from './oauth-pkce.js';\nimport { withStateFileLock } from './state-lock.js';\nimport {\n createSupabaseFetch,\n deriveSupabaseProjectBaseUrl,\n type SupabaseDataRuntime,\n type SupabaseRestRuntime,\n} from './supabase-client.js';\nimport {\n fingerprintSecret,\n fingerprintUserApiKey,\n requireUserApiKeyCredentials,\n} from './user-api-key.js';\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\nconst SESSION_REFRESH_WINDOW_SECONDS = 300;\n\nexport type CachedSupabaseSessionRecord = {\n schema_version: 2;\n auth_method: 'oauth' | 'legacy_user_api_key';\n supabase_url: string;\n publishable_key_fingerprint: string;\n auth_binding_fingerprint: string;\n user_email: string;\n access_token: string;\n refresh_token: string;\n expires_at: number | null;\n granted_scopes: string[];\n updated_at_utc: string;\n};\n\nexport type ResolvedSupabaseUserSession = {\n accessToken: string;\n refreshToken: string;\n expiresAt: number | null;\n userEmail: string;\n projectBaseUrl: string;\n sessionFile: string | null;\n authMethod: 'oauth' | 'access_token' | 'legacy_user_api_key';\n source: 'memory' | 'cache' | 'refresh' | 'oauth_login' | 'legacy_signin' | 'access_token';\n};\n\ntype RuntimeIdentity = {\n projectBaseUrl: string;\n publishableKeyFingerprint: string;\n authMethod: 'oauth' | 'access_token' | 'legacy_user_api_key';\n authBindingFingerprint: string;\n sessionFilePath: string | null;\n memoKey: string;\n};\n\nconst SESSION_MEMORY_CACHE = new Map<string, CachedSupabaseSessionRecord>();\nconst ACCESS_TOKEN_MEMORY_CACHE = new Map<string, ResolvedSupabaseUserSession>();\nconst SESSION_OPERATION_CHAINS = new Map<string, Promise<void>>();\n\nfunction trimToken(value: unknown): string {\n return typeof value === 'string' ? value.trim() : '';\n}\n\nfunction nowSeconds(now: Date): number {\n return Math.floor(now.getTime() / 1000);\n}\n\ntype SessionTokenFields = Pick<\n Session,\n 'access_token' | 'refresh_token' | 'expires_at' | 'expires_in'\n>;\n\nfunction computeExpiresAt(session: SessionTokenFields, now: Date): number | null {\n if (typeof session.expires_at === 'number' && Number.isFinite(session.expires_at)) {\n return Math.floor(session.expires_at);\n }\n\n if (typeof session.expires_in === 'number' && Number.isFinite(session.expires_in)) {\n return nowSeconds(now) + Math.max(Math.floor(session.expires_in), 0);\n }\n\n return null;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction parseCachedSessionRecord(value: unknown): CachedSupabaseSessionRecord | null {\n if (!isRecord(value)) {\n return null;\n }\n\n if (value.schema_version !== 1 && value.schema_version !== 2) {\n return null;\n }\n\n const supabaseUrl = trimToken(value.supabase_url);\n const publishableKeyFingerprint = trimToken(value.publishable_key_fingerprint);\n const authMethod =\n value.schema_version === 1\n ? 'legacy_user_api_key'\n : value.auth_method === 'oauth' || value.auth_method === 'legacy_user_api_key'\n ? value.auth_method\n : null;\n const authBindingFingerprint =\n value.schema_version === 1\n ? trimToken(value.user_api_key_fingerprint)\n : trimToken(value.auth_binding_fingerprint);\n const userEmail = trimToken(value.user_email);\n const accessToken = trimToken(value.access_token);\n const refreshToken = trimToken(value.refresh_token);\n const updatedAtUtc = trimToken(value.updated_at_utc);\n const expiresAt =\n typeof value.expires_at === 'number' && Number.isFinite(value.expires_at)\n ? Math.floor(value.expires_at)\n : value.expires_at === null\n ? null\n : NaN;\n const grantedScopes =\n value.schema_version === 1\n ? []\n : Array.isArray(value.granted_scopes) &&\n value.granted_scopes.every((scope) => typeof scope === 'string' && scope.trim())\n ? [...new Set(value.granted_scopes.map((scope) => scope.trim()))].sort((left, right) =>\n left.localeCompare(right),\n )\n : null;\n\n if (\n !supabaseUrl ||\n !publishableKeyFingerprint ||\n !authMethod ||\n !authBindingFingerprint ||\n !userEmail ||\n !accessToken ||\n !refreshToken ||\n !updatedAtUtc ||\n Number.isNaN(expiresAt) ||\n grantedScopes === null\n ) {\n return null;\n }\n\n return {\n schema_version: 2,\n auth_method: authMethod,\n supabase_url: supabaseUrl,\n publishable_key_fingerprint: publishableKeyFingerprint,\n auth_binding_fingerprint: authBindingFingerprint,\n user_email: userEmail,\n access_token: accessToken,\n refresh_token: refreshToken,\n expires_at: expiresAt,\n granted_scopes: grantedScopes,\n updated_at_utc: updatedAtUtc,\n };\n}\n\nfunction resolveDefaultSessionFilePath(options: {\n platform: NodeJS.Platform;\n homeDir: string;\n xdgStateHome: string | null;\n localAppData: string | null;\n}): string {\n if (options.xdgStateHome) {\n return path.join(options.xdgStateHome, 'tiangong-lca-cli', 'session.json');\n }\n\n if (options.homeDir) {\n return path.join(options.homeDir, '.local', 'state', 'tiangong-lca-cli', 'session.json');\n }\n\n if (options.platform === 'darwin') {\n return path.join(\n os.homedir(),\n 'Library',\n 'Application Support',\n 'tiangong-lca-cli',\n 'session.json',\n );\n }\n\n if (options.platform === 'win32' && options.localAppData) {\n return path.join(options.localAppData, 'tiangong-lca-cli', 'session.json');\n }\n\n return path.resolve('.tiangong-lca-session.json');\n}\n\nfunction resolveSessionFilePath(runtime: SupabaseRestRuntime): string | null {\n if (runtime.authMode === 'access_token' || runtime.disableSessionCache) {\n return null;\n }\n\n if (runtime.sessionFile) {\n return path.resolve(runtime.sessionFile);\n }\n\n return resolveDefaultSessionFilePath({\n platform: process.platform,\n homeDir: trimToken(os.homedir()),\n xdgStateHome: trimToken(process.env.XDG_STATE_HOME) || null,\n localAppData: trimToken(process.env.LOCALAPPDATA) || null,\n });\n}\n\nfunction buildRuntimeIdentity(runtime: SupabaseRestRuntime): RuntimeIdentity {\n const projectBaseUrl = deriveSupabaseProjectBaseUrl(runtime.apiBaseUrl);\n const publishableKeyFingerprint = fingerprintSecret(runtime.publishableKey);\n const authBindingFingerprint =\n runtime.authMode === 'oauth'\n ? fingerprintSecret(`oauth-client:${runtime.oauthClientId as string}`)\n : runtime.authMode === 'access_token'\n ? fingerprintSecret(runtime.accessToken as string)\n : fingerprintUserApiKey(runtime.userApiKey as string);\n const sessionFilePath = resolveSessionFilePath(runtime);\n\n return {\n projectBaseUrl,\n publishableKeyFingerprint,\n authMethod: runtime.authMode,\n authBindingFingerprint,\n sessionFilePath,\n memoKey: [\n projectBaseUrl,\n publishableKeyFingerprint,\n runtime.authMode,\n authBindingFingerprint,\n sessionFilePath ?? 'memory-only',\n ].join('|'),\n };\n}\n\nfunction recordMatchesRuntime(\n record: CachedSupabaseSessionRecord,\n runtime: RuntimeIdentity,\n): boolean {\n return (\n record.supabase_url === runtime.projectBaseUrl &&\n record.publishable_key_fingerprint === runtime.publishableKeyFingerprint &&\n record.auth_method === runtime.authMethod &&\n record.auth_binding_fingerprint === runtime.authBindingFingerprint\n );\n}\n\nfunction isSessionFresh(record: CachedSupabaseSessionRecord, now: Date): boolean {\n return (\n typeof record.expires_at === 'number' &&\n Number.isFinite(record.expires_at) &&\n record.expires_at > nowSeconds(now) + SESSION_REFRESH_WINDOW_SECONDS\n );\n}\n\nfunction buildCachedSessionRecord(options: {\n runtime: RuntimeIdentity;\n session: SessionTokenFields;\n userEmail: string;\n grantedScopes?: string[];\n now: Date;\n}): CachedSupabaseSessionRecord {\n const accessToken = trimToken(options.session.access_token);\n const refreshToken = trimToken(options.session.refresh_token);\n if (!accessToken || !refreshToken) {\n throw new CliError('Supabase auth did not return a usable session.', {\n code: 'SUPABASE_AUTH_SESSION_INVALID',\n exitCode: 1,\n });\n }\n\n return {\n schema_version: 2,\n auth_method: options.runtime.authMethod === 'oauth' ? 'oauth' : 'legacy_user_api_key',\n supabase_url: options.runtime.projectBaseUrl,\n publishable_key_fingerprint: options.runtime.publishableKeyFingerprint,\n auth_binding_fingerprint: options.runtime.authBindingFingerprint,\n user_email: options.userEmail,\n access_token: accessToken,\n refresh_token: refreshToken,\n expires_at: computeExpiresAt(options.session, options.now),\n granted_scopes: [...new Set(options.grantedScopes ?? [])].sort(),\n updated_at_utc: options.now.toISOString(),\n };\n}\n\nfunction toResolvedSession(\n record: CachedSupabaseSessionRecord,\n runtime: RuntimeIdentity,\n source: ResolvedSupabaseUserSession['source'],\n): ResolvedSupabaseUserSession {\n return {\n accessToken: record.access_token,\n refreshToken: record.refresh_token,\n expiresAt: record.expires_at,\n userEmail: record.user_email,\n projectBaseUrl: runtime.projectBaseUrl,\n sessionFile: runtime.sessionFilePath,\n authMethod: runtime.authMethod,\n source,\n };\n}\n\nfunction readCachedSessionRecord(\n sessionFilePath: string,\n platform: NodeJS.Platform = process.platform,\n): CachedSupabaseSessionRecord | null {\n try {\n const stat = statSync(sessionFilePath);\n if (!stat.isFile() || (platform !== 'win32' && (stat.mode & 0o077) !== 0)) {\n return null;\n }\n const text = readFileSync(sessionFilePath, 'utf8').trim();\n if (!text) {\n return null;\n }\n\n return parseCachedSessionRecord(JSON.parse(text));\n } catch {\n return null;\n }\n}\n\nfunction writeCachedSessionRecord(\n sessionFilePath: string,\n record: CachedSupabaseSessionRecord,\n platform: NodeJS.Platform = process.platform,\n): void {\n mkdirSync(path.dirname(sessionFilePath), {\n recursive: true,\n mode: 0o700,\n });\n if (platform !== 'win32') {\n chmodSync(path.dirname(sessionFilePath), 0o700);\n }\n\n const tempPath = `${sessionFilePath}.${process.pid}.${Date.now()}.tmp`;\n try {\n writeFileSync(tempPath, `${JSON.stringify(record, null, 2)}\\n`, {\n encoding: 'utf8',\n flag: 'wx',\n mode: 0o600,\n });\n renameSync(tempPath, sessionFilePath);\n chmodSync(sessionFilePath, 0o600);\n } catch (error) {\n rmSync(tempPath, { force: true });\n throw error;\n }\n}\n\nfunction getMemoizedRecord(runtime: RuntimeIdentity): CachedSupabaseSessionRecord | null {\n return SESSION_MEMORY_CACHE.get(runtime.memoKey) ?? null;\n}\n\nfunction memoizeRecord(runtime: RuntimeIdentity, record: CachedSupabaseSessionRecord): void {\n SESSION_MEMORY_CACHE.set(runtime.memoKey, record);\n}\n\nfunction dropMemoizedRecord(runtime: RuntimeIdentity): void {\n SESSION_MEMORY_CACHE.delete(runtime.memoKey);\n}\n\nasync function withSessionOperationLock<T>(memoKey: string, task: () => Promise<T>): Promise<T> {\n const previous = SESSION_OPERATION_CHAINS.get(memoKey) ?? Promise.resolve();\n let release!: () => void;\n const gate = new Promise<void>((resolve) => {\n release = resolve;\n });\n const chain = previous.catch(() => undefined).then(() => gate);\n SESSION_OPERATION_CHAINS.set(memoKey, chain);\n\n await previous.catch(() => undefined);\n try {\n return await task();\n } finally {\n release();\n if (SESSION_OPERATION_CHAINS.get(memoKey) === chain) {\n SESSION_OPERATION_CHAINS.delete(memoKey);\n }\n }\n}\n\nfunction createSupabaseAuthClient(\n runtime: RuntimeIdentity,\n publishableKey: string,\n fetchImpl: FetchLike,\n timeoutMs: number,\n) {\n return createClient(runtime.projectBaseUrl, publishableKey, {\n auth: {\n autoRefreshToken: false,\n persistSession: false,\n detectSessionInUrl: false,\n },\n global: {\n fetch: createSupabaseFetch(fetchImpl, timeoutMs),\n },\n });\n}\n\nasync function signInWithUserApiKey(options: {\n runtime: SupabaseRestRuntime;\n runtimeIdentity: RuntimeIdentity;\n fetchImpl: FetchLike;\n timeoutMs: number;\n now: Date;\n}): Promise<CachedSupabaseSessionRecord> {\n const credentials = requireUserApiKeyCredentials(options.runtime.userApiKey as string);\n const authClient = createSupabaseAuthClient(\n options.runtimeIdentity,\n options.runtime.publishableKey,\n options.fetchImpl,\n options.timeoutMs,\n );\n const { data, error } = await authClient.auth.signInWithPassword({\n email: credentials.email,\n password: credentials.password,\n });\n\n if (error || !data.session) {\n throw new CliError('Failed to sign in with TIANGONG_LCA_API_KEY.', {\n code: 'SUPABASE_AUTH_SIGN_IN_FAILED',\n exitCode: 1,\n details: error?.message ?? 'Supabase auth session missing from sign-in response.',\n });\n }\n\n return buildCachedSessionRecord({\n runtime: options.runtimeIdentity,\n session: data.session,\n userEmail: trimToken(data.user?.email) || credentials.email,\n grantedScopes: [],\n now: options.now,\n });\n}\n\nasync function refreshWithRefreshToken(options: {\n runtime: SupabaseRestRuntime;\n runtimeIdentity: RuntimeIdentity;\n refreshToken: string;\n userEmail: string;\n fetchImpl: FetchLike;\n timeoutMs: number;\n now: Date;\n}): Promise<CachedSupabaseSessionRecord | null> {\n const normalizedRefreshToken = trimToken(options.refreshToken);\n if (!normalizedRefreshToken) {\n return null;\n }\n\n try {\n if (options.runtime.authMode === 'oauth') {\n const tokens = await refreshOAuthTokens({\n projectBaseUrl: options.runtimeIdentity.projectBaseUrl,\n clientId: options.runtime.oauthClientId as string,\n refreshToken: normalizedRefreshToken,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n });\n const userInfo = await fetchOAuthUserInfo({\n projectBaseUrl: options.runtimeIdentity.projectBaseUrl,\n accessToken: tokens.accessToken,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n });\n return buildCachedSessionRecord({\n runtime: options.runtimeIdentity,\n session: {\n access_token: tokens.accessToken,\n refresh_token: tokens.refreshToken,\n expires_at: undefined,\n expires_in: tokens.expiresIn,\n },\n userEmail: userInfo.email,\n grantedScopes: tokens.scope,\n now: options.now,\n });\n }\n\n if (options.runtime.authMode !== 'legacy_user_api_key') {\n return null;\n }\n\n const authClient = createSupabaseAuthClient(\n options.runtimeIdentity,\n options.runtime.publishableKey,\n options.fetchImpl,\n options.timeoutMs,\n );\n const { data, error } = await authClient.auth.refreshSession({\n refresh_token: normalizedRefreshToken,\n });\n\n if (error || !data.session) {\n return null;\n }\n\n return buildCachedSessionRecord({\n runtime: options.runtimeIdentity,\n session: data.session,\n userEmail: trimToken(data.user?.email) || options.userEmail,\n grantedScopes: [],\n now: options.now,\n });\n } catch {\n return null;\n }\n}\n\nasync function resolveExplicitAccessToken(options: {\n runtime: SupabaseRestRuntime;\n runtimeIdentity: RuntimeIdentity;\n fetchImpl: FetchLike;\n timeoutMs: number;\n}): Promise<ResolvedSupabaseUserSession> {\n const cached = ACCESS_TOKEN_MEMORY_CACHE.get(options.runtimeIdentity.memoKey);\n if (cached) {\n return cached;\n }\n const accessToken = trimToken(options.runtime.accessToken);\n const authClient = createSupabaseAuthClient(\n options.runtimeIdentity,\n options.runtime.publishableKey,\n options.fetchImpl,\n options.timeoutMs,\n );\n const { data, error } = await authClient.auth.getUser(accessToken);\n const userEmail = trimToken(data.user?.email);\n if (error || !data.user?.id || data.user.role !== 'authenticated' || !userEmail) {\n throw new CliError('TIANGONG_LCA_ACCESS_TOKEN did not resolve to an authenticated user.', {\n code: 'SUPABASE_ACCESS_TOKEN_INVALID',\n exitCode: 1,\n details: error?.message ?? 'Authenticated user identity missing from access token.',\n });\n }\n\n const resolved: ResolvedSupabaseUserSession = {\n accessToken,\n refreshToken: '',\n expiresAt: null,\n userEmail,\n projectBaseUrl: options.runtimeIdentity.projectBaseUrl,\n sessionFile: null,\n authMethod: 'access_token',\n source: 'access_token',\n };\n ACCESS_TOKEN_MEMORY_CACHE.set(options.runtimeIdentity.memoKey, resolved);\n return resolved;\n}\n\nasync function resolveAndPersistSession(options: {\n runtime: SupabaseRestRuntime;\n runtimeIdentity: RuntimeIdentity;\n fetchImpl: FetchLike;\n timeoutMs: number;\n now: Date;\n forceRefresh: boolean;\n}): Promise<ResolvedSupabaseUserSession> {\n const { runtime, runtimeIdentity } = options;\n if (runtime.authMode === 'access_token') {\n return resolveExplicitAccessToken({\n runtime,\n runtimeIdentity,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n });\n }\n const memoized = getMemoizedRecord(runtimeIdentity);\n if (\n !options.forceRefresh &&\n !runtime.forceReauth &&\n memoized &&\n recordMatchesRuntime(memoized, runtimeIdentity) &&\n isSessionFresh(memoized, options.now)\n ) {\n return toResolvedSession(memoized, runtimeIdentity, 'memory');\n }\n\n const cachedFromDisk =\n runtimeIdentity.sessionFilePath !== null\n ? readCachedSessionRecord(runtimeIdentity.sessionFilePath)\n : null;\n if (\n !options.forceRefresh &&\n !runtime.forceReauth &&\n cachedFromDisk &&\n recordMatchesRuntime(cachedFromDisk, runtimeIdentity) &&\n isSessionFresh(cachedFromDisk, options.now)\n ) {\n memoizeRecord(runtimeIdentity, cachedFromDisk);\n return toResolvedSession(cachedFromDisk, runtimeIdentity, 'cache');\n }\n\n if (!runtime.forceReauth) {\n const refreshCandidate =\n cachedFromDisk &&\n recordMatchesRuntime(cachedFromDisk, runtimeIdentity) &&\n trimToken(cachedFromDisk.refresh_token)\n ? cachedFromDisk\n : memoized &&\n recordMatchesRuntime(memoized, runtimeIdentity) &&\n trimToken(memoized.refresh_token)\n ? memoized\n : null;\n\n if (refreshCandidate) {\n const refreshed = await refreshWithRefreshToken({\n runtime,\n runtimeIdentity,\n refreshToken: refreshCandidate.refresh_token,\n userEmail: refreshCandidate.user_email,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n now: options.now,\n });\n\n if (refreshed) {\n if (runtimeIdentity.sessionFilePath) {\n writeCachedSessionRecord(runtimeIdentity.sessionFilePath, refreshed);\n }\n memoizeRecord(runtimeIdentity, refreshed);\n return toResolvedSession(refreshed, runtimeIdentity, 'refresh');\n }\n }\n }\n\n if (runtime.authMode === 'oauth') {\n dropMemoizedRecord(runtimeIdentity);\n throw new CliError(\n 'No usable OAuth session is available. Run `tiangong-lca auth login` in a trusted terminal.',\n {\n code: 'SUPABASE_OAUTH_LOGIN_REQUIRED',\n exitCode: 1,\n },\n );\n }\n\n const signedIn = await signInWithUserApiKey({\n runtime,\n runtimeIdentity,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n now: options.now,\n });\n\n if (runtimeIdentity.sessionFilePath) {\n writeCachedSessionRecord(runtimeIdentity.sessionFilePath, signedIn);\n }\n memoizeRecord(runtimeIdentity, signedIn);\n return toResolvedSession(signedIn, runtimeIdentity, 'legacy_signin');\n}\n\nexport async function resolveSupabaseUserSession(options: {\n runtime: SupabaseRestRuntime;\n fetchImpl: FetchLike;\n timeoutMs?: number;\n now?: Date;\n forceRefresh?: boolean;\n}): Promise<ResolvedSupabaseUserSession> {\n const runtimeIdentity = buildRuntimeIdentity(options.runtime);\n const now = options.now ?? new Date();\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const forceRefresh = Boolean(options.forceRefresh);\n\n if (options.runtime.authMode === 'access_token') {\n return resolveExplicitAccessToken({\n runtime: options.runtime,\n runtimeIdentity,\n fetchImpl: options.fetchImpl,\n timeoutMs,\n });\n }\n\n if (!forceRefresh && !options.runtime.forceReauth) {\n const memoized = getMemoizedRecord(runtimeIdentity);\n if (\n memoized &&\n recordMatchesRuntime(memoized, runtimeIdentity) &&\n isSessionFresh(memoized, now)\n ) {\n return toResolvedSession(memoized, runtimeIdentity, 'memory');\n }\n\n if (runtimeIdentity.sessionFilePath) {\n const cached = readCachedSessionRecord(runtimeIdentity.sessionFilePath);\n if (cached && recordMatchesRuntime(cached, runtimeIdentity) && isSessionFresh(cached, now)) {\n memoizeRecord(runtimeIdentity, cached);\n return toResolvedSession(cached, runtimeIdentity, 'cache');\n }\n }\n }\n\n return withSessionOperationLock(runtimeIdentity.memoKey, async () => {\n if (runtimeIdentity.sessionFilePath) {\n return withStateFileLock(\n runtimeIdentity.sessionFilePath,\n {\n reason: forceRefresh ? 'refresh_supabase_user_session' : 'resolve_supabase_user_session',\n },\n () =>\n resolveAndPersistSession({\n runtime: options.runtime,\n runtimeIdentity,\n fetchImpl: options.fetchImpl,\n timeoutMs,\n now,\n forceRefresh,\n }),\n );\n }\n\n return resolveAndPersistSession({\n runtime: options.runtime,\n runtimeIdentity,\n fetchImpl: options.fetchImpl,\n timeoutMs,\n now,\n forceRefresh,\n });\n });\n}\n\nexport type OAuthLoginReceipt = {\n schemaVersion: 'tiangong.cli-oauth-login.v1';\n status: 'authenticated';\n authMethod: 'oauth';\n expiresAt: number;\n grantedScopes: string[];\n sessionCache: 'private-file';\n};\n\nexport type OAuthLogoutReceipt = {\n schemaVersion: 'tiangong.cli-oauth-logout.v1';\n status: 'logged-out';\n removed: boolean;\n};\n\nexport type AuthStatusReceipt = {\n schemaVersion: 'tiangong.cli-auth-status.v1';\n status: 'ready' | 'login-required';\n authMethod: ResolvedSupabaseUserSession['authMethod'];\n sessionState: 'fresh' | 'refresh-required' | 'memory-only' | 'transition-only' | 'missing';\n sessionCache: 'private-file' | 'disabled' | 'memory-only';\n expiresAt: number | null;\n grantedScopes: string[];\n onlineVerified: false;\n};\n\nexport function inspectSupabaseAuthStatus(options: {\n runtime: SupabaseRestRuntime;\n now?: Date;\n}): AuthStatusReceipt {\n const runtimeIdentity = buildRuntimeIdentity(options.runtime);\n const now = options.now ?? new Date();\n\n if (options.runtime.authMode === 'access_token') {\n return {\n schemaVersion: 'tiangong.cli-auth-status.v1',\n status: 'ready',\n authMethod: 'access_token',\n sessionState: 'memory-only',\n sessionCache: 'memory-only',\n expiresAt: null,\n grantedScopes: [],\n onlineVerified: false,\n };\n }\n\n if (options.runtime.authMode === 'legacy_user_api_key') {\n return {\n schemaVersion: 'tiangong.cli-auth-status.v1',\n status: 'ready',\n authMethod: 'legacy_user_api_key',\n sessionState: 'transition-only',\n sessionCache: runtimeIdentity.sessionFilePath ? 'private-file' : 'disabled',\n expiresAt: null,\n grantedScopes: [],\n onlineVerified: false,\n };\n }\n\n const memoized = getMemoizedRecord(runtimeIdentity);\n const cached =\n memoized && recordMatchesRuntime(memoized, runtimeIdentity)\n ? memoized\n : runtimeIdentity.sessionFilePath\n ? readCachedSessionRecord(runtimeIdentity.sessionFilePath)\n : null;\n const matching = cached && recordMatchesRuntime(cached, runtimeIdentity) ? cached : null;\n if (!matching || !trimToken(matching.refresh_token)) {\n return {\n schemaVersion: 'tiangong.cli-auth-status.v1',\n status: 'login-required',\n authMethod: 'oauth',\n sessionState: 'missing',\n sessionCache: runtimeIdentity.sessionFilePath ? 'private-file' : 'disabled',\n expiresAt: null,\n grantedScopes: [],\n onlineVerified: false,\n };\n }\n\n return {\n schemaVersion: 'tiangong.cli-auth-status.v1',\n status: 'ready',\n authMethod: 'oauth',\n sessionState: isSessionFresh(matching, now) ? 'fresh' : 'refresh-required',\n sessionCache: 'private-file',\n expiresAt: matching.expires_at,\n grantedScopes: matching.granted_scopes,\n onlineVerified: false,\n };\n}\n\nexport async function loginWithSupabaseOAuth(options: {\n runtime: SupabaseRestRuntime;\n fetchImpl: FetchLike;\n requestTimeoutMs?: number;\n loginTimeoutMs?: number;\n now?: Date;\n createPkceValuesImpl?: () => OAuthPkceValues;\n receiveCallbackImpl?: typeof receiveOAuthLoopbackCallback;\n openBrowserImpl?: (authorizationUrl: string) => Promise<void>;\n browserOptions?: { platform: NodeJS.Platform; spawnImpl: BrowserSpawn };\n exchangeCodeImpl?: typeof exchangeOAuthAuthorizationCode;\n fetchUserInfoImpl?: typeof fetchOAuthUserInfo;\n}): Promise<OAuthLoginReceipt> {\n if (\n options.runtime.authMode !== 'oauth' ||\n !options.runtime.oauthClientId ||\n !options.runtime.oauthRedirectUri\n ) {\n throw new CliError('OAuth login requires TIANGONG_LCA_AUTH_MODE=oauth and a client ID.', {\n code: 'SUPABASE_OAUTH_RUNTIME_REQUIRED',\n exitCode: 2,\n });\n }\n\n const runtimeIdentity = buildRuntimeIdentity(options.runtime);\n if (!runtimeIdentity.sessionFilePath) {\n throw new CliError('OAuth login requires the private session cache to be enabled.', {\n code: 'SUPABASE_OAUTH_SESSION_CACHE_REQUIRED',\n exitCode: 2,\n });\n }\n\n const requestTimeoutMs = options.requestTimeoutMs ?? DEFAULT_TIMEOUT_MS;\n const loginTimeoutMs = options.loginTimeoutMs ?? 180_000;\n const now = options.now ?? new Date();\n const createPkceValuesImpl = options.createPkceValuesImpl ?? createOAuthPkceValues;\n const receiveCallbackImpl = options.receiveCallbackImpl ?? receiveOAuthLoopbackCallback;\n const browserOptions = options.browserOptions ?? SYSTEM_BROWSER_OPTIONS;\n const openBrowserImpl =\n options.openBrowserImpl ??\n ((authorizationUrl) => openSystemBrowser(authorizationUrl, browserOptions));\n const exchangeCodeImpl = options.exchangeCodeImpl ?? exchangeOAuthAuthorizationCode;\n const fetchUserInfoImpl = options.fetchUserInfoImpl ?? fetchOAuthUserInfo;\n\n return withSessionOperationLock(runtimeIdentity.memoKey, () =>\n withStateFileLock(\n runtimeIdentity.sessionFilePath as string,\n { reason: 'supabase_oauth_pkce_login' },\n async () => {\n const pkce = createPkceValuesImpl();\n const authorizationUrl = buildOAuthAuthorizationUrl({\n projectBaseUrl: runtimeIdentity.projectBaseUrl,\n clientId: options.runtime.oauthClientId as string,\n redirectUri: options.runtime.oauthRedirectUri as string,\n codeChallenge: pkce.codeChallenge,\n state: pkce.state,\n });\n const authorizationCode = await receiveCallbackImpl({\n redirectUri: options.runtime.oauthRedirectUri as string,\n expectedState: pkce.state,\n timeoutMs: loginTimeoutMs,\n onListening: () => openBrowserImpl(authorizationUrl),\n });\n const tokens = await exchangeCodeImpl({\n projectBaseUrl: runtimeIdentity.projectBaseUrl,\n clientId: options.runtime.oauthClientId as string,\n redirectUri: options.runtime.oauthRedirectUri as string,\n authorizationCode,\n codeVerifier: pkce.codeVerifier,\n fetchImpl: options.fetchImpl,\n timeoutMs: requestTimeoutMs,\n });\n const userInfo = await fetchUserInfoImpl({\n projectBaseUrl: runtimeIdentity.projectBaseUrl,\n accessToken: tokens.accessToken,\n fetchImpl: options.fetchImpl,\n timeoutMs: requestTimeoutMs,\n });\n const grantedScopes = tokens.scope.length > 0 ? tokens.scope : [...DEFAULT_OAUTH_SCOPES];\n const record = buildCachedSessionRecord({\n runtime: runtimeIdentity,\n session: {\n access_token: tokens.accessToken,\n refresh_token: tokens.refreshToken,\n expires_at: undefined,\n expires_in: tokens.expiresIn,\n },\n userEmail: userInfo.email,\n grantedScopes,\n now,\n });\n writeCachedSessionRecord(runtimeIdentity.sessionFilePath as string, record);\n memoizeRecord(runtimeIdentity, record);\n return {\n schemaVersion: 'tiangong.cli-oauth-login.v1',\n status: 'authenticated',\n authMethod: 'oauth',\n expiresAt: record.expires_at as number,\n grantedScopes: record.granted_scopes,\n sessionCache: 'private-file',\n };\n },\n ),\n );\n}\n\nexport async function logoutSupabaseUserSession(options: {\n runtime: SupabaseRestRuntime;\n}): Promise<OAuthLogoutReceipt> {\n const runtimeIdentity = buildRuntimeIdentity(options.runtime);\n return withSessionOperationLock(runtimeIdentity.memoKey, async () => {\n let removed = false;\n const removeCurrent = () => {\n const cached = runtimeIdentity.sessionFilePath\n ? readCachedSessionRecord(runtimeIdentity.sessionFilePath)\n : null;\n if (\n runtimeIdentity.sessionFilePath &&\n cached &&\n recordMatchesRuntime(cached, runtimeIdentity)\n ) {\n rmSync(runtimeIdentity.sessionFilePath, { force: true });\n removed = true;\n }\n dropMemoizedRecord(runtimeIdentity);\n ACCESS_TOKEN_MEMORY_CACHE.delete(runtimeIdentity.memoKey);\n };\n\n if (runtimeIdentity.sessionFilePath) {\n await withStateFileLock(\n runtimeIdentity.sessionFilePath,\n { reason: 'supabase_oauth_local_logout' },\n removeCurrent,\n );\n } else {\n removeCurrent();\n }\n\n return {\n schemaVersion: 'tiangong.cli-oauth-logout.v1',\n status: 'logged-out',\n removed,\n };\n });\n}\n\nexport function createSupabaseDataRuntime(options: {\n runtime: SupabaseRestRuntime;\n fetchImpl: FetchLike;\n timeoutMs?: number;\n now?: Date;\n}): SupabaseDataRuntime {\n const runtime: SupabaseDataRuntime = {\n apiBaseUrl: options.runtime.apiBaseUrl,\n publishableKey: options.runtime.publishableKey,\n getAccessToken: async () =>\n (\n await resolveSupabaseUserSession({\n runtime: options.runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n now: options.now,\n })\n ).accessToken,\n };\n if (options.runtime.authMode !== 'access_token') {\n runtime.refreshAccessToken = async () =>\n (\n await resolveSupabaseUserSession({\n runtime: options.runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n now: options.now,\n forceRefresh: true,\n })\n ).accessToken;\n }\n return runtime;\n}\n\nexport const __testInternals = {\n SESSION_MEMORY_CACHE,\n ACCESS_TOKEN_MEMORY_CACHE,\n SESSION_OPERATION_CHAINS,\n buildCachedSessionRecord,\n buildRuntimeIdentity,\n computeExpiresAt,\n createSupabaseAuthClient,\n dropMemoizedRecord,\n getMemoizedRecord,\n isSessionFresh,\n memoizeRecord,\n parseCachedSessionRecord,\n readCachedSessionRecord,\n recordMatchesRuntime,\n refreshWithRefreshToken,\n resolveDefaultSessionFilePath,\n resolveAndPersistSession,\n resolveSessionFilePath,\n signInWithUserApiKey,\n withSessionOperationLock,\n writeCachedSessionRecord,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"supabase-session.js","sourceRoot":"","sources":["../../../src/lib/supabase-session.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n chmodSync,\n mkdirSync,\n readFileSync,\n renameSync,\n rmSync,\n statSync,\n writeFileSync,\n} from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { createClient, type Session } from '@supabase/supabase-js';\nimport { CliError } from './errors.js';\nimport type { FetchLike } from './http.js';\nimport {\n openSystemBrowser,\n receiveOAuthLoopbackCallback,\n SYSTEM_BROWSER_OPTIONS,\n type BrowserSpawn,\n} from './oauth-loopback.js';\nimport {\n buildOAuthAuthorizationUrl,\n createOAuthPkceValues,\n DEFAULT_OAUTH_SCOPES,\n exchangeOAuthAuthorizationCode,\n fetchOAuthUserInfo,\n refreshOAuthTokens,\n type OAuthPkceValues,\n} from './oauth-pkce.js';\nimport { withStateFileLock } from './state-lock.js';\nimport {\n createSupabaseFetch,\n deriveSupabaseProjectBaseUrl,\n type SupabaseDataRuntime,\n type SupabaseRestRuntime,\n} from './supabase-client.js';\nimport { fingerprintSecret } from './credential-safety.js';\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\nconst SESSION_REFRESH_WINDOW_SECONDS = 300;\n\nexport type CachedSupabaseSessionRecord = {\n schema_version: 2;\n auth_method: 'oauth';\n supabase_url: string;\n publishable_key_fingerprint: string;\n auth_binding_fingerprint: string;\n user_email: string;\n access_token: string;\n refresh_token: string;\n expires_at: number | null;\n granted_scopes: string[];\n updated_at_utc: string;\n};\n\nexport type ResolvedSupabaseUserSession = {\n accessToken: string;\n refreshToken: string;\n expiresAt: number | null;\n userEmail: string;\n projectBaseUrl: string;\n sessionFile: string | null;\n authMethod: 'oauth' | 'access_token';\n source: 'memory' | 'cache' | 'refresh' | 'oauth_login' | 'access_token';\n};\n\ntype RuntimeIdentity = {\n projectBaseUrl: string;\n publishableKeyFingerprint: string;\n authMethod: 'oauth' | 'access_token';\n authBindingFingerprint: string;\n sessionFilePath: string | null;\n memoKey: string;\n};\n\nconst SESSION_MEMORY_CACHE = new Map<string, CachedSupabaseSessionRecord>();\nconst ACCESS_TOKEN_MEMORY_CACHE = new Map<string, ResolvedSupabaseUserSession>();\nconst SESSION_OPERATION_CHAINS = new Map<string, Promise<void>>();\n\nfunction trimToken(value: unknown): string {\n return typeof value === 'string' ? value.trim() : '';\n}\n\nfunction nowSeconds(now: Date): number {\n return Math.floor(now.getTime() / 1000);\n}\n\ntype SessionTokenFields = Pick<\n Session,\n 'access_token' | 'refresh_token' | 'expires_at' | 'expires_in'\n>;\n\nfunction computeExpiresAt(session: SessionTokenFields, now: Date): number | null {\n if (typeof session.expires_at === 'number' && Number.isFinite(session.expires_at)) {\n return Math.floor(session.expires_at);\n }\n\n if (typeof session.expires_in === 'number' && Number.isFinite(session.expires_in)) {\n return nowSeconds(now) + Math.max(Math.floor(session.expires_in), 0);\n }\n\n return null;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction parseCachedSessionRecord(value: unknown): CachedSupabaseSessionRecord | null {\n if (!isRecord(value)) {\n return null;\n }\n\n if (value.schema_version !== 2) {\n return null;\n }\n\n const supabaseUrl = trimToken(value.supabase_url);\n const publishableKeyFingerprint = trimToken(value.publishable_key_fingerprint);\n const authMethod = value.auth_method === 'oauth' ? 'oauth' : null;\n const authBindingFingerprint = trimToken(value.auth_binding_fingerprint);\n const userEmail = trimToken(value.user_email);\n const accessToken = trimToken(value.access_token);\n const refreshToken = trimToken(value.refresh_token);\n const updatedAtUtc = trimToken(value.updated_at_utc);\n const expiresAt =\n typeof value.expires_at === 'number' && Number.isFinite(value.expires_at)\n ? Math.floor(value.expires_at)\n : value.expires_at === null\n ? null\n : NaN;\n const grantedScopes =\n Array.isArray(value.granted_scopes) &&\n value.granted_scopes.every((scope) => typeof scope === 'string' && scope.trim())\n ? [...new Set(value.granted_scopes.map((scope) => scope.trim()))].sort((left, right) =>\n left.localeCompare(right),\n )\n : null;\n\n if (\n !supabaseUrl ||\n !publishableKeyFingerprint ||\n !authMethod ||\n !authBindingFingerprint ||\n !userEmail ||\n !accessToken ||\n !refreshToken ||\n !updatedAtUtc ||\n Number.isNaN(expiresAt) ||\n grantedScopes === null\n ) {\n return null;\n }\n\n return {\n schema_version: 2,\n auth_method: authMethod,\n supabase_url: supabaseUrl,\n publishable_key_fingerprint: publishableKeyFingerprint,\n auth_binding_fingerprint: authBindingFingerprint,\n user_email: userEmail,\n access_token: accessToken,\n refresh_token: refreshToken,\n expires_at: expiresAt,\n granted_scopes: grantedScopes,\n updated_at_utc: updatedAtUtc,\n };\n}\n\nfunction resolveDefaultSessionFilePath(options: {\n platform: NodeJS.Platform;\n homeDir: string;\n xdgStateHome: string | null;\n localAppData: string | null;\n}): string {\n if (options.xdgStateHome) {\n return path.join(options.xdgStateHome, 'tiangong-lca-cli', 'session.json');\n }\n\n if (options.homeDir) {\n return path.join(options.homeDir, '.local', 'state', 'tiangong-lca-cli', 'session.json');\n }\n\n if (options.platform === 'darwin') {\n return path.join(\n os.homedir(),\n 'Library',\n 'Application Support',\n 'tiangong-lca-cli',\n 'session.json',\n );\n }\n\n if (options.platform === 'win32' && options.localAppData) {\n return path.join(options.localAppData, 'tiangong-lca-cli', 'session.json');\n }\n\n return path.resolve('.tiangong-lca-session.json');\n}\n\nfunction resolveSessionFilePath(runtime: SupabaseRestRuntime): string | null {\n if (runtime.authMode === 'access_token' || runtime.disableSessionCache) {\n return null;\n }\n\n if (runtime.sessionFile) {\n return path.resolve(runtime.sessionFile);\n }\n\n return resolveDefaultSessionFilePath({\n platform: process.platform,\n homeDir: trimToken(os.homedir()),\n xdgStateHome: trimToken(process.env.XDG_STATE_HOME) || null,\n localAppData: trimToken(process.env.LOCALAPPDATA) || null,\n });\n}\n\nfunction buildRuntimeIdentity(runtime: SupabaseRestRuntime): RuntimeIdentity {\n const projectBaseUrl = deriveSupabaseProjectBaseUrl(runtime.apiBaseUrl);\n const publishableKeyFingerprint = fingerprintSecret(runtime.publishableKey);\n const authBindingFingerprint =\n runtime.authMode === 'oauth'\n ? fingerprintSecret(`oauth-client:${runtime.oauthClientId as string}`)\n : fingerprintSecret(runtime.accessToken as string);\n const sessionFilePath = resolveSessionFilePath(runtime);\n\n return {\n projectBaseUrl,\n publishableKeyFingerprint,\n authMethod: runtime.authMode,\n authBindingFingerprint,\n sessionFilePath,\n memoKey: [\n projectBaseUrl,\n publishableKeyFingerprint,\n runtime.authMode,\n authBindingFingerprint,\n sessionFilePath ?? 'memory-only',\n ].join('|'),\n };\n}\n\nfunction recordMatchesRuntime(\n record: CachedSupabaseSessionRecord,\n runtime: RuntimeIdentity,\n): boolean {\n return (\n record.supabase_url === runtime.projectBaseUrl &&\n record.publishable_key_fingerprint === runtime.publishableKeyFingerprint &&\n record.auth_method === runtime.authMethod &&\n record.auth_binding_fingerprint === runtime.authBindingFingerprint\n );\n}\n\nfunction isSessionFresh(record: CachedSupabaseSessionRecord, now: Date): boolean {\n return (\n typeof record.expires_at === 'number' &&\n Number.isFinite(record.expires_at) &&\n record.expires_at > nowSeconds(now) + SESSION_REFRESH_WINDOW_SECONDS\n );\n}\n\nfunction buildCachedSessionRecord(options: {\n runtime: RuntimeIdentity;\n session: SessionTokenFields;\n userEmail: string;\n grantedScopes?: string[];\n now: Date;\n}): CachedSupabaseSessionRecord {\n const accessToken = trimToken(options.session.access_token);\n const refreshToken = trimToken(options.session.refresh_token);\n if (!accessToken || !refreshToken) {\n throw new CliError('Supabase auth did not return a usable session.', {\n code: 'SUPABASE_AUTH_SESSION_INVALID',\n exitCode: 1,\n });\n }\n\n return {\n schema_version: 2,\n auth_method: 'oauth',\n supabase_url: options.runtime.projectBaseUrl,\n publishable_key_fingerprint: options.runtime.publishableKeyFingerprint,\n auth_binding_fingerprint: options.runtime.authBindingFingerprint,\n user_email: options.userEmail,\n access_token: accessToken,\n refresh_token: refreshToken,\n expires_at: computeExpiresAt(options.session, options.now),\n granted_scopes: [...new Set(options.grantedScopes ?? [])].sort(),\n updated_at_utc: options.now.toISOString(),\n };\n}\n\nfunction toResolvedSession(\n record: CachedSupabaseSessionRecord,\n runtime: RuntimeIdentity,\n source: ResolvedSupabaseUserSession['source'],\n): ResolvedSupabaseUserSession {\n return {\n accessToken: record.access_token,\n refreshToken: record.refresh_token,\n expiresAt: record.expires_at,\n userEmail: record.user_email,\n projectBaseUrl: runtime.projectBaseUrl,\n sessionFile: runtime.sessionFilePath,\n authMethod: runtime.authMethod,\n source,\n };\n}\n\nfunction readCachedSessionRecord(\n sessionFilePath: string,\n platform: NodeJS.Platform = process.platform,\n): CachedSupabaseSessionRecord | null {\n try {\n const stat = statSync(sessionFilePath);\n if (!stat.isFile() || (platform !== 'win32' && (stat.mode & 0o077) !== 0)) {\n return null;\n }\n const text = readFileSync(sessionFilePath, 'utf8').trim();\n if (!text) {\n return null;\n }\n\n return parseCachedSessionRecord(JSON.parse(text));\n } catch {\n return null;\n }\n}\n\nfunction writeCachedSessionRecord(\n sessionFilePath: string,\n record: CachedSupabaseSessionRecord,\n platform: NodeJS.Platform = process.platform,\n): void {\n mkdirSync(path.dirname(sessionFilePath), {\n recursive: true,\n mode: 0o700,\n });\n if (platform !== 'win32') {\n chmodSync(path.dirname(sessionFilePath), 0o700);\n }\n\n const tempPath = `${sessionFilePath}.${process.pid}.${Date.now()}.tmp`;\n try {\n writeFileSync(tempPath, `${JSON.stringify(record, null, 2)}\\n`, {\n encoding: 'utf8',\n flag: 'wx',\n mode: 0o600,\n });\n renameSync(tempPath, sessionFilePath);\n chmodSync(sessionFilePath, 0o600);\n } catch (error) {\n rmSync(tempPath, { force: true });\n throw error;\n }\n}\n\nfunction getMemoizedRecord(runtime: RuntimeIdentity): CachedSupabaseSessionRecord | null {\n return SESSION_MEMORY_CACHE.get(runtime.memoKey) ?? null;\n}\n\nfunction memoizeRecord(runtime: RuntimeIdentity, record: CachedSupabaseSessionRecord): void {\n SESSION_MEMORY_CACHE.set(runtime.memoKey, record);\n}\n\nfunction dropMemoizedRecord(runtime: RuntimeIdentity): void {\n SESSION_MEMORY_CACHE.delete(runtime.memoKey);\n}\n\nasync function withSessionOperationLock<T>(memoKey: string, task: () => Promise<T>): Promise<T> {\n const previous = SESSION_OPERATION_CHAINS.get(memoKey) ?? Promise.resolve();\n let release!: () => void;\n const gate = new Promise<void>((resolve) => {\n release = resolve;\n });\n const chain = previous.catch(() => undefined).then(() => gate);\n SESSION_OPERATION_CHAINS.set(memoKey, chain);\n\n await previous.catch(() => undefined);\n try {\n return await task();\n } finally {\n release();\n if (SESSION_OPERATION_CHAINS.get(memoKey) === chain) {\n SESSION_OPERATION_CHAINS.delete(memoKey);\n }\n }\n}\n\nfunction createSupabaseAuthClient(\n runtime: RuntimeIdentity,\n publishableKey: string,\n fetchImpl: FetchLike,\n timeoutMs: number,\n) {\n return createClient(runtime.projectBaseUrl, publishableKey, {\n auth: {\n autoRefreshToken: false,\n persistSession: false,\n detectSessionInUrl: false,\n },\n global: {\n fetch: createSupabaseFetch(fetchImpl, timeoutMs),\n },\n });\n}\n\nasync function refreshWithRefreshToken(options: {\n runtime: SupabaseRestRuntime;\n runtimeIdentity: RuntimeIdentity;\n refreshToken: string;\n fetchImpl: FetchLike;\n timeoutMs: number;\n now: Date;\n}): Promise<CachedSupabaseSessionRecord | null> {\n const normalizedRefreshToken = trimToken(options.refreshToken);\n if (!normalizedRefreshToken) {\n return null;\n }\n\n try {\n const tokens = await refreshOAuthTokens({\n projectBaseUrl: options.runtimeIdentity.projectBaseUrl,\n clientId: options.runtime.oauthClientId as string,\n refreshToken: normalizedRefreshToken,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n });\n const userInfo = await fetchOAuthUserInfo({\n projectBaseUrl: options.runtimeIdentity.projectBaseUrl,\n accessToken: tokens.accessToken,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n });\n return buildCachedSessionRecord({\n runtime: options.runtimeIdentity,\n session: {\n access_token: tokens.accessToken,\n refresh_token: tokens.refreshToken,\n expires_at: undefined,\n expires_in: tokens.expiresIn,\n },\n userEmail: userInfo.email,\n grantedScopes: tokens.scope,\n now: options.now,\n });\n } catch {\n return null;\n }\n}\n\nasync function resolveExplicitAccessToken(options: {\n runtime: SupabaseRestRuntime;\n runtimeIdentity: RuntimeIdentity;\n fetchImpl: FetchLike;\n timeoutMs: number;\n}): Promise<ResolvedSupabaseUserSession> {\n const cached = ACCESS_TOKEN_MEMORY_CACHE.get(options.runtimeIdentity.memoKey);\n if (cached) {\n return cached;\n }\n const accessToken = trimToken(options.runtime.accessToken);\n const authClient = createSupabaseAuthClient(\n options.runtimeIdentity,\n options.runtime.publishableKey,\n options.fetchImpl,\n options.timeoutMs,\n );\n const { data, error } = await authClient.auth.getUser(accessToken);\n const userEmail = trimToken(data.user?.email);\n if (error || !data.user?.id || data.user.role !== 'authenticated' || !userEmail) {\n throw new CliError('TIANGONG_LCA_ACCESS_TOKEN did not resolve to an authenticated user.', {\n code: 'SUPABASE_ACCESS_TOKEN_INVALID',\n exitCode: 1,\n details: error?.message ?? 'Authenticated user identity missing from access token.',\n });\n }\n\n const resolved: ResolvedSupabaseUserSession = {\n accessToken,\n refreshToken: '',\n expiresAt: null,\n userEmail,\n projectBaseUrl: options.runtimeIdentity.projectBaseUrl,\n sessionFile: null,\n authMethod: 'access_token',\n source: 'access_token',\n };\n ACCESS_TOKEN_MEMORY_CACHE.set(options.runtimeIdentity.memoKey, resolved);\n return resolved;\n}\n\nasync function resolveAndPersistSession(options: {\n runtime: SupabaseRestRuntime;\n runtimeIdentity: RuntimeIdentity;\n fetchImpl: FetchLike;\n timeoutMs: number;\n now: Date;\n forceRefresh: boolean;\n}): Promise<ResolvedSupabaseUserSession> {\n const { runtime, runtimeIdentity } = options;\n if (runtime.authMode === 'access_token') {\n return resolveExplicitAccessToken({\n runtime,\n runtimeIdentity,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n });\n }\n const memoized = getMemoizedRecord(runtimeIdentity);\n if (\n !options.forceRefresh &&\n !runtime.forceReauth &&\n memoized &&\n recordMatchesRuntime(memoized, runtimeIdentity) &&\n isSessionFresh(memoized, options.now)\n ) {\n return toResolvedSession(memoized, runtimeIdentity, 'memory');\n }\n\n const cachedFromDisk =\n runtimeIdentity.sessionFilePath !== null\n ? readCachedSessionRecord(runtimeIdentity.sessionFilePath)\n : null;\n if (\n !options.forceRefresh &&\n !runtime.forceReauth &&\n cachedFromDisk &&\n recordMatchesRuntime(cachedFromDisk, runtimeIdentity) &&\n isSessionFresh(cachedFromDisk, options.now)\n ) {\n memoizeRecord(runtimeIdentity, cachedFromDisk);\n return toResolvedSession(cachedFromDisk, runtimeIdentity, 'cache');\n }\n\n if (!runtime.forceReauth) {\n const refreshCandidate =\n cachedFromDisk &&\n recordMatchesRuntime(cachedFromDisk, runtimeIdentity) &&\n trimToken(cachedFromDisk.refresh_token)\n ? cachedFromDisk\n : memoized &&\n recordMatchesRuntime(memoized, runtimeIdentity) &&\n trimToken(memoized.refresh_token)\n ? memoized\n : null;\n\n if (refreshCandidate) {\n const refreshed = await refreshWithRefreshToken({\n runtime,\n runtimeIdentity,\n refreshToken: refreshCandidate.refresh_token,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n now: options.now,\n });\n\n if (refreshed) {\n if (runtimeIdentity.sessionFilePath) {\n writeCachedSessionRecord(runtimeIdentity.sessionFilePath, refreshed);\n }\n memoizeRecord(runtimeIdentity, refreshed);\n return toResolvedSession(refreshed, runtimeIdentity, 'refresh');\n }\n }\n }\n\n dropMemoizedRecord(runtimeIdentity);\n throw new CliError(\n 'No usable OAuth session is available. Run `tiangong-lca auth login` in a trusted terminal.',\n {\n code: 'SUPABASE_OAUTH_LOGIN_REQUIRED',\n exitCode: 1,\n },\n );\n}\n\nexport async function resolveSupabaseUserSession(options: {\n runtime: SupabaseRestRuntime;\n fetchImpl: FetchLike;\n timeoutMs?: number;\n now?: Date;\n forceRefresh?: boolean;\n}): Promise<ResolvedSupabaseUserSession> {\n const runtimeIdentity = buildRuntimeIdentity(options.runtime);\n const now = options.now ?? new Date();\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const forceRefresh = Boolean(options.forceRefresh);\n\n if (options.runtime.authMode === 'access_token') {\n return resolveExplicitAccessToken({\n runtime: options.runtime,\n runtimeIdentity,\n fetchImpl: options.fetchImpl,\n timeoutMs,\n });\n }\n\n if (!forceRefresh && !options.runtime.forceReauth) {\n const memoized = getMemoizedRecord(runtimeIdentity);\n if (\n memoized &&\n recordMatchesRuntime(memoized, runtimeIdentity) &&\n isSessionFresh(memoized, now)\n ) {\n return toResolvedSession(memoized, runtimeIdentity, 'memory');\n }\n\n if (runtimeIdentity.sessionFilePath) {\n const cached = readCachedSessionRecord(runtimeIdentity.sessionFilePath);\n if (cached && recordMatchesRuntime(cached, runtimeIdentity) && isSessionFresh(cached, now)) {\n memoizeRecord(runtimeIdentity, cached);\n return toResolvedSession(cached, runtimeIdentity, 'cache');\n }\n }\n }\n\n return withSessionOperationLock(runtimeIdentity.memoKey, async () => {\n if (runtimeIdentity.sessionFilePath) {\n return withStateFileLock(\n runtimeIdentity.sessionFilePath,\n {\n reason: forceRefresh ? 'refresh_supabase_user_session' : 'resolve_supabase_user_session',\n },\n () =>\n resolveAndPersistSession({\n runtime: options.runtime,\n runtimeIdentity,\n fetchImpl: options.fetchImpl,\n timeoutMs,\n now,\n forceRefresh,\n }),\n );\n }\n\n return resolveAndPersistSession({\n runtime: options.runtime,\n runtimeIdentity,\n fetchImpl: options.fetchImpl,\n timeoutMs,\n now,\n forceRefresh,\n });\n });\n}\n\nexport type OAuthLoginReceipt = {\n schemaVersion: 'tiangong.cli-oauth-login.v1';\n status: 'authenticated';\n authMethod: 'oauth';\n expiresAt: number;\n grantedScopes: string[];\n sessionCache: 'private-file';\n};\n\nexport type OAuthLogoutReceipt = {\n schemaVersion: 'tiangong.cli-oauth-logout.v1';\n status: 'logged-out';\n removed: boolean;\n};\n\nexport type AuthStatusReceipt = {\n schemaVersion: 'tiangong.cli-auth-status.v1';\n status: 'ready' | 'login-required';\n authMethod: ResolvedSupabaseUserSession['authMethod'];\n sessionState: 'fresh' | 'refresh-required' | 'memory-only' | 'missing';\n sessionCache: 'private-file' | 'disabled' | 'memory-only';\n expiresAt: number | null;\n grantedScopes: string[];\n onlineVerified: false;\n};\n\nexport function inspectSupabaseAuthStatus(options: {\n runtime: SupabaseRestRuntime;\n now?: Date;\n}): AuthStatusReceipt {\n const runtimeIdentity = buildRuntimeIdentity(options.runtime);\n const now = options.now ?? new Date();\n\n if (options.runtime.authMode === 'access_token') {\n return {\n schemaVersion: 'tiangong.cli-auth-status.v1',\n status: 'ready',\n authMethod: 'access_token',\n sessionState: 'memory-only',\n sessionCache: 'memory-only',\n expiresAt: null,\n grantedScopes: [],\n onlineVerified: false,\n };\n }\n\n const memoized = getMemoizedRecord(runtimeIdentity);\n const cached =\n memoized && recordMatchesRuntime(memoized, runtimeIdentity)\n ? memoized\n : runtimeIdentity.sessionFilePath\n ? readCachedSessionRecord(runtimeIdentity.sessionFilePath)\n : null;\n const matching = cached && recordMatchesRuntime(cached, runtimeIdentity) ? cached : null;\n if (!matching || !trimToken(matching.refresh_token)) {\n return {\n schemaVersion: 'tiangong.cli-auth-status.v1',\n status: 'login-required',\n authMethod: 'oauth',\n sessionState: 'missing',\n sessionCache: runtimeIdentity.sessionFilePath ? 'private-file' : 'disabled',\n expiresAt: null,\n grantedScopes: [],\n onlineVerified: false,\n };\n }\n\n return {\n schemaVersion: 'tiangong.cli-auth-status.v1',\n status: 'ready',\n authMethod: 'oauth',\n sessionState: isSessionFresh(matching, now) ? 'fresh' : 'refresh-required',\n sessionCache: 'private-file',\n expiresAt: matching.expires_at,\n grantedScopes: matching.granted_scopes,\n onlineVerified: false,\n };\n}\n\nexport async function loginWithSupabaseOAuth(options: {\n runtime: SupabaseRestRuntime;\n fetchImpl: FetchLike;\n requestTimeoutMs?: number;\n loginTimeoutMs?: number;\n now?: Date;\n createPkceValuesImpl?: () => OAuthPkceValues;\n receiveCallbackImpl?: typeof receiveOAuthLoopbackCallback;\n openBrowserImpl?: (authorizationUrl: string) => Promise<void>;\n browserOptions?: { platform: NodeJS.Platform; spawnImpl: BrowserSpawn };\n exchangeCodeImpl?: typeof exchangeOAuthAuthorizationCode;\n fetchUserInfoImpl?: typeof fetchOAuthUserInfo;\n}): Promise<OAuthLoginReceipt> {\n if (\n options.runtime.authMode !== 'oauth' ||\n !options.runtime.oauthClientId ||\n !options.runtime.oauthRedirectUri\n ) {\n throw new CliError('OAuth login requires TIANGONG_LCA_AUTH_MODE=oauth and a client ID.', {\n code: 'SUPABASE_OAUTH_RUNTIME_REQUIRED',\n exitCode: 2,\n });\n }\n\n const runtimeIdentity = buildRuntimeIdentity(options.runtime);\n if (!runtimeIdentity.sessionFilePath) {\n throw new CliError('OAuth login requires the private session cache to be enabled.', {\n code: 'SUPABASE_OAUTH_SESSION_CACHE_REQUIRED',\n exitCode: 2,\n });\n }\n\n const requestTimeoutMs = options.requestTimeoutMs ?? DEFAULT_TIMEOUT_MS;\n const loginTimeoutMs = options.loginTimeoutMs ?? 180_000;\n const now = options.now ?? new Date();\n const createPkceValuesImpl = options.createPkceValuesImpl ?? createOAuthPkceValues;\n const receiveCallbackImpl = options.receiveCallbackImpl ?? receiveOAuthLoopbackCallback;\n const browserOptions = options.browserOptions ?? SYSTEM_BROWSER_OPTIONS;\n const openBrowserImpl =\n options.openBrowserImpl ??\n ((authorizationUrl) => openSystemBrowser(authorizationUrl, browserOptions));\n const exchangeCodeImpl = options.exchangeCodeImpl ?? exchangeOAuthAuthorizationCode;\n const fetchUserInfoImpl = options.fetchUserInfoImpl ?? fetchOAuthUserInfo;\n\n return withSessionOperationLock(runtimeIdentity.memoKey, () =>\n withStateFileLock(\n runtimeIdentity.sessionFilePath as string,\n { reason: 'supabase_oauth_pkce_login' },\n async () => {\n const pkce = createPkceValuesImpl();\n const authorizationUrl = buildOAuthAuthorizationUrl({\n projectBaseUrl: runtimeIdentity.projectBaseUrl,\n clientId: options.runtime.oauthClientId as string,\n redirectUri: options.runtime.oauthRedirectUri as string,\n codeChallenge: pkce.codeChallenge,\n state: pkce.state,\n });\n const authorizationCode = await receiveCallbackImpl({\n redirectUri: options.runtime.oauthRedirectUri as string,\n expectedState: pkce.state,\n timeoutMs: loginTimeoutMs,\n onListening: () => openBrowserImpl(authorizationUrl),\n });\n const tokens = await exchangeCodeImpl({\n projectBaseUrl: runtimeIdentity.projectBaseUrl,\n clientId: options.runtime.oauthClientId as string,\n redirectUri: options.runtime.oauthRedirectUri as string,\n authorizationCode,\n codeVerifier: pkce.codeVerifier,\n fetchImpl: options.fetchImpl,\n timeoutMs: requestTimeoutMs,\n });\n const userInfo = await fetchUserInfoImpl({\n projectBaseUrl: runtimeIdentity.projectBaseUrl,\n accessToken: tokens.accessToken,\n fetchImpl: options.fetchImpl,\n timeoutMs: requestTimeoutMs,\n });\n const grantedScopes = tokens.scope.length > 0 ? tokens.scope : [...DEFAULT_OAUTH_SCOPES];\n const record = buildCachedSessionRecord({\n runtime: runtimeIdentity,\n session: {\n access_token: tokens.accessToken,\n refresh_token: tokens.refreshToken,\n expires_at: undefined,\n expires_in: tokens.expiresIn,\n },\n userEmail: userInfo.email,\n grantedScopes,\n now,\n });\n writeCachedSessionRecord(runtimeIdentity.sessionFilePath as string, record);\n memoizeRecord(runtimeIdentity, record);\n return {\n schemaVersion: 'tiangong.cli-oauth-login.v1',\n status: 'authenticated',\n authMethod: 'oauth',\n expiresAt: record.expires_at as number,\n grantedScopes: record.granted_scopes,\n sessionCache: 'private-file',\n };\n },\n ),\n );\n}\n\nexport async function logoutSupabaseUserSession(options: {\n runtime: SupabaseRestRuntime;\n}): Promise<OAuthLogoutReceipt> {\n const runtimeIdentity = buildRuntimeIdentity(options.runtime);\n return withSessionOperationLock(runtimeIdentity.memoKey, async () => {\n let removed = false;\n const removeCurrent = () => {\n const cached = runtimeIdentity.sessionFilePath\n ? readCachedSessionRecord(runtimeIdentity.sessionFilePath)\n : null;\n if (\n runtimeIdentity.sessionFilePath &&\n cached &&\n recordMatchesRuntime(cached, runtimeIdentity)\n ) {\n rmSync(runtimeIdentity.sessionFilePath, { force: true });\n removed = true;\n }\n dropMemoizedRecord(runtimeIdentity);\n ACCESS_TOKEN_MEMORY_CACHE.delete(runtimeIdentity.memoKey);\n };\n\n if (runtimeIdentity.sessionFilePath) {\n await withStateFileLock(\n runtimeIdentity.sessionFilePath,\n { reason: 'supabase_oauth_local_logout' },\n removeCurrent,\n );\n } else {\n removeCurrent();\n }\n\n return {\n schemaVersion: 'tiangong.cli-oauth-logout.v1',\n status: 'logged-out',\n removed,\n };\n });\n}\n\nexport function createSupabaseDataRuntime(options: {\n runtime: SupabaseRestRuntime;\n fetchImpl: FetchLike;\n timeoutMs?: number;\n now?: Date;\n}): SupabaseDataRuntime {\n const runtime: SupabaseDataRuntime = {\n apiBaseUrl: options.runtime.apiBaseUrl,\n publishableKey: options.runtime.publishableKey,\n getAccessToken: async () =>\n (\n await resolveSupabaseUserSession({\n runtime: options.runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n now: options.now,\n })\n ).accessToken,\n };\n if (options.runtime.authMode !== 'access_token') {\n runtime.refreshAccessToken = async () =>\n (\n await resolveSupabaseUserSession({\n runtime: options.runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n now: options.now,\n forceRefresh: true,\n })\n ).accessToken;\n }\n return runtime;\n}\n\nexport const __testInternals = {\n SESSION_MEMORY_CACHE,\n ACCESS_TOKEN_MEMORY_CACHE,\n SESSION_OPERATION_CHAINS,\n buildCachedSessionRecord,\n buildRuntimeIdentity,\n computeExpiresAt,\n createSupabaseAuthClient,\n dropMemoizedRecord,\n getMemoizedRecord,\n isSessionFresh,\n memoizeRecord,\n parseCachedSessionRecord,\n readCachedSessionRecord,\n recordMatchesRuntime,\n refreshWithRefreshToken,\n resolveDefaultSessionFilePath,\n resolveAndPersistSession,\n resolveSessionFilePath,\n withSessionOperationLock,\n writeCachedSessionRecord,\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiangong-lca/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "Unified TianGong LCA CLI with direct REST adapters and low-entropy command surface.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -91,7 +91,6 @@
|
|
|
91
91
|
"test:coverage": "pnpm build && node ./scripts/run-test-coverage.cjs",
|
|
92
92
|
"test:coverage:assert-full": "node ./dist/scripts/assert-full-coverage.js",
|
|
93
93
|
"peers:check": "pnpm peers check",
|
|
94
|
-
"case:auth-identity:production": "pnpm build && node ./dist/scripts/run-auth-identity-production-case.js",
|
|
95
94
|
"prepush:gate": "pnpm lint && pnpm peers:check && pnpm test:package && pnpm test:coverage && pnpm test:coverage:assert-full",
|
|
96
95
|
"release:check-tag": "node ./scripts/ci/check-release-tag.cjs cli",
|
|
97
96
|
"release:assert-unpublished": "node ./scripts/ci/release-version.cjs assert-unpublished",
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export type UserApiKeyCredentials = {
|
|
2
|
-
email: string;
|
|
3
|
-
password: string;
|
|
4
|
-
};
|
|
5
|
-
declare function normalizeToken(value: unknown): string;
|
|
6
|
-
declare function normalizeCredentialValue(value: unknown): string;
|
|
7
|
-
export declare function decodeUserApiKey(apiKey: string): UserApiKeyCredentials | null;
|
|
8
|
-
export declare function requireUserApiKeyCredentials(apiKey: string): UserApiKeyCredentials;
|
|
9
|
-
export declare function fingerprintSecret(value: string): string;
|
|
10
|
-
export declare function fingerprintUserApiKey(apiKey: string): string;
|
|
11
|
-
export declare function redactEmail(email: string): string;
|
|
12
|
-
export declare const __testInternals: {
|
|
13
|
-
normalizeCredentialValue: typeof normalizeCredentialValue;
|
|
14
|
-
normalizeToken: typeof normalizeToken;
|
|
15
|
-
};
|
|
16
|
-
export {};
|