@tutti-os/auth-bridge 0.0.190 → 0.0.192
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 +6 -1
- package/dist/node.d.ts +1 -0
- package/dist/node.js +32 -20
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,12 +21,17 @@ import { createTuttiNodeAuthClient } from "@tutti-os/auth-bridge/node";
|
|
|
21
21
|
|
|
22
22
|
const auth = createTuttiNodeAuthClient({
|
|
23
23
|
authJsonPath,
|
|
24
|
-
appCallbackUrl
|
|
24
|
+
appCallbackUrl,
|
|
25
|
+
accountHeaders: { "x-environment-lane": "example" }
|
|
25
26
|
});
|
|
26
27
|
|
|
27
28
|
const { session, user } = await auth.login();
|
|
28
29
|
```
|
|
29
30
|
|
|
31
|
+
`accountHeaders` adds host-owned headers to Account API requests. The bridge
|
|
32
|
+
always owns and overwrites its JSON content negotiation and Desktop session
|
|
33
|
+
cookie headers.
|
|
34
|
+
|
|
30
35
|
## Local Desktop Callback
|
|
31
36
|
|
|
32
37
|
The Node bridge starts a loopback HTTP server for desktop sign-in. New desktop OAuth completions use:
|
package/dist/node.d.ts
CHANGED
package/dist/node.js
CHANGED
|
@@ -46,6 +46,7 @@ function createTuttiNodeAuthClient(options) {
|
|
|
46
46
|
idleTimeoutMs,
|
|
47
47
|
positiveMs(options.loginMaxTimeoutMs, DEFAULT_LOGIN_MAX_TIMEOUT_MS)
|
|
48
48
|
);
|
|
49
|
+
const accountHeaders = { ...options.accountHeaders };
|
|
49
50
|
async function readSession() {
|
|
50
51
|
return await readAuthJson(authJsonPath);
|
|
51
52
|
}
|
|
@@ -57,7 +58,11 @@ function createTuttiNodeAuthClient(options) {
|
|
|
57
58
|
if (!session) {
|
|
58
59
|
return null;
|
|
59
60
|
}
|
|
60
|
-
const user = await fetchUserInfo(
|
|
61
|
+
const user = await fetchUserInfo(
|
|
62
|
+
accountBaseUrl,
|
|
63
|
+
session.cookie,
|
|
64
|
+
accountHeaders
|
|
65
|
+
);
|
|
61
66
|
if (!user) {
|
|
62
67
|
return null;
|
|
63
68
|
}
|
|
@@ -86,6 +91,7 @@ function createTuttiNodeAuthClient(options) {
|
|
|
86
91
|
hostname: options.hostname?.trim() || hostname()
|
|
87
92
|
});
|
|
88
93
|
const pending = {
|
|
94
|
+
accountHeaders,
|
|
89
95
|
accountBaseUrl,
|
|
90
96
|
appId,
|
|
91
97
|
appCallbackUrl,
|
|
@@ -120,7 +126,12 @@ function createTuttiNodeAuthClient(options) {
|
|
|
120
126
|
logout: async () => {
|
|
121
127
|
const session = await readSession();
|
|
122
128
|
if (session) {
|
|
123
|
-
await logoutSession(
|
|
129
|
+
await logoutSession(
|
|
130
|
+
accountBaseUrl,
|
|
131
|
+
appId,
|
|
132
|
+
session.cookie,
|
|
133
|
+
accountHeaders
|
|
134
|
+
);
|
|
124
135
|
}
|
|
125
136
|
await clearSession();
|
|
126
137
|
},
|
|
@@ -357,7 +368,8 @@ async function completePendingLogin(input, transferCode) {
|
|
|
357
368
|
const sessionId = await redeemDesktopTransferCode(input, transferCode);
|
|
358
369
|
const user = await fetchUserInfo(
|
|
359
370
|
input.accountBaseUrl,
|
|
360
|
-
buildSessionCookie(sessionId)
|
|
371
|
+
buildSessionCookie(sessionId),
|
|
372
|
+
input.accountHeaders
|
|
361
373
|
);
|
|
362
374
|
if (!user) {
|
|
363
375
|
throw new Error("Failed to load user info after login");
|
|
@@ -381,16 +393,12 @@ async function waitForCompletion(input, completion) {
|
|
|
381
393
|
}
|
|
382
394
|
}
|
|
383
395
|
}
|
|
384
|
-
async function fetchUserInfo(accountBaseUrl, cookie) {
|
|
396
|
+
async function fetchUserInfo(accountBaseUrl, cookie, accountHeaders) {
|
|
385
397
|
const response = await fetch(
|
|
386
398
|
buildAccountUrl(accountBaseUrl, "/user/v1/user_info"),
|
|
387
399
|
{
|
|
388
400
|
method: "POST",
|
|
389
|
-
headers:
|
|
390
|
-
Accept: "application/json",
|
|
391
|
-
"Content-Type": "application/json",
|
|
392
|
-
Cookie: cookie
|
|
393
|
-
},
|
|
401
|
+
headers: buildAccountHeaders(accountHeaders, cookie),
|
|
394
402
|
body: JSON.stringify({})
|
|
395
403
|
}
|
|
396
404
|
);
|
|
@@ -411,10 +419,7 @@ async function redeemDesktopTransferCode(input, transferCode) {
|
|
|
411
419
|
),
|
|
412
420
|
{
|
|
413
421
|
method: "POST",
|
|
414
|
-
headers:
|
|
415
|
-
Accept: "application/json",
|
|
416
|
-
"Content-Type": "application/json"
|
|
417
|
-
},
|
|
422
|
+
headers: buildAccountHeaders(input.accountHeaders),
|
|
418
423
|
body: JSON.stringify({
|
|
419
424
|
transfer_code: transferCode,
|
|
420
425
|
attempt_id: input.attemptId,
|
|
@@ -431,17 +436,13 @@ async function redeemDesktopTransferCode(input, transferCode) {
|
|
|
431
436
|
}
|
|
432
437
|
return sessionId;
|
|
433
438
|
}
|
|
434
|
-
async function logoutSession(accountBaseUrl, appId, cookie) {
|
|
439
|
+
async function logoutSession(accountBaseUrl, appId, cookie, accountHeaders) {
|
|
435
440
|
const response = await fetch(
|
|
436
441
|
buildAccountUrl(accountBaseUrl, "/auth/v1/logout-web-session"),
|
|
437
442
|
{
|
|
438
443
|
method: "POST",
|
|
439
|
-
headers:
|
|
440
|
-
|
|
441
|
-
"Content-Type": "application/json",
|
|
442
|
-
Cookie: cookie
|
|
443
|
-
},
|
|
444
|
-
body: JSON.stringify({ appId })
|
|
444
|
+
headers: buildAccountHeaders(accountHeaders, cookie),
|
|
445
|
+
body: JSON.stringify({ app_id: appId })
|
|
445
446
|
}
|
|
446
447
|
);
|
|
447
448
|
const payload = await response.json().catch(() => null);
|
|
@@ -449,6 +450,17 @@ async function logoutSession(accountBaseUrl, appId, cookie) {
|
|
|
449
450
|
throw readEnvelopeError(response, payload);
|
|
450
451
|
}
|
|
451
452
|
}
|
|
453
|
+
function buildAccountHeaders(accountHeaders, cookie) {
|
|
454
|
+
const headers = new Headers(accountHeaders);
|
|
455
|
+
headers.set("Accept", "application/json");
|
|
456
|
+
headers.set("Content-Type", "application/json");
|
|
457
|
+
if (cookie) {
|
|
458
|
+
headers.set("Cookie", cookie);
|
|
459
|
+
} else {
|
|
460
|
+
headers.delete("Cookie");
|
|
461
|
+
}
|
|
462
|
+
return headers;
|
|
463
|
+
}
|
|
452
464
|
async function findAvailablePort() {
|
|
453
465
|
for (let port = AUTH_SERVER_BASE_PORT; port <= AUTH_SERVER_MAX_PORT; port += 1) {
|
|
454
466
|
const available = await new Promise((resolve) => {
|