fix(endpoint-auth): accept authorization requests without response_type - #884
fix(endpoint-auth): accept authorization requests without response_type#884rmdes wants to merge 2 commits into
response_type#884Conversation
|
Confirmed against a live Indiekit deployment: signing in through indieauth.com Being precise about what that evidences, since the deployment runs a fork: the Worth noting the two fixes are sequential. This one lets the authorization |
dc99992 to
aa13053
Compare
|
I’m not opposed to this change, ultimately it feels like better UX and a more robust approach. I just want to check, is this behaviour compatible with the IndieAuth spec do you think? |
|
Honest answer: no, not strictly. The spec requires The trade-off is narrower than it looks, and it's time-limited. indielogin.com — the replacement — doesn't need this change. Its authorization request is built by The only client that needs this is indieauth.com, which now carries a deprecation notice pointing at indielogin.com. Its request is built at So: accepting a non-conforming request, to support a service being retired, which the thing replacing it doesn't need. It's still serving today and people still sign in with it — I hit this myself — but the value has an end date, and if you'd rather not carry the leniency for that, closing this is reasonable. If it does go in, one detail worth your view: the default is |
|
Perhaps the pragmatic and most explicit approach then is to only allow this behaviour for indieauth.com. That would mean Indiekit is spec-compliant, while providing support for a deprecated yet still widely-used service. If this exception is commented and easily deletable, even better! |
6ac8cde to
a6a1aa5
Compare
|
@paulrobertlloyd Done both ways round — scoped to indieauth.com, and the exception is a single commented block.
// Deprecated exception, delete this block and restore
// `request.query.response_type` below: indieauth.com omits `response_type`,
// the pre-specification form of an authentication-only request (`id`). Its
// replacement, indielogin.com, sends `response_type=code` and needs none of
// this. `client_id` is not yet known to be a URL, so it is checked before
// being compared.
const clientId = String(request.query.client_id);
const isDeprecatedClient =
URL.canParse(clientId) && isSameOrigin(clientId, "https://indieauth.com");
const responseType =
request.query.response_type ?? (isDeprecatedClient ? "id" : undefined);Deleting that block and putting
One implementation detail worth your eye: the value is threaded through as a local rather than written back to Tests cover both sides — a request from any other client still reports the missing parameter, one from indieauth.com reaches the consent form. CI here fails at Download localisations before it installs anything: this branch is on my fork, so |
Signing in through indieauth.com, which is how the IndieWeb wiki authenticates people, failed against an Indiekit authorization endpoint with "Missing parameter: response_type". The controller required response_type to be present, then separately accepted either code or the deprecated id. That combination is inconsistent: id means authenticate only, and clients of that era commonly omit the parameter entirely, which is the older form of the same thing. indieauth.com sends the omitted form, alongside the empty scope that §5.2 describes as the case where only the user's profile URL is returned. A missing value is now treated as id. Nothing downstream branches on it — whether an access token is issued depends on the requested scope — and an unrecognised value is still rejected. This changes behaviour that 200-authorization-no-response-type.js asserted deliberately, so that test is rewritten to assert the request is accepted and renamed for the status it now expects. Fixes getindiekit#883
A request without `response_type` is rejected again, as the specification requires, except when `client_id` is indieauth.com — the one widely-used client that omits it, and one carrying a deprecation notice pointing at indielogin.com, which sends a conforming request. The exception is a single commented block. Deleting it and restoring `request.query.response_type` in the two places below returns the endpoint to strict behaviour. The value is threaded as a local rather than written back to `request.query`: the application sets Express's query parser to `simple`, which re-parses on every access, so an assignment there is discarded before it can be read. Tests cover both sides of the exception: a request from any other client still reports the missing parameter, one from indieauth.com redirects to the consent form.
a6a1aa5 to
838f20c
Compare
|
CI can't run on these — the branches are on my fork, so the Localazy step has no
The one skipped test ( The order these want reading in, which the titles don't convey:
#891 and #893 both touch |

Fixes #883.
Problem
authorization.jsrequiresresponse_typeto be present, then separately accepts eithercodeor the deprecatedid. That combination is inconsistent:idmeans "authenticate only, don't issue a token", and clients of that era commonly omit the parameter entirely, which is the older form of the same thing.indieauth.com sends the omitted form, together with an empty
scope:That empty scope is exactly the case §5.2 describes:
So an Indiekit authorization endpoint rejects an authentication-only request from the reference implementation, and anyone using Indiekit for IndieAuth cannot sign in through indieauth.com.
Fix
A missing
response_typeis treated asid:Nothing downstream branches on the value — whether an access token is issued depends on the requested scope — and an unrecognised value such as
tokenis still rejected.This changes behaviour you tested on purpose
200-authorization-no-response-type.jsasserted that a missingresponse_typeproducesMissing parameter: response_type, so this was a deliberate strictness rather than an oversight. I've rewritten that test to assert the request is accepted and renamed it302-…for the status it now expects — but if the strictness was intentional and you'd rather keep it, this should be closed rather than merged, and the incompatibility is worth documenting instead.My reasoning for preferring compatibility: the endpoint already honours
idwhen sent explicitly, so accepting its absence is consistent rather than newly permissive, and the practical cost of strictness is being locked out of the wiki.Testing
endpoint-auth;eslintandprettierclean.scopeincluded, and asserts the redirect to consent.Update: the client this affects is deprecated
indieauth.com now carries a deprecation notice — the service is being retired in favour of indielogin.com.
The replacement does not need this fix. When it delegates to a user's own IndieAuth server it sends the parameters:
response_type=codeis set byindieauth-client-php(src/IndieAuth/Client.php:435), andgrant_type=authorization_codetogether withcode_verifieratapp/Provider/IndieAuth.php:73.So this is compatibility with a service on its way out, and worth weighing on that basis. Against that: indieauth.com is still serving, and people still sign in through it — confirmed against a live Indiekit deployment today — so the breakage is real until the shutdown happens.
I also wrote above that indieauth.com is what the IndieWeb wiki authenticates with. I went to verify that and could not: I found no reference to either service on indieweb.org's login or front page. I should not have asserted it, so treat that claim as withdrawn — it does not affect the rest, which is about what indieauth.com sends.