@wlfi-agent/cli 1.4.12 → 1.4.13
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/dist/wlfc/index.cjs +78 -133
- package/dist/wlfc/index.js +75 -130
- package/package.json +1 -1
package/dist/wlfc/index.cjs
CHANGED
|
@@ -178,6 +178,31 @@ var getErrorMessage = (error) => {
|
|
|
178
178
|
}
|
|
179
179
|
return String(error);
|
|
180
180
|
};
|
|
181
|
+
var WC_STATUS_POLL_INTERVAL_MS = 1500;
|
|
182
|
+
var sleep = (ms) => new Promise((resolve) => {
|
|
183
|
+
setTimeout(resolve, ms);
|
|
184
|
+
});
|
|
185
|
+
var waitForWcCompletionToken = async (client, requestId) => {
|
|
186
|
+
const deadline = Date.now() + DEFAULT_LOGIN_TIMEOUT_MS;
|
|
187
|
+
while (Date.now() < deadline) {
|
|
188
|
+
const status = await client.wcStatus({
|
|
189
|
+
consume: true,
|
|
190
|
+
requestId
|
|
191
|
+
});
|
|
192
|
+
const completed = status.completed === true;
|
|
193
|
+
const token = typeof status.token === "string" ? status.token.trim() : void 0;
|
|
194
|
+
if (completed && token) {
|
|
195
|
+
return token;
|
|
196
|
+
}
|
|
197
|
+
if (completed && !token) {
|
|
198
|
+
throw new Error(
|
|
199
|
+
"Backend reported wc completion without a session token payload"
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
await sleep(WC_STATUS_POLL_INTERVAL_MS);
|
|
203
|
+
}
|
|
204
|
+
throw new Error("Timed out waiting for wc completion; request expired");
|
|
205
|
+
};
|
|
181
206
|
var printJson = (value) => {
|
|
182
207
|
console.log(JSON.stringify(value, null, 2));
|
|
183
208
|
};
|
|
@@ -370,38 +395,33 @@ var getAuthedClient = async (flags) => {
|
|
|
370
395
|
token
|
|
371
396
|
});
|
|
372
397
|
};
|
|
398
|
+
var verifySessionToken = async (token) => {
|
|
399
|
+
const authedClient = _agentwalletsdk.createAgentWalletClient.call(void 0, {
|
|
400
|
+
baseUrl: resolveBaseUrl(),
|
|
401
|
+
token
|
|
402
|
+
});
|
|
403
|
+
try {
|
|
404
|
+
await authedClient.listProjects();
|
|
405
|
+
} catch (error) {
|
|
406
|
+
if (error instanceof _agentwalletsdk.AgentWalletSdkError && (error.status === 401 || error.status === 403)) {
|
|
407
|
+
throw new Error("Session token is not authorized");
|
|
408
|
+
}
|
|
409
|
+
console.warn(
|
|
410
|
+
`Warning: session token saved, but backend project query failed: ${getErrorMessage(error)}`
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
var saveSessionToken = async (token) => {
|
|
415
|
+
const config = await loadConfig();
|
|
416
|
+
await saveConfig({
|
|
417
|
+
...config,
|
|
418
|
+
token
|
|
419
|
+
});
|
|
420
|
+
console.log("Saved credentials to ~/.config/wlfc-agent/config.json");
|
|
421
|
+
};
|
|
373
422
|
var startCallbackServer = async (options) => {
|
|
374
423
|
const { port } = options;
|
|
375
424
|
const client = _agentwalletsdk.createAgentWalletClient.call(void 0, { baseUrl: resolveBaseUrl() });
|
|
376
|
-
let resolved = false;
|
|
377
|
-
let settle = null;
|
|
378
|
-
let rejectSettle = null;
|
|
379
|
-
let timeout;
|
|
380
|
-
const tokenPromise = new Promise((resolve, reject) => {
|
|
381
|
-
settle = resolve;
|
|
382
|
-
rejectSettle = reject;
|
|
383
|
-
});
|
|
384
|
-
const complete = (token) => {
|
|
385
|
-
if (resolved) {
|
|
386
|
-
return false;
|
|
387
|
-
}
|
|
388
|
-
resolved = true;
|
|
389
|
-
if (timeout) {
|
|
390
|
-
clearTimeout(timeout);
|
|
391
|
-
}
|
|
392
|
-
_optionalChain([settle, 'optionalCall', _3 => _3(token)]);
|
|
393
|
-
return true;
|
|
394
|
-
};
|
|
395
|
-
const fail = (error) => {
|
|
396
|
-
if (resolved) {
|
|
397
|
-
return;
|
|
398
|
-
}
|
|
399
|
-
resolved = true;
|
|
400
|
-
if (timeout) {
|
|
401
|
-
clearTimeout(timeout);
|
|
402
|
-
}
|
|
403
|
-
_optionalChain([rejectSettle, 'optionalCall', _4 => _4(error)]);
|
|
404
|
-
};
|
|
405
425
|
const server = _http.createServer.call(void 0, async (request, response) => {
|
|
406
426
|
const requestUrl = new URL(_nullishCoalesce(request.url, () => ( "/")), `http://127.0.0.1:${port}`);
|
|
407
427
|
if (request.method === "GET" && requestUrl.pathname === "/") {
|
|
@@ -421,7 +441,7 @@ var startCallbackServer = async (options) => {
|
|
|
421
441
|
<li><a href="/login">/login?requestId=<id></a></li>
|
|
422
442
|
<li><a href="/register">/register?requestId=<id></a></li>
|
|
423
443
|
</ul>
|
|
424
|
-
<p>This server
|
|
444
|
+
<p>This server hosts local login/register pages while your terminal polls backend status.</p>
|
|
425
445
|
</body>
|
|
426
446
|
</html>`);
|
|
427
447
|
return;
|
|
@@ -494,7 +514,7 @@ var startCallbackServer = async (options) => {
|
|
|
494
514
|
if (!response.ok) {
|
|
495
515
|
throw new Error(payload?.message || ("HTTP " + response.status));
|
|
496
516
|
}
|
|
497
|
-
setStatus("Success.
|
|
517
|
+
setStatus("Success. Login completed. Return to terminal; it is polling for your session.");
|
|
498
518
|
form.style.display = "none";
|
|
499
519
|
} catch (error) {
|
|
500
520
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -696,7 +716,7 @@ var startCallbackServer = async (options) => {
|
|
|
696
716
|
throw new Error(payload?.message || ("HTTP " + response.status));
|
|
697
717
|
}
|
|
698
718
|
|
|
699
|
-
setStatus("Success.
|
|
719
|
+
setStatus("Success. Registration completed. Return to terminal; it is polling for your session.");
|
|
700
720
|
totpForm.style.display = "none";
|
|
701
721
|
} catch (error) {
|
|
702
722
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -712,7 +732,7 @@ var startCallbackServer = async (options) => {
|
|
|
712
732
|
try {
|
|
713
733
|
const rawBody = await readRequestBody(request);
|
|
714
734
|
const parsed = JSON.parse(rawBody);
|
|
715
|
-
const payload = await client.
|
|
735
|
+
const payload = await client.wcLoginComplete({
|
|
716
736
|
otpSignature: typeof parsed.otpSignature === "string" ? parsed.otpSignature : "",
|
|
717
737
|
requestId: typeof parsed.requestId === "string" ? parsed.requestId : ""
|
|
718
738
|
});
|
|
@@ -754,7 +774,7 @@ var startCallbackServer = async (options) => {
|
|
|
754
774
|
try {
|
|
755
775
|
const rawBody = await readRequestBody(request);
|
|
756
776
|
const parsed = JSON.parse(rawBody);
|
|
757
|
-
const payload = await client.
|
|
777
|
+
const payload = await client.wcRegisterComplete({
|
|
758
778
|
otpCode: typeof parsed.otpCode === "string" ? parsed.otpCode : "",
|
|
759
779
|
requestId: typeof parsed.requestId === "string" ? parsed.requestId : "",
|
|
760
780
|
totpId: typeof parsed.totpId === "string" ? parsed.totpId : ""
|
|
@@ -770,51 +790,14 @@ var startCallbackServer = async (options) => {
|
|
|
770
790
|
}
|
|
771
791
|
return;
|
|
772
792
|
}
|
|
773
|
-
if (
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
return;
|
|
782
|
-
}
|
|
783
|
-
const accepted = complete(token);
|
|
784
|
-
response.statusCode = accepted ? 200 : 409;
|
|
785
|
-
response.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
786
|
-
response.end(`<!doctype html>
|
|
787
|
-
<html>
|
|
788
|
-
<head><meta charset="utf-8" /><title>wlfc login callback</title></head>
|
|
789
|
-
<body style="font-family: ui-sans-serif, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; margin: 24px;">
|
|
790
|
-
<h1>${accepted ? "wlfc login completed" : "wlfc callback already consumed"}</h1>
|
|
791
|
-
<p>You can return to your terminal.</p>
|
|
792
|
-
</body>
|
|
793
|
-
</html>`);
|
|
794
|
-
return;
|
|
795
|
-
}
|
|
796
|
-
if (request.method === "POST" && requestUrl.pathname === "/callback") {
|
|
797
|
-
try {
|
|
798
|
-
const rawBody = await readRequestBody(request);
|
|
799
|
-
const parsed = JSON.parse(rawBody);
|
|
800
|
-
const token = typeof parsed === "object" && parsed !== null && "token" in parsed && typeof parsed.token === "string" ? parsed.token.trim() : "";
|
|
801
|
-
if (!token) {
|
|
802
|
-
response.statusCode = 400;
|
|
803
|
-
response.setHeader("Content-Type", "application/json");
|
|
804
|
-
response.end(
|
|
805
|
-
JSON.stringify({ message: "Missing token in callback payload" })
|
|
806
|
-
);
|
|
807
|
-
return;
|
|
808
|
-
}
|
|
809
|
-
const accepted = complete(token);
|
|
810
|
-
response.statusCode = accepted ? 200 : 409;
|
|
811
|
-
response.setHeader("Content-Type", "application/json");
|
|
812
|
-
response.end(JSON.stringify({ ok: accepted }));
|
|
813
|
-
} catch (error) {
|
|
814
|
-
response.statusCode = 400;
|
|
815
|
-
response.setHeader("Content-Type", "application/json");
|
|
816
|
-
response.end(JSON.stringify(getErrorPayload(error)));
|
|
817
|
-
}
|
|
793
|
+
if (requestUrl.pathname === "/callback") {
|
|
794
|
+
response.statusCode = 410;
|
|
795
|
+
response.setHeader("Content-Type", "application/json");
|
|
796
|
+
response.end(
|
|
797
|
+
JSON.stringify({
|
|
798
|
+
message: "Callback endpoint is no longer used. Complete the flow in browser and wait for CLI polling."
|
|
799
|
+
})
|
|
800
|
+
);
|
|
818
801
|
return;
|
|
819
802
|
}
|
|
820
803
|
response.statusCode = 404;
|
|
@@ -829,13 +812,6 @@ var startCallbackServer = async (options) => {
|
|
|
829
812
|
resolve();
|
|
830
813
|
});
|
|
831
814
|
});
|
|
832
|
-
timeout = setTimeout(() => {
|
|
833
|
-
fail(
|
|
834
|
-
new Error(
|
|
835
|
-
`Timed out waiting for callback on http://127.0.0.1:${port}/callback`
|
|
836
|
-
)
|
|
837
|
-
);
|
|
838
|
-
}, DEFAULT_LOGIN_TIMEOUT_MS);
|
|
839
815
|
const close = async () => {
|
|
840
816
|
await new Promise((resolve) => {
|
|
841
817
|
server.close(() => resolve());
|
|
@@ -843,30 +819,14 @@ var startCallbackServer = async (options) => {
|
|
|
843
819
|
};
|
|
844
820
|
return {
|
|
845
821
|
callbackUrl: `http://127.0.0.1:${port}/callback`,
|
|
846
|
-
close
|
|
847
|
-
waitForToken: async () => {
|
|
848
|
-
try {
|
|
849
|
-
return await tokenPromise;
|
|
850
|
-
} finally {
|
|
851
|
-
await close();
|
|
852
|
-
}
|
|
853
|
-
}
|
|
822
|
+
close
|
|
854
823
|
};
|
|
855
824
|
};
|
|
856
825
|
var login = async (args, flags) => {
|
|
857
826
|
const token = (_nullishCoalesce(flags.token, () => ( ""))).trim();
|
|
858
827
|
if (token) {
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
token
|
|
862
|
-
});
|
|
863
|
-
await client2.listProjects();
|
|
864
|
-
const config2 = await loadConfig();
|
|
865
|
-
await saveConfig({
|
|
866
|
-
...config2,
|
|
867
|
-
token
|
|
868
|
-
});
|
|
869
|
-
console.log("Saved credentials to ~/.config/wlfc-agent/config.json");
|
|
828
|
+
await verifySessionToken(token);
|
|
829
|
+
await saveSessionToken(token);
|
|
870
830
|
return;
|
|
871
831
|
}
|
|
872
832
|
const email = (_nullishCoalesce(_nullishCoalesce(flags.email, () => ( args[0])), () => ( ""))).trim().toLowerCase();
|
|
@@ -907,20 +867,11 @@ var login = async (args, flags) => {
|
|
|
907
867
|
if (!loginResult.token) {
|
|
908
868
|
throw new Error("Login response did not include a session token");
|
|
909
869
|
}
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
token: loginResult.token
|
|
913
|
-
});
|
|
914
|
-
await authedClient.listProjects();
|
|
915
|
-
const config = await loadConfig();
|
|
916
|
-
await saveConfig({
|
|
917
|
-
...config,
|
|
918
|
-
token: loginResult.token
|
|
919
|
-
});
|
|
920
|
-
console.log("Saved credentials to ~/.config/wlfc-agent/config.json");
|
|
870
|
+
await verifySessionToken(loginResult.token);
|
|
871
|
+
await saveSessionToken(loginResult.token);
|
|
921
872
|
};
|
|
922
873
|
var register = async (args, flags) => {
|
|
923
|
-
const email = _optionalChain([args, 'access',
|
|
874
|
+
const email = _optionalChain([args, 'access', _3 => _3[0], 'optionalAccess', _4 => _4.trim, 'call', _5 => _5(), 'access', _6 => _6.toLowerCase, 'call', _7 => _7()]);
|
|
924
875
|
if (!email) {
|
|
925
876
|
throw new Error("register requires an email argument");
|
|
926
877
|
}
|
|
@@ -946,21 +897,15 @@ var register = async (args, flags) => {
|
|
|
946
897
|
${start.setupUrl}`
|
|
947
898
|
);
|
|
948
899
|
}
|
|
949
|
-
|
|
950
|
-
const
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
await
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
...config,
|
|
958
|
-
token: callbackToken
|
|
959
|
-
});
|
|
960
|
-
console.log("Saved credentials to ~/.config/wlfc-agent/config.json");
|
|
961
|
-
} catch (error) {
|
|
900
|
+
console.log("Waiting for registration completion...");
|
|
901
|
+
const callbackToken = await waitForWcCompletionToken(
|
|
902
|
+
client,
|
|
903
|
+
start.requestId
|
|
904
|
+
);
|
|
905
|
+
await verifySessionToken(callbackToken);
|
|
906
|
+
await saveSessionToken(callbackToken);
|
|
907
|
+
} finally {
|
|
962
908
|
await callback.close();
|
|
963
|
-
throw error;
|
|
964
909
|
}
|
|
965
910
|
};
|
|
966
911
|
var logout = async () => {
|
|
@@ -1046,7 +991,7 @@ var doctor = async (flags) => {
|
|
|
1046
991
|
return count;
|
|
1047
992
|
}
|
|
1048
993
|
const secret = new URL(content).searchParams.get("secret");
|
|
1049
|
-
return _optionalChain([secret, 'optionalAccess',
|
|
994
|
+
return _optionalChain([secret, 'optionalAccess', _8 => _8.trim, 'call', _9 => _9()]) ? count + 1 : count;
|
|
1050
995
|
}, 0);
|
|
1051
996
|
checks.push({
|
|
1052
997
|
detail: otpSecrets > 0 ? `${otpSecrets} OTP secret file(s) found in ${OTP_DIR}` : `No valid OTP secret found in ${OTP_DIR}`,
|
|
@@ -1096,7 +1041,7 @@ var doctor = async (flags) => {
|
|
|
1096
1041
|
try {
|
|
1097
1042
|
const configs = await client.listWalletConfigs();
|
|
1098
1043
|
const activePolicies = configs.filter(
|
|
1099
|
-
(configItem) => Boolean(configItem.policy) && _optionalChain([configItem, 'access',
|
|
1044
|
+
(configItem) => Boolean(configItem.policy) && _optionalChain([configItem, 'access', _10 => _10.policy, 'optionalAccess', _11 => _11.status]) !== "deleted"
|
|
1100
1045
|
).length;
|
|
1101
1046
|
checks.push({
|
|
1102
1047
|
detail: `${activePolicies} wallet policy config(s) visible`,
|
package/dist/wlfc/index.js
CHANGED
|
@@ -178,6 +178,31 @@ var getErrorMessage = (error) => {
|
|
|
178
178
|
}
|
|
179
179
|
return String(error);
|
|
180
180
|
};
|
|
181
|
+
var WC_STATUS_POLL_INTERVAL_MS = 1500;
|
|
182
|
+
var sleep = (ms) => new Promise((resolve) => {
|
|
183
|
+
setTimeout(resolve, ms);
|
|
184
|
+
});
|
|
185
|
+
var waitForWcCompletionToken = async (client, requestId) => {
|
|
186
|
+
const deadline = Date.now() + DEFAULT_LOGIN_TIMEOUT_MS;
|
|
187
|
+
while (Date.now() < deadline) {
|
|
188
|
+
const status = await client.wcStatus({
|
|
189
|
+
consume: true,
|
|
190
|
+
requestId
|
|
191
|
+
});
|
|
192
|
+
const completed = status.completed === true;
|
|
193
|
+
const token = typeof status.token === "string" ? status.token.trim() : void 0;
|
|
194
|
+
if (completed && token) {
|
|
195
|
+
return token;
|
|
196
|
+
}
|
|
197
|
+
if (completed && !token) {
|
|
198
|
+
throw new Error(
|
|
199
|
+
"Backend reported wc completion without a session token payload"
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
await sleep(WC_STATUS_POLL_INTERVAL_MS);
|
|
203
|
+
}
|
|
204
|
+
throw new Error("Timed out waiting for wc completion; request expired");
|
|
205
|
+
};
|
|
181
206
|
var printJson = (value) => {
|
|
182
207
|
console.log(JSON.stringify(value, null, 2));
|
|
183
208
|
};
|
|
@@ -370,38 +395,33 @@ var getAuthedClient = async (flags) => {
|
|
|
370
395
|
token
|
|
371
396
|
});
|
|
372
397
|
};
|
|
398
|
+
var verifySessionToken = async (token) => {
|
|
399
|
+
const authedClient = createAgentWalletClient({
|
|
400
|
+
baseUrl: resolveBaseUrl(),
|
|
401
|
+
token
|
|
402
|
+
});
|
|
403
|
+
try {
|
|
404
|
+
await authedClient.listProjects();
|
|
405
|
+
} catch (error) {
|
|
406
|
+
if (error instanceof AgentWalletSdkError && (error.status === 401 || error.status === 403)) {
|
|
407
|
+
throw new Error("Session token is not authorized");
|
|
408
|
+
}
|
|
409
|
+
console.warn(
|
|
410
|
+
`Warning: session token saved, but backend project query failed: ${getErrorMessage(error)}`
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
var saveSessionToken = async (token) => {
|
|
415
|
+
const config = await loadConfig();
|
|
416
|
+
await saveConfig({
|
|
417
|
+
...config,
|
|
418
|
+
token
|
|
419
|
+
});
|
|
420
|
+
console.log("Saved credentials to ~/.config/wlfc-agent/config.json");
|
|
421
|
+
};
|
|
373
422
|
var startCallbackServer = async (options) => {
|
|
374
423
|
const { port } = options;
|
|
375
424
|
const client = createAgentWalletClient({ baseUrl: resolveBaseUrl() });
|
|
376
|
-
let resolved = false;
|
|
377
|
-
let settle = null;
|
|
378
|
-
let rejectSettle = null;
|
|
379
|
-
let timeout;
|
|
380
|
-
const tokenPromise = new Promise((resolve, reject) => {
|
|
381
|
-
settle = resolve;
|
|
382
|
-
rejectSettle = reject;
|
|
383
|
-
});
|
|
384
|
-
const complete = (token) => {
|
|
385
|
-
if (resolved) {
|
|
386
|
-
return false;
|
|
387
|
-
}
|
|
388
|
-
resolved = true;
|
|
389
|
-
if (timeout) {
|
|
390
|
-
clearTimeout(timeout);
|
|
391
|
-
}
|
|
392
|
-
settle?.(token);
|
|
393
|
-
return true;
|
|
394
|
-
};
|
|
395
|
-
const fail = (error) => {
|
|
396
|
-
if (resolved) {
|
|
397
|
-
return;
|
|
398
|
-
}
|
|
399
|
-
resolved = true;
|
|
400
|
-
if (timeout) {
|
|
401
|
-
clearTimeout(timeout);
|
|
402
|
-
}
|
|
403
|
-
rejectSettle?.(error);
|
|
404
|
-
};
|
|
405
425
|
const server = createServer(async (request, response) => {
|
|
406
426
|
const requestUrl = new URL(request.url ?? "/", `http://127.0.0.1:${port}`);
|
|
407
427
|
if (request.method === "GET" && requestUrl.pathname === "/") {
|
|
@@ -421,7 +441,7 @@ var startCallbackServer = async (options) => {
|
|
|
421
441
|
<li><a href="/login">/login?requestId=<id></a></li>
|
|
422
442
|
<li><a href="/register">/register?requestId=<id></a></li>
|
|
423
443
|
</ul>
|
|
424
|
-
<p>This server
|
|
444
|
+
<p>This server hosts local login/register pages while your terminal polls backend status.</p>
|
|
425
445
|
</body>
|
|
426
446
|
</html>`);
|
|
427
447
|
return;
|
|
@@ -494,7 +514,7 @@ var startCallbackServer = async (options) => {
|
|
|
494
514
|
if (!response.ok) {
|
|
495
515
|
throw new Error(payload?.message || ("HTTP " + response.status));
|
|
496
516
|
}
|
|
497
|
-
setStatus("Success.
|
|
517
|
+
setStatus("Success. Login completed. Return to terminal; it is polling for your session.");
|
|
498
518
|
form.style.display = "none";
|
|
499
519
|
} catch (error) {
|
|
500
520
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -696,7 +716,7 @@ var startCallbackServer = async (options) => {
|
|
|
696
716
|
throw new Error(payload?.message || ("HTTP " + response.status));
|
|
697
717
|
}
|
|
698
718
|
|
|
699
|
-
setStatus("Success.
|
|
719
|
+
setStatus("Success. Registration completed. Return to terminal; it is polling for your session.");
|
|
700
720
|
totpForm.style.display = "none";
|
|
701
721
|
} catch (error) {
|
|
702
722
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -712,7 +732,7 @@ var startCallbackServer = async (options) => {
|
|
|
712
732
|
try {
|
|
713
733
|
const rawBody = await readRequestBody(request);
|
|
714
734
|
const parsed = JSON.parse(rawBody);
|
|
715
|
-
const payload = await client.
|
|
735
|
+
const payload = await client.wcLoginComplete({
|
|
716
736
|
otpSignature: typeof parsed.otpSignature === "string" ? parsed.otpSignature : "",
|
|
717
737
|
requestId: typeof parsed.requestId === "string" ? parsed.requestId : ""
|
|
718
738
|
});
|
|
@@ -754,7 +774,7 @@ var startCallbackServer = async (options) => {
|
|
|
754
774
|
try {
|
|
755
775
|
const rawBody = await readRequestBody(request);
|
|
756
776
|
const parsed = JSON.parse(rawBody);
|
|
757
|
-
const payload = await client.
|
|
777
|
+
const payload = await client.wcRegisterComplete({
|
|
758
778
|
otpCode: typeof parsed.otpCode === "string" ? parsed.otpCode : "",
|
|
759
779
|
requestId: typeof parsed.requestId === "string" ? parsed.requestId : "",
|
|
760
780
|
totpId: typeof parsed.totpId === "string" ? parsed.totpId : ""
|
|
@@ -770,51 +790,14 @@ var startCallbackServer = async (options) => {
|
|
|
770
790
|
}
|
|
771
791
|
return;
|
|
772
792
|
}
|
|
773
|
-
if (
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
return;
|
|
782
|
-
}
|
|
783
|
-
const accepted = complete(token);
|
|
784
|
-
response.statusCode = accepted ? 200 : 409;
|
|
785
|
-
response.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
786
|
-
response.end(`<!doctype html>
|
|
787
|
-
<html>
|
|
788
|
-
<head><meta charset="utf-8" /><title>wlfc login callback</title></head>
|
|
789
|
-
<body style="font-family: ui-sans-serif, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; margin: 24px;">
|
|
790
|
-
<h1>${accepted ? "wlfc login completed" : "wlfc callback already consumed"}</h1>
|
|
791
|
-
<p>You can return to your terminal.</p>
|
|
792
|
-
</body>
|
|
793
|
-
</html>`);
|
|
794
|
-
return;
|
|
795
|
-
}
|
|
796
|
-
if (request.method === "POST" && requestUrl.pathname === "/callback") {
|
|
797
|
-
try {
|
|
798
|
-
const rawBody = await readRequestBody(request);
|
|
799
|
-
const parsed = JSON.parse(rawBody);
|
|
800
|
-
const token = typeof parsed === "object" && parsed !== null && "token" in parsed && typeof parsed.token === "string" ? parsed.token.trim() : "";
|
|
801
|
-
if (!token) {
|
|
802
|
-
response.statusCode = 400;
|
|
803
|
-
response.setHeader("Content-Type", "application/json");
|
|
804
|
-
response.end(
|
|
805
|
-
JSON.stringify({ message: "Missing token in callback payload" })
|
|
806
|
-
);
|
|
807
|
-
return;
|
|
808
|
-
}
|
|
809
|
-
const accepted = complete(token);
|
|
810
|
-
response.statusCode = accepted ? 200 : 409;
|
|
811
|
-
response.setHeader("Content-Type", "application/json");
|
|
812
|
-
response.end(JSON.stringify({ ok: accepted }));
|
|
813
|
-
} catch (error) {
|
|
814
|
-
response.statusCode = 400;
|
|
815
|
-
response.setHeader("Content-Type", "application/json");
|
|
816
|
-
response.end(JSON.stringify(getErrorPayload(error)));
|
|
817
|
-
}
|
|
793
|
+
if (requestUrl.pathname === "/callback") {
|
|
794
|
+
response.statusCode = 410;
|
|
795
|
+
response.setHeader("Content-Type", "application/json");
|
|
796
|
+
response.end(
|
|
797
|
+
JSON.stringify({
|
|
798
|
+
message: "Callback endpoint is no longer used. Complete the flow in browser and wait for CLI polling."
|
|
799
|
+
})
|
|
800
|
+
);
|
|
818
801
|
return;
|
|
819
802
|
}
|
|
820
803
|
response.statusCode = 404;
|
|
@@ -829,13 +812,6 @@ var startCallbackServer = async (options) => {
|
|
|
829
812
|
resolve();
|
|
830
813
|
});
|
|
831
814
|
});
|
|
832
|
-
timeout = setTimeout(() => {
|
|
833
|
-
fail(
|
|
834
|
-
new Error(
|
|
835
|
-
`Timed out waiting for callback on http://127.0.0.1:${port}/callback`
|
|
836
|
-
)
|
|
837
|
-
);
|
|
838
|
-
}, DEFAULT_LOGIN_TIMEOUT_MS);
|
|
839
815
|
const close = async () => {
|
|
840
816
|
await new Promise((resolve) => {
|
|
841
817
|
server.close(() => resolve());
|
|
@@ -843,30 +819,14 @@ var startCallbackServer = async (options) => {
|
|
|
843
819
|
};
|
|
844
820
|
return {
|
|
845
821
|
callbackUrl: `http://127.0.0.1:${port}/callback`,
|
|
846
|
-
close
|
|
847
|
-
waitForToken: async () => {
|
|
848
|
-
try {
|
|
849
|
-
return await tokenPromise;
|
|
850
|
-
} finally {
|
|
851
|
-
await close();
|
|
852
|
-
}
|
|
853
|
-
}
|
|
822
|
+
close
|
|
854
823
|
};
|
|
855
824
|
};
|
|
856
825
|
var login = async (args, flags) => {
|
|
857
826
|
const token = (flags.token ?? "").trim();
|
|
858
827
|
if (token) {
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
token
|
|
862
|
-
});
|
|
863
|
-
await client2.listProjects();
|
|
864
|
-
const config2 = await loadConfig();
|
|
865
|
-
await saveConfig({
|
|
866
|
-
...config2,
|
|
867
|
-
token
|
|
868
|
-
});
|
|
869
|
-
console.log("Saved credentials to ~/.config/wlfc-agent/config.json");
|
|
828
|
+
await verifySessionToken(token);
|
|
829
|
+
await saveSessionToken(token);
|
|
870
830
|
return;
|
|
871
831
|
}
|
|
872
832
|
const email = (flags.email ?? args[0] ?? "").trim().toLowerCase();
|
|
@@ -907,17 +867,8 @@ var login = async (args, flags) => {
|
|
|
907
867
|
if (!loginResult.token) {
|
|
908
868
|
throw new Error("Login response did not include a session token");
|
|
909
869
|
}
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
token: loginResult.token
|
|
913
|
-
});
|
|
914
|
-
await authedClient.listProjects();
|
|
915
|
-
const config = await loadConfig();
|
|
916
|
-
await saveConfig({
|
|
917
|
-
...config,
|
|
918
|
-
token: loginResult.token
|
|
919
|
-
});
|
|
920
|
-
console.log("Saved credentials to ~/.config/wlfc-agent/config.json");
|
|
870
|
+
await verifySessionToken(loginResult.token);
|
|
871
|
+
await saveSessionToken(loginResult.token);
|
|
921
872
|
};
|
|
922
873
|
var register = async (args, flags) => {
|
|
923
874
|
const email = args[0]?.trim().toLowerCase();
|
|
@@ -946,21 +897,15 @@ var register = async (args, flags) => {
|
|
|
946
897
|
${start.setupUrl}`
|
|
947
898
|
);
|
|
948
899
|
}
|
|
949
|
-
|
|
950
|
-
const
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
await
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
...config,
|
|
958
|
-
token: callbackToken
|
|
959
|
-
});
|
|
960
|
-
console.log("Saved credentials to ~/.config/wlfc-agent/config.json");
|
|
961
|
-
} catch (error) {
|
|
900
|
+
console.log("Waiting for registration completion...");
|
|
901
|
+
const callbackToken = await waitForWcCompletionToken(
|
|
902
|
+
client,
|
|
903
|
+
start.requestId
|
|
904
|
+
);
|
|
905
|
+
await verifySessionToken(callbackToken);
|
|
906
|
+
await saveSessionToken(callbackToken);
|
|
907
|
+
} finally {
|
|
962
908
|
await callback.close();
|
|
963
|
-
throw error;
|
|
964
909
|
}
|
|
965
910
|
};
|
|
966
911
|
var logout = async () => {
|