@anchrd/intel-api 0.16.0 → 0.16.1
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/adapters/openid/openid.js +21 -3
- package/dist/intel/intel.js +10 -1
- package/package.json +1 -1
|
@@ -162,9 +162,20 @@ export function createOpenId(deps) {
|
|
|
162
162
|
// one with a 404, which surfaced as a bare 500 on /auth/connect (#93). The fallback repeats the
|
|
163
163
|
// operation once with the OAuth document; when both fail, the second error is thrown because it
|
|
164
164
|
// belongs to the attempt that got further for the issuer that needed the fallback at all.
|
|
165
|
-
async function withAlgorithmFallback(run) {
|
|
165
|
+
async function withAlgorithmFallback(run, usable = () => true) {
|
|
166
166
|
try {
|
|
167
|
-
|
|
167
|
+
const first = await run();
|
|
168
|
+
// ⚠️ A THROW is not the only way the OIDC document can be the wrong one (#425). Cloudflare
|
|
169
|
+
// Access answers `/.well-known/openid-configuration` with **200** and a two-field stub —
|
|
170
|
+
// `issuer` and `jwks_uri`, nothing else — while the endpoints live only under RFC 8414's
|
|
171
|
+
// `oauth-authorization-server`. Discovery therefore SUCCEEDS, the fallback never runs, and
|
|
172
|
+
// the missing endpoint surfaces minutes later inside `buildAuthorizationUrl` as
|
|
173
|
+
// `authorization server metadata does not contain a valid "as.authorization_endpoint"` — a
|
|
174
|
+
// 500 on `/auth/connect` with nothing in it pointing at discovery.
|
|
175
|
+
//
|
|
176
|
+
// So the question is not "did it fail" but "is what came back usable". An answer that parses
|
|
177
|
+
// and carries nothing is the same situation as a 404, and it gets the same second attempt.
|
|
178
|
+
return usable(first) ? first : await run("oauth2");
|
|
168
179
|
}
|
|
169
180
|
catch {
|
|
170
181
|
return await run("oauth2");
|
|
@@ -174,7 +185,14 @@ export function createOpenId(deps) {
|
|
|
174
185
|
const key = `${issuer}#${clientId}`;
|
|
175
186
|
let configuration = configurations.get(key);
|
|
176
187
|
if (!configuration) {
|
|
177
|
-
configuration = withAlgorithmFallback((algorithm) => client.discovery(new URL(issuer), clientId, { token_endpoint_auth_method: "none" }, client.None(), { ...options(issuer), ...(algorithm ? { algorithm } : {}) })
|
|
188
|
+
configuration = withAlgorithmFallback((algorithm) => client.discovery(new URL(issuer), clientId, { token_endpoint_auth_method: "none" }, client.None(), { ...options(issuer), ...(algorithm ? { algorithm } : {}) }),
|
|
189
|
+
// The two endpoints every flow here needs. Asking for exactly them rather than for a long
|
|
190
|
+
// list keeps the check honest: a server that publishes these two is usable, and one that
|
|
191
|
+
// publishes neither is the stub case above, whatever else it carries.
|
|
192
|
+
(resolved) => {
|
|
193
|
+
const metadata = resolved.serverMetadata();
|
|
194
|
+
return Boolean(metadata.authorization_endpoint && metadata.token_endpoint);
|
|
195
|
+
});
|
|
178
196
|
configurations.set(key, configuration);
|
|
179
197
|
void configuration.catch(() => configurations.delete(key));
|
|
180
198
|
}
|
package/dist/intel/intel.js
CHANGED
|
@@ -60,7 +60,16 @@ export function createIntel(deps) {
|
|
|
60
60
|
if (error instanceof IntelError) {
|
|
61
61
|
return context.redirect(`/tools?connectError=${encodeURIComponent(error.code)}`);
|
|
62
62
|
}
|
|
63
|
-
|
|
63
|
+
// ⚠️ Everything else used to be rethrown, and the outer handler turned it into a bare 500
|
|
64
|
+
// with a generic body (#425). For an API that is the right answer; for a route a BROWSER is
|
|
65
|
+
// sent to it is a dead end — the reader gets JSON instead of a screen, and the Tools page
|
|
66
|
+
// never learns that the attempt happened at all, so it says "no access" about a sign-in
|
|
67
|
+
// that crashed.
|
|
68
|
+
//
|
|
69
|
+
// The trace still goes to the log, which is the operator's channel; what changes is that
|
|
70
|
+
// the reader is returned to a screen that can say "this broke" instead of "you may not".
|
|
71
|
+
reportUnexpectedError(error);
|
|
72
|
+
return context.redirect("/tools?connectError=portal_sign_in_failed");
|
|
64
73
|
}
|
|
65
74
|
});
|
|
66
75
|
app.get("/auth/callback", async (context) => await browserAuth.callback(new URL(context.req.url), context.req.raw.headers));
|