authflow-cli 0.4.1 → 0.5.0
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 +157 -5
- package/dist/checks.d.ts +30 -0
- package/dist/checks.js +36 -0
- package/dist/checks.js.map +1 -0
- package/dist/client-conformance.d.ts +5 -1
- package/dist/client-conformance.js +9 -1
- package/dist/client-conformance.js.map +1 -1
- package/dist/commands/doctor.js +5 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/register.js +30 -2
- package/dist/commands/register.js.map +1 -1
- package/dist/commands/set-domain.d.ts +34 -0
- package/dist/commands/set-domain.js +162 -0
- package/dist/commands/set-domain.js.map +1 -0
- package/dist/config.d.ts +32 -1
- package/dist/config.js.map +1 -1
- package/dist/custom-domain.d.ts +96 -0
- package/dist/custom-domain.js +289 -0
- package/dist/custom-domain.js.map +1 -0
- package/dist/doctor.d.ts +31 -23
- package/dist/doctor.js +271 -57
- package/dist/doctor.js.map +1 -1
- package/dist/google-redirect.d.ts +5 -1
- package/dist/google-redirect.js +11 -5
- package/dist/google-redirect.js.map +1 -1
- package/dist/mcp/server.d.ts +8 -1
- package/dist/mcp/server.js +137 -7
- package/dist/mcp/server.js.map +1 -1
- package/dist/program.js +4 -1
- package/dist/program.js.map +1 -1
- package/dist/rail.d.ts +16 -0
- package/dist/rail.js +39 -0
- package/dist/rail.js.map +1 -1
- package/dist/resource-urls.d.ts +27 -0
- package/dist/resource-urls.js +56 -0
- package/dist/resource-urls.js.map +1 -0
- package/dist/status.d.ts +15 -1
- package/dist/status.js +59 -5
- package/dist/status.js.map +1 -1
- package/dist/surface.d.ts +1 -0
- package/dist/surface.js +1 -0
- package/dist/surface.js.map +1 -1
- package/dist/tenant-host.d.ts +49 -0
- package/dist/tenant-host.js +367 -0
- package/dist/tenant-host.js.map +1 -0
- package/dist/version.d.ts +10 -0
- package/dist/version.js +27 -0
- package/dist/version.js.map +1 -0
- package/package.json +4 -4
package/dist/doctor.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import { fetchOrNull, type DoctorCheck } from "./checks.js";
|
|
2
|
+
import { type ResourceEndpoints } from "./resource-urls.js";
|
|
3
|
+
import { type HostProbes } from "./tenant-host.js";
|
|
4
|
+
export { fetchOrNull };
|
|
5
|
+
export type { DoctorCheck, FetchOutcome } from "./checks.js";
|
|
1
6
|
/**
|
|
2
7
|
* Preflight against a rail deployment, from a tenant's point of view.
|
|
3
8
|
*
|
|
@@ -8,41 +13,44 @@
|
|
|
8
13
|
* showed up again as 500 HTML on /login (and the other consumer pages) when returnUrl is
|
|
9
14
|
* missing — it looks like an outage, it is an unhandled throw. These checks do.
|
|
10
15
|
*/
|
|
11
|
-
export type DoctorCheck = {
|
|
12
|
-
name: string;
|
|
13
|
-
pass: boolean;
|
|
14
|
-
detail: string;
|
|
15
|
-
/** What to do about it. Empty when the check passed. */
|
|
16
|
-
remedy?: string;
|
|
17
|
-
};
|
|
18
16
|
export type DoctorReport = {
|
|
19
17
|
issuer: string;
|
|
20
18
|
slug?: string;
|
|
19
|
+
/** Tenant hostname whose DNS, certificate and discovery documents were checked (`--host`). */
|
|
20
|
+
host?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Where the resource's PRM and 401 challenge were probed, so the checks that follow (the Google
|
|
23
|
+
* redirect) look at the same URLs. Only present when a slug was given.
|
|
24
|
+
*/
|
|
25
|
+
endpoints?: ResourceEndpoints;
|
|
21
26
|
/** MCP clients whose OAuth registration was replayed; absent when `--client` was not passed. */
|
|
22
27
|
clients?: string[];
|
|
23
28
|
dryRun?: boolean;
|
|
29
|
+
/** True when the slug is a correct draft: paywall 404s are expected, not a rail outage. */
|
|
30
|
+
draft?: boolean;
|
|
24
31
|
pass: boolean;
|
|
25
32
|
checks: DoctorCheck[];
|
|
26
33
|
};
|
|
27
|
-
export
|
|
34
|
+
export type DoctorOptions = HostProbes & {
|
|
35
|
+
adminKey?: string;
|
|
36
|
+
/**
|
|
37
|
+
* A tenant's own hostname to verify end to end (DNS, TLS, redirect, PRM, 401). It supersedes the
|
|
38
|
+
* slug's own PRM and challenge checks, which would probe the same URLs a second time; the slug
|
|
39
|
+
* then only selects the receipt the host is compared against.
|
|
40
|
+
*/
|
|
41
|
+
host?: string;
|
|
42
|
+
};
|
|
43
|
+
export declare function runDoctor(issuer: string, slug?: string, options?: DoctorOptions): Promise<DoctorReport>;
|
|
28
44
|
export declare function checkConsumerPages(base: string): Promise<DoctorCheck>;
|
|
29
45
|
/**
|
|
30
46
|
* The paywall is a transport-level 401 carrying `resource_metadata`. If this is not exactly right,
|
|
31
47
|
* MCP clients never prompt for auth, which presents as "the server just does not work in Claude".
|
|
48
|
+
*
|
|
49
|
+
* `target` is where the resource actually answers (from the receipt). Without it the slug URL on
|
|
50
|
+
* the issuer is assumed, which is only true for a resource on the gateway host.
|
|
32
51
|
*/
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
export declare function checkGatewayChallenge(base: string, slug: string): Promise<DoctorCheck>;
|
|
38
|
-
export type FetchOutcome = {
|
|
39
|
-
ok: boolean;
|
|
40
|
-
status?: number;
|
|
41
|
-
body?: string;
|
|
42
|
-
headers?: Headers;
|
|
43
|
-
location?: string;
|
|
44
|
-
error?: string;
|
|
45
|
-
};
|
|
46
|
-
/** Network failures are a diagnosis here, not an exception — every one of them is a real finding. */
|
|
47
|
-
export declare function fetchOrNull(url: string, init?: RequestInit): Promise<FetchOutcome>;
|
|
52
|
+
export declare function checkGatewayChallenge(base: string, slug: string, draft?: boolean, target?: {
|
|
53
|
+
url: string;
|
|
54
|
+
publicHost?: string;
|
|
55
|
+
}): Promise<DoctorCheck>;
|
|
48
56
|
export declare function formatDoctorReport(report: DoctorReport): string;
|
package/dist/doctor.js
CHANGED
|
@@ -1,23 +1,83 @@
|
|
|
1
|
+
import { fetchOrNull, unauthenticatedInitialize } from "./checks.js";
|
|
1
2
|
import { OriginProtocol } from "./constants.js";
|
|
2
|
-
|
|
3
|
-
|
|
3
|
+
import { parsePublicHost } from "./custom-domain.js";
|
|
4
|
+
import { resolveResourceEndpoints, slugEndpoints } from "./resource-urls.js";
|
|
5
|
+
import { runTenantHostChecks } from "./tenant-host.js";
|
|
6
|
+
// These live in checks.ts so the tenant-host checks can share them without importing this file.
|
|
7
|
+
// Re-exported because google-redirect.ts and client-conformance.ts import them from here.
|
|
8
|
+
export { fetchOrNull };
|
|
9
|
+
export async function runDoctor(issuer, slug, options = {}) {
|
|
4
10
|
const base = issuer.trim().replace(/\/+$/, "");
|
|
5
11
|
const checks = [];
|
|
12
|
+
const adminKey = (options.adminKey ?? process.env.AUTHFLOW_ADMIN_API_KEY ?? "").trim() || undefined;
|
|
13
|
+
const host = options.host === undefined ? undefined : parsePublicHost(options.host);
|
|
6
14
|
const reachable = await checkHostBound(base);
|
|
7
15
|
checks.push(reachable);
|
|
8
16
|
// Every later check reads a document from this host. If the host is not the rail, they would all
|
|
9
17
|
// fail with misleading messages that each look like a separate rail bug — which is exactly the
|
|
10
18
|
// pile of bugs this whole function exists to prevent.
|
|
11
19
|
if (!reachable.pass) {
|
|
12
|
-
return { issuer: base, slug, pass: false, checks };
|
|
20
|
+
return { issuer: base, slug, host, pass: false, checks };
|
|
13
21
|
}
|
|
14
22
|
checks.push(...(await checkOriginKeys(base)));
|
|
15
23
|
checks.push(await checkConsumerPages(base));
|
|
24
|
+
let draft = false;
|
|
25
|
+
let receipt;
|
|
26
|
+
let owned;
|
|
27
|
+
if (adminKey) {
|
|
28
|
+
const admin = await checkAdminKey(base, adminKey, slug);
|
|
29
|
+
checks.push(admin.check);
|
|
30
|
+
draft = admin.status === "draft";
|
|
31
|
+
receipt = admin.receipt;
|
|
32
|
+
owned = admin.resources;
|
|
33
|
+
}
|
|
34
|
+
// The receipt, not the slug, says where the resource answers: on its own hostname it answers
|
|
35
|
+
// nowhere else, and the slug URL on the issuer is a 404 by design.
|
|
36
|
+
const endpoints = slug ? resolveResourceEndpoints(base, slug, receipt) : undefined;
|
|
37
|
+
if (slug && endpoints && !host) {
|
|
38
|
+
checks.push(...(await checkProtectedResourceMetadata(base, slug, draft, endpoints)));
|
|
39
|
+
checks.push(await checkGatewayChallenge(base, slug, draft, {
|
|
40
|
+
url: endpoints.gatewayUrl,
|
|
41
|
+
publicHost: endpoints.publicHost,
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
if (host) {
|
|
45
|
+
const found = receiptForHost(host, slug, adminKey, receipt, owned);
|
|
46
|
+
checks.push(...(await runTenantHostChecks({
|
|
47
|
+
host,
|
|
48
|
+
receipt: found.receipt,
|
|
49
|
+
receiptNote: found.note,
|
|
50
|
+
dns: options.dns,
|
|
51
|
+
tls: options.tls,
|
|
52
|
+
now: options.now,
|
|
53
|
+
})));
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
issuer: base,
|
|
57
|
+
slug,
|
|
58
|
+
host,
|
|
59
|
+
endpoints,
|
|
60
|
+
draft: draft || undefined,
|
|
61
|
+
pass: checks.every((c) => c.pass),
|
|
62
|
+
checks,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The receipt a tenant host is compared against: the slug's when one was given, otherwise whichever
|
|
67
|
+
* of this key's resources is registered on the host. Says why there is none, because a doctor that
|
|
68
|
+
* silently compares nothing reads as a pass.
|
|
69
|
+
*/
|
|
70
|
+
function receiptForHost(host, slug, adminKey, receipt, owned) {
|
|
71
|
+
if (!adminKey) {
|
|
72
|
+
return { note: "no admin key to read it with; pass --admin-key or set AUTHFLOW_ADMIN_API_KEY" };
|
|
73
|
+
}
|
|
16
74
|
if (slug) {
|
|
17
|
-
|
|
18
|
-
checks.push(await checkGatewayChallenge(base, slug));
|
|
75
|
+
return receipt ? { receipt } : { note: `the admin key check above could not read slug '${slug}'` };
|
|
19
76
|
}
|
|
20
|
-
|
|
77
|
+
const match = (owned ?? []).find((resource) => resource.public_host?.trim().toLowerCase() === host);
|
|
78
|
+
return match
|
|
79
|
+
? { receipt: match }
|
|
80
|
+
: { note: `no resource owned by this admin key is registered on ${host}` };
|
|
21
81
|
}
|
|
22
82
|
/**
|
|
23
83
|
* An unbound Azure custom domain answers `404 Site Not Found` on every path, `/healthz` included.
|
|
@@ -170,17 +230,128 @@ export async function checkConsumerPages(base) {
|
|
|
170
230
|
"in AS metadata.",
|
|
171
231
|
};
|
|
172
232
|
}
|
|
173
|
-
async function
|
|
174
|
-
const url =
|
|
233
|
+
async function checkAdminKey(base, adminKey, slug) {
|
|
234
|
+
const url = slug
|
|
235
|
+
? `${base}/admin/resources/${encodeURIComponent(slug)}`
|
|
236
|
+
: `${base}/admin/resources`;
|
|
237
|
+
const response = await fetchOrNull(url, {
|
|
238
|
+
headers: { Authorization: `Bearer ${adminKey}` },
|
|
239
|
+
});
|
|
240
|
+
if (response.status === 401) {
|
|
241
|
+
let errorCode = "";
|
|
242
|
+
try {
|
|
243
|
+
errorCode = String(JSON.parse(response.body ?? "").error_code ?? "");
|
|
244
|
+
}
|
|
245
|
+
catch {
|
|
246
|
+
errorCode = "";
|
|
247
|
+
}
|
|
248
|
+
const stale = errorCode === "admin_key_invalid";
|
|
249
|
+
return {
|
|
250
|
+
check: {
|
|
251
|
+
name: "admin API key",
|
|
252
|
+
pass: false,
|
|
253
|
+
detail: `${url} returned 401${errorCode ? ` (${errorCode})` : ""}.`,
|
|
254
|
+
remedy: stale
|
|
255
|
+
? "This admin key is not valid in this environment. After a sandbox reset the previous " +
|
|
256
|
+
"key is gone — run authflow_signup and replace AUTHFLOW_ADMIN_API_KEY (including in " +
|
|
257
|
+
"~/.cursor/mcp.json), then restart the onboarding MCP."
|
|
258
|
+
: "Send a tenant afa_ key (or the operator Registry:AdminApiKey) as Authorization: Bearer.",
|
|
259
|
+
},
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
if (response.status === 404 && slug) {
|
|
263
|
+
return {
|
|
264
|
+
check: {
|
|
265
|
+
name: "admin API key",
|
|
266
|
+
pass: false,
|
|
267
|
+
detail: `${url} returned 404. The key is valid but this slug is unknown to it.`,
|
|
268
|
+
remedy: "Use authflow_list_resources to recover the slug, or register it.",
|
|
269
|
+
},
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
if (response.status !== 200) {
|
|
273
|
+
return {
|
|
274
|
+
check: {
|
|
275
|
+
name: "admin API key",
|
|
276
|
+
pass: false,
|
|
277
|
+
detail: `${url} returned ${response.status ?? response.error}, expected 200.`,
|
|
278
|
+
remedy: "The rail is up but the admin surface failed. File a rail bug.",
|
|
279
|
+
},
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
// One body, read once: the slug form is a receipt, the list form wraps them in `resources`. The
|
|
283
|
+
// receipt is what tells doctor where the resource really answers.
|
|
284
|
+
let status;
|
|
285
|
+
let receipt;
|
|
286
|
+
let resources;
|
|
287
|
+
try {
|
|
288
|
+
const parsed = JSON.parse(response.body ?? "");
|
|
289
|
+
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
290
|
+
if (slug) {
|
|
291
|
+
receipt = parsed;
|
|
292
|
+
status = receipt.status;
|
|
293
|
+
}
|
|
294
|
+
else if (Array.isArray(parsed.resources)) {
|
|
295
|
+
resources = parsed.resources;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
catch {
|
|
300
|
+
// Not JSON: the check still passes on the 200, and later checks fall back to the slug form.
|
|
301
|
+
}
|
|
302
|
+
return {
|
|
303
|
+
check: {
|
|
304
|
+
name: "admin API key",
|
|
305
|
+
pass: true,
|
|
306
|
+
detail: slug
|
|
307
|
+
? `Admin key can read slug '${slug}' (${status ?? "unknown status"}).`
|
|
308
|
+
: `${url} returned 200.`,
|
|
309
|
+
},
|
|
310
|
+
status,
|
|
311
|
+
receipt,
|
|
312
|
+
resources,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
async function checkProtectedResourceMetadata(base, slug, draft, endpoints) {
|
|
316
|
+
const url = endpoints.prmUrl;
|
|
175
317
|
const response = await fetchOrNull(url);
|
|
318
|
+
// A draft's custom host has no DNS or certificate until its domain is ready, so the fetch fails
|
|
319
|
+
// outright instead of 404ing. That is the expected state of a draft, not a rail outage.
|
|
320
|
+
if (draft && endpoints.publicHost && !response.ok) {
|
|
321
|
+
return [
|
|
322
|
+
{
|
|
323
|
+
name: "protected resource metadata",
|
|
324
|
+
pass: true,
|
|
325
|
+
skipped: true,
|
|
326
|
+
detail: `${url} could not be reached yet (${response.error}). A draft resource's own hostname does ` +
|
|
327
|
+
"not answer until its custom domain is ready.",
|
|
328
|
+
},
|
|
329
|
+
];
|
|
330
|
+
}
|
|
176
331
|
if (response.status === 404) {
|
|
332
|
+
if (draft) {
|
|
333
|
+
return [
|
|
334
|
+
{
|
|
335
|
+
name: "protected resource metadata",
|
|
336
|
+
pass: true,
|
|
337
|
+
skipped: true,
|
|
338
|
+
detail: `${url} returned 404. A draft resource 404s here by design.`,
|
|
339
|
+
},
|
|
340
|
+
];
|
|
341
|
+
}
|
|
177
342
|
return [
|
|
178
343
|
{
|
|
179
344
|
name: "protected resource metadata",
|
|
180
345
|
pass: false,
|
|
181
346
|
detail: `${url} returned 404.`,
|
|
182
|
-
remedy:
|
|
183
|
-
|
|
347
|
+
remedy: endpoints.publicHost
|
|
348
|
+
? `${endpoints.publicHost} is this resource's own hostname and the rail does not recognise it ` +
|
|
349
|
+
`there: its custom domain is not ready, or the edge is not forwarding the host. Run: ` +
|
|
350
|
+
`authflow doctor --host ${endpoints.publicHost}`
|
|
351
|
+
: `No live resource is registered at slug '${slug}'. A draft resource 404s here by design — ` +
|
|
352
|
+
"check its pending_requirements, or pass an admin key so doctor can tell a draft from an " +
|
|
353
|
+
"unknown slug. (A resource registered on its own hostname answers only there; with an " +
|
|
354
|
+
"admin key doctor reads the host from the receipt.)",
|
|
184
355
|
},
|
|
185
356
|
];
|
|
186
357
|
}
|
|
@@ -197,14 +368,18 @@ async function checkProtectedResourceMetadata(base, slug) {
|
|
|
197
368
|
const checks = [
|
|
198
369
|
{ name: "protected resource metadata", pass: true, detail: `${url} returned 200.` },
|
|
199
370
|
];
|
|
200
|
-
checks.push(checkPrmResourceIdentifier(base, url, response.body));
|
|
371
|
+
checks.push(checkPrmResourceIdentifier(base, endpoints, url, response.body));
|
|
201
372
|
return checks;
|
|
202
373
|
}
|
|
203
374
|
/**
|
|
204
|
-
* Tokens are audience-bound to the PRM `resource
|
|
205
|
-
*
|
|
375
|
+
* Tokens are audience-bound to the PRM `resource`, so it has to be the resource the client was told
|
|
376
|
+
* to connect to. With a receipt that is a byte-for-byte comparison against the receipt's `resource`.
|
|
377
|
+
* Without one, or for a resource on the gateway host, it also has to sit on the issuer the client
|
|
378
|
+
* connected to — otherwise /authorize rejects the request as invalid_target, which reads as a rail
|
|
379
|
+
* outage. A resource on its own hostname legitimately differs from the issuer, so that part of the
|
|
380
|
+
* check does not apply to it.
|
|
206
381
|
*/
|
|
207
|
-
function checkPrmResourceIdentifier(base, url, body) {
|
|
382
|
+
function checkPrmResourceIdentifier(base, endpoints, url, body) {
|
|
208
383
|
let resource;
|
|
209
384
|
try {
|
|
210
385
|
const document = JSON.parse(body ?? "");
|
|
@@ -226,25 +401,20 @@ function checkPrmResourceIdentifier(base, url, body) {
|
|
|
226
401
|
remedy: "PRM must name the RFC 8707 resource clients send at /authorize. File a rail bug.",
|
|
227
402
|
};
|
|
228
403
|
}
|
|
229
|
-
|
|
230
|
-
const resourceOrigin = new URL(resource).origin;
|
|
231
|
-
const issuerOrigin = new URL(base).origin;
|
|
232
|
-
if (resourceOrigin === issuerOrigin) {
|
|
233
|
-
return {
|
|
234
|
-
name: "protected resource identifier",
|
|
235
|
-
pass: true,
|
|
236
|
-
detail: `PRM resource is ${resource}.`,
|
|
237
|
-
};
|
|
238
|
-
}
|
|
404
|
+
if (endpoints.resource && resource !== endpoints.resource) {
|
|
239
405
|
return {
|
|
240
406
|
name: "protected resource identifier",
|
|
241
407
|
pass: false,
|
|
242
|
-
detail: `PRM resource is '${resource}', but the
|
|
243
|
-
remedy: "
|
|
244
|
-
"
|
|
245
|
-
"
|
|
408
|
+
detail: `PRM resource is '${resource}', but the receipt says the resource is '${endpoints.resource}'.`,
|
|
409
|
+
remedy: "Tokens are audience-bound to the PRM resource, so a client that connected at the receipt's URL " +
|
|
410
|
+
"is issued a token for a different audience and /authorize rejects it as invalid_target. The " +
|
|
411
|
+
"registry and the document being served disagree: re-run set-domain, or file a rail bug.",
|
|
246
412
|
};
|
|
247
413
|
}
|
|
414
|
+
let parsed;
|
|
415
|
+
try {
|
|
416
|
+
parsed = new URL(resource);
|
|
417
|
+
}
|
|
248
418
|
catch {
|
|
249
419
|
return {
|
|
250
420
|
name: "protected resource identifier",
|
|
@@ -253,23 +423,74 @@ function checkPrmResourceIdentifier(base, url, body) {
|
|
|
253
423
|
remedy: "File this against the rail.",
|
|
254
424
|
};
|
|
255
425
|
}
|
|
426
|
+
if (endpoints.publicHost) {
|
|
427
|
+
if (parsed.host !== endpoints.publicHost) {
|
|
428
|
+
return {
|
|
429
|
+
name: "protected resource identifier",
|
|
430
|
+
pass: false,
|
|
431
|
+
detail: `PRM resource is '${resource}', but the resource is registered on ${endpoints.publicHost}.`,
|
|
432
|
+
remedy: "A resource on its own hostname must name that hostname, or clients are issued tokens for the " +
|
|
433
|
+
"wrong audience. Re-run set-domain, or file a rail bug.",
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
return {
|
|
437
|
+
name: "protected resource identifier",
|
|
438
|
+
pass: true,
|
|
439
|
+
detail: `PRM resource is ${resource}${endpoints.resource ? ", matching the receipt" : ""}.`,
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
if (parsed.origin === urlOrigin(base)) {
|
|
443
|
+
return {
|
|
444
|
+
name: "protected resource identifier",
|
|
445
|
+
pass: true,
|
|
446
|
+
detail: `PRM resource is ${resource}${endpoints.resource ? ", matching the receipt" : ""}.`,
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
return {
|
|
450
|
+
name: "protected resource identifier",
|
|
451
|
+
pass: false,
|
|
452
|
+
detail: `PRM resource is '${resource}', but the issuer is '${base}'.`,
|
|
453
|
+
remedy: "Audience-bound tokens will not match a client that connected at the issuer host, and " +
|
|
454
|
+
"/authorize with the issuer-shaped resource fails as invalid_target. Register the " +
|
|
455
|
+
"resource URI clients actually connect to, or point doctor at the hostname in the PRM.",
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
function urlOrigin(value) {
|
|
459
|
+
try {
|
|
460
|
+
return new URL(value).origin;
|
|
461
|
+
}
|
|
462
|
+
catch {
|
|
463
|
+
return undefined;
|
|
464
|
+
}
|
|
256
465
|
}
|
|
257
466
|
/**
|
|
258
467
|
* The paywall is a transport-level 401 carrying `resource_metadata`. If this is not exactly right,
|
|
259
468
|
* MCP clients never prompt for auth, which presents as "the server just does not work in Claude".
|
|
469
|
+
*
|
|
470
|
+
* `target` is where the resource actually answers (from the receipt). Without it the slug URL on
|
|
471
|
+
* the issuer is assumed, which is only true for a resource on the gateway host.
|
|
260
472
|
*/
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
473
|
+
export async function checkGatewayChallenge(base, slug, draft = false, target) {
|
|
474
|
+
const url = target?.url ?? slugEndpoints(base, slug).gatewayUrl;
|
|
475
|
+
const response = await fetchOrNull(url, unauthenticatedInitialize());
|
|
476
|
+
if (draft && target?.publicHost && !response.ok) {
|
|
477
|
+
return {
|
|
478
|
+
name: "gateway 401 challenge",
|
|
479
|
+
pass: true,
|
|
480
|
+
skipped: true,
|
|
481
|
+
detail: `Unauthenticated POST ${url} could not be reached yet (${response.error}). A draft resource's ` +
|
|
482
|
+
"own hostname does not answer until its custom domain is ready.",
|
|
483
|
+
};
|
|
484
|
+
}
|
|
272
485
|
if (response.status !== 401) {
|
|
486
|
+
if (response.status === 404 && draft) {
|
|
487
|
+
return {
|
|
488
|
+
name: "gateway 401 challenge",
|
|
489
|
+
pass: true,
|
|
490
|
+
skipped: true,
|
|
491
|
+
detail: `Unauthenticated POST ${url} returned 404. A draft resource 404s here by design.`,
|
|
492
|
+
};
|
|
493
|
+
}
|
|
273
494
|
return {
|
|
274
495
|
name: "gateway 401 challenge",
|
|
275
496
|
pass: false,
|
|
@@ -294,27 +515,14 @@ export async function checkGatewayChallenge(base, slug) {
|
|
|
294
515
|
detail: "401 with a resource_metadata challenge.",
|
|
295
516
|
};
|
|
296
517
|
}
|
|
297
|
-
/** Network failures are a diagnosis here, not an exception — every one of them is a real finding. */
|
|
298
|
-
export async function fetchOrNull(url, init = {}) {
|
|
299
|
-
try {
|
|
300
|
-
const response = await fetch(url, { ...init, signal: AbortSignal.timeout(timeoutMs) });
|
|
301
|
-
return {
|
|
302
|
-
ok: true,
|
|
303
|
-
status: response.status,
|
|
304
|
-
body: await response.text(),
|
|
305
|
-
headers: response.headers,
|
|
306
|
-
location: response.headers.get("location") ?? undefined,
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
catch (err) {
|
|
310
|
-
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
518
|
export function formatDoctorReport(report) {
|
|
314
519
|
const lines = [`issuer: ${report.issuer}`];
|
|
315
520
|
if (report.slug) {
|
|
316
521
|
lines.push(`slug: ${report.slug}`);
|
|
317
522
|
}
|
|
523
|
+
if (report.host) {
|
|
524
|
+
lines.push(`host: ${report.host}`);
|
|
525
|
+
}
|
|
318
526
|
if (report.clients && report.clients.length > 0) {
|
|
319
527
|
lines.push(`client: ${report.clients.join(", ")}`);
|
|
320
528
|
}
|
|
@@ -323,14 +531,20 @@ export function formatDoctorReport(report) {
|
|
|
323
531
|
}
|
|
324
532
|
lines.push("");
|
|
325
533
|
for (const check of report.checks) {
|
|
326
|
-
|
|
534
|
+
const mark = check.skipped ? "SKIP" : check.pass ? "PASS" : "FAIL";
|
|
535
|
+
lines.push(`${mark} ${check.name}`);
|
|
327
536
|
lines.push(` ${check.detail}`);
|
|
328
537
|
if (!check.pass && check.remedy) {
|
|
329
538
|
lines.push(` -> ${check.remedy}`);
|
|
330
539
|
}
|
|
331
540
|
}
|
|
332
541
|
lines.push("");
|
|
333
|
-
|
|
542
|
+
if (report.pass && report.draft) {
|
|
543
|
+
lines.push("Overall: PASS (draft)");
|
|
544
|
+
}
|
|
545
|
+
else {
|
|
546
|
+
lines.push(report.pass ? "Overall: PASS" : "Overall: FAIL");
|
|
547
|
+
}
|
|
334
548
|
if (report.checks.some((c) => !c.pass && c.detail.startsWith("DCR 400:"))) {
|
|
335
549
|
lines.push("");
|
|
336
550
|
lines.push("A DCR 400 is the interesting result. Paste error= and error_description= verbatim into a " +
|
package/dist/doctor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,8 +23,12 @@ export declare function expectedGoogleCallbackUri(issuer: string): string;
|
|
|
23
23
|
export declare function checkGoogleRedirectUri(issuer: string, options?: {
|
|
24
24
|
slug?: string;
|
|
25
25
|
dryRun?: boolean;
|
|
26
|
+
/** The resource's PRM URL from its receipt; the issuer-plus-slug form when absent. */
|
|
27
|
+
prmUrl?: string;
|
|
28
|
+
}): Promise<DoctorCheck[]>;
|
|
29
|
+
export declare function probeGoogleRedirectUri(issuer: string, slug: string, options?: {
|
|
30
|
+
prmUrl?: string;
|
|
26
31
|
}): Promise<DoctorCheck[]>;
|
|
27
|
-
export declare function probeGoogleRedirectUri(issuer: string, slug: string): Promise<DoctorCheck[]>;
|
|
28
32
|
/** OAuth error code, not UI copy — present in the URL even when the HTML is localized. */
|
|
29
33
|
export declare function googleRedirectUriRejected(location?: string, body?: string): boolean;
|
|
30
34
|
export declare function googleRedirectUriAccepted(location?: string): boolean;
|
package/dist/google-redirect.js
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
import { createHash, randomBytes } from "node:crypto";
|
|
20
20
|
import { cursorCanonicalDcr, dcrProbeClientNamePrefix } from "./client-fixtures.js";
|
|
21
21
|
import { fetchOrNull } from "./doctor.js";
|
|
22
|
+
import { slugEndpoints } from "./resource-urls.js";
|
|
22
23
|
/** ASP.NET Google handler default CallbackPath; the rail does not override it. */
|
|
23
24
|
export const googleCallbackPath = "/signin-google";
|
|
24
25
|
const googleHost = "accounts.google.com";
|
|
@@ -43,12 +44,12 @@ export async function checkGoogleRedirectUri(issuer, options = {}) {
|
|
|
43
44
|
},
|
|
44
45
|
];
|
|
45
46
|
}
|
|
46
|
-
return probeGoogleRedirectUri(issuer, options.slug);
|
|
47
|
+
return probeGoogleRedirectUri(issuer, options.slug, { prmUrl: options.prmUrl });
|
|
47
48
|
}
|
|
48
|
-
export async function probeGoogleRedirectUri(issuer, slug) {
|
|
49
|
+
export async function probeGoogleRedirectUri(issuer, slug, options = {}) {
|
|
49
50
|
const base = issuer.trim().replace(/\/+$/, "");
|
|
50
51
|
const expected = expectedGoogleCallbackUri(base);
|
|
51
|
-
const resource = await fetchResourceIdentifier(base, slug);
|
|
52
|
+
const resource = await fetchResourceIdentifier(base, slug, options.prmUrl);
|
|
52
53
|
if (!resource.ok) {
|
|
53
54
|
return [resource.check];
|
|
54
55
|
}
|
|
@@ -90,8 +91,13 @@ export async function probeGoogleRedirectUri(issuer, slug) {
|
|
|
90
91
|
const registered = await askGoogle(challenge.googleUrl, emitted);
|
|
91
92
|
return [callback, registered];
|
|
92
93
|
}
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
/**
|
|
95
|
+
* The resource identifier clients send at /authorize is whatever the resource's PRM says. A resource
|
|
96
|
+
* on its own hostname publishes that document there, not on the issuer, so the caller passes the
|
|
97
|
+
* receipt's PRM URL; the slug form is only right for a resource on the gateway host.
|
|
98
|
+
*/
|
|
99
|
+
async function fetchResourceIdentifier(base, slug, prmUrl) {
|
|
100
|
+
const url = prmUrl ?? slugEndpoints(base, slug).prmUrl;
|
|
95
101
|
const response = await fetchOrNull(url);
|
|
96
102
|
if (response.status !== 200) {
|
|
97
103
|
return {
|