mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-10 15:32:05 -03:30
Improve session polling to prevent accidental redirects
Closes #33071 Signed-off-by: Jon Koops <jonkoops@gmail.com> (cherry picked from commit 687223f3b17f1804ddea1b74cacdc6b3564b73e6)
This commit is contained in:
parent
73ed0613ee
commit
7acb30269b
@ -91,7 +91,7 @@
|
||||
<#if recaptchaRequired?? && !(recaptchaVisible!false)>
|
||||
<script>
|
||||
function onSubmitRecaptcha(token) {
|
||||
document.getElementById("kc-register-form").submit();
|
||||
document.getElementById("kc-register-form").requestSubmit();
|
||||
}
|
||||
</script>
|
||||
<div id="kc-form-buttons" class="${properties.kcFormButtonsClass!}">
|
||||
|
||||
@ -1,18 +1,23 @@
|
||||
const CHECK_INTERVAL_MILLISECS = 2000;
|
||||
const SESSION_POLLING_INTERVAL = 2000;
|
||||
const initialSession = getSession();
|
||||
|
||||
const forms = Array.from(document.forms);
|
||||
let timeout;
|
||||
|
||||
// Remove the timeout when unloading to avoid execution of the
|
||||
// checkCookiesAndSetTimer when the page is already submitted
|
||||
addEventListener("beforeunload", () => {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
timeout = undefined;
|
||||
}
|
||||
});
|
||||
// Stop polling for a session when a form is submitted to prevent unexpected redirects.
|
||||
// This is required as Safari does not support the 'beforeunload' event properly.
|
||||
// See: https://bugs.webkit.org/show_bug.cgi?id=219102
|
||||
forms.forEach((form) =>
|
||||
form.addEventListener("submit", () => stopSessionPolling()),
|
||||
);
|
||||
|
||||
export function checkCookiesAndSetTimer(loginRestartUrl) {
|
||||
// Stop polling for a session when the page is unloaded to prevent unexpected redirects.
|
||||
globalThis.addEventListener("beforeunload", () => stopSessionPolling());
|
||||
|
||||
/**
|
||||
* Starts polling to check if a new session was started in another context (e.g. a tab or window), and redirects to the specified URL if a session is detected.
|
||||
* @param {string} redirectUrl - The URL to redirect to if a new session is detected.
|
||||
*/
|
||||
export function startSessionPolling(redirectUrl) {
|
||||
if (initialSession) {
|
||||
// We started with a session, so there is nothing to do, exit.
|
||||
return;
|
||||
@ -21,14 +26,25 @@ export function checkCookiesAndSetTimer(loginRestartUrl) {
|
||||
const session = getSession();
|
||||
|
||||
if (!session) {
|
||||
// The session is not present, check again later.
|
||||
// No new session detected, check again later.
|
||||
timeout = setTimeout(
|
||||
() => checkCookiesAndSetTimer(loginRestartUrl),
|
||||
CHECK_INTERVAL_MILLISECS,
|
||||
() => startSessionPolling(redirectUrl),
|
||||
SESSION_POLLING_INTERVAL,
|
||||
);
|
||||
} else {
|
||||
// Redirect to the login restart URL. This can typically automatically login user due the SSO
|
||||
location.href = loginRestartUrl;
|
||||
// A new session was detected, redirect to the specified URL and stop polling.
|
||||
location.href = redirectUrl;
|
||||
stopSessionPolling();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops polling the session.
|
||||
*/
|
||||
function stopSessionPolling() {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
timeout = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -73,10 +73,10 @@ export function returnSuccess(result) {
|
||||
if (result.response.userHandle) {
|
||||
document.getElementById("userHandle").value = base64url.stringify(new Uint8Array(result.response.userHandle), { pad: false });
|
||||
}
|
||||
document.getElementById("webauth").submit();
|
||||
document.getElementById("webauth").requestSubmit();
|
||||
}
|
||||
|
||||
export function returnFailure(err) {
|
||||
document.getElementById("error").value = err;
|
||||
document.getElementById("webauth").submit();
|
||||
}
|
||||
document.getElementById("webauth").requestSubmit();
|
||||
}
|
||||
|
||||
@ -131,10 +131,10 @@ function returnSuccess(result, initLabel, initLabelPrompt) {
|
||||
}
|
||||
document.getElementById("authenticatorLabel").value = labelResult;
|
||||
|
||||
document.getElementById("register").submit();
|
||||
document.getElementById("register").requestSubmit();
|
||||
}
|
||||
|
||||
function returnFailure(err) {
|
||||
document.getElementById("error").value = err;
|
||||
document.getElementById("register").submit();
|
||||
document.getElementById("register").requestSubmit();
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<#if section = "header">
|
||||
${msg("saml.post-form.title")}
|
||||
<#elseif section = "form">
|
||||
<script>window.onload = function() {document.forms[0].submit()};</script>
|
||||
<script>window.onload = function() {document.forms[0].requestSubmit()};</script>
|
||||
<p>${msg("saml.post-form.message")}</p>
|
||||
<form name="saml-post-binding" method="post" action="${samlPost.url}">
|
||||
<#if samlPost.SAMLRequest??>
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
<#list user.organizations as organization>
|
||||
<li>
|
||||
<a id="organization-${organization.alias}" class="${properties.kcFormSocialAccountListButtonClass!} <#if user.organizations?size gt 3>${properties.kcFormSocialAccountGridItem!}</#if>"
|
||||
type="button" onclick="document.forms[0]['kc.org'].value = '${organization.alias}'; document.forms[0].submit()">
|
||||
type="button" onclick="document.forms[0]['kc.org'].value = '${organization.alias}'; document.forms[0].requestSubmit()">
|
||||
<span class="${properties.kcFormSocialAccountNameClass!}">${organization.name!}</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@ -44,9 +44,9 @@
|
||||
</#list>
|
||||
</#if>
|
||||
<script type="module">
|
||||
import { checkCookiesAndSetTimer } from "${url.resourcesPath}/js/authChecker.js";
|
||||
import { startSessionPolling } from "${url.resourcesPath}/js/authChecker.js";
|
||||
|
||||
checkCookiesAndSetTimer(
|
||||
startSessionPolling(
|
||||
"${url.ssoLoginInOtherTabsUrl?no_esc}"
|
||||
);
|
||||
</script>
|
||||
@ -148,7 +148,7 @@
|
||||
<div class="${properties.kcFormGroupClass!}">
|
||||
<input type="hidden" name="tryAnotherWay" value="on"/>
|
||||
<a href="#" id="try-another-way"
|
||||
onclick="document.forms['kc-select-try-another-way-form'].submit();return false;">${msg("doTryAnotherWay")}</a>
|
||||
onclick="document.forms['kc-select-try-another-way-form'].requestSubmit();return false;">${msg("doTryAnotherWay")}</a>
|
||||
</div>
|
||||
</form>
|
||||
</#if>
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
refreshPage = () => {
|
||||
document.getElementById('isSetRetry').value = 'retry';
|
||||
document.getElementById('executionValue').value = '${execution}';
|
||||
document.getElementById('kc-error-credential-form').submit();
|
||||
document.getElementById('kc-error-credential-form').requestSubmit();
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
<form id="kc-select-credential-form" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
|
||||
<input type="hidden" name="authenticationExecution" value="${authenticationSelection.authExecId}">
|
||||
</form>
|
||||
<div class="${properties.kcSelectAuthListItemClass!}" onclick="document.forms[${authenticationSelection?index}].submit()">
|
||||
<div class="${properties.kcSelectAuthListItemClass!}" onclick="document.forms[${authenticationSelection?index}].requestSubmit()">
|
||||
<div class="pf-v5-c-data-list__item-content">
|
||||
<div class="${properties.kcSelectAuthListItemIconClass!}">
|
||||
<i class="${properties['${authenticationSelection.iconCssClass}']!authenticationSelection.iconCssClass} ${properties.kcSelectAuthListItemIconPropertyClass!}"></i>
|
||||
|
||||
@ -66,9 +66,9 @@
|
||||
</#if>
|
||||
<script type="module" src="${url.resourcesPath}/js/passwordVisibility.js"></script>
|
||||
<script type="module">
|
||||
import { checkCookiesAndSetTimer } from "${url.resourcesPath}/js/authChecker.js";
|
||||
import { startSessionPolling } from "${url.resourcesPath}/js/authChecker.js";
|
||||
|
||||
checkCookiesAndSetTimer(
|
||||
startSessionPolling(
|
||||
"${url.ssoLoginInOtherTabsUrl?no_esc}"
|
||||
);
|
||||
|
||||
@ -190,7 +190,7 @@
|
||||
<#if auth?has_content && auth.showTryAnotherWayLink()>
|
||||
<form id="kc-select-try-another-way-form" action="${url.loginAction}" method="post" novalidate="novalidate">
|
||||
<input type="hidden" name="tryAnotherWay" value="on"/>
|
||||
<a id="try-another-way" href="javascript:document.forms['kc-select-try-another-way-form'].submit()"
|
||||
<a id="try-another-way" href="javascript:document.forms['kc-select-try-another-way-form'].requestSubmit()"
|
||||
class="${properties.kcButtonSecondaryClass} ${properties.kcButtonBlockClass} ${properties.kcMarginTopClass}">
|
||||
${kcSanitize(msg("doTryAnotherWay"))?no_esc}
|
||||
</a>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user