tangled
alpha
login
or
join now
dunkirk.sh
/
indiko
6
fork
atom
my own indieAuth provider!
indiko.dunkirk.sh/docs
indieauth
oauth2-server
6
fork
atom
overview
issues
pulls
pipelines
chore: fix client id validation
dunkirk.sh
2 months ago
ad135326
87c0d960
verified
This commit was signed with the committer's
known signature
.
dunkirk.sh
SSH Key Fingerprint:
SHA256:DqcG0RXYExE26KiWo3VxJnsxswN1QNfTBvB+bdSpk80=
+33
-12
1 changed file
expand all
collapse all
unified
split
src
routes
indieauth.ts
+33
-12
src/routes/indieauth.ts
···
110
110
return hash === challenge;
111
111
}
112
112
113
113
-
// Canonicalize URL per IndieAuth spec
113
113
+
// Canonicalize URL per IndieAuth spec (only for actual URLs, not internal IDs)
114
114
function canonicalizeURL(urlString: string): string {
115
115
+
// Only canonicalize if it looks like a URL
116
116
+
if (!urlString.startsWith("http://") && !urlString.startsWith("https://")) {
117
117
+
return urlString;
118
118
+
}
115
119
const url = new URL(urlString);
116
120
// Lowercase hostname per spec
117
121
url.hostname = url.hostname.toLowerCase();
···
584
588
return new Response("Missing required parameters", { status: 400 });
585
589
}
586
590
587
587
-
// Canonicalize URLs for consistent storage and comparison
588
588
-
const clientId = canonicalizeURL(rawClientId);
589
589
-
const redirectUri = canonicalizeURL(rawRedirectUri);
590
590
-
591
591
-
// Validate redirect_uri is a valid URL
591
591
+
// Validate and canonicalize URLs for consistent storage and comparison
592
592
+
let clientId: string;
593
593
+
let redirectUri: string;
592
594
try {
593
593
-
new URL(redirectUri);
595
595
+
clientId = canonicalizeURL(rawClientId);
596
596
+
redirectUri = canonicalizeURL(rawRedirectUri);
594
597
} catch {
595
598
return new Response(
596
599
`<!DOCTYPE html>
···
672
675
</p>
673
676
<div class="error-details">
674
677
<strong>Provided redirect_uri:</strong>
675
675
-
<code>${redirectUri}</code>
678
678
+
<code>${rawRedirectUri}</code>
676
679
</div>
677
680
<p style="margin-top: 1.5rem; font-size: 0.875rem; color: var(--old-rose);">
678
681
The redirect URI must be a valid, absolute URL (e.g., https://example.com/callback).
···
1364
1367
}
1365
1368
1366
1369
// Canonicalize URLs for consistent storage and comparison
1367
1367
-
const clientId = canonicalizeURL(rawClientId);
1368
1368
-
const redirectUri = canonicalizeURL(rawRedirectUri);
1370
1370
+
let clientId: string;
1371
1371
+
let redirectUri: string;
1372
1372
+
try {
1373
1373
+
clientId = canonicalizeURL(rawClientId);
1374
1374
+
redirectUri = canonicalizeURL(rawRedirectUri);
1375
1375
+
} catch {
1376
1376
+
return new Response("Invalid client_id or redirect_uri URL format", { status: 400 });
1377
1377
+
}
1369
1378
1370
1379
if (action === "deny") {
1371
1380
return Response.redirect(
···
1474
1483
} = body;
1475
1484
1476
1485
// Canonicalize URLs for consistent comparison with stored values
1477
1477
-
const client_id = raw_client_id ? canonicalizeURL(raw_client_id) : undefined;
1478
1478
-
const redirect_uri = raw_redirect_uri ? canonicalizeURL(raw_redirect_uri) : undefined;
1486
1486
+
let client_id: string | undefined;
1487
1487
+
let redirect_uri: string | undefined;
1488
1488
+
try {
1489
1489
+
client_id = raw_client_id ? canonicalizeURL(raw_client_id) : undefined;
1490
1490
+
redirect_uri = raw_redirect_uri ? canonicalizeURL(raw_redirect_uri) : undefined;
1491
1491
+
} catch {
1492
1492
+
return Response.json(
1493
1493
+
{
1494
1494
+
error: "invalid_request",
1495
1495
+
error_description: "Invalid client_id or redirect_uri URL format",
1496
1496
+
},
1497
1497
+
{ status: 400 },
1498
1498
+
);
1499
1499
+
}
1479
1500
1480
1501
if (grant_type !== "authorization_code" && grant_type !== "refresh_token") {
1481
1502
return Response.json(