Stop OpenBao login redirect loop by removing URL rewriting
Remove redirect-bootstrap and mount polling that fought Ember's token fallback. Keep cosmetic overlay and direct KeyCape OIDC on sign-in only.
This commit is contained in:
parent
64d7c18c3f
commit
80648a78b7
6 changed files with 8 additions and 95 deletions
|
|
@ -31,7 +31,7 @@ behaviour.
|
||||||
| `VERSION` | OpenBao image tag this overlay targets (`openbao-values.yaml`) |
|
| `VERSION` | OpenBao image tag this overlay targets (`openbao-values.yaml`) |
|
||||||
| `presets.json` | Hidden login defaults (`netkingdom`, `platform-admin`, …) |
|
| `presets.json` | Hidden login defaults (`netkingdom`, `platform-admin`, …) |
|
||||||
| `overlay.css` | Hide raw OpenBao login fields |
|
| `overlay.css` | Hide raw OpenBao login fields |
|
||||||
| `overlay.js` | Apply presets, branding, mount deep-link |
|
| `overlay.js` | Apply presets, branding, direct KeyCape OIDC sign-in |
|
||||||
| `nginx.conf` | Gateway proxy + HTML injection |
|
| `nginx.conf` | Gateway proxy + HTML injection |
|
||||||
| `patches/<version>/manifest.sha256` | Upstream UI fingerprints for drift detection |
|
| `patches/<version>/manifest.sha256` | Upstream UI fingerprints for drift detection |
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ http {
|
||||||
|
|
||||||
sub_filter_types text/html;
|
sub_filter_types text/html;
|
||||||
sub_filter_once on;
|
sub_filter_once on;
|
||||||
sub_filter '</head>' '<script src="/ui/platform-overlay/redirect-bootstrap.js"></script><link rel="stylesheet" href="/ui/platform-overlay/overlay.css"><script src="/ui/platform-overlay/overlay.js"></script></head>';
|
sub_filter '</head>' '<link rel="stylesheet" href="/ui/platform-overlay/overlay.css"><script src="/ui/platform-overlay/overlay.js" defer></script></head>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,8 +4,6 @@
|
||||||
const PRESETS_URL = "/ui/platform-overlay/presets.json";
|
const PRESETS_URL = "/ui/platform-overlay/presets.json";
|
||||||
const MAX_APPLY_ATTEMPTS = 40;
|
const MAX_APPLY_ATTEMPTS = 40;
|
||||||
const APPLY_INTERVAL_MS = 250;
|
const APPLY_INTERVAL_MS = 250;
|
||||||
const MOUNT_WATCH_MS = 500;
|
|
||||||
const MOUNT_WATCH_MAX = 24;
|
|
||||||
const DEFAULT_PRESETS = {
|
const DEFAULT_PRESETS = {
|
||||||
namespace: "",
|
namespace: "",
|
||||||
method: "oidc",
|
method: "oidc",
|
||||||
|
|
@ -20,7 +18,6 @@
|
||||||
let presets = { ...DEFAULT_PRESETS };
|
let presets = { ...DEFAULT_PRESETS };
|
||||||
let applyAttempts = 0;
|
let applyAttempts = 0;
|
||||||
let applyTimer = null;
|
let applyTimer = null;
|
||||||
let mountWatchTimer = null;
|
|
||||||
let overlayApplied = false;
|
let overlayApplied = false;
|
||||||
let signInHandlerInstalled = false;
|
let signInHandlerInstalled = false;
|
||||||
|
|
||||||
|
|
@ -32,38 +29,8 @@
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizedMount(value) {
|
function isOidcCallbackPage() {
|
||||||
return (value || "").replace(/\/$/, "");
|
return window.location.pathname.includes("/oidc/");
|
||||||
}
|
|
||||||
|
|
||||||
function desiredMount() {
|
|
||||||
return normalizedMount(presets.mount || "netkingdom");
|
|
||||||
}
|
|
||||||
|
|
||||||
function currentMountFromQuery() {
|
|
||||||
return normalizedMount(
|
|
||||||
new URLSearchParams(window.location.search).get("with") || ""
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureAuthMountSelected() {
|
|
||||||
const mount = desiredMount();
|
|
||||||
const current = currentMountFromQuery();
|
|
||||||
|
|
||||||
if (current === mount || current === "keycape") {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isAuthPage() || window.location.pathname.includes("/oidc/")) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const params = new URLSearchParams(window.location.search);
|
|
||||||
params.set("with", `${mount}/`);
|
|
||||||
window.location.replace(
|
|
||||||
`${window.location.pathname}?${params.toString()}`
|
|
||||||
);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideNode(node) {
|
function hideNode(node) {
|
||||||
|
|
@ -121,7 +88,7 @@
|
||||||
document.addEventListener(
|
document.addEventListener(
|
||||||
"click",
|
"click",
|
||||||
(event) => {
|
(event) => {
|
||||||
if (!isAuthPage()) return;
|
if (!isAuthPage() || isOidcCallbackPage()) return;
|
||||||
|
|
||||||
const button = event.target.closest(
|
const button = event.target.closest(
|
||||||
'#auth-submit, button[data-test="auth-submit"], form#auth-form button[type="submit"]'
|
'#auth-submit, button[data-test="auth-submit"], form#auth-form button[type="submit"]'
|
||||||
|
|
@ -151,7 +118,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyDom() {
|
function applyDom() {
|
||||||
if (!isAuthPage() || overlayApplied) return false;
|
if (!isAuthPage() || isOidcCallbackPage() || overlayApplied) return false;
|
||||||
|
|
||||||
hideNode(document.querySelector(".toolbar-namespace-picker"));
|
hideNode(document.querySelector(".toolbar-namespace-picker"));
|
||||||
document
|
document
|
||||||
|
|
@ -245,25 +212,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function stopMountWatch() {
|
|
||||||
if (mountWatchTimer !== null) {
|
|
||||||
window.clearInterval(mountWatchTimer);
|
|
||||||
mountWatchTimer = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function watchAuthMount() {
|
|
||||||
stopMountWatch();
|
|
||||||
let checks = 0;
|
|
||||||
|
|
||||||
mountWatchTimer = window.setInterval(() => {
|
|
||||||
checks += 1;
|
|
||||||
if (ensureAuthMountSelected() || checks >= MOUNT_WATCH_MAX) {
|
|
||||||
stopMountWatch();
|
|
||||||
}
|
|
||||||
}, MOUNT_WATCH_MS);
|
|
||||||
}
|
|
||||||
|
|
||||||
function scheduleApply() {
|
function scheduleApply() {
|
||||||
stopApplyLoop();
|
stopApplyLoop();
|
||||||
applyAttempts = 0;
|
applyAttempts = 0;
|
||||||
|
|
@ -292,15 +240,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
if (!isAuthPage()) return;
|
if (!isAuthPage() || isOidcCallbackPage()) return;
|
||||||
|
|
||||||
await loadPresets();
|
await loadPresets();
|
||||||
|
|
||||||
if (ensureAuthMountSelected()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
watchAuthMount();
|
|
||||||
installKeyCapeSignInHandler();
|
installKeyCapeSignInHandler();
|
||||||
|
|
||||||
if (document.readyState === "loading") {
|
if (document.readyState === "loading") {
|
||||||
|
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
(function () {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var path = window.location.pathname;
|
|
||||||
if (path.indexOf("/oidc/") !== -1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!/\/ui\/vault\/auth(?:\/|$)/.test(path) && !/\/ui\/?$/.test(path)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var params = new URLSearchParams(window.location.search);
|
|
||||||
var current = (params.get("with") || "").replace(/\/$/, "");
|
|
||||||
if (current === "netkingdom" || current === "keycape") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
params.set("with", "netkingdom/");
|
|
||||||
window.location.replace(
|
|
||||||
window.location.pathname + "?" + params.toString()
|
|
||||||
);
|
|
||||||
})();
|
|
||||||
|
|
@ -27,7 +27,7 @@ if [ "${1:-}" = "-h" ] || [ "${1:-}" = "--help" ]; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for required in overlay.css overlay.js redirect-bootstrap.js presets.json nginx.conf VERSION; do
|
for required in overlay.css overlay.js presets.json nginx.conf VERSION; do
|
||||||
if [ ! -f "$OVERLAY_DIR/$required" ]; then
|
if [ ! -f "$OVERLAY_DIR/$required" ]; then
|
||||||
echo "missing overlay asset: $OVERLAY_DIR/$required" >&2
|
echo "missing overlay asset: $OVERLAY_DIR/$required" >&2
|
||||||
exit 1
|
exit 1
|
||||||
|
|
@ -47,7 +47,6 @@ $KUBECTL create configmap openbao-ui-overlay \
|
||||||
--namespace "$OPENBAO_NAMESPACE" \
|
--namespace "$OPENBAO_NAMESPACE" \
|
||||||
--from-file="$OVERLAY_DIR/overlay.css" \
|
--from-file="$OVERLAY_DIR/overlay.css" \
|
||||||
--from-file="$OVERLAY_DIR/overlay.js" \
|
--from-file="$OVERLAY_DIR/overlay.js" \
|
||||||
--from-file="$OVERLAY_DIR/redirect-bootstrap.js" \
|
|
||||||
--from-file="$OVERLAY_DIR/presets.json" \
|
--from-file="$OVERLAY_DIR/presets.json" \
|
||||||
--from-file="$OVERLAY_DIR/VERSION" \
|
--from-file="$OVERLAY_DIR/VERSION" \
|
||||||
--dry-run=client -o yaml | $KUBECTL apply -f -
|
--dry-run=client -o yaml | $KUBECTL apply -f -
|
||||||
|
|
|
||||||
|
|
@ -58,11 +58,6 @@ overlay_js="$(curl -fsS "$BASE_URL/ui/platform-overlay/overlay.js")"
|
||||||
overlay_css="$(curl -fsS "$BASE_URL/ui/platform-overlay/overlay.css")"
|
overlay_css="$(curl -fsS "$BASE_URL/ui/platform-overlay/overlay.css")"
|
||||||
presets_json="$(curl -fsS "$BASE_URL/ui/platform-overlay/presets.json")"
|
presets_json="$(curl -fsS "$BASE_URL/ui/platform-overlay/presets.json")"
|
||||||
|
|
||||||
require_pattern \
|
|
||||||
"index.html injects redirect bootstrap" \
|
|
||||||
"$index_html" \
|
|
||||||
'/ui/platform-overlay/redirect-bootstrap\.js'
|
|
||||||
|
|
||||||
require_pattern \
|
require_pattern \
|
||||||
"index.html injects overlay.js" \
|
"index.html injects overlay.js" \
|
||||||
"$index_html" \
|
"$index_html" \
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue