fix(console): accept localhost redirect URIs without path nor port (#11001)

<!--
Please inform yourself about the contribution guidelines on submitting a
PR here:
https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md#submit-a-pull-request-pr.
Take note of how PR/commit titles should be written and replace the
template texts in the sections below. Don't remove any of the sections.
It is important that the commit history clearly shows what is changed
and why.
Important: By submitting a contribution you agree to the terms from our
Licensing Policy as described here:
https://github.com/zitadel/zitadel/blob/main/LICENSING.md#community-contributions.
-->

# Which Problems Are Solved

Some native OIDC applications use localhost without a path as redirect
URI. Currently, setting http://localhost as a redirect URI leads to a
compliance warning (Redirect URIs must begin with your own protocol,
http://127.0.0.1, http://[::1] or http://localhost.), while
http://localhost/some/path and http://localhost:some-port are accepted).

# How the Problems Are Solved

This PR parses the redirect URI instead of using prefix check to test if
hostname part is localhost, 127.0.0.1 or [::1] (IPv6 addresses are
canonicalized during parsing).

# Additional Context

This PR is a follow-up of https://github.com/zitadel/zitadel/pull/10836.

Signed-off-by: Yann Soubeyrand <[email protected]>
Co-authored-by: Ramon <[email protected]>
This commit is contained in:
Yann Soubeyrand
2025-12-30 10:53:04 +01:00
committed by GitHub
co-authored by Ramon
parent 740669a4bd
commit 4489ffb82e
@@ -6,32 +6,17 @@ import { Pipe, PipeTransform } from '@angular/core';
})
export class RedirectPipe implements PipeTransform {
public transform(uri: string, isNative: boolean): boolean {
if (isNative) {
if (
uri.startsWith('http://localhost/') ||
uri.startsWith('http://localhost:') ||
uri.startsWith('http://127.0.0.1') ||
uri.startsWith('http://[::1]') ||
uri.startsWith('http://[0:0:0:0:0:0:0:1]') ||
uri.startsWith('https://localhost/') ||
uri.startsWith('https://localhost:') ||
uri.startsWith('https://127.0.0.1') ||
uri.startsWith('https://[::1]') ||
uri.startsWith('https://[0:0:0:0:0:0:0:1]')
) {
return true;
}
if (!uri.startsWith('https://') && !uri.startsWith('http://')) {
return true;
} else {
return false;
}
} else {
if (uri.startsWith('https://')) {
return true;
} else {
return false;
}
const parsedURI = URL.parse(uri);
if (parsedURI === null) {
return false;
}
if (!isNative) {
return parsedURI.protocol === 'https:';
}
if (parsedURI.protocol !== 'http:' && parsedURI.protocol !== 'https:') {
return true;
}
const hostname = parsedURI.hostname;
return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '[::1]';
}
}