From 8fb7d2259127c835b1e6c74affdfea52c6b8db28 Mon Sep 17 00:00:00 2001 From: GandC Date: Wed, 16 Sep 2026 21:50:25 +0300 Subject: [PATCH] fix sso login failure --- .gitea/workflows/desktop.yml | 241 ++++++++++++++++++++++++++++++----- 1 file changed, 210 insertions(+), 31 deletions(-) diff --git a/.gitea/workflows/desktop.yml b/.gitea/workflows/desktop.yml index 04d643c..948b408 100644 --- a/.gitea/workflows/desktop.yml +++ b/.gitea/workflows/desktop.yml @@ -68,41 +68,17 @@ jobs: node --version pnpm --version - - name: Setup Rust - shell: bash + shell: powershell run: | - set -euxo pipefail + $ErrorActionPreference = "Stop" - RUST_VERSION="1.98.1" - - rm -f /tmp/rustup-init - - curl \ - --fail \ - --location \ - --retry 5 \ - --retry-delay 3 \ - --retry-all-errors \ - --connect-timeout 20 \ - https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init \ - -o /tmp/rustup-init - - chmod +x /tmp/rustup-init - - /tmp/rustup-init \ - -y \ - --profile minimal \ - --default-toolchain "${RUST_VERSION}" \ - --default-host x86_64-unknown-linux-gnu \ - --no-modify-path - - echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" - - "$HOME/.cargo/bin/rustc" --version - "$HOME/.cargo/bin/cargo" --version - "$HOME/.cargo/bin/rustup" --version + rustup update stable + rustup default stable + rustup target add x86_64-pc-windows-msvc + rustc --version + cargo --version - name: Show build tools shell: powershell @@ -174,6 +150,101 @@ jobs: throw "CANARY_APP_URL was not configured" } + $WindowPath = "fluxer-src\fluxer_desktop\src\main\Window.ts" + + if (-not (Test-Path $WindowPath)) { + throw "Window.ts not found at $WindowPath" + } + + $WindowContent = Get-Content $WindowPath -Raw + + $NavigationPattern = "webContents\.on\('will-navigate', \(event, url\) => \{\r?\n\s*if \(!isTrustedOrigin\(url\)\) \{\r?\n\s*event\.preventDefault\(\);\r?\n\s*\}\r?\n\s*\}\);" + + $NavigationReplacementLines = @( + "let externalSsoNavigationActive = false;" + "" + "`twebContents.on('will-navigate', (event, url) => {" + "`t`tif (isTrustedOrigin(url)) {" + "`t`t`tif (externalSsoNavigationActive) {" + "`t`t`t`tlogger.info('SSO navigation returned to trusted origin', {url});" + "`t`t`t}" + "`t`t`texternalSsoNavigationActive = false;" + "`t`t`treturn;" + "`t`t}" + "" + "`t`ttry {" + "`t`t`tconst target = new URL(url);" + "" + "`t`t`tif (externalSsoNavigationActive) {" + "`t`t`t`tif (target.protocol === 'https:' || target.protocol === 'http:') {" + "`t`t`t`t`tlogger.info('Allowing active SSO navigation', {" + "`t`t`t`t`t`torigin: target.origin," + "`t`t`t`t`t});" + "`t`t`t`t`treturn;" + "`t`t`t`t}" + "" + "`t`t`t`tlogger.warn('Blocked non-HTTP navigation during SSO', {" + "`t`t`t`t`turl," + "`t`t`t`t});" + "`t`t`t`tevent.preventDefault();" + "`t`t`t`treturn;" + "`t`t`t}" + "" + "`t`t`tconst isKeycloakAuthorization =" + "`t`t`t`ttarget.protocol === 'https:' &&" + "`t`t`t`ttarget.pathname.includes('/protocol/openid-connect/auth') &&" + "`t`t`t`ttarget.searchParams.has('client_id') &&" + "`t`t`t`ttarget.searchParams.has('redirect_uri') &&" + "`t`t`t`ttarget.searchParams.has('state');" + "" + "`t`t`tif (" + "`t`t`t`tisKeycloakAuthorization &&" + "`t`t`t`tisTrustedOrigin(webContents.getURL())" + "`t`t`t) {" + "`t`t`t`texternalSsoNavigationActive = true;" + "" + "`t`t`t`tlogger.info('Allowing Keycloak SSO navigation', {" + "`t`t`t`t`torigin: target.origin," + "`t`t`t`t});" + "" + "`t`t`t`treturn;" + "`t`t`t}" + "`t`t} catch (error) {" + "`t`t`tlogger.warn('Failed to parse navigation URL', {" + "`t`t`t`turl," + "`t`t`t`terror," + "`t`t`t});" + "`t`t}" + "" + "`t`tevent.preventDefault();" + "`t});" + ) + + $NavigationReplacement = $NavigationReplacementLines -join "`n" + + $PatchedWindowContent = [regex]::Replace( + $WindowContent, + $NavigationPattern, + $NavigationReplacement, + 1 + ) + + if ($PatchedWindowContent -eq $WindowContent) { + throw "Unable to patch Window.ts SSO navigation handler" + } + + Set-Content ` + -Path $WindowPath ` + -Value $PatchedWindowContent ` + -NoNewline ` + -Encoding utf8 + + Write-Host "SSO navigation patch applied" + + Select-String ` + -Path $WindowPath ` + -Pattern "externalSsoNavigationActive|Allowing Keycloak SSO navigation" + - name: Install dependencies shell: powershell @@ -586,6 +657,114 @@ jobs: print(result) PY + python3 <<'PY' + from pathlib import Path + import re + + path = Path( + "fluxer-src/fluxer_desktop/src/main/Window.ts" + ) + + if not path.is_file(): + raise SystemExit( + f"Window.ts not found: {path}" + ) + + data = path.read_text( + encoding="utf-8" + ) + + pattern = re.compile( + r"webContents\.on\('will-navigate', \(event, url\) => \{\s*" + r"if \(!isTrustedOrigin\(url\)\) \{\s*" + r"event\.preventDefault\(\);\s*" + r"\}\s*" + r"\}\);" + ) + + replacement = "\n".join([ + "let externalSsoNavigationActive = false;", + "", + "\twebContents.on('will-navigate', (event, url) => {", + "\t\tif (isTrustedOrigin(url)) {", + "\t\t\tif (externalSsoNavigationActive) {", + "\t\t\t\tlogger.info('SSO navigation returned to trusted origin', {url});", + "\t\t\t}", + "\t\t\texternalSsoNavigationActive = false;", + "\t\t\treturn;", + "\t\t}", + "", + "\t\ttry {", + "\t\t\tconst target = new URL(url);", + "", + "\t\t\tif (externalSsoNavigationActive) {", + "\t\t\t\tif (target.protocol === 'https:' || target.protocol === 'http:') {", + "\t\t\t\t\tlogger.info('Allowing active SSO navigation', {", + "\t\t\t\t\t\torigin: target.origin,", + "\t\t\t\t\t});", + "\t\t\t\t\treturn;", + "\t\t\t\t}", + "", + "\t\t\t\tlogger.warn('Blocked non-HTTP navigation during SSO', {", + "\t\t\t\t\turl,", + "\t\t\t\t});", + "\t\t\t\tevent.preventDefault();", + "\t\t\t\treturn;", + "\t\t\t}", + "", + "\t\t\tconst isKeycloakAuthorization =", + "\t\t\t\ttarget.protocol === 'https:' &&", + "\t\t\t\ttarget.pathname.includes('/protocol/openid-connect/auth') &&", + "\t\t\t\ttarget.searchParams.has('client_id') &&", + "\t\t\t\ttarget.searchParams.has('redirect_uri') &&", + "\t\t\t\ttarget.searchParams.has('state');", + "", + "\t\t\tif (", + "\t\t\t\tisKeycloakAuthorization &&", + "\t\t\t\tisTrustedOrigin(webContents.getURL())", + "\t\t\t) {", + "\t\t\t\texternalSsoNavigationActive = true;", + "", + "\t\t\t\tlogger.info('Allowing Keycloak SSO navigation', {", + "\t\t\t\t\torigin: target.origin,", + "\t\t\t\t});", + "", + "\t\t\t\treturn;", + "\t\t\t}", + "\t\t} catch (error) {", + "\t\t\tlogger.warn('Failed to parse navigation URL', {", + "\t\t\t\turl,", + "\t\t\t\terror,", + "\t\t\t});", + "\t\t}", + "", + "\t\tevent.preventDefault();", + "\t});", + ]) + + data, count = pattern.subn( + replacement, + data, + count=1, + ) + + if count != 1: + raise SystemExit( + "Unable to patch Window.ts SSO navigation handler" + ) + + path.write_text( + data, + encoding="utf-8", + ) + + print("SSO navigation patch applied") + PY + + grep -n \ + -E 'externalSsoNavigationActive|Allowing Keycloak SSO navigation' \ + fluxer-src/fluxer_desktop/src/main/Window.ts + - name: Install dependencies shell: bash