wood-fired-tasks 2.0.4 → 2.0.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/CHANGELOG.md +17 -0
- package/dist/cli/commands/setup.d.ts +17 -0
- package/dist/cli/commands/setup.js +53 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -13,6 +13,23 @@ vulnerabilities, supply-chain pinning) are always called out under `Security`.
|
|
|
13
13
|
|
|
14
14
|
_No changes yet._
|
|
15
15
|
|
|
16
|
+
## [v2.0.5] - 2026-06-08
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
- **`tasks setup` → Remote now tells you the truth about what a server needs for
|
|
20
|
+
browser login.** When the server reports OIDC ready but you entered a
|
|
21
|
+
**plain-http, non-localhost URL**, browser/device login via Google SSO can
|
|
22
|
+
never complete — identity providers reject non-`https` OAuth redirect URIs
|
|
23
|
+
except for `localhost`. Previously setup would launch the device flow anyway
|
|
24
|
+
and the verification page dead-ended at the IdP callback ("unable to connect").
|
|
25
|
+
Setup now detects this up front and explains it: it tells you to either re-run
|
|
26
|
+
with an **https** URL (front the server with a TLS reverse proxy / real domain
|
|
27
|
+
so Google SSO completes) or **paste a personal access token**, and prints the
|
|
28
|
+
exact on-host command to mint one (`tasks db mint-token --user <email-or-id>`),
|
|
29
|
+
then drops straight into manual-PAT entry. `https` and `http://localhost`
|
|
30
|
+
servers are unaffected and complete browser login as before. New exported
|
|
31
|
+
helper `canUseBrowserSso()`.
|
|
32
|
+
|
|
16
33
|
## [v2.0.4] - 2026-06-08
|
|
17
34
|
|
|
18
35
|
### Fixed
|
|
@@ -334,6 +334,23 @@ export declare function probeOidcState(baseUrl: string): Promise<OidcProbeResult
|
|
|
334
334
|
* - probe failure → manual-PAT (connectivity escape hatch).
|
|
335
335
|
*/
|
|
336
336
|
export declare function selectRemoteOnboardingMethod(probe: OidcProbeResult): RemoteOnboardingMethod;
|
|
337
|
+
/**
|
|
338
|
+
* Whether the browser/device login (Google SSO) can actually COMPLETE against
|
|
339
|
+
* `baseUrl` (#835).
|
|
340
|
+
*
|
|
341
|
+
* The whole OIDC dance — the verification page AND the IdP's OAuth callback —
|
|
342
|
+
* happens at the server's origin, and identity providers (Google especially)
|
|
343
|
+
* reject non-`https` OAuth redirect URIs *except* for `localhost`/`127.0.0.1`.
|
|
344
|
+
* So a server reached over plain `http` at a non-localhost address can report
|
|
345
|
+
* `oidc: 'ready'` yet still be unable to finish browser login: the user's
|
|
346
|
+
* browser gets bounced to an `http://…/auth/callback` the IdP won't honor. We
|
|
347
|
+
* detect that up front so the interview can tell the user the truth (need https,
|
|
348
|
+
* or use a PAT) instead of opening a URL that dead-ends.
|
|
349
|
+
*
|
|
350
|
+
* Returns true for any `https` URL and for `http://localhost` / `127.0.0.1` /
|
|
351
|
+
* `[::1]`; false for plain-http non-loopback hosts and unparseable input.
|
|
352
|
+
*/
|
|
353
|
+
export declare function canUseBrowserSso(baseUrl: string): boolean;
|
|
337
354
|
/**
|
|
338
355
|
* The minimal identity envelope `GET /api/v1/me` returns (task #809). Mirrors
|
|
339
356
|
* the fields {@link writeCredentials} needs so a manually-pasted PAT lands in
|
|
@@ -604,6 +604,37 @@ export function selectRemoteOnboardingMethod(probe) {
|
|
|
604
604
|
return 'manual-pat';
|
|
605
605
|
return probe.oidc === 'ready' ? 'device-flow' : 'manual-pat';
|
|
606
606
|
}
|
|
607
|
+
/**
|
|
608
|
+
* Whether the browser/device login (Google SSO) can actually COMPLETE against
|
|
609
|
+
* `baseUrl` (#835).
|
|
610
|
+
*
|
|
611
|
+
* The whole OIDC dance — the verification page AND the IdP's OAuth callback —
|
|
612
|
+
* happens at the server's origin, and identity providers (Google especially)
|
|
613
|
+
* reject non-`https` OAuth redirect URIs *except* for `localhost`/`127.0.0.1`.
|
|
614
|
+
* So a server reached over plain `http` at a non-localhost address can report
|
|
615
|
+
* `oidc: 'ready'` yet still be unable to finish browser login: the user's
|
|
616
|
+
* browser gets bounced to an `http://…/auth/callback` the IdP won't honor. We
|
|
617
|
+
* detect that up front so the interview can tell the user the truth (need https,
|
|
618
|
+
* or use a PAT) instead of opening a URL that dead-ends.
|
|
619
|
+
*
|
|
620
|
+
* Returns true for any `https` URL and for `http://localhost` / `127.0.0.1` /
|
|
621
|
+
* `[::1]`; false for plain-http non-loopback hosts and unparseable input.
|
|
622
|
+
*/
|
|
623
|
+
export function canUseBrowserSso(baseUrl) {
|
|
624
|
+
let url;
|
|
625
|
+
try {
|
|
626
|
+
url = new URL(baseUrl);
|
|
627
|
+
}
|
|
628
|
+
catch {
|
|
629
|
+
return false;
|
|
630
|
+
}
|
|
631
|
+
if (url.protocol === 'https:')
|
|
632
|
+
return true;
|
|
633
|
+
if (url.protocol !== 'http:')
|
|
634
|
+
return false;
|
|
635
|
+
const host = url.hostname.toLowerCase();
|
|
636
|
+
return host === 'localhost' || host === '127.0.0.1' || host === '::1' || host === '[::1]';
|
|
637
|
+
}
|
|
607
638
|
/**
|
|
608
639
|
* Default manual-PAT persistence (task #809).
|
|
609
640
|
*
|
|
@@ -811,6 +842,28 @@ export async function runRemoteOnboarding(options = {}) {
|
|
|
811
842
|
// 3. Branch on the selected method.
|
|
812
843
|
let method = selectRemoteOnboardingMethod(probeResult);
|
|
813
844
|
const oidc = probeResult.ok ? probeResult.oidc : null;
|
|
845
|
+
// #835: even when the server reports OIDC ready, browser login can only
|
|
846
|
+
// COMPLETE over https (or localhost) — Google rejects non-https OAuth
|
|
847
|
+
// redirect URIs everywhere else. Catch a plain-http non-localhost URL here
|
|
848
|
+
// and tell the user plainly, then route to manual-PAT entry (with on-host
|
|
849
|
+
// mint instructions) rather than opening a verification URL that dead-ends at
|
|
850
|
+
// the IdP callback.
|
|
851
|
+
if (method === 'device-flow' && !canUseBrowserSso(baseUrl)) {
|
|
852
|
+
log('');
|
|
853
|
+
log(`"${baseUrl}" is plain http at a non-localhost address.`);
|
|
854
|
+
log('Browser login via Google SSO requires an https URL — identity providers');
|
|
855
|
+
log('reject non-https OAuth redirect URIs except for localhost — so the device');
|
|
856
|
+
log('flow cannot complete against this server. To finish setup, either:');
|
|
857
|
+
log(' • re-run with an https URL for this server (e.g. front it with a TLS');
|
|
858
|
+
log(' reverse proxy / real domain so Google SSO completes), or');
|
|
859
|
+
log(' • paste a personal access token now.');
|
|
860
|
+
log('');
|
|
861
|
+
log('To mint a PAT, run this ON THE SERVER HOST:');
|
|
862
|
+
log(' tasks db mint-token --user <your-email-or-user-id>');
|
|
863
|
+
log('(or create one from your account page once logged in via the browser).');
|
|
864
|
+
log('');
|
|
865
|
+
method = 'manual-pat';
|
|
866
|
+
}
|
|
814
867
|
if (method === 'device-flow') {
|
|
815
868
|
// Self-provision a PAT via the OIDC device flow (#806). runDeviceLogin owns
|
|
816
869
|
// the entire RFC 8628 exchange AND persists the minted PAT via the
|