@tiangong-lca/cli 0.1.2 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +51 -12
  2. package/dist/src/auth-identity-receipt.d.ts +2 -0
  3. package/dist/src/auth-identity-receipt.js +2 -0
  4. package/dist/src/auth-identity-receipt.js.map +1 -0
  5. package/dist/src/cli.d.ts +4 -0
  6. package/dist/src/cli.js +264 -7
  7. package/dist/src/cli.js.map +1 -1
  8. package/dist/src/lib/auth-identity-receipt.d.ts +2 -2
  9. package/dist/src/lib/auth-identity-receipt.js +20 -12
  10. package/dist/src/lib/auth-identity-receipt.js.map +1 -1
  11. package/dist/src/lib/env.d.ts +8 -0
  12. package/dist/src/lib/env.js +36 -3
  13. package/dist/src/lib/env.js.map +1 -1
  14. package/dist/src/lib/lca-release.d.ts +1 -1
  15. package/dist/src/lib/lca-release.js +3 -4
  16. package/dist/src/lib/lca-release.js.map +1 -1
  17. package/dist/src/lib/lifecyclemodel-resulting-process.js +6 -2
  18. package/dist/src/lib/lifecyclemodel-resulting-process.js.map +1 -1
  19. package/dist/src/lib/oauth-loopback.d.ts +52 -0
  20. package/dist/src/lib/oauth-loopback.js +229 -0
  21. package/dist/src/lib/oauth-loopback.js.map +1 -0
  22. package/dist/src/lib/oauth-pkce.d.ts +63 -0
  23. package/dist/src/lib/oauth-pkce.js +268 -0
  24. package/dist/src/lib/oauth-pkce.js.map +1 -0
  25. package/dist/src/lib/process-refresh-references.js +2 -2
  26. package/dist/src/lib/process-refresh-references.js.map +1 -1
  27. package/dist/src/lib/process-scope-statistics.js +8 -3
  28. package/dist/src/lib/process-scope-statistics.js.map +1 -1
  29. package/dist/src/lib/state-lock.js +10 -4
  30. package/dist/src/lib/state-lock.js.map +1 -1
  31. package/dist/src/lib/supabase-client.d.ts +13 -1
  32. package/dist/src/lib/supabase-client.js +64 -3
  33. package/dist/src/lib/supabase-client.js.map +1 -1
  34. package/dist/src/lib/supabase-json-ordered-write.js +7 -3
  35. package/dist/src/lib/supabase-json-ordered-write.js.map +1 -1
  36. package/dist/src/lib/supabase-session.d.ts +63 -8
  37. package/dist/src/lib/supabase-session.js +315 -21
  38. package/dist/src/lib/supabase-session.js.map +1 -1
  39. package/package.json +5 -1
@@ -4,7 +4,7 @@ import { type ResolvedSupabaseUserSession } from './supabase-session.js';
4
4
  export declare const AUTH_IDENTITY_RECEIPT_SCHEMA: 'tiangong-lca.auth-identity-receipt.v1';
5
5
  export declare const AUTH_IDENTITY_MAX_TIMEOUT_MS = 2147483647;
6
6
  declare const CLI_PACKAGE_NAME: '@tiangong-lca/cli';
7
- declare const SESSION_SOURCES: readonly ['memory', 'cache', 'refresh', 'signin'];
7
+ declare const SESSION_SOURCES: readonly ['memory', 'cache', 'refresh', 'oauth_login', 'legacy_signin', 'access_token'];
8
8
  declare const CACHE_MODES: readonly ['disabled', 'custom-file', 'platform-default'];
9
9
  type SessionSource = (typeof SESSION_SOURCES)[number];
10
10
  type CacheMode = (typeof CACHE_MODES)[number];
@@ -91,7 +91,7 @@ declare function assertSessionBinding(options: {
91
91
  runtime: SupabaseRestRuntime;
92
92
  session: ResolvedSupabaseUserSession;
93
93
  projectBaseUrl: string;
94
- apiKeyEmail: string;
94
+ credentialEmail: string | null;
95
95
  now: Date;
96
96
  }): void;
97
97
  declare function currentUserFailureStatus(error: unknown): number | null;
@@ -14,7 +14,14 @@ const SESSION_REFRESH_WINDOW_SECONDS = 300;
14
14
  const SHA256_PATTERN = /^[0-9a-f]{64}$/u;
15
15
  const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/u;
16
16
  const EMAIL_PATTERN = /^[^@\s]+@[^@\s]+\.[^@\s]+$/u;
17
- const SESSION_SOURCES = ['memory', 'cache', 'refresh', 'signin'];
17
+ const SESSION_SOURCES = [
18
+ 'memory',
19
+ 'cache',
20
+ 'refresh',
21
+ 'oauth_login',
22
+ 'legacy_signin',
23
+ 'access_token',
24
+ ];
18
25
  const CACHE_MODES = ['disabled', 'custom-file', 'platform-default'];
19
26
  class ResponseBodyTooLargeError extends Error {
20
27
  constructor() {
@@ -149,7 +156,7 @@ function resolveProjectIdentity(apiBaseUrl) {
149
156
  return { projectBaseUrl, projectRef };
150
157
  }
151
158
  function cacheMode(runtime) {
152
- if (runtime.disableSessionCache) {
159
+ if (runtime.authMode === 'access_token' || runtime.disableSessionCache) {
153
160
  return 'disabled';
154
161
  }
155
162
  return runtime.sessionFile ? 'custom-file' : 'platform-default';
@@ -170,7 +177,7 @@ function sessionExpiresAtUtc(expiresAt) {
170
177
  function assertSessionBinding(options) {
171
178
  const { runtime, session } = options;
172
179
  const sessionEmail = normalizeEmail(session.userEmail);
173
- const apiKeyEmail = normalizeEmail(options.apiKeyEmail);
180
+ const credentialEmail = options.credentialEmail ? normalizeEmail(options.credentialEmail) : null;
174
181
  const accessToken = token(session.accessToken);
175
182
  const source = session.source;
176
183
  const expectedMode = cacheMode(runtime);
@@ -187,10 +194,10 @@ function assertSessionBinding(options) {
187
194
  session.expiresAt >
188
195
  Math.floor(options.now.getTime() / 1000) + SESSION_REFRESH_WINDOW_SECONDS);
189
196
  if (!accessToken ||
197
+ session.authMethod !== runtime.authMode ||
190
198
  session.projectBaseUrl !== options.projectBaseUrl ||
191
199
  !sessionEmail ||
192
- !apiKeyEmail ||
193
- sessionEmail !== apiKeyEmail ||
200
+ (credentialEmail !== null && sessionEmail !== credentialEmail) ||
194
201
  !SESSION_SOURCES.includes(session.source) ||
195
202
  !cachePathMatches ||
196
203
  !cacheSourceFresh ||
@@ -486,7 +493,9 @@ export async function runAuthIdentityReceipt(options) {
486
493
  if (expectedProjectRef !== null && expectedProjectRef !== projectRef) {
487
494
  return identityError('Authenticated project does not match --expected-project-ref.', 'AUTH_IDENTITY_PROJECT_MISMATCH', { details: { expected_project_ref: expectedProjectRef, observed_project_ref: projectRef } });
488
495
  }
489
- const credentials = requireUserApiKeyCredentials(runtime.userApiKey);
496
+ const credentialEmail = runtime.authMode === 'legacy_user_api_key'
497
+ ? requireUserApiKeyCredentials(runtime.userApiKey).email
498
+ : null;
490
499
  let session = await resolveBoundSession({
491
500
  runtime,
492
501
  fetchImpl: options.fetchImpl,
@@ -498,7 +507,7 @@ export async function runAuthIdentityReceipt(options) {
498
507
  runtime,
499
508
  session,
500
509
  projectBaseUrl,
501
- apiKeyEmail: credentials.email,
510
+ credentialEmail,
502
511
  now,
503
512
  });
504
513
  let currentUser;
@@ -528,7 +537,7 @@ export async function runAuthIdentityReceipt(options) {
528
537
  runtime,
529
538
  session,
530
539
  projectBaseUrl,
531
- apiKeyEmail: credentials.email,
540
+ credentialEmail,
532
541
  now,
533
542
  });
534
543
  currentUser = await fetchCurrentUser({
@@ -540,12 +549,11 @@ export async function runAuthIdentityReceipt(options) {
540
549
  });
541
550
  }
542
551
  const sessionEmail = normalizeEmail(session.userEmail);
543
- const apiKeyEmail = normalizeEmail(credentials.email);
552
+ const normalizedCredentialEmail = credentialEmail ? normalizeEmail(credentialEmail) : null;
544
553
  if (!sessionEmail ||
545
- !apiKeyEmail ||
546
554
  currentUser.email !== sessionEmail ||
547
- currentUser.email !== apiKeyEmail) {
548
- return identityError('Server-verified current user does not match the API-key and session identity.', 'AUTH_IDENTITY_SESSION_MISMATCH');
555
+ (normalizedCredentialEmail !== null && currentUser.email !== normalizedCredentialEmail)) {
556
+ return identityError('Server-verified current user does not match the resolved session identity.', 'AUTH_IDENTITY_SESSION_MISMATCH');
549
557
  }
550
558
  if (expectedUserId !== null && expectedUserId !== currentUser.userId) {
551
559
  return identityError('Authenticated user does not match --expected-user-id.', 'AUTH_IDENTITY_USER_MISMATCH', { details: { expected_user_id: expectedUserId, observed_user_id: currentUser.userId } });
@@ -1 +1 @@
1
- {"version":3,"file":"auth-identity-receipt.js","sourceRoot":"","sources":["../../../src/lib/auth-identity-receipt.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto';\nimport path from 'node:path';\nimport { CliError } from './errors.js';\nimport type { FetchLike } from './http.js';\nimport {\n buildSupabaseAuthHeaders,\n deriveSupabaseProjectBaseUrl,\n requireSupabaseRestRuntime,\n type SupabaseRestRuntime,\n} from './supabase-client.js';\nimport {\n resolveSupabaseUserSession,\n type ResolvedSupabaseUserSession,\n} from './supabase-session.js';\nimport { redactEmail, requireUserApiKeyCredentials } from './user-api-key.js';\n\nexport const AUTH_IDENTITY_RECEIPT_SCHEMA = 'tiangong-lca.auth-identity-receipt.v1' as const;\nexport const AUTH_IDENTITY_MAX_TIMEOUT_MS = 2_147_483_647;\n\nconst CLI_PACKAGE_NAME = '@tiangong-lca/cli' as const;\nconst CURRENT_USER_PATH = '/auth/v1/user' as const;\nconst DEFAULT_TIMEOUT_MS = 10_000;\nconst MAX_RESPONSE_BYTES = 64 * 1024;\nconst SESSION_REFRESH_WINDOW_SECONDS = 300;\nconst SHA256_PATTERN = /^[0-9a-f]{64}$/u;\nconst UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/u;\nconst EMAIL_PATTERN = /^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/u;\nconst SESSION_SOURCES = ['memory', 'cache', 'refresh', 'signin'] as const;\nconst CACHE_MODES = ['disabled', 'custom-file', 'platform-default'] as const;\n\ntype SessionSource = (typeof SESSION_SOURCES)[number];\ntype CacheMode = (typeof CACHE_MODES)[number];\ntype JsonObject = Record<string, unknown>;\n\nclass ResponseBodyTooLargeError extends Error {\n constructor() {\n super('Response body exceeded the identity receipt byte limit.');\n this.name = 'ResponseBodyTooLargeError';\n }\n}\n\nexport type AuthIdentityReceiptScope = {\n schema: typeof AUTH_IDENTITY_RECEIPT_SCHEMA;\n status: 'passed';\n operation: 'current-user-read';\n remote_write_mode: 'read-only';\n captured_at_utc: string;\n cli: {\n package_name: typeof CLI_PACKAGE_NAME;\n package_version: string;\n };\n project: {\n project_ref: string;\n project_base_url: string;\n };\n identity: {\n user_id: string;\n display_email: string;\n };\n session: {\n source: SessionSource;\n cache_mode: CacheMode;\n force_reauth: boolean;\n expires_at_utc: string | null;\n };\n bindings: {\n request_sha256: string;\n response_sha256: string;\n };\n assertions: {\n mode: 'observed' | 'partial' | 'intent-bound';\n requested_count: 0 | 1 | 2;\n expected_project_ref: string | null;\n expected_user_id: string | null;\n project_ref_passed: true | null;\n user_id_passed: true | null;\n passed: true;\n };\n};\n\nexport type AuthIdentityReceipt = AuthIdentityReceiptScope & {\n receipt_scope_sha256: string;\n};\n\nexport type ResolveAuthIdentitySession = (options: {\n runtime: SupabaseRestRuntime;\n fetchImpl: FetchLike;\n timeoutMs?: number;\n now?: Date;\n forceRefresh?: boolean;\n}) => Promise<ResolvedSupabaseUserSession>;\n\nexport type RunAuthIdentityReceiptOptions = {\n env: NodeJS.ProcessEnv;\n fetchImpl: FetchLike;\n cliVersion: string;\n expectedProjectRef?: string | null;\n expectedUserId?: string | null;\n timeoutMs?: number;\n now?: Date;\n resolveSessionImpl?: ResolveAuthIdentitySession;\n};\n\nfunction isRecord(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction stableJsonValue(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(stableJsonValue);\n }\n if (isRecord(value)) {\n return Object.fromEntries(\n Object.keys(value)\n .sort()\n .map((key) => [key, stableJsonValue(value[key])]),\n );\n }\n return value;\n}\n\nfunction sha256Json(value: unknown): string {\n return createHash('sha256')\n .update(JSON.stringify(stableJsonValue(value)))\n .digest('hex');\n}\n\nfunction token(value: unknown): string | null {\n if (typeof value !== 'string') {\n return null;\n }\n const normalized = value.trim();\n return normalized || null;\n}\n\nfunction normalizeEmail(value: unknown): string | null {\n const normalized = token(value)?.toLowerCase() ?? null;\n if (!normalized || normalized.length > 254 || !EMAIL_PATTERN.test(normalized)) {\n return null;\n }\n return normalized;\n}\n\nfunction isCanonicalUuid(value: unknown): value is string {\n return typeof value === 'string' && UUID_PATTERN.test(value);\n}\n\nfunction identityError(\n message: string,\n code: string,\n options: { exitCode?: number; details?: unknown } = {},\n): never {\n throw new CliError(message, {\n code,\n exitCode: options.exitCode ?? 1,\n ...(options.details === undefined ? {} : { details: options.details }),\n });\n}\n\nfunction receiptInvalid(message: string): never {\n return identityError(message, 'AUTH_IDENTITY_RECEIPT_INVALID');\n}\n\nfunction normalizeExpectation(value: string | null | undefined, label: string): string | null {\n if (value === null || value === undefined) {\n return null;\n }\n const normalized = token(value);\n if (!normalized) {\n return identityError(\n `${label} must be a non-empty string when provided.`,\n 'AUTH_IDENTITY_EXPECTATION_INVALID',\n {\n exitCode: 2,\n details: { option: label },\n },\n );\n }\n return normalized;\n}\n\nfunction normalizeExpectedUserId(value: string | null | undefined): string | null {\n const normalized = normalizeExpectation(value, '--expected-user-id');\n if (normalized !== null && !isCanonicalUuid(normalized)) {\n return identityError(\n '--expected-user-id must be a canonical lowercase UUID.',\n 'AUTH_IDENTITY_EXPECTATION_INVALID',\n { exitCode: 2, details: { option: '--expected-user-id' } },\n );\n }\n return normalized;\n}\n\nfunction normalizeTimeoutMs(value: number | undefined): number {\n const normalized = value ?? DEFAULT_TIMEOUT_MS;\n if (\n !Number.isInteger(normalized) ||\n normalized <= 0 ||\n normalized > AUTH_IDENTITY_MAX_TIMEOUT_MS\n ) {\n return identityError(\n `Auth identity timeout must be an integer between 1 and ${AUTH_IDENTITY_MAX_TIMEOUT_MS}.`,\n 'AUTH_IDENTITY_TIMEOUT_INVALID',\n { exitCode: 2 },\n );\n }\n return normalized;\n}\n\nfunction canonicalTimestamp(value: unknown): value is string {\n if (typeof value !== 'string') {\n return false;\n }\n const timestamp = new Date(value);\n return !Number.isNaN(timestamp.getTime()) && timestamp.toISOString() === value;\n}\n\nfunction canonicalProjectIdentity(\n projectBaseUrl: unknown,\n): { projectBaseUrl: string; projectRef: string } | null {\n const normalized = token(projectBaseUrl);\n if (!normalized || normalized !== projectBaseUrl) {\n return null;\n }\n try {\n const url = new URL(normalized);\n const suffix = '.supabase.co';\n const hostname = url.hostname.toLowerCase();\n const projectRef = hostname.endsWith(suffix) ? hostname.slice(0, -suffix.length) : '';\n if (\n url.protocol !== 'https:' ||\n url.origin !== normalized ||\n url.username ||\n url.password ||\n url.port ||\n !projectRef ||\n projectRef.includes('.') ||\n !/^[a-z0-9-]+$/u.test(projectRef)\n ) {\n return null;\n }\n return { projectBaseUrl: url.origin, projectRef };\n } catch {\n return null;\n }\n}\n\nfunction projectRefFromBaseUrl(projectBaseUrl: string): string {\n const identity = canonicalProjectIdentity(projectBaseUrl);\n if (!identity) {\n return identityError(\n 'The Supabase project URL did not contain a project identity.',\n 'AUTH_IDENTITY_PROJECT_INVALID',\n { exitCode: 2 },\n );\n }\n return identity.projectRef;\n}\n\nfunction resolveProjectIdentity(apiBaseUrl: string): {\n projectBaseUrl: string;\n projectRef: string;\n} {\n let projectBaseUrl: string;\n try {\n projectBaseUrl = deriveSupabaseProjectBaseUrl(apiBaseUrl);\n } catch {\n return identityError(\n 'TIANGONG_LCA_API_BASE_URL must identify a canonical Supabase project.',\n 'AUTH_IDENTITY_PROJECT_INVALID',\n { exitCode: 2 },\n );\n }\n const projectRef = projectRefFromBaseUrl(projectBaseUrl);\n return { projectBaseUrl, projectRef };\n}\n\nfunction cacheMode(runtime: SupabaseRestRuntime): CacheMode {\n if (runtime.disableSessionCache) {\n return 'disabled';\n }\n return runtime.sessionFile ? 'custom-file' : 'platform-default';\n}\n\nfunction sessionExpiresAtUtc(expiresAt: number | null): string | null {\n if (expiresAt === null) {\n return null;\n }\n if (!Number.isFinite(expiresAt)) {\n return identityError(\n 'Resolved auth session contained an invalid expiry.',\n 'AUTH_IDENTITY_SESSION_MISMATCH',\n );\n }\n const timestamp = new Date(Math.floor(expiresAt) * 1000);\n if (Number.isNaN(timestamp.getTime())) {\n return identityError(\n 'Resolved auth session contained an invalid expiry.',\n 'AUTH_IDENTITY_SESSION_MISMATCH',\n );\n }\n return timestamp.toISOString();\n}\n\nfunction assertSessionBinding(options: {\n runtime: SupabaseRestRuntime;\n session: ResolvedSupabaseUserSession;\n projectBaseUrl: string;\n apiKeyEmail: string;\n now: Date;\n}): void {\n const { runtime, session } = options;\n const sessionEmail = normalizeEmail(session.userEmail);\n const apiKeyEmail = normalizeEmail(options.apiKeyEmail);\n const accessToken = token(session.accessToken);\n const source = session.source as string;\n const expectedMode = cacheMode(runtime);\n const customSessionPath = runtime.sessionFile ? path.resolve(runtime.sessionFile) : null;\n const sessionPath = session.sessionFile ? path.resolve(session.sessionFile) : null;\n const cachePathMatches =\n expectedMode === 'disabled'\n ? sessionPath === null\n : expectedMode === 'custom-file'\n ? sessionPath === customSessionPath\n : sessionPath !== null;\n const cacheSourceFresh =\n !['memory', 'cache'].includes(source) ||\n (typeof session.expiresAt === 'number' &&\n Number.isFinite(session.expiresAt) &&\n session.expiresAt >\n Math.floor(options.now.getTime() / 1000) + SESSION_REFRESH_WINDOW_SECONDS);\n\n if (\n !accessToken ||\n session.projectBaseUrl !== options.projectBaseUrl ||\n !sessionEmail ||\n !apiKeyEmail ||\n sessionEmail !== apiKeyEmail ||\n !SESSION_SOURCES.includes(session.source) ||\n !cachePathMatches ||\n !cacheSourceFresh ||\n (runtime.forceReauth && ['memory', 'cache'].includes(source))\n ) {\n identityError(\n 'Resolved auth session does not match the requested credential, project, or cache boundary.',\n 'AUTH_IDENTITY_SESSION_MISMATCH',\n );\n }\n}\n\nasync function resolveBoundSession(options: {\n runtime: SupabaseRestRuntime;\n fetchImpl: FetchLike;\n timeoutMs: number;\n now: Date;\n forceRefresh?: boolean;\n resolveSessionImpl: ResolveAuthIdentitySession;\n}): Promise<ResolvedSupabaseUserSession> {\n try {\n return await options.resolveSessionImpl({\n runtime: options.runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n now: options.now,\n forceRefresh: options.forceRefresh,\n });\n } catch (error) {\n const causeCode =\n error instanceof CliError\n ? error.code\n : isRecord(error) && typeof error.code === 'string'\n ? error.code\n : 'UNEXPECTED_SESSION_FAILURE';\n return identityError(\n 'Failed to resolve the authenticated user session.',\n 'AUTH_IDENTITY_SESSION_FAILED',\n { details: { cause_code: causeCode } },\n );\n }\n}\n\nfunction currentUserFailureStatus(error: unknown): number | null {\n if (\n !(error instanceof CliError) ||\n error.code !== 'AUTH_IDENTITY_REMOTE_REQUEST_FAILED' ||\n !isRecord(error.details) ||\n typeof error.details.status !== 'number' ||\n !Number.isInteger(error.details.status)\n ) {\n return null;\n }\n return error.details.status;\n}\n\nfunction declaredResponseBytes(response: {\n headers: { get(name: string): string | null };\n}): number | null {\n const value = response.headers.get('content-length')?.trim() ?? '';\n if (!/^\\d+$/u.test(value)) {\n return null;\n }\n return Number(value);\n}\n\nasync function readBoundedResponseText(response: {\n body?: ReadableStream<Uint8Array> | null;\n headers: { get(name: string): string | null };\n text(): Promise<string>;\n}): Promise<string> {\n const declaredBytes = declaredResponseBytes(response);\n if (declaredBytes !== null && declaredBytes > MAX_RESPONSE_BYTES) {\n throw new ResponseBodyTooLargeError();\n }\n if (!response.body) {\n const text = await response.text();\n if (Buffer.byteLength(text, 'utf8') > MAX_RESPONSE_BYTES) {\n throw new ResponseBodyTooLargeError();\n }\n return text;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let observedBytes = 0;\n let text = '';\n try {\n while (true) {\n const chunk = await reader.read();\n if (chunk.done) {\n break;\n }\n observedBytes += chunk.value.byteLength;\n if (observedBytes > MAX_RESPONSE_BYTES) {\n await Promise.allSettled([reader.cancel()]);\n throw new ResponseBodyTooLargeError();\n }\n text += decoder.decode(chunk.value, { stream: true });\n }\n text += decoder.decode();\n return text;\n } finally {\n reader.releaseLock();\n }\n}\n\nasync function fetchCurrentUser(options: {\n projectBaseUrl: string;\n publishableKey: string;\n accessToken: string;\n timeoutMs: number;\n fetchImpl: FetchLike;\n}): Promise<{ userId: string; email: string }> {\n const url = `${options.projectBaseUrl}${CURRENT_USER_PATH}`;\n let response;\n try {\n response = await options.fetchImpl(url, {\n method: 'GET',\n headers: buildSupabaseAuthHeaders(options.publishableKey, options.accessToken),\n redirect: 'error',\n signal: AbortSignal.timeout(options.timeoutMs),\n });\n } catch (error) {\n return identityError(\n 'Authenticated current-user lookup failed before a response was received.',\n 'AUTH_IDENTITY_REMOTE_REQUEST_FAILED',\n {\n details: {\n endpoint: CURRENT_USER_PATH,\n cause: error instanceof Error ? error.name : typeof error,\n },\n },\n );\n }\n\n if (!response.ok) {\n return identityError(\n `Authenticated current-user lookup returned HTTP ${response.status}.`,\n 'AUTH_IDENTITY_REMOTE_REQUEST_FAILED',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n const contentType = response.headers.get('content-type')?.toLowerCase() ?? '';\n if (!contentType.includes('application/json')) {\n return identityError(\n 'Authenticated current-user response did not declare JSON content.',\n 'AUTH_IDENTITY_REMOTE_INVALID_JSON',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n\n let text: string;\n try {\n text = await readBoundedResponseText(response);\n } catch (error) {\n if (error instanceof ResponseBodyTooLargeError) {\n return identityError(\n 'Authenticated current-user response exceeded the bounded receipt limit.',\n 'AUTH_IDENTITY_RESPONSE_TOO_LARGE',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n return identityError(\n 'Authenticated current-user response could not be read.',\n 'AUTH_IDENTITY_REMOTE_REQUEST_FAILED',\n {\n details: {\n endpoint: CURRENT_USER_PATH,\n status: response.status,\n cause: error instanceof Error ? error.name : typeof error,\n },\n },\n );\n }\n\n let payload: unknown;\n try {\n payload = JSON.parse(text);\n } catch {\n return identityError(\n 'Authenticated current-user response was not valid JSON.',\n 'AUTH_IDENTITY_REMOTE_INVALID_JSON',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n if (isRecord(payload) && payload.ok === false) {\n return identityError(\n 'Authenticated current-user response explicitly reported ok:false.',\n 'AUTH_IDENTITY_REMOTE_REJECTED',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n const userId = isRecord(payload) && isCanonicalUuid(payload.id) ? payload.id : null;\n const email = isRecord(payload) ? normalizeEmail(payload.email) : null;\n if (!userId || !email) {\n return identityError(\n 'Authenticated current-user response did not contain a valid id and email.',\n 'AUTH_IDENTITY_RESPONSE_INVALID',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n return { userId, email };\n}\n\nfunction requestFingerprint(projectRef: string): string {\n return sha256Json({\n method: 'GET',\n path: CURRENT_USER_PATH,\n project_ref: projectRef,\n redirect: 'error',\n header_names: ['accept', 'apikey', 'authorization'],\n });\n}\n\nfunction responseFingerprint(options: {\n projectRef: string;\n userId: string;\n displayEmail: string;\n}): string {\n return sha256Json({\n project_ref: options.projectRef,\n user_id: options.userId,\n display_email: options.displayEmail,\n });\n}\n\nfunction hasExactKeys(value: JsonObject, expected: readonly string[]): boolean {\n const actual = Object.keys(value).sort();\n const sortedExpected = [...expected].sort();\n return (\n actual.length === sortedExpected.length &&\n actual.every((key, index) => key === sortedExpected[index])\n );\n}\n\nfunction isOneOf<T extends string>(value: unknown, values: readonly T[]): value is T {\n return typeof value === 'string' && values.includes(value as T);\n}\n\nfunction isCanonicalToken(value: unknown): value is string {\n return typeof value === 'string' && token(value) === value;\n}\n\nfunction isMaskedEmail(value: unknown): value is string {\n return isCanonicalToken(value) && /^(?:[^*@\\s]{2})?\\*{4}@[^@\\s]+\\.[^@\\s]+$/u.test(value);\n}\n\nfunction receiptScope(receipt: AuthIdentityReceipt): AuthIdentityReceiptScope {\n const { receipt_scope_sha256: _receiptScopeSha256, ...scope } = receipt;\n return scope;\n}\n\nexport function parseAuthIdentityReceipt(value: unknown): AuthIdentityReceipt {\n if (\n !isRecord(value) ||\n !hasExactKeys(value, [\n 'assertions',\n 'bindings',\n 'captured_at_utc',\n 'cli',\n 'identity',\n 'operation',\n 'project',\n 'receipt_scope_sha256',\n 'remote_write_mode',\n 'schema',\n 'session',\n 'status',\n ])\n ) {\n return receiptInvalid('Auth identity receipt must be an exact object.');\n }\n\n const cli = value.cli;\n const project = value.project;\n const identity = value.identity;\n const session = value.session;\n const bindings = value.bindings;\n const assertions = value.assertions;\n const parsedProject =\n isRecord(project) && typeof project.project_base_url === 'string'\n ? canonicalProjectIdentity(project.project_base_url)\n : null;\n if (\n value.schema !== AUTH_IDENTITY_RECEIPT_SCHEMA ||\n value.status !== 'passed' ||\n value.operation !== 'current-user-read' ||\n value.remote_write_mode !== 'read-only' ||\n !canonicalTimestamp(value.captured_at_utc) ||\n !isRecord(cli) ||\n !hasExactKeys(cli, ['package_name', 'package_version']) ||\n cli.package_name !== CLI_PACKAGE_NAME ||\n !isCanonicalToken(cli.package_version) ||\n !isRecord(project) ||\n !hasExactKeys(project, ['project_base_url', 'project_ref']) ||\n !isCanonicalToken(project.project_ref) ||\n !parsedProject ||\n parsedProject.projectRef !== project.project_ref ||\n !isRecord(identity) ||\n !hasExactKeys(identity, ['display_email', 'user_id']) ||\n !isCanonicalUuid(identity.user_id) ||\n !isMaskedEmail(identity.display_email) ||\n !isRecord(session) ||\n !hasExactKeys(session, ['cache_mode', 'expires_at_utc', 'force_reauth', 'source']) ||\n !isOneOf(session.source, SESSION_SOURCES) ||\n !isOneOf(session.cache_mode, CACHE_MODES) ||\n typeof session.force_reauth !== 'boolean' ||\n !(session.expires_at_utc === null || canonicalTimestamp(session.expires_at_utc)) ||\n !isRecord(bindings) ||\n !hasExactKeys(bindings, ['request_sha256', 'response_sha256']) ||\n typeof bindings.request_sha256 !== 'string' ||\n !SHA256_PATTERN.test(bindings.request_sha256) ||\n typeof bindings.response_sha256 !== 'string' ||\n !SHA256_PATTERN.test(bindings.response_sha256) ||\n bindings.request_sha256 !== requestFingerprint(project.project_ref as string) ||\n bindings.response_sha256 !==\n responseFingerprint({\n projectRef: project.project_ref as string,\n userId: identity.user_id as string,\n displayEmail: identity.display_email as string,\n }) ||\n !isRecord(assertions) ||\n !hasExactKeys(assertions, [\n 'expected_project_ref',\n 'expected_user_id',\n 'mode',\n 'passed',\n 'project_ref_passed',\n 'requested_count',\n 'user_id_passed',\n ]) ||\n !isOneOf(assertions.mode, ['observed', 'partial', 'intent-bound'] as const) ||\n ![0, 1, 2].includes(assertions.requested_count as number) ||\n !(\n assertions.expected_project_ref === null || isCanonicalToken(assertions.expected_project_ref)\n ) ||\n !(assertions.expected_user_id === null || isCanonicalUuid(assertions.expected_user_id)) ||\n !(assertions.project_ref_passed === true || assertions.project_ref_passed === null) ||\n !(assertions.user_id_passed === true || assertions.user_id_passed === null) ||\n assertions.passed !== true ||\n (assertions.expected_project_ref === null) !== (assertions.project_ref_passed === null) ||\n (assertions.expected_user_id === null) !== (assertions.user_id_passed === null) ||\n assertions.requested_count !==\n Number(assertions.expected_project_ref !== null) +\n Number(assertions.expected_user_id !== null) ||\n assertions.mode !==\n (assertions.requested_count === 0\n ? 'observed'\n : assertions.requested_count === 2\n ? 'intent-bound'\n : 'partial') ||\n (assertions.expected_project_ref !== null &&\n assertions.expected_project_ref !== project.project_ref) ||\n (assertions.expected_user_id !== null && assertions.expected_user_id !== identity.user_id) ||\n typeof value.receipt_scope_sha256 !== 'string' ||\n !SHA256_PATTERN.test(value.receipt_scope_sha256)\n ) {\n return receiptInvalid('Auth identity receipt failed schema validation.');\n }\n\n const receipt = value as AuthIdentityReceipt;\n if (receipt.receipt_scope_sha256 !== sha256Json(receiptScope(receipt))) {\n return receiptInvalid('Auth identity receipt canonical scope hash does not match.');\n }\n return receipt;\n}\n\nexport async function runAuthIdentityReceipt(\n options: RunAuthIdentityReceiptOptions,\n): Promise<AuthIdentityReceipt> {\n const timeoutMs = normalizeTimeoutMs(options.timeoutMs);\n const expectedProjectRef = normalizeExpectation(\n options.expectedProjectRef,\n '--expected-project-ref',\n );\n const expectedUserId = normalizeExpectedUserId(options.expectedUserId);\n const cliVersion = token(options.cliVersion);\n if (!cliVersion) {\n return identityError(\n 'CLI package version is required for an identity receipt.',\n 'AUTH_IDENTITY_VERSION_INVALID',\n { exitCode: 2 },\n );\n }\n const now = options.now ?? new Date();\n if (Number.isNaN(now.getTime())) {\n return identityError(\n 'Identity receipt capture time is invalid.',\n 'AUTH_IDENTITY_CAPTURE_TIME_INVALID',\n { exitCode: 2 },\n );\n }\n\n const runtime = requireSupabaseRestRuntime(options.env);\n const { projectBaseUrl, projectRef } = resolveProjectIdentity(runtime.apiBaseUrl);\n if (expectedProjectRef !== null && expectedProjectRef !== projectRef) {\n return identityError(\n 'Authenticated project does not match --expected-project-ref.',\n 'AUTH_IDENTITY_PROJECT_MISMATCH',\n { details: { expected_project_ref: expectedProjectRef, observed_project_ref: projectRef } },\n );\n }\n const credentials = requireUserApiKeyCredentials(runtime.userApiKey);\n\n let session = await resolveBoundSession({\n runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs,\n now,\n resolveSessionImpl: options.resolveSessionImpl ?? resolveSupabaseUserSession,\n });\n assertSessionBinding({\n runtime,\n session,\n projectBaseUrl,\n apiKeyEmail: credentials.email,\n now,\n });\n\n let currentUser: Awaited<ReturnType<typeof fetchCurrentUser>>;\n try {\n currentUser = await fetchCurrentUser({\n projectBaseUrl,\n publishableKey: runtime.publishableKey,\n accessToken: session.accessToken,\n timeoutMs,\n fetchImpl: options.fetchImpl,\n });\n } catch (error) {\n const status = currentUserFailureStatus(error);\n if (status === null || ![401, 403].includes(status)) {\n throw error;\n }\n session = await resolveBoundSession({\n runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs,\n now,\n forceRefresh: true,\n resolveSessionImpl: options.resolveSessionImpl ?? resolveSupabaseUserSession,\n });\n assertSessionBinding({\n runtime,\n session,\n projectBaseUrl,\n apiKeyEmail: credentials.email,\n now,\n });\n currentUser = await fetchCurrentUser({\n projectBaseUrl,\n publishableKey: runtime.publishableKey,\n accessToken: session.accessToken,\n timeoutMs,\n fetchImpl: options.fetchImpl,\n });\n }\n const sessionEmail = normalizeEmail(session.userEmail);\n const apiKeyEmail = normalizeEmail(credentials.email);\n if (\n !sessionEmail ||\n !apiKeyEmail ||\n currentUser.email !== sessionEmail ||\n currentUser.email !== apiKeyEmail\n ) {\n return identityError(\n 'Server-verified current user does not match the API-key and session identity.',\n 'AUTH_IDENTITY_SESSION_MISMATCH',\n );\n }\n if (expectedUserId !== null && expectedUserId !== currentUser.userId) {\n return identityError(\n 'Authenticated user does not match --expected-user-id.',\n 'AUTH_IDENTITY_USER_MISMATCH',\n { details: { expected_user_id: expectedUserId, observed_user_id: currentUser.userId } },\n );\n }\n\n const displayEmail = redactEmail(currentUser.email);\n const requestedAssertionCount =\n Number(expectedProjectRef !== null) + Number(expectedUserId !== null);\n const scope: AuthIdentityReceiptScope = {\n schema: AUTH_IDENTITY_RECEIPT_SCHEMA,\n status: 'passed',\n operation: 'current-user-read',\n remote_write_mode: 'read-only',\n captured_at_utc: now.toISOString(),\n cli: {\n package_name: CLI_PACKAGE_NAME,\n package_version: cliVersion,\n },\n project: {\n project_ref: projectRef,\n project_base_url: projectBaseUrl,\n },\n identity: {\n user_id: currentUser.userId,\n display_email: displayEmail,\n },\n session: {\n source: session.source,\n cache_mode: cacheMode(runtime),\n force_reauth: runtime.forceReauth,\n expires_at_utc: sessionExpiresAtUtc(session.expiresAt),\n },\n bindings: {\n request_sha256: requestFingerprint(projectRef),\n response_sha256: responseFingerprint({\n projectRef,\n userId: currentUser.userId,\n displayEmail,\n }),\n },\n assertions: {\n mode:\n requestedAssertionCount === 0\n ? 'observed'\n : requestedAssertionCount === 2\n ? 'intent-bound'\n : 'partial',\n requested_count: requestedAssertionCount as 0 | 1 | 2,\n expected_project_ref: expectedProjectRef,\n expected_user_id: expectedUserId,\n project_ref_passed: expectedProjectRef === null ? null : true,\n user_id_passed: expectedUserId === null ? null : true,\n passed: true,\n },\n };\n return parseAuthIdentityReceipt({\n ...scope,\n receipt_scope_sha256: sha256Json(scope),\n });\n}\n\nexport const __testInternals = {\n MAX_RESPONSE_BYTES,\n assertSessionBinding,\n cacheMode,\n canonicalTimestamp,\n canonicalProjectIdentity,\n currentUserFailureStatus,\n declaredResponseBytes,\n fetchCurrentUser,\n hasExactKeys,\n isCanonicalToken,\n isCanonicalUuid,\n isMaskedEmail,\n isOneOf,\n normalizeEmail,\n normalizeExpectation,\n normalizeExpectedUserId,\n normalizeTimeoutMs,\n projectRefFromBaseUrl,\n readBoundedResponseText,\n requestFingerprint,\n responseFingerprint,\n resolveProjectIdentity,\n sessionExpiresAtUtc,\n sha256Json,\n stableJsonValue,\n token,\n};\n"]}
1
+ {"version":3,"file":"auth-identity-receipt.js","sourceRoot":"","sources":["../../../src/lib/auth-identity-receipt.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto';\nimport path from 'node:path';\nimport { CliError } from './errors.js';\nimport type { FetchLike } from './http.js';\nimport {\n buildSupabaseAuthHeaders,\n deriveSupabaseProjectBaseUrl,\n requireSupabaseRestRuntime,\n type SupabaseRestRuntime,\n} from './supabase-client.js';\nimport {\n resolveSupabaseUserSession,\n type ResolvedSupabaseUserSession,\n} from './supabase-session.js';\nimport { redactEmail, requireUserApiKeyCredentials } from './user-api-key.js';\n\nexport const AUTH_IDENTITY_RECEIPT_SCHEMA = 'tiangong-lca.auth-identity-receipt.v1' as const;\nexport const AUTH_IDENTITY_MAX_TIMEOUT_MS = 2_147_483_647;\n\nconst CLI_PACKAGE_NAME = '@tiangong-lca/cli' as const;\nconst CURRENT_USER_PATH = '/auth/v1/user' as const;\nconst DEFAULT_TIMEOUT_MS = 10_000;\nconst MAX_RESPONSE_BYTES = 64 * 1024;\nconst SESSION_REFRESH_WINDOW_SECONDS = 300;\nconst SHA256_PATTERN = /^[0-9a-f]{64}$/u;\nconst UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/u;\nconst EMAIL_PATTERN = /^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/u;\nconst SESSION_SOURCES = [\n 'memory',\n 'cache',\n 'refresh',\n 'oauth_login',\n 'legacy_signin',\n 'access_token',\n] as const;\nconst CACHE_MODES = ['disabled', 'custom-file', 'platform-default'] as const;\n\ntype SessionSource = (typeof SESSION_SOURCES)[number];\ntype CacheMode = (typeof CACHE_MODES)[number];\ntype JsonObject = Record<string, unknown>;\n\nclass ResponseBodyTooLargeError extends Error {\n constructor() {\n super('Response body exceeded the identity receipt byte limit.');\n this.name = 'ResponseBodyTooLargeError';\n }\n}\n\nexport type AuthIdentityReceiptScope = {\n schema: typeof AUTH_IDENTITY_RECEIPT_SCHEMA;\n status: 'passed';\n operation: 'current-user-read';\n remote_write_mode: 'read-only';\n captured_at_utc: string;\n cli: {\n package_name: typeof CLI_PACKAGE_NAME;\n package_version: string;\n };\n project: {\n project_ref: string;\n project_base_url: string;\n };\n identity: {\n user_id: string;\n display_email: string;\n };\n session: {\n source: SessionSource;\n cache_mode: CacheMode;\n force_reauth: boolean;\n expires_at_utc: string | null;\n };\n bindings: {\n request_sha256: string;\n response_sha256: string;\n };\n assertions: {\n mode: 'observed' | 'partial' | 'intent-bound';\n requested_count: 0 | 1 | 2;\n expected_project_ref: string | null;\n expected_user_id: string | null;\n project_ref_passed: true | null;\n user_id_passed: true | null;\n passed: true;\n };\n};\n\nexport type AuthIdentityReceipt = AuthIdentityReceiptScope & {\n receipt_scope_sha256: string;\n};\n\nexport type ResolveAuthIdentitySession = (options: {\n runtime: SupabaseRestRuntime;\n fetchImpl: FetchLike;\n timeoutMs?: number;\n now?: Date;\n forceRefresh?: boolean;\n}) => Promise<ResolvedSupabaseUserSession>;\n\nexport type RunAuthIdentityReceiptOptions = {\n env: NodeJS.ProcessEnv;\n fetchImpl: FetchLike;\n cliVersion: string;\n expectedProjectRef?: string | null;\n expectedUserId?: string | null;\n timeoutMs?: number;\n now?: Date;\n resolveSessionImpl?: ResolveAuthIdentitySession;\n};\n\nfunction isRecord(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction stableJsonValue(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(stableJsonValue);\n }\n if (isRecord(value)) {\n return Object.fromEntries(\n Object.keys(value)\n .sort()\n .map((key) => [key, stableJsonValue(value[key])]),\n );\n }\n return value;\n}\n\nfunction sha256Json(value: unknown): string {\n return createHash('sha256')\n .update(JSON.stringify(stableJsonValue(value)))\n .digest('hex');\n}\n\nfunction token(value: unknown): string | null {\n if (typeof value !== 'string') {\n return null;\n }\n const normalized = value.trim();\n return normalized || null;\n}\n\nfunction normalizeEmail(value: unknown): string | null {\n const normalized = token(value)?.toLowerCase() ?? null;\n if (!normalized || normalized.length > 254 || !EMAIL_PATTERN.test(normalized)) {\n return null;\n }\n return normalized;\n}\n\nfunction isCanonicalUuid(value: unknown): value is string {\n return typeof value === 'string' && UUID_PATTERN.test(value);\n}\n\nfunction identityError(\n message: string,\n code: string,\n options: { exitCode?: number; details?: unknown } = {},\n): never {\n throw new CliError(message, {\n code,\n exitCode: options.exitCode ?? 1,\n ...(options.details === undefined ? {} : { details: options.details }),\n });\n}\n\nfunction receiptInvalid(message: string): never {\n return identityError(message, 'AUTH_IDENTITY_RECEIPT_INVALID');\n}\n\nfunction normalizeExpectation(value: string | null | undefined, label: string): string | null {\n if (value === null || value === undefined) {\n return null;\n }\n const normalized = token(value);\n if (!normalized) {\n return identityError(\n `${label} must be a non-empty string when provided.`,\n 'AUTH_IDENTITY_EXPECTATION_INVALID',\n {\n exitCode: 2,\n details: { option: label },\n },\n );\n }\n return normalized;\n}\n\nfunction normalizeExpectedUserId(value: string | null | undefined): string | null {\n const normalized = normalizeExpectation(value, '--expected-user-id');\n if (normalized !== null && !isCanonicalUuid(normalized)) {\n return identityError(\n '--expected-user-id must be a canonical lowercase UUID.',\n 'AUTH_IDENTITY_EXPECTATION_INVALID',\n { exitCode: 2, details: { option: '--expected-user-id' } },\n );\n }\n return normalized;\n}\n\nfunction normalizeTimeoutMs(value: number | undefined): number {\n const normalized = value ?? DEFAULT_TIMEOUT_MS;\n if (\n !Number.isInteger(normalized) ||\n normalized <= 0 ||\n normalized > AUTH_IDENTITY_MAX_TIMEOUT_MS\n ) {\n return identityError(\n `Auth identity timeout must be an integer between 1 and ${AUTH_IDENTITY_MAX_TIMEOUT_MS}.`,\n 'AUTH_IDENTITY_TIMEOUT_INVALID',\n { exitCode: 2 },\n );\n }\n return normalized;\n}\n\nfunction canonicalTimestamp(value: unknown): value is string {\n if (typeof value !== 'string') {\n return false;\n }\n const timestamp = new Date(value);\n return !Number.isNaN(timestamp.getTime()) && timestamp.toISOString() === value;\n}\n\nfunction canonicalProjectIdentity(\n projectBaseUrl: unknown,\n): { projectBaseUrl: string; projectRef: string } | null {\n const normalized = token(projectBaseUrl);\n if (!normalized || normalized !== projectBaseUrl) {\n return null;\n }\n try {\n const url = new URL(normalized);\n const suffix = '.supabase.co';\n const hostname = url.hostname.toLowerCase();\n const projectRef = hostname.endsWith(suffix) ? hostname.slice(0, -suffix.length) : '';\n if (\n url.protocol !== 'https:' ||\n url.origin !== normalized ||\n url.username ||\n url.password ||\n url.port ||\n !projectRef ||\n projectRef.includes('.') ||\n !/^[a-z0-9-]+$/u.test(projectRef)\n ) {\n return null;\n }\n return { projectBaseUrl: url.origin, projectRef };\n } catch {\n return null;\n }\n}\n\nfunction projectRefFromBaseUrl(projectBaseUrl: string): string {\n const identity = canonicalProjectIdentity(projectBaseUrl);\n if (!identity) {\n return identityError(\n 'The Supabase project URL did not contain a project identity.',\n 'AUTH_IDENTITY_PROJECT_INVALID',\n { exitCode: 2 },\n );\n }\n return identity.projectRef;\n}\n\nfunction resolveProjectIdentity(apiBaseUrl: string): {\n projectBaseUrl: string;\n projectRef: string;\n} {\n let projectBaseUrl: string;\n try {\n projectBaseUrl = deriveSupabaseProjectBaseUrl(apiBaseUrl);\n } catch {\n return identityError(\n 'TIANGONG_LCA_API_BASE_URL must identify a canonical Supabase project.',\n 'AUTH_IDENTITY_PROJECT_INVALID',\n { exitCode: 2 },\n );\n }\n const projectRef = projectRefFromBaseUrl(projectBaseUrl);\n return { projectBaseUrl, projectRef };\n}\n\nfunction cacheMode(runtime: SupabaseRestRuntime): CacheMode {\n if (runtime.authMode === 'access_token' || runtime.disableSessionCache) {\n return 'disabled';\n }\n return runtime.sessionFile ? 'custom-file' : 'platform-default';\n}\n\nfunction sessionExpiresAtUtc(expiresAt: number | null): string | null {\n if (expiresAt === null) {\n return null;\n }\n if (!Number.isFinite(expiresAt)) {\n return identityError(\n 'Resolved auth session contained an invalid expiry.',\n 'AUTH_IDENTITY_SESSION_MISMATCH',\n );\n }\n const timestamp = new Date(Math.floor(expiresAt) * 1000);\n if (Number.isNaN(timestamp.getTime())) {\n return identityError(\n 'Resolved auth session contained an invalid expiry.',\n 'AUTH_IDENTITY_SESSION_MISMATCH',\n );\n }\n return timestamp.toISOString();\n}\n\nfunction assertSessionBinding(options: {\n runtime: SupabaseRestRuntime;\n session: ResolvedSupabaseUserSession;\n projectBaseUrl: string;\n credentialEmail: string | null;\n now: Date;\n}): void {\n const { runtime, session } = options;\n const sessionEmail = normalizeEmail(session.userEmail);\n const credentialEmail = options.credentialEmail ? normalizeEmail(options.credentialEmail) : null;\n const accessToken = token(session.accessToken);\n const source = session.source as string;\n const expectedMode = cacheMode(runtime);\n const customSessionPath = runtime.sessionFile ? path.resolve(runtime.sessionFile) : null;\n const sessionPath = session.sessionFile ? path.resolve(session.sessionFile) : null;\n const cachePathMatches =\n expectedMode === 'disabled'\n ? sessionPath === null\n : expectedMode === 'custom-file'\n ? sessionPath === customSessionPath\n : sessionPath !== null;\n const cacheSourceFresh =\n !['memory', 'cache'].includes(source) ||\n (typeof session.expiresAt === 'number' &&\n Number.isFinite(session.expiresAt) &&\n session.expiresAt >\n Math.floor(options.now.getTime() / 1000) + SESSION_REFRESH_WINDOW_SECONDS);\n\n if (\n !accessToken ||\n session.authMethod !== runtime.authMode ||\n session.projectBaseUrl !== options.projectBaseUrl ||\n !sessionEmail ||\n (credentialEmail !== null && sessionEmail !== credentialEmail) ||\n !SESSION_SOURCES.includes(session.source) ||\n !cachePathMatches ||\n !cacheSourceFresh ||\n (runtime.forceReauth && ['memory', 'cache'].includes(source))\n ) {\n identityError(\n 'Resolved auth session does not match the requested credential, project, or cache boundary.',\n 'AUTH_IDENTITY_SESSION_MISMATCH',\n );\n }\n}\n\nasync function resolveBoundSession(options: {\n runtime: SupabaseRestRuntime;\n fetchImpl: FetchLike;\n timeoutMs: number;\n now: Date;\n forceRefresh?: boolean;\n resolveSessionImpl: ResolveAuthIdentitySession;\n}): Promise<ResolvedSupabaseUserSession> {\n try {\n return await options.resolveSessionImpl({\n runtime: options.runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n now: options.now,\n forceRefresh: options.forceRefresh,\n });\n } catch (error) {\n const causeCode =\n error instanceof CliError\n ? error.code\n : isRecord(error) && typeof error.code === 'string'\n ? error.code\n : 'UNEXPECTED_SESSION_FAILURE';\n return identityError(\n 'Failed to resolve the authenticated user session.',\n 'AUTH_IDENTITY_SESSION_FAILED',\n { details: { cause_code: causeCode } },\n );\n }\n}\n\nfunction currentUserFailureStatus(error: unknown): number | null {\n if (\n !(error instanceof CliError) ||\n error.code !== 'AUTH_IDENTITY_REMOTE_REQUEST_FAILED' ||\n !isRecord(error.details) ||\n typeof error.details.status !== 'number' ||\n !Number.isInteger(error.details.status)\n ) {\n return null;\n }\n return error.details.status;\n}\n\nfunction declaredResponseBytes(response: {\n headers: { get(name: string): string | null };\n}): number | null {\n const value = response.headers.get('content-length')?.trim() ?? '';\n if (!/^\\d+$/u.test(value)) {\n return null;\n }\n return Number(value);\n}\n\nasync function readBoundedResponseText(response: {\n body?: ReadableStream<Uint8Array> | null;\n headers: { get(name: string): string | null };\n text(): Promise<string>;\n}): Promise<string> {\n const declaredBytes = declaredResponseBytes(response);\n if (declaredBytes !== null && declaredBytes > MAX_RESPONSE_BYTES) {\n throw new ResponseBodyTooLargeError();\n }\n if (!response.body) {\n const text = await response.text();\n if (Buffer.byteLength(text, 'utf8') > MAX_RESPONSE_BYTES) {\n throw new ResponseBodyTooLargeError();\n }\n return text;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let observedBytes = 0;\n let text = '';\n try {\n while (true) {\n const chunk = await reader.read();\n if (chunk.done) {\n break;\n }\n observedBytes += chunk.value.byteLength;\n if (observedBytes > MAX_RESPONSE_BYTES) {\n await Promise.allSettled([reader.cancel()]);\n throw new ResponseBodyTooLargeError();\n }\n text += decoder.decode(chunk.value, { stream: true });\n }\n text += decoder.decode();\n return text;\n } finally {\n reader.releaseLock();\n }\n}\n\nasync function fetchCurrentUser(options: {\n projectBaseUrl: string;\n publishableKey: string;\n accessToken: string;\n timeoutMs: number;\n fetchImpl: FetchLike;\n}): Promise<{ userId: string; email: string }> {\n const url = `${options.projectBaseUrl}${CURRENT_USER_PATH}`;\n let response;\n try {\n response = await options.fetchImpl(url, {\n method: 'GET',\n headers: buildSupabaseAuthHeaders(options.publishableKey, options.accessToken),\n redirect: 'error',\n signal: AbortSignal.timeout(options.timeoutMs),\n });\n } catch (error) {\n return identityError(\n 'Authenticated current-user lookup failed before a response was received.',\n 'AUTH_IDENTITY_REMOTE_REQUEST_FAILED',\n {\n details: {\n endpoint: CURRENT_USER_PATH,\n cause: error instanceof Error ? error.name : typeof error,\n },\n },\n );\n }\n\n if (!response.ok) {\n return identityError(\n `Authenticated current-user lookup returned HTTP ${response.status}.`,\n 'AUTH_IDENTITY_REMOTE_REQUEST_FAILED',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n const contentType = response.headers.get('content-type')?.toLowerCase() ?? '';\n if (!contentType.includes('application/json')) {\n return identityError(\n 'Authenticated current-user response did not declare JSON content.',\n 'AUTH_IDENTITY_REMOTE_INVALID_JSON',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n\n let text: string;\n try {\n text = await readBoundedResponseText(response);\n } catch (error) {\n if (error instanceof ResponseBodyTooLargeError) {\n return identityError(\n 'Authenticated current-user response exceeded the bounded receipt limit.',\n 'AUTH_IDENTITY_RESPONSE_TOO_LARGE',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n return identityError(\n 'Authenticated current-user response could not be read.',\n 'AUTH_IDENTITY_REMOTE_REQUEST_FAILED',\n {\n details: {\n endpoint: CURRENT_USER_PATH,\n status: response.status,\n cause: error instanceof Error ? error.name : typeof error,\n },\n },\n );\n }\n\n let payload: unknown;\n try {\n payload = JSON.parse(text);\n } catch {\n return identityError(\n 'Authenticated current-user response was not valid JSON.',\n 'AUTH_IDENTITY_REMOTE_INVALID_JSON',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n if (isRecord(payload) && payload.ok === false) {\n return identityError(\n 'Authenticated current-user response explicitly reported ok:false.',\n 'AUTH_IDENTITY_REMOTE_REJECTED',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n const userId = isRecord(payload) && isCanonicalUuid(payload.id) ? payload.id : null;\n const email = isRecord(payload) ? normalizeEmail(payload.email) : null;\n if (!userId || !email) {\n return identityError(\n 'Authenticated current-user response did not contain a valid id and email.',\n 'AUTH_IDENTITY_RESPONSE_INVALID',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n return { userId, email };\n}\n\nfunction requestFingerprint(projectRef: string): string {\n return sha256Json({\n method: 'GET',\n path: CURRENT_USER_PATH,\n project_ref: projectRef,\n redirect: 'error',\n header_names: ['accept', 'apikey', 'authorization'],\n });\n}\n\nfunction responseFingerprint(options: {\n projectRef: string;\n userId: string;\n displayEmail: string;\n}): string {\n return sha256Json({\n project_ref: options.projectRef,\n user_id: options.userId,\n display_email: options.displayEmail,\n });\n}\n\nfunction hasExactKeys(value: JsonObject, expected: readonly string[]): boolean {\n const actual = Object.keys(value).sort();\n const sortedExpected = [...expected].sort();\n return (\n actual.length === sortedExpected.length &&\n actual.every((key, index) => key === sortedExpected[index])\n );\n}\n\nfunction isOneOf<T extends string>(value: unknown, values: readonly T[]): value is T {\n return typeof value === 'string' && values.includes(value as T);\n}\n\nfunction isCanonicalToken(value: unknown): value is string {\n return typeof value === 'string' && token(value) === value;\n}\n\nfunction isMaskedEmail(value: unknown): value is string {\n return isCanonicalToken(value) && /^(?:[^*@\\s]{2})?\\*{4}@[^@\\s]+\\.[^@\\s]+$/u.test(value);\n}\n\nfunction receiptScope(receipt: AuthIdentityReceipt): AuthIdentityReceiptScope {\n const { receipt_scope_sha256: _receiptScopeSha256, ...scope } = receipt;\n return scope;\n}\n\nexport function parseAuthIdentityReceipt(value: unknown): AuthIdentityReceipt {\n if (\n !isRecord(value) ||\n !hasExactKeys(value, [\n 'assertions',\n 'bindings',\n 'captured_at_utc',\n 'cli',\n 'identity',\n 'operation',\n 'project',\n 'receipt_scope_sha256',\n 'remote_write_mode',\n 'schema',\n 'session',\n 'status',\n ])\n ) {\n return receiptInvalid('Auth identity receipt must be an exact object.');\n }\n\n const cli = value.cli;\n const project = value.project;\n const identity = value.identity;\n const session = value.session;\n const bindings = value.bindings;\n const assertions = value.assertions;\n const parsedProject =\n isRecord(project) && typeof project.project_base_url === 'string'\n ? canonicalProjectIdentity(project.project_base_url)\n : null;\n if (\n value.schema !== AUTH_IDENTITY_RECEIPT_SCHEMA ||\n value.status !== 'passed' ||\n value.operation !== 'current-user-read' ||\n value.remote_write_mode !== 'read-only' ||\n !canonicalTimestamp(value.captured_at_utc) ||\n !isRecord(cli) ||\n !hasExactKeys(cli, ['package_name', 'package_version']) ||\n cli.package_name !== CLI_PACKAGE_NAME ||\n !isCanonicalToken(cli.package_version) ||\n !isRecord(project) ||\n !hasExactKeys(project, ['project_base_url', 'project_ref']) ||\n !isCanonicalToken(project.project_ref) ||\n !parsedProject ||\n parsedProject.projectRef !== project.project_ref ||\n !isRecord(identity) ||\n !hasExactKeys(identity, ['display_email', 'user_id']) ||\n !isCanonicalUuid(identity.user_id) ||\n !isMaskedEmail(identity.display_email) ||\n !isRecord(session) ||\n !hasExactKeys(session, ['cache_mode', 'expires_at_utc', 'force_reauth', 'source']) ||\n !isOneOf(session.source, SESSION_SOURCES) ||\n !isOneOf(session.cache_mode, CACHE_MODES) ||\n typeof session.force_reauth !== 'boolean' ||\n !(session.expires_at_utc === null || canonicalTimestamp(session.expires_at_utc)) ||\n !isRecord(bindings) ||\n !hasExactKeys(bindings, ['request_sha256', 'response_sha256']) ||\n typeof bindings.request_sha256 !== 'string' ||\n !SHA256_PATTERN.test(bindings.request_sha256) ||\n typeof bindings.response_sha256 !== 'string' ||\n !SHA256_PATTERN.test(bindings.response_sha256) ||\n bindings.request_sha256 !== requestFingerprint(project.project_ref as string) ||\n bindings.response_sha256 !==\n responseFingerprint({\n projectRef: project.project_ref as string,\n userId: identity.user_id as string,\n displayEmail: identity.display_email as string,\n }) ||\n !isRecord(assertions) ||\n !hasExactKeys(assertions, [\n 'expected_project_ref',\n 'expected_user_id',\n 'mode',\n 'passed',\n 'project_ref_passed',\n 'requested_count',\n 'user_id_passed',\n ]) ||\n !isOneOf(assertions.mode, ['observed', 'partial', 'intent-bound'] as const) ||\n ![0, 1, 2].includes(assertions.requested_count as number) ||\n !(\n assertions.expected_project_ref === null || isCanonicalToken(assertions.expected_project_ref)\n ) ||\n !(assertions.expected_user_id === null || isCanonicalUuid(assertions.expected_user_id)) ||\n !(assertions.project_ref_passed === true || assertions.project_ref_passed === null) ||\n !(assertions.user_id_passed === true || assertions.user_id_passed === null) ||\n assertions.passed !== true ||\n (assertions.expected_project_ref === null) !== (assertions.project_ref_passed === null) ||\n (assertions.expected_user_id === null) !== (assertions.user_id_passed === null) ||\n assertions.requested_count !==\n Number(assertions.expected_project_ref !== null) +\n Number(assertions.expected_user_id !== null) ||\n assertions.mode !==\n (assertions.requested_count === 0\n ? 'observed'\n : assertions.requested_count === 2\n ? 'intent-bound'\n : 'partial') ||\n (assertions.expected_project_ref !== null &&\n assertions.expected_project_ref !== project.project_ref) ||\n (assertions.expected_user_id !== null && assertions.expected_user_id !== identity.user_id) ||\n typeof value.receipt_scope_sha256 !== 'string' ||\n !SHA256_PATTERN.test(value.receipt_scope_sha256)\n ) {\n return receiptInvalid('Auth identity receipt failed schema validation.');\n }\n\n const receipt = value as AuthIdentityReceipt;\n if (receipt.receipt_scope_sha256 !== sha256Json(receiptScope(receipt))) {\n return receiptInvalid('Auth identity receipt canonical scope hash does not match.');\n }\n return receipt;\n}\n\nexport async function runAuthIdentityReceipt(\n options: RunAuthIdentityReceiptOptions,\n): Promise<AuthIdentityReceipt> {\n const timeoutMs = normalizeTimeoutMs(options.timeoutMs);\n const expectedProjectRef = normalizeExpectation(\n options.expectedProjectRef,\n '--expected-project-ref',\n );\n const expectedUserId = normalizeExpectedUserId(options.expectedUserId);\n const cliVersion = token(options.cliVersion);\n if (!cliVersion) {\n return identityError(\n 'CLI package version is required for an identity receipt.',\n 'AUTH_IDENTITY_VERSION_INVALID',\n { exitCode: 2 },\n );\n }\n const now = options.now ?? new Date();\n if (Number.isNaN(now.getTime())) {\n return identityError(\n 'Identity receipt capture time is invalid.',\n 'AUTH_IDENTITY_CAPTURE_TIME_INVALID',\n { exitCode: 2 },\n );\n }\n\n const runtime = requireSupabaseRestRuntime(options.env);\n const { projectBaseUrl, projectRef } = resolveProjectIdentity(runtime.apiBaseUrl);\n if (expectedProjectRef !== null && expectedProjectRef !== projectRef) {\n return identityError(\n 'Authenticated project does not match --expected-project-ref.',\n 'AUTH_IDENTITY_PROJECT_MISMATCH',\n { details: { expected_project_ref: expectedProjectRef, observed_project_ref: projectRef } },\n );\n }\n const credentialEmail =\n runtime.authMode === 'legacy_user_api_key'\n ? requireUserApiKeyCredentials(runtime.userApiKey as string).email\n : null;\n\n let session = await resolveBoundSession({\n runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs,\n now,\n resolveSessionImpl: options.resolveSessionImpl ?? resolveSupabaseUserSession,\n });\n assertSessionBinding({\n runtime,\n session,\n projectBaseUrl,\n credentialEmail,\n now,\n });\n\n let currentUser: Awaited<ReturnType<typeof fetchCurrentUser>>;\n try {\n currentUser = await fetchCurrentUser({\n projectBaseUrl,\n publishableKey: runtime.publishableKey,\n accessToken: session.accessToken,\n timeoutMs,\n fetchImpl: options.fetchImpl,\n });\n } catch (error) {\n const status = currentUserFailureStatus(error);\n if (status === null || ![401, 403].includes(status)) {\n throw error;\n }\n session = await resolveBoundSession({\n runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs,\n now,\n forceRefresh: true,\n resolveSessionImpl: options.resolveSessionImpl ?? resolveSupabaseUserSession,\n });\n assertSessionBinding({\n runtime,\n session,\n projectBaseUrl,\n credentialEmail,\n now,\n });\n currentUser = await fetchCurrentUser({\n projectBaseUrl,\n publishableKey: runtime.publishableKey,\n accessToken: session.accessToken,\n timeoutMs,\n fetchImpl: options.fetchImpl,\n });\n }\n const sessionEmail = normalizeEmail(session.userEmail);\n const normalizedCredentialEmail = credentialEmail ? normalizeEmail(credentialEmail) : null;\n if (\n !sessionEmail ||\n currentUser.email !== sessionEmail ||\n (normalizedCredentialEmail !== null && currentUser.email !== normalizedCredentialEmail)\n ) {\n return identityError(\n 'Server-verified current user does not match the resolved session identity.',\n 'AUTH_IDENTITY_SESSION_MISMATCH',\n );\n }\n if (expectedUserId !== null && expectedUserId !== currentUser.userId) {\n return identityError(\n 'Authenticated user does not match --expected-user-id.',\n 'AUTH_IDENTITY_USER_MISMATCH',\n { details: { expected_user_id: expectedUserId, observed_user_id: currentUser.userId } },\n );\n }\n\n const displayEmail = redactEmail(currentUser.email);\n const requestedAssertionCount =\n Number(expectedProjectRef !== null) + Number(expectedUserId !== null);\n const scope: AuthIdentityReceiptScope = {\n schema: AUTH_IDENTITY_RECEIPT_SCHEMA,\n status: 'passed',\n operation: 'current-user-read',\n remote_write_mode: 'read-only',\n captured_at_utc: now.toISOString(),\n cli: {\n package_name: CLI_PACKAGE_NAME,\n package_version: cliVersion,\n },\n project: {\n project_ref: projectRef,\n project_base_url: projectBaseUrl,\n },\n identity: {\n user_id: currentUser.userId,\n display_email: displayEmail,\n },\n session: {\n source: session.source,\n cache_mode: cacheMode(runtime),\n force_reauth: runtime.forceReauth,\n expires_at_utc: sessionExpiresAtUtc(session.expiresAt),\n },\n bindings: {\n request_sha256: requestFingerprint(projectRef),\n response_sha256: responseFingerprint({\n projectRef,\n userId: currentUser.userId,\n displayEmail,\n }),\n },\n assertions: {\n mode:\n requestedAssertionCount === 0\n ? 'observed'\n : requestedAssertionCount === 2\n ? 'intent-bound'\n : 'partial',\n requested_count: requestedAssertionCount as 0 | 1 | 2,\n expected_project_ref: expectedProjectRef,\n expected_user_id: expectedUserId,\n project_ref_passed: expectedProjectRef === null ? null : true,\n user_id_passed: expectedUserId === null ? null : true,\n passed: true,\n },\n };\n return parseAuthIdentityReceipt({\n ...scope,\n receipt_scope_sha256: sha256Json(scope),\n });\n}\n\nexport const __testInternals = {\n MAX_RESPONSE_BYTES,\n assertSessionBinding,\n cacheMode,\n canonicalTimestamp,\n canonicalProjectIdentity,\n currentUserFailureStatus,\n declaredResponseBytes,\n fetchCurrentUser,\n hasExactKeys,\n isCanonicalToken,\n isCanonicalUuid,\n isMaskedEmail,\n isOneOf,\n normalizeEmail,\n normalizeExpectation,\n normalizeExpectedUserId,\n normalizeTimeoutMs,\n projectRefFromBaseUrl,\n readBoundedResponseText,\n requestFingerprint,\n responseFingerprint,\n resolveProjectIdentity,\n sessionExpiresAtUtc,\n sha256Json,\n stableJsonValue,\n token,\n};\n"]}
@@ -13,6 +13,10 @@ export type ResolvedEnv = {
13
13
  export declare const ENV_KEYS: {
14
14
  readonly apiBaseUrl: 'TIANGONG_LCA_API_BASE_URL';
15
15
  readonly apiKey: 'TIANGONG_LCA_API_KEY';
16
+ readonly authMode: 'TIANGONG_LCA_AUTH_MODE';
17
+ readonly oauthClientId: 'TIANGONG_LCA_OAUTH_CLIENT_ID';
18
+ readonly oauthRedirectUri: 'TIANGONG_LCA_OAUTH_REDIRECT_URI';
19
+ readonly accessToken: 'TIANGONG_LCA_ACCESS_TOKEN';
16
20
  readonly region: 'TIANGONG_LCA_REGION';
17
21
  readonly supabasePublishableKey: 'TIANGONG_LCA_SUPABASE_PUBLISHABLE_KEY';
18
22
  readonly sessionFile: 'TIANGONG_LCA_SESSION_FILE';
@@ -38,6 +42,10 @@ export type DoctorReport = {
38
42
  export type RuntimeEnv = {
39
43
  apiBaseUrl: string | null;
40
44
  apiKey: string | null;
45
+ authMode: string | null;
46
+ oauthClientId: string | null;
47
+ oauthRedirectUri: string | null;
48
+ accessToken: string | null;
41
49
  region: string;
42
50
  supabasePublishableKey: string | null;
43
51
  sessionFile: string | null;
@@ -1,6 +1,10 @@
1
1
  export const ENV_KEYS = {
2
2
  apiBaseUrl: 'TIANGONG_LCA_API_BASE_URL',
3
3
  apiKey: 'TIANGONG_LCA_API_KEY',
4
+ authMode: 'TIANGONG_LCA_AUTH_MODE',
5
+ oauthClientId: 'TIANGONG_LCA_OAUTH_CLIENT_ID',
6
+ oauthRedirectUri: 'TIANGONG_LCA_OAUTH_REDIRECT_URI',
7
+ accessToken: 'TIANGONG_LCA_ACCESS_TOKEN',
4
8
  region: 'TIANGONG_LCA_REGION',
5
9
  supabasePublishableKey: 'TIANGONG_LCA_SUPABASE_PUBLISHABLE_KEY',
6
10
  sessionFile: 'TIANGONG_LCA_SESSION_FILE',
@@ -15,8 +19,8 @@ export const ENV_SPECS = [
15
19
  },
16
20
  {
17
21
  key: ENV_KEYS.apiKey,
18
- required: true,
19
- description: 'Main TianGong LCA API key',
22
+ required: false,
23
+ description: 'Deprecated legacy email/password API key bootstrap',
20
24
  },
21
25
  {
22
26
  key: ENV_KEYS.region,
@@ -46,6 +50,26 @@ export const ENV_SPECS = [
46
50
  description: 'Ignore cached sessions and force a fresh login when set to true',
47
51
  defaultValue: 'false',
48
52
  },
53
+ {
54
+ key: ENV_KEYS.authMode,
55
+ required: false,
56
+ description: 'Optional explicit auth mode: oauth, access-token, or legacy-user-api-key',
57
+ },
58
+ {
59
+ key: ENV_KEYS.oauthClientId,
60
+ required: false,
61
+ description: 'Registered public Supabase OAuth client ID',
62
+ },
63
+ {
64
+ key: ENV_KEYS.oauthRedirectUri,
65
+ required: false,
66
+ description: 'Exact registered CLI loopback OAuth redirect URI',
67
+ },
68
+ {
69
+ key: ENV_KEYS.accessToken,
70
+ required: false,
71
+ description: 'Explicit short-lived actor access token for headless execution',
72
+ },
49
73
  ];
50
74
  function parseBooleanEnv(value) {
51
75
  if (typeof value !== 'string') {
@@ -94,9 +118,17 @@ export function readRuntimeEnv(env) {
94
118
  const sessionFile = resolveEnv(ENV_SPECS[4], env).value;
95
119
  const disableSessionCache = parseBooleanEnv(resolveEnv(ENV_SPECS[5], env).value);
96
120
  const forceReauth = parseBooleanEnv(resolveEnv(ENV_SPECS[6], env).value);
121
+ const authMode = resolveEnv(ENV_SPECS[7], env).value;
122
+ const oauthClientId = resolveEnv(ENV_SPECS[8], env).value;
123
+ const oauthRedirectUri = resolveEnv(ENV_SPECS[9], env).value;
124
+ const accessToken = resolveEnv(ENV_SPECS[10], env).value;
97
125
  return {
98
126
  apiBaseUrl,
99
127
  apiKey,
128
+ authMode,
129
+ oauthClientId,
130
+ oauthRedirectUri,
131
+ accessToken,
100
132
  region,
101
133
  supabasePublishableKey,
102
134
  sessionFile,
@@ -126,7 +158,8 @@ export function buildDoctorReport(env, dotEnvStatus) {
126
158
  };
127
159
  });
128
160
  return {
129
- ok: checks.every((check) => !check.required || check.present),
161
+ ok: checks.every((check) => !check.required || check.present) &&
162
+ [ENV_KEYS.oauthClientId, ENV_KEYS.accessToken, ENV_KEYS.apiKey].some((key) => checks.find((check) => check.key === key)?.present),
130
163
  loadedDotEnv: dotEnvStatus.loaded,
131
164
  dotEnvPath: dotEnvStatus.path,
132
165
  dotEnvKeysLoaded: dotEnvStatus.count,
@@ -1 +1 @@
1
- {"version":3,"file":"env.js","sourceRoot":"","sources":["../../../src/lib/env.ts"],"names":[],"mappings":"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","sourcesContent":["export type EnvSpec = {\n key: string;\n required: boolean;\n description: string;\n defaultValue?: string;\n};\n\nexport type ResolvedEnv = {\n key: string;\n source: 'env' | 'default' | 'missing';\n value: string | null;\n present: boolean;\n};\n\nexport const ENV_KEYS = {\n apiBaseUrl: 'TIANGONG_LCA_API_BASE_URL',\n apiKey: 'TIANGONG_LCA_API_KEY',\n region: 'TIANGONG_LCA_REGION',\n supabasePublishableKey: 'TIANGONG_LCA_SUPABASE_PUBLISHABLE_KEY',\n sessionFile: 'TIANGONG_LCA_SESSION_FILE',\n disableSessionCache: 'TIANGONG_LCA_DISABLE_SESSION_CACHE',\n forceReauth: 'TIANGONG_LCA_FORCE_REAUTH',\n} as const;\n\nexport const ENV_SPECS: EnvSpec[] = [\n {\n key: ENV_KEYS.apiBaseUrl,\n required: true,\n description: 'Main TianGong LCA API / Edge Functions base URL',\n },\n {\n key: ENV_KEYS.apiKey,\n required: true,\n description: 'Main TianGong LCA API key',\n },\n {\n key: ENV_KEYS.region,\n required: false,\n description: 'Target TianGong LCA API region',\n defaultValue: 'us-east-1',\n },\n {\n key: ENV_KEYS.supabasePublishableKey,\n required: true,\n description: 'Supabase publishable key used to bootstrap and refresh user sessions',\n },\n {\n key: ENV_KEYS.sessionFile,\n required: false,\n description: 'Optional local path for the CLI session cache file',\n },\n {\n key: ENV_KEYS.disableSessionCache,\n required: false,\n description: 'Disable the persistent CLI session cache when set to true',\n defaultValue: 'false',\n },\n {\n key: ENV_KEYS.forceReauth,\n required: false,\n description: 'Ignore cached sessions and force a fresh login when set to true',\n defaultValue: 'false',\n },\n];\n\nexport type DoctorCheck = {\n key: string;\n description: string;\n required: boolean;\n source: ResolvedEnv['source'];\n present: boolean;\n valuePreview: string | null;\n};\n\nexport type DoctorReport = {\n ok: boolean;\n loadedDotEnv: boolean;\n dotEnvPath: string;\n dotEnvKeysLoaded: number;\n checks: DoctorCheck[];\n};\n\nexport type RuntimeEnv = {\n apiBaseUrl: string | null;\n apiKey: string | null;\n region: string;\n supabasePublishableKey: string | null;\n sessionFile: string | null;\n disableSessionCache: boolean;\n forceReauth: boolean;\n};\n\nfunction parseBooleanEnv(value: string | null): boolean {\n if (typeof value !== 'string') {\n return false;\n }\n\n switch (value.trim().toLowerCase()) {\n case '1':\n case 'true':\n case 'yes':\n case 'on':\n return true;\n default:\n return false;\n }\n}\n\nexport function resolveEnv(spec: EnvSpec, env: NodeJS.ProcessEnv): ResolvedEnv {\n const envValue = env[spec.key];\n if (envValue) {\n return {\n key: spec.key,\n source: 'env',\n value: envValue,\n present: true,\n };\n }\n\n if (spec.defaultValue !== undefined) {\n return {\n key: spec.key,\n source: 'default',\n value: spec.defaultValue,\n present: true,\n };\n }\n\n return {\n key: spec.key,\n source: 'missing',\n value: null,\n present: false,\n };\n}\n\nexport function readRuntimeEnv(env: NodeJS.ProcessEnv): RuntimeEnv {\n const apiBaseUrl = resolveEnv(ENV_SPECS[0], env).value;\n const apiKey = resolveEnv(ENV_SPECS[1], env).value;\n const region = resolveEnv(ENV_SPECS[2], env).value as string;\n const supabasePublishableKey = resolveEnv(ENV_SPECS[3], env).value;\n const sessionFile = resolveEnv(ENV_SPECS[4], env).value;\n const disableSessionCache = parseBooleanEnv(resolveEnv(ENV_SPECS[5], env).value);\n const forceReauth = parseBooleanEnv(resolveEnv(ENV_SPECS[6], env).value);\n\n return {\n apiBaseUrl,\n apiKey,\n region,\n supabasePublishableKey,\n sessionFile,\n disableSessionCache,\n forceReauth,\n };\n}\n\nexport function maskSecret(value: string | null): string | null {\n if (!value) {\n return value;\n }\n if (value.length <= 8) {\n return value;\n }\n return `${value.slice(0, 4)}...${value.slice(-4)}`;\n}\n\nexport function buildDoctorReport(\n env: NodeJS.ProcessEnv,\n dotEnvStatus: { loaded: boolean; path: string; count: number },\n): DoctorReport {\n const checks = ENV_SPECS.map((spec) => {\n const resolved = resolveEnv(spec, env);\n return {\n key: spec.key,\n description: spec.description,\n required: spec.required,\n source: resolved.source,\n present: resolved.present,\n valuePreview: maskSecret(resolved.value),\n };\n });\n\n return {\n ok: checks.every((check) => !check.required || check.present),\n loadedDotEnv: dotEnvStatus.loaded,\n dotEnvPath: dotEnvStatus.path,\n dotEnvKeysLoaded: dotEnvStatus.count,\n checks,\n };\n}\n\nexport const __testInternals = {\n parseBooleanEnv,\n};\n"]}
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../../src/lib/env.ts"],"names":[],"mappings":"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","sourcesContent":["export type EnvSpec = {\n key: string;\n required: boolean;\n description: string;\n defaultValue?: string;\n};\n\nexport type ResolvedEnv = {\n key: string;\n source: 'env' | 'default' | 'missing';\n value: string | null;\n present: boolean;\n};\n\nexport const ENV_KEYS = {\n apiBaseUrl: 'TIANGONG_LCA_API_BASE_URL',\n apiKey: 'TIANGONG_LCA_API_KEY',\n authMode: 'TIANGONG_LCA_AUTH_MODE',\n oauthClientId: 'TIANGONG_LCA_OAUTH_CLIENT_ID',\n oauthRedirectUri: 'TIANGONG_LCA_OAUTH_REDIRECT_URI',\n accessToken: 'TIANGONG_LCA_ACCESS_TOKEN',\n region: 'TIANGONG_LCA_REGION',\n supabasePublishableKey: 'TIANGONG_LCA_SUPABASE_PUBLISHABLE_KEY',\n sessionFile: 'TIANGONG_LCA_SESSION_FILE',\n disableSessionCache: 'TIANGONG_LCA_DISABLE_SESSION_CACHE',\n forceReauth: 'TIANGONG_LCA_FORCE_REAUTH',\n} as const;\n\nexport const ENV_SPECS: EnvSpec[] = [\n {\n key: ENV_KEYS.apiBaseUrl,\n required: true,\n description: 'Main TianGong LCA API / Edge Functions base URL',\n },\n {\n key: ENV_KEYS.apiKey,\n required: false,\n description: 'Deprecated legacy email/password API key bootstrap',\n },\n {\n key: ENV_KEYS.region,\n required: false,\n description: 'Target TianGong LCA API region',\n defaultValue: 'us-east-1',\n },\n {\n key: ENV_KEYS.supabasePublishableKey,\n required: true,\n description: 'Supabase publishable key used to bootstrap and refresh user sessions',\n },\n {\n key: ENV_KEYS.sessionFile,\n required: false,\n description: 'Optional local path for the CLI session cache file',\n },\n {\n key: ENV_KEYS.disableSessionCache,\n required: false,\n description: 'Disable the persistent CLI session cache when set to true',\n defaultValue: 'false',\n },\n {\n key: ENV_KEYS.forceReauth,\n required: false,\n description: 'Ignore cached sessions and force a fresh login when set to true',\n defaultValue: 'false',\n },\n {\n key: ENV_KEYS.authMode,\n required: false,\n description: 'Optional explicit auth mode: oauth, access-token, or legacy-user-api-key',\n },\n {\n key: ENV_KEYS.oauthClientId,\n required: false,\n description: 'Registered public Supabase OAuth client ID',\n },\n {\n key: ENV_KEYS.oauthRedirectUri,\n required: false,\n description: 'Exact registered CLI loopback OAuth redirect URI',\n },\n {\n key: ENV_KEYS.accessToken,\n required: false,\n description: 'Explicit short-lived actor access token for headless execution',\n },\n];\n\nexport type DoctorCheck = {\n key: string;\n description: string;\n required: boolean;\n source: ResolvedEnv['source'];\n present: boolean;\n valuePreview: string | null;\n};\n\nexport type DoctorReport = {\n ok: boolean;\n loadedDotEnv: boolean;\n dotEnvPath: string;\n dotEnvKeysLoaded: number;\n checks: DoctorCheck[];\n};\n\nexport type RuntimeEnv = {\n apiBaseUrl: string | null;\n apiKey: string | null;\n authMode: string | null;\n oauthClientId: string | null;\n oauthRedirectUri: string | null;\n accessToken: string | null;\n region: string;\n supabasePublishableKey: string | null;\n sessionFile: string | null;\n disableSessionCache: boolean;\n forceReauth: boolean;\n};\n\nfunction parseBooleanEnv(value: string | null): boolean {\n if (typeof value !== 'string') {\n return false;\n }\n\n switch (value.trim().toLowerCase()) {\n case '1':\n case 'true':\n case 'yes':\n case 'on':\n return true;\n default:\n return false;\n }\n}\n\nexport function resolveEnv(spec: EnvSpec, env: NodeJS.ProcessEnv): ResolvedEnv {\n const envValue = env[spec.key];\n if (envValue) {\n return {\n key: spec.key,\n source: 'env',\n value: envValue,\n present: true,\n };\n }\n\n if (spec.defaultValue !== undefined) {\n return {\n key: spec.key,\n source: 'default',\n value: spec.defaultValue,\n present: true,\n };\n }\n\n return {\n key: spec.key,\n source: 'missing',\n value: null,\n present: false,\n };\n}\n\nexport function readRuntimeEnv(env: NodeJS.ProcessEnv): RuntimeEnv {\n const apiBaseUrl = resolveEnv(ENV_SPECS[0], env).value;\n const apiKey = resolveEnv(ENV_SPECS[1], env).value;\n const region = resolveEnv(ENV_SPECS[2], env).value as string;\n const supabasePublishableKey = resolveEnv(ENV_SPECS[3], env).value;\n const sessionFile = resolveEnv(ENV_SPECS[4], env).value;\n const disableSessionCache = parseBooleanEnv(resolveEnv(ENV_SPECS[5], env).value);\n const forceReauth = parseBooleanEnv(resolveEnv(ENV_SPECS[6], env).value);\n const authMode = resolveEnv(ENV_SPECS[7], env).value;\n const oauthClientId = resolveEnv(ENV_SPECS[8], env).value;\n const oauthRedirectUri = resolveEnv(ENV_SPECS[9], env).value;\n const accessToken = resolveEnv(ENV_SPECS[10], env).value;\n\n return {\n apiBaseUrl,\n apiKey,\n authMode,\n oauthClientId,\n oauthRedirectUri,\n accessToken,\n region,\n supabasePublishableKey,\n sessionFile,\n disableSessionCache,\n forceReauth,\n };\n}\n\nexport function maskSecret(value: string | null): string | null {\n if (!value) {\n return value;\n }\n if (value.length <= 8) {\n return value;\n }\n return `${value.slice(0, 4)}...${value.slice(-4)}`;\n}\n\nexport function buildDoctorReport(\n env: NodeJS.ProcessEnv,\n dotEnvStatus: { loaded: boolean; path: string; count: number },\n): DoctorReport {\n const checks = ENV_SPECS.map((spec) => {\n const resolved = resolveEnv(spec, env);\n return {\n key: spec.key,\n description: spec.description,\n required: spec.required,\n source: resolved.source,\n present: resolved.present,\n valuePreview: maskSecret(resolved.value),\n };\n });\n\n return {\n ok:\n checks.every((check) => !check.required || check.present) &&\n [ENV_KEYS.oauthClientId, ENV_KEYS.accessToken, ENV_KEYS.apiKey].some(\n (key) => checks.find((check) => check.key === key)?.present,\n ),\n loadedDotEnv: dotEnvStatus.loaded,\n dotEnvPath: dotEnvStatus.path,\n dotEnvKeysLoaded: dotEnvStatus.count,\n checks,\n };\n}\n\nexport const __testInternals = {\n parseBooleanEnv,\n};\n"]}
@@ -52,7 +52,7 @@ declare function outputRef(outputPath: string, bytes: Uint8Array, mediaType: str
52
52
  declare function writeOutput(outputPath: string, bytes: Uint8Array, mediaType: string, force: boolean): LcaReleaseOutput;
53
53
  declare function writeJsonOutput(outputPath: string, value: unknown, force: boolean): LcaReleaseOutput;
54
54
  declare function commandAction(action: LcaReleaseAction): string;
55
- declare function buildCommandPayload(options: RunLcaReleaseOptions, userApiKey: string): {
55
+ declare function buildCommandPayload(options: RunLcaReleaseOptions): {
56
56
  body: JsonRecord;
57
57
  inputPath: string | null;
58
58
  };
@@ -6,7 +6,6 @@ import { CliError } from './errors.js';
6
6
  import { readJsonInput } from './io.js';
7
7
  import { buildSupabaseAuthHeaders, createSupabaseFetch, deriveSupabaseFunctionsBaseUrl, requireSupabaseRestRuntime, } from './supabase-client.js';
8
8
  import { resolveSupabaseUserSession } from './supabase-session.js';
9
- import { fingerprintUserApiKey } from './user-api-key.js';
10
9
  export const LCA_RELEASE_ACTIONS = [
11
10
  'prepare',
12
11
  'upload',
@@ -140,7 +139,7 @@ function commandAction(action) {
140
139
  }
141
140
  return result;
142
141
  }
143
- function buildCommandPayload(options, userApiKey) {
142
+ function buildCommandPayload(options) {
144
143
  if (options.action === 'prepare' ||
145
144
  options.action === 'finalize' ||
146
145
  options.action === 'approve' ||
@@ -150,7 +149,7 @@ function buildCommandPayload(options, userApiKey) {
150
149
  const input = readObjectInput(options.inputPath);
151
150
  const body = { ...input.value, action: commandAction(options.action) };
152
151
  if (options.action === 'publish') {
153
- body.credentialFingerprint = fingerprintUserApiKey(userApiKey).replace(/^sha256:/u, '');
152
+ delete body.credentialFingerprint;
154
153
  }
155
154
  return { body, inputPath: input.inputPath };
156
155
  }
@@ -575,7 +574,7 @@ export async function runLcaRelease(options) {
575
574
  const url = edgeUrl(runtime.apiBaseUrl);
576
575
  if (options.action === 'upload')
577
576
  return runUpload(options, runtime, url);
578
- const command = buildCommandPayload(options, runtime.userApiKey);
577
+ const command = buildCommandPayload(options);
579
578
  if (options.dryRun) {
580
579
  return {
581
580
  schemaVersion: 'tiangong.cli.lca-release.v1',