@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.
- package/README.md +51 -12
- package/dist/src/auth-identity-receipt.d.ts +2 -0
- package/dist/src/auth-identity-receipt.js +2 -0
- package/dist/src/auth-identity-receipt.js.map +1 -0
- package/dist/src/cli.d.ts +4 -0
- package/dist/src/cli.js +264 -7
- package/dist/src/cli.js.map +1 -1
- package/dist/src/lib/auth-identity-receipt.d.ts +2 -2
- package/dist/src/lib/auth-identity-receipt.js +20 -12
- package/dist/src/lib/auth-identity-receipt.js.map +1 -1
- package/dist/src/lib/env.d.ts +8 -0
- package/dist/src/lib/env.js +36 -3
- package/dist/src/lib/env.js.map +1 -1
- package/dist/src/lib/lca-release.d.ts +1 -1
- package/dist/src/lib/lca-release.js +3 -4
- package/dist/src/lib/lca-release.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-resulting-process.js +6 -2
- package/dist/src/lib/lifecyclemodel-resulting-process.js.map +1 -1
- package/dist/src/lib/oauth-loopback.d.ts +52 -0
- package/dist/src/lib/oauth-loopback.js +229 -0
- package/dist/src/lib/oauth-loopback.js.map +1 -0
- package/dist/src/lib/oauth-pkce.d.ts +63 -0
- package/dist/src/lib/oauth-pkce.js +268 -0
- package/dist/src/lib/oauth-pkce.js.map +1 -0
- package/dist/src/lib/process-refresh-references.js +2 -2
- package/dist/src/lib/process-refresh-references.js.map +1 -1
- package/dist/src/lib/process-scope-statistics.js +8 -3
- package/dist/src/lib/process-scope-statistics.js.map +1 -1
- package/dist/src/lib/state-lock.js +10 -4
- package/dist/src/lib/state-lock.js.map +1 -1
- package/dist/src/lib/supabase-client.d.ts +13 -1
- package/dist/src/lib/supabase-client.js +64 -3
- package/dist/src/lib/supabase-client.js.map +1 -1
- package/dist/src/lib/supabase-json-ordered-write.js +7 -3
- package/dist/src/lib/supabase-json-ordered-write.js.map +1 -1
- package/dist/src/lib/supabase-session.d.ts +63 -8
- package/dist/src/lib/supabase-session.js +315 -21
- package/dist/src/lib/supabase-session.js.map +1 -1
- 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', '
|
|
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
|
-
|
|
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 = [
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
552
|
+
const normalizedCredentialEmail = credentialEmail ? normalizeEmail(credentialEmail) : null;
|
|
544
553
|
if (!sessionEmail ||
|
|
545
|
-
!apiKeyEmail ||
|
|
546
554
|
currentUser.email !== sessionEmail ||
|
|
547
|
-
currentUser.email !==
|
|
548
|
-
return identityError('Server-verified current user does not match the
|
|
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":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EACL,wBAAwB,EACxB,4BAA4B,EAC5B,0BAA0B,GAE3B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,0BAA0B,GAE3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AAE9E,MAAM,CAAC,MAAM,4BAA4B,GAAG,uCAAgD,CAAC;AAC7F,MAAM,CAAC,MAAM,4BAA4B,GAAG,aAAa,CAAC;AAE1D,MAAM,gBAAgB,GAAG,mBAA4B,CAAC;AACtD,MAAM,iBAAiB,GAAG,eAAwB,CAAC;AACnD,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAClC,MAAM,kBAAkB,GAAG,EAAE,GAAG,IAAI,CAAC;AACrC,MAAM,8BAA8B,GAAG,GAAG,CAAC;AAC3C,MAAM,cAAc,GAAG,iBAAiB,CAAC;AACzC,MAAM,YAAY,GAAG,iEAAiE,CAAC;AACvF,MAAM,aAAa,GAAG,6BAA6B,CAAC;AACpD,MAAM,eAAe,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAU,CAAC;AAC1E,MAAM,WAAW,GAAG,CAAC,UAAU,EAAE,aAAa,EAAE,kBAAkB,CAAU,CAAC;AAM7E,MAAM,yBAA0B,SAAQ,KAAK;IAC3C;QACE,KAAK,CAAC,yDAAyD,CAAC,CAAC;QACjE,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;IAC1C,CAAC;CACF;AAgED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACpB,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;aACf,IAAI,EAAE;aACN,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CACpD,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,OAAO,UAAU,CAAC,QAAQ,CAAC;SACxB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;SAC9C,MAAM,CAAC,KAAK,CAAC,CAAC;AACnB,CAAC;AAED,SAAS,KAAK,CAAC,KAAc;IAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAChC,OAAO,UAAU,IAAI,IAAI,CAAC;AAC5B,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACpC,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,WAAW,EAAE,IAAI,IAAI,CAAC;IACvD,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9E,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,aAAa,CACpB,OAAe,EACf,IAAY,EACZ,OAAO,GAA6C,EAAE;IAEtD,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE;QAC1B,IAAI;QACJ,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,CAAC;QAC/B,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;KACvE,CAAC,CAAC;AACL,CAAC;AAED,SAAS,cAAc,CAAC,OAAe;IACrC,OAAO,aAAa,CAAC,OAAO,EAAE,+BAA+B,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAgC,EAAE,KAAa;IAC3E,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IAChC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,aAAa,CAClB,GAAG,KAAK,4CAA4C,EACpD,mCAAmC,EACnC;YACE,QAAQ,EAAE,CAAC;YACX,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;SAC3B,CACF,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,uBAAuB,CAAC,KAAgC;IAC/D,MAAM,UAAU,GAAG,oBAAoB,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC;IACrE,IAAI,UAAU,KAAK,IAAI,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,EAAE,CAAC;QACxD,OAAO,aAAa,CAClB,wDAAwD,EACxD,mCAAmC,EACnC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE,EAAE,CAC3D,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAyB;IACnD,MAAM,UAAU,GAAG,KAAK,IAAI,kBAAkB,CAAC;IAC/C,IACE,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC;QAC7B,UAAU,IAAI,CAAC;QACf,UAAU,GAAG,4BAA4B,EACzC,CAAC;QACD,OAAO,aAAa,CAClB,0DAA0D,4BAA4B,GAAG,EACzF,+BAA+B,EAC/B,EAAE,QAAQ,EAAE,CAAC,EAAE,CAChB,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAc;IACxC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,SAAS,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC;AACjF,CAAC;AAED,SAAS,wBAAwB,CAC/B,cAAuB;IAEvB,MAAM,UAAU,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC;IACzC,IAAI,CAAC,UAAU,IAAI,UAAU,KAAK,cAAc,EAAE,CAAC;QACjD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;QAChC,MAAM,MAAM,GAAG,cAAc,CAAC;QAC9B,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC5C,MAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACtF,IACE,GAAG,CAAC,QAAQ,KAAK,QAAQ;YACzB,GAAG,CAAC,MAAM,KAAK,UAAU;YACzB,GAAG,CAAC,QAAQ;YACZ,GAAG,CAAC,QAAQ;YACZ,GAAG,CAAC,IAAI;YACR,CAAC,UAAU;YACX,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC;YACxB,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,EACjC,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,EAAE,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,cAAsB;IACnD,MAAM,QAAQ,GAAG,wBAAwB,CAAC,cAAc,CAAC,CAAC;IAC1D,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,aAAa,CAClB,8DAA8D,EAC9D,+BAA+B,EAC/B,EAAE,QAAQ,EAAE,CAAC,EAAE,CAChB,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC,UAAU,CAAC;AAC7B,CAAC;AAED,SAAS,sBAAsB,CAAC,UAAkB;IAIhD,IAAI,cAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,cAAc,GAAG,4BAA4B,CAAC,UAAU,CAAC,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,aAAa,CAClB,uEAAuE,EACvE,+BAA+B,EAC/B,EAAE,QAAQ,EAAE,CAAC,EAAE,CAChB,CAAC;IACJ,CAAC;IACD,MAAM,UAAU,GAAG,qBAAqB,CAAC,cAAc,CAAC,CAAC;IACzD,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC;AACxC,CAAC;AAED,SAAS,SAAS,CAAC,OAA4B;IAC7C,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;QAChC,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,OAAO,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,kBAAkB,CAAC;AAClE,CAAC;AAED,SAAS,mBAAmB,CAAC,SAAwB;IACnD,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAChC,OAAO,aAAa,CAClB,oDAAoD,EACpD,gCAAgC,CACjC,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;IACzD,IAAI,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QACtC,OAAO,aAAa,CAClB,oDAAoD,EACpD,gCAAgC,CACjC,CAAC;IACJ,CAAC;IACD,OAAO,SAAS,CAAC,WAAW,EAAE,CAAC;AACjC,CAAC;AAED,SAAS,oBAAoB,CAAC,OAM7B;IACC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACrC,MAAM,YAAY,GAAG,cAAc,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACvD,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACxD,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAgB,CAAC;IACxC,MAAM,YAAY,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACzF,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACnF,MAAM,gBAAgB,GACpB,YAAY,KAAK,UAAU;QACzB,CAAC,CAAC,WAAW,KAAK,IAAI;QACtB,CAAC,CAAC,YAAY,KAAK,aAAa;YAC9B,CAAC,CAAC,WAAW,KAAK,iBAAiB;YACnC,CAAC,CAAC,WAAW,KAAK,IAAI,CAAC;IAC7B,MAAM,gBAAgB,GACpB,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;QACrC,CAAC,OAAO,OAAO,CAAC,SAAS,KAAK,QAAQ;YACpC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC;YAClC,OAAO,CAAC,SAAS;gBACf,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,8BAA8B,CAAC,CAAC;IAEjF,IACE,CAAC,WAAW;QACZ,OAAO,CAAC,cAAc,KAAK,OAAO,CAAC,cAAc;QACjD,CAAC,YAAY;QACb,CAAC,WAAW;QACZ,YAAY,KAAK,WAAW;QAC5B,CAAC,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;QACzC,CAAC,gBAAgB;QACjB,CAAC,gBAAgB;QACjB,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAC7D,CAAC;QACD,aAAa,CACX,4FAA4F,EAC5F,gCAAgC,CACjC,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,OAOlC;IACC,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,kBAAkB,CAAC;YACtC,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,YAAY,EAAE,OAAO,CAAC,YAAY;SACnC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,SAAS,GACb,KAAK,YAAY,QAAQ;YACvB,CAAC,CAAC,KAAK,CAAC,IAAI;YACZ,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;gBACjD,CAAC,CAAC,KAAK,CAAC,IAAI;gBACZ,CAAC,CAAC,4BAA4B,CAAC;QACrC,OAAO,aAAa,CAClB,mDAAmD,EACnD,8BAA8B,EAC9B,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,CACvC,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,wBAAwB,CAAC,KAAc;IAC9C,IACE,CAAC,CAAC,KAAK,YAAY,QAAQ,CAAC;QAC5B,KAAK,CAAC,IAAI,KAAK,qCAAqC;QACpD,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC;QACxB,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,QAAQ;QACxC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EACvC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;AAC9B,CAAC;AAED,SAAS,qBAAqB,CAAC,QAE9B;IACC,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACnE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,KAAK,UAAU,uBAAuB,CAAC,QAItC;IACC,MAAM,aAAa,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IACtD,IAAI,aAAa,KAAK,IAAI,IAAI,aAAa,GAAG,kBAAkB,EAAE,CAAC;QACjE,MAAM,IAAI,yBAAyB,EAAE,CAAC;IACxC,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,kBAAkB,EAAE,CAAC;YACzD,MAAM,IAAI,yBAAyB,EAAE,CAAC;QACxC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,CAAC;QACH,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YAClC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBACf,MAAM;YACR,CAAC;YACD,aAAa,IAAI,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC;YACxC,IAAI,aAAa,GAAG,kBAAkB,EAAE,CAAC;gBACvC,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;gBAC5C,MAAM,IAAI,yBAAyB,EAAE,CAAC;YACxC,CAAC;YACD,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,WAAW,EAAE,CAAC;IACvB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,OAM/B;IACC,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,cAAc,GAAG,iBAAiB,EAAE,CAAC;IAC5D,IAAI,QAAQ,CAAC;IACb,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE;YACtC,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,wBAAwB,CAAC,OAAO,CAAC,cAAc,EAAE,OAAO,CAAC,WAAW,CAAC;YAC9E,QAAQ,EAAE,OAAO;YACjB,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;SAC/C,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,aAAa,CAClB,0EAA0E,EAC1E,qCAAqC,EACrC;YACE,OAAO,EAAE;gBACP,QAAQ,EAAE,iBAAiB;gBAC3B,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,KAAK;aAC1D;SACF,CACF,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,OAAO,aAAa,CAClB,mDAAmD,QAAQ,CAAC,MAAM,GAAG,EACrE,qCAAqC,EACrC,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CACtE,CAAC;IACJ,CAAC;IACD,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IAC9E,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC9C,OAAO,aAAa,CAClB,mEAAmE,EACnE,mCAAmC,EACnC,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CACtE,CAAC;IACJ,CAAC;IAED,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,yBAAyB,EAAE,CAAC;YAC/C,OAAO,aAAa,CAClB,yEAAyE,EACzE,kCAAkC,EAClC,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CACtE,CAAC;QACJ,CAAC;QACD,OAAO,aAAa,CAClB,wDAAwD,EACxD,qCAAqC,EACrC;YACE,OAAO,EAAE;gBACP,QAAQ,EAAE,iBAAiB;gBAC3B,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,KAAK;aAC1D;SACF,CACF,CAAC;IACJ,CAAC;IAED,IAAI,OAAgB,CAAC;IACrB,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,aAAa,CAClB,yDAAyD,EACzD,mCAAmC,EACnC,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CACtE,CAAC;IACJ,CAAC;IACD,IAAI,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;QAC9C,OAAO,aAAa,CAClB,mEAAmE,EACnE,+BAA+B,EAC/B,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CACtE,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACpF,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACvE,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,aAAa,CAClB,2EAA2E,EAC3E,gCAAgC,EAChC,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CACtE,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC3B,CAAC;AAED,SAAS,kBAAkB,CAAC,UAAkB;IAC5C,OAAO,UAAU,CAAC;QAChB,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,UAAU;QACvB,QAAQ,EAAE,OAAO;QACjB,YAAY,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,eAAe,CAAC;KACpD,CAAC,CAAC;AACL,CAAC;AAED,SAAS,mBAAmB,CAAC,OAI5B;IACC,OAAO,UAAU,CAAC;QAChB,WAAW,EAAE,OAAO,CAAC,UAAU;QAC/B,OAAO,EAAE,OAAO,CAAC,MAAM;QACvB,aAAa,EAAE,OAAO,CAAC,YAAY;KACpC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,YAAY,CAAC,KAAiB,EAAE,QAA2B;IAClE,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IACzC,MAAM,cAAc,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5C,OAAO,CACL,MAAM,CAAC,MAAM,KAAK,cAAc,CAAC,MAAM;QACvC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,cAAc,CAAC,KAAK,CAAC,CAAC,CAC5D,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CAAmB,KAAc,EAAE,MAAoB;IACrE,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAU,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc;IACtC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC;AAC7D,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,gBAAgB,CAAC,KAAK,CAAC,IAAI,0CAA0C,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC3F,CAAC;AAED,SAAS,YAAY,CAAC,OAA4B;IAChD,MAAM,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IACxE,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAc;IACrD,IACE,CAAC,QAAQ,CAAC,KAAK,CAAC;QAChB,CAAC,YAAY,CAAC,KAAK,EAAE;YACnB,YAAY;YACZ,UAAU;YACV,iBAAiB;YACjB,KAAK;YACL,UAAU;YACV,WAAW;YACX,SAAS;YACT,sBAAsB;YACtB,mBAAmB;YACnB,QAAQ;YACR,SAAS;YACT,QAAQ;SACT,CAAC,EACF,CAAC;QACD,OAAO,cAAc,CAAC,gDAAgD,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;IACtB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC9B,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAChC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC9B,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAChC,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;IACpC,MAAM,aAAa,GACjB,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,OAAO,CAAC,gBAAgB,KAAK,QAAQ;QAC/D,CAAC,CAAC,wBAAwB,CAAC,OAAO,CAAC,gBAAgB,CAAC;QACpD,CAAC,CAAC,IAAI,CAAC;IACX,IACE,KAAK,CAAC,MAAM,KAAK,4BAA4B;QAC7C,KAAK,CAAC,MAAM,KAAK,QAAQ;QACzB,KAAK,CAAC,SAAS,KAAK,mBAAmB;QACvC,KAAK,CAAC,iBAAiB,KAAK,WAAW;QACvC,CAAC,kBAAkB,CAAC,KAAK,CAAC,eAAe,CAAC;QAC1C,CAAC,QAAQ,CAAC,GAAG,CAAC;QACd,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,cAAc,EAAE,iBAAiB,CAAC,CAAC;QACvD,GAAG,CAAC,YAAY,KAAK,gBAAgB;QACrC,CAAC,gBAAgB,CAAC,GAAG,CAAC,eAAe,CAAC;QACtC,CAAC,QAAQ,CAAC,OAAO,CAAC;QAClB,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,kBAAkB,EAAE,aAAa,CAAC,CAAC;QAC3D,CAAC,gBAAgB,CAAC,OAAO,CAAC,WAAW,CAAC;QACtC,CAAC,aAAa;QACd,aAAa,CAAC,UAAU,KAAK,OAAO,CAAC,WAAW;QAChD,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACnB,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;QACrD,CAAC,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC;QAClC,CAAC,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC;QACtC,CAAC,QAAQ,CAAC,OAAO,CAAC;QAClB,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,QAAQ,CAAC,CAAC;QAClF,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,eAAe,CAAC;QACzC,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,WAAW,CAAC;QACzC,OAAO,OAAO,CAAC,YAAY,KAAK,SAAS;QACzC,CAAC,CAAC,OAAO,CAAC,cAAc,KAAK,IAAI,IAAI,kBAAkB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAChF,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACnB,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,CAAC;QAC9D,OAAO,QAAQ,CAAC,cAAc,KAAK,QAAQ;QAC3C,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC;QAC7C,OAAO,QAAQ,CAAC,eAAe,KAAK,QAAQ;QAC5C,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC;QAC9C,QAAQ,CAAC,cAAc,KAAK,kBAAkB,CAAC,OAAO,CAAC,WAAqB,CAAC;QAC7E,QAAQ,CAAC,eAAe;YACtB,mBAAmB,CAAC;gBAClB,UAAU,EAAE,OAAO,CAAC,WAAqB;gBACzC,MAAM,EAAE,QAAQ,CAAC,OAAiB;gBAClC,YAAY,EAAE,QAAQ,CAAC,aAAuB;aAC/C,CAAC;QACJ,CAAC,QAAQ,CAAC,UAAU,CAAC;QACrB,CAAC,YAAY,CAAC,UAAU,EAAE;YACxB,sBAAsB;YACtB,kBAAkB;YAClB,MAAM;YACN,QAAQ;YACR,oBAAoB;YACpB,iBAAiB;YACjB,gBAAgB;SACjB,CAAC;QACF,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,cAAc,CAAU,CAAC;QAC3E,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,eAAyB,CAAC;QACzD,CAAC,CACC,UAAU,CAAC,oBAAoB,KAAK,IAAI,IAAI,gBAAgB,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAC9F;QACD,CAAC,CAAC,UAAU,CAAC,gBAAgB,KAAK,IAAI,IAAI,eAAe,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;QACvF,CAAC,CAAC,UAAU,CAAC,kBAAkB,KAAK,IAAI,IAAI,UAAU,CAAC,kBAAkB,KAAK,IAAI,CAAC;QACnF,CAAC,CAAC,UAAU,CAAC,cAAc,KAAK,IAAI,IAAI,UAAU,CAAC,cAAc,KAAK,IAAI,CAAC;QAC3E,UAAU,CAAC,MAAM,KAAK,IAAI;QAC1B,CAAC,UAAU,CAAC,oBAAoB,KAAK,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,kBAAkB,KAAK,IAAI,CAAC;QACvF,CAAC,UAAU,CAAC,gBAAgB,KAAK,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,cAAc,KAAK,IAAI,CAAC;QAC/E,UAAU,CAAC,eAAe;YACxB,MAAM,CAAC,UAAU,CAAC,oBAAoB,KAAK,IAAI,CAAC;gBAC9C,MAAM,CAAC,UAAU,CAAC,gBAAgB,KAAK,IAAI,CAAC;QAChD,UAAU,CAAC,IAAI;YACb,CAAC,UAAU,CAAC,eAAe,KAAK,CAAC;gBAC/B,CAAC,CAAC,UAAU;gBACZ,CAAC,CAAC,UAAU,CAAC,eAAe,KAAK,CAAC;oBAChC,CAAC,CAAC,cAAc;oBAChB,CAAC,CAAC,SAAS,CAAC;QAClB,CAAC,UAAU,CAAC,oBAAoB,KAAK,IAAI;YACvC,UAAU,CAAC,oBAAoB,KAAK,OAAO,CAAC,WAAW,CAAC;QAC1D,CAAC,UAAU,CAAC,gBAAgB,KAAK,IAAI,IAAI,UAAU,CAAC,gBAAgB,KAAK,QAAQ,CAAC,OAAO,CAAC;QAC1F,OAAO,KAAK,CAAC,oBAAoB,KAAK,QAAQ;QAC9C,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,EAChD,CAAC;QACD,OAAO,cAAc,CAAC,iDAAiD,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,OAAO,GAAG,KAA4B,CAAC;IAC7C,IAAI,OAAO,CAAC,oBAAoB,KAAK,UAAU,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;QACvE,OAAO,cAAc,CAAC,4DAA4D,CAAC,CAAC;IACtF,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,OAAsC;IAEtC,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACxD,MAAM,kBAAkB,GAAG,oBAAoB,CAC7C,OAAO,CAAC,kBAAkB,EAC1B,wBAAwB,CACzB,CAAC;IACF,MAAM,cAAc,GAAG,uBAAuB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACvE,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,aAAa,CAClB,0DAA0D,EAC1D,+BAA+B,EAC/B,EAAE,QAAQ,EAAE,CAAC,EAAE,CAChB,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;IACtC,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QAChC,OAAO,aAAa,CAClB,2CAA2C,EAC3C,oCAAoC,EACpC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAChB,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,0BAA0B,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACxD,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,GAAG,sBAAsB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAClF,IAAI,kBAAkB,KAAK,IAAI,IAAI,kBAAkB,KAAK,UAAU,EAAE,CAAC;QACrE,OAAO,aAAa,CAClB,8DAA8D,EAC9D,gCAAgC,EAChC,EAAE,OAAO,EAAE,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,UAAU,EAAE,EAAE,CAC5F,CAAC;IACJ,CAAC;IACD,MAAM,WAAW,GAAG,4BAA4B,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAErE,IAAI,OAAO,GAAG,MAAM,mBAAmB,CAAC;QACtC,OAAO;QACP,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,SAAS;QACT,GAAG;QACH,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,IAAI,0BAA0B;KAC7E,CAAC,CAAC;IACH,oBAAoB,CAAC;QACnB,OAAO;QACP,OAAO;QACP,cAAc;QACd,WAAW,EAAE,WAAW,CAAC,KAAK;QAC9B,GAAG;KACJ,CAAC,CAAC;IAEH,IAAI,WAAyD,CAAC;IAC9D,IAAI,CAAC;QACH,WAAW,GAAG,MAAM,gBAAgB,CAAC;YACnC,cAAc;YACd,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,SAAS;YACT,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACpD,MAAM,KAAK,CAAC;QACd,CAAC;QACD,OAAO,GAAG,MAAM,mBAAmB,CAAC;YAClC,OAAO;YACP,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,SAAS;YACT,GAAG;YACH,YAAY,EAAE,IAAI;YAClB,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,IAAI,0BAA0B;SAC7E,CAAC,CAAC;QACH,oBAAoB,CAAC;YACnB,OAAO;YACP,OAAO;YACP,cAAc;YACd,WAAW,EAAE,WAAW,CAAC,KAAK;YAC9B,GAAG;SACJ,CAAC,CAAC;QACH,WAAW,GAAG,MAAM,gBAAgB,CAAC;YACnC,cAAc;YACd,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,SAAS;YACT,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC,CAAC;IACL,CAAC;IACD,MAAM,YAAY,GAAG,cAAc,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACvD,MAAM,WAAW,GAAG,cAAc,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACtD,IACE,CAAC,YAAY;QACb,CAAC,WAAW;QACZ,WAAW,CAAC,KAAK,KAAK,YAAY;QAClC,WAAW,CAAC,KAAK,KAAK,WAAW,EACjC,CAAC;QACD,OAAO,aAAa,CAClB,+EAA+E,EAC/E,gCAAgC,CACjC,CAAC;IACJ,CAAC;IACD,IAAI,cAAc,KAAK,IAAI,IAAI,cAAc,KAAK,WAAW,CAAC,MAAM,EAAE,CAAC;QACrE,OAAO,aAAa,CAClB,uDAAuD,EACvD,6BAA6B,EAC7B,EAAE,OAAO,EAAE,EAAE,gBAAgB,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,CAAC,MAAM,EAAE,EAAE,CACxF,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAG,WAAW,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,uBAAuB,GAC3B,MAAM,CAAC,kBAAkB,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,cAAc,KAAK,IAAI,CAAC,CAAC;IACxE,MAAM,KAAK,GAA6B;QACtC,MAAM,EAAE,4BAA4B;QACpC,MAAM,EAAE,QAAQ;QAChB,SAAS,EAAE,mBAAmB;QAC9B,iBAAiB,EAAE,WAAW;QAC9B,eAAe,EAAE,GAAG,CAAC,WAAW,EAAE;QAClC,GAAG,EAAE;YACH,YAAY,EAAE,gBAAgB;YAC9B,eAAe,EAAE,UAAU;SAC5B;QACD,OAAO,EAAE;YACP,WAAW,EAAE,UAAU;YACvB,gBAAgB,EAAE,cAAc;SACjC;QACD,QAAQ,EAAE;YACR,OAAO,EAAE,WAAW,CAAC,MAAM;YAC3B,aAAa,EAAE,YAAY;SAC5B;QACD,OAAO,EAAE;YACP,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,UAAU,EAAE,SAAS,CAAC,OAAO,CAAC;YAC9B,YAAY,EAAE,OAAO,CAAC,WAAW;YACjC,cAAc,EAAE,mBAAmB,CAAC,OAAO,CAAC,SAAS,CAAC;SACvD;QACD,QAAQ,EAAE;YACR,cAAc,EAAE,kBAAkB,CAAC,UAAU,CAAC;YAC9C,eAAe,EAAE,mBAAmB,CAAC;gBACnC,UAAU;gBACV,MAAM,EAAE,WAAW,CAAC,MAAM;gBAC1B,YAAY;aACb,CAAC;SACH;QACD,UAAU,EAAE;YACV,IAAI,EACF,uBAAuB,KAAK,CAAC;gBAC3B,CAAC,CAAC,UAAU;gBACZ,CAAC,CAAC,uBAAuB,KAAK,CAAC;oBAC7B,CAAC,CAAC,cAAc;oBAChB,CAAC,CAAC,SAAS;YACjB,eAAe,EAAE,uBAAoC;YACrD,oBAAoB,EAAE,kBAAkB;YACxC,gBAAgB,EAAE,cAAc;YAChC,kBAAkB,EAAE,kBAAkB,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;YAC7D,cAAc,EAAE,cAAc,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;YACrD,MAAM,EAAE,IAAI;SACb;KACF,CAAC;IACF,OAAO,wBAAwB,CAAC;QAC9B,GAAG,KAAK;QACR,oBAAoB,EAAE,UAAU,CAAC,KAAK,CAAC;KACxC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,kBAAkB;IAClB,oBAAoB;IACpB,SAAS;IACT,kBAAkB;IAClB,wBAAwB;IACxB,wBAAwB;IACxB,qBAAqB;IACrB,gBAAgB;IAChB,YAAY;IACZ,gBAAgB;IAChB,eAAe;IACf,aAAa;IACb,OAAO;IACP,cAAc;IACd,oBAAoB;IACpB,uBAAuB;IACvB,kBAAkB;IAClB,qBAAqB;IACrB,uBAAuB;IACvB,kBAAkB;IAClB,mBAAmB;IACnB,sBAAsB;IACtB,mBAAmB;IACnB,UAAU;IACV,eAAe;IACf,KAAK;CACN,CAAC","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"]}
|
package/dist/src/lib/env.d.ts
CHANGED
|
@@ -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;
|
package/dist/src/lib/env.js
CHANGED
|
@@ -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:
|
|
19
|
-
description: '
|
|
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,
|
package/dist/src/lib/env.js.map
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
577
|
+
const command = buildCommandPayload(options);
|
|
579
578
|
if (options.dryRun) {
|
|
580
579
|
return {
|
|
581
580
|
schemaVersion: 'tiangong.cli.lca-release.v1',
|