diff --git a/frontend/src/lib/hooks/redirect-uri.ts b/frontend/src/lib/hooks/redirect-uri.ts index 99b14f07..305673b5 100644 --- a/frontend/src/lib/hooks/redirect-uri.ts +++ b/frontend/src/lib/hooks/redirect-uri.ts @@ -9,6 +9,7 @@ type IuseRedirectUri = { export const useRedirectUri = ( redirect_uri: string | undefined, cookieDomain: string, + appUrl: string, subdomainsEnabled: boolean, ): IuseRedirectUri => { let isValid = false; @@ -16,6 +17,19 @@ export const useRedirectUri = ( let isAllowedProto = false; let isHttpsDowngrade = false; + let appUrlObj: URL; + + try { + appUrlObj = new URL(appUrl); + } catch { + return { + valid: isValid, + trusted: isTrusted, + allowedProto: isAllowedProto, + httpsDowngrade: isHttpsDowngrade, + }; + } + if (!redirect_uri) { return { valid: isValid, @@ -40,11 +54,7 @@ export const useRedirectUri = ( isValid = true; - if (url.hostname == cookieDomain) { - isTrusted = true; - } - - if (subdomainsEnabled && url.hostname.endsWith("." + cookieDomain)) { + if (isTrustedDomain(url, appUrlObj, cookieDomain, subdomainsEnabled)) { isTrusted = true; } @@ -64,3 +74,45 @@ export const useRedirectUri = ( httpsDowngrade: isHttpsDowngrade, }; }; + +// ported from internal/controller/oauth_controller.go +const getEffectivePort = (url: URL): string => { + if (url.port) { + return url.port; + } + + if (url.protocol == "https:") { + return "443"; + } + + return "80"; +}; + +const isTrustedDomain = ( + url: URL, + appUrl: URL, + cookieDomain: string, + subdomainsEnabled: boolean, +): boolean => { + if (url.protocol != appUrl.protocol) { + return false; + } + + if (getEffectivePort(url) != getEffectivePort(appUrl)) { + return false; + } + + if (url.hostname == appUrl.hostname) { + return true; + } + + if (!subdomainsEnabled) { + return false; + } + + if (url.hostname.endsWith("." + cookieDomain.toLowerCase())) { + return true; + } + + return false; +}; diff --git a/frontend/src/pages/continue-page.tsx b/frontend/src/pages/continue-page.tsx index e63bb7e0..a4e34fc5 100644 --- a/frontend/src/pages/continue-page.tsx +++ b/frontend/src/pages/continue-page.tsx @@ -37,6 +37,7 @@ export const ContinuePage = () => { const { url, valid, trusted, allowedProto, httpsDowngrade } = useRedirectUri( redirectUri, app.cookieDomain, + app.appUrl, app.subdomainsEnabled, );