fix sso login failure
This commit is contained in:
1 file changed
+210
-31
+210
-31
@@ -68,41 +68,17 @@ jobs:
|
|||||||
node --version
|
node --version
|
||||||
pnpm --version
|
pnpm --version
|
||||||
|
|
||||||
|
|
||||||
- name: Setup Rust
|
- name: Setup Rust
|
||||||
shell: bash
|
shell: powershell
|
||||||
run: |
|
run: |
|
||||||
set -euxo pipefail
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
RUST_VERSION="1.98.1"
|
rustup update stable
|
||||||
|
rustup default stable
|
||||||
rm -f /tmp/rustup-init
|
rustup target add x86_64-pc-windows-msvc
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
rustc --version
|
||||||
|
cargo --version
|
||||||
|
|
||||||
- name: Show build tools
|
- name: Show build tools
|
||||||
shell: powershell
|
shell: powershell
|
||||||
@@ -174,6 +150,101 @@ jobs:
|
|||||||
throw "CANARY_APP_URL was not configured"
|
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
|
- name: Install dependencies
|
||||||
shell: powershell
|
shell: powershell
|
||||||
@@ -586,6 +657,114 @@ jobs:
|
|||||||
print(result)
|
print(result)
|
||||||
PY
|
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
|
- name: Install dependencies
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
Reference in new issue
Block a user