Skip to content

Commit a631bf8

Browse files
committed
Fix redirect loop on logout and session expired
1 parent 24b4129 commit a631bf8

File tree

5 files changed

+42
-24
lines changed

5 files changed

+42
-24
lines changed

auth-libs/web-component/dist/hanko-auth.esm.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4502,9 +4502,12 @@ let ge = class extends Ut {
45024502
} catch (n) {
45034503
this.logError("Hanko logout failed:", n);
45044504
}
4505-
this._clearAuthState(), this.log(
4505+
if (this._clearAuthState(), this.log(
45064506
"✅ Logout complete - component will re-render with updated state"
4507-
), this.redirectAfterLogout && (this.log("🔄 Redirecting after logout to:", this.redirectAfterLogout), window.location.href = this.redirectAfterLogout);
4507+
), this.redirectAfterLogout) {
4508+
const n = window.location.href.replace(/\/$/, ""), e = this.redirectAfterLogout.replace(/\/$/, "");
4509+
n !== e && !n.startsWith(e + "#") ? (this.log("🔄 Redirecting after logout to:", this.redirectAfterLogout), window.location.href = this.redirectAfterLogout) : this.log("⏭️ Already on logout target, skipping redirect");
4510+
}
45084511
}
45094512
/**
45104513
* Clear all auth state - shared between logout and session expired handlers
@@ -4542,19 +4545,22 @@ let ge = class extends Ut {
45424545
} catch (n) {
45434546
this.logError("❌ OSM disconnect failed:", n);
45444547
}
4545-
this._clearAuthState(), this.log("✅ Session cleanup complete"), this.redirectAfterLogout && (this.log(
4546-
"🔄 Redirecting after session expired to:",
4547-
this.redirectAfterLogout
4548-
), window.location.href = this.redirectAfterLogout);
4548+
if (this._clearAuthState(), this.log("✅ Session cleanup complete"), this.redirectAfterLogout) {
4549+
const n = window.location.href.replace(/\/$/, ""), e = this.redirectAfterLogout.replace(/\/$/, "");
4550+
n !== e && !n.startsWith(e + "#") ? (this.log(
4551+
"🔄 Redirecting after session expired to:",
4552+
this.redirectAfterLogout
4553+
), window.location.href = this.redirectAfterLogout) : this.log("⏭️ Already on logout target, skipping redirect");
4554+
}
45494555
}
45504556
handleUserLoggedOut() {
45514557
this.log("🚪 User logged out in another window/tab"), this.handleSessionExpired();
45524558
}
45534559
handleDropdownSelect(n) {
45544560
const e = n.detail.item.value;
45554561
if (this.log("🎯 Dropdown item selected:", e), e === "profile") {
4556-
const t = this.hankoUrl, o = this.redirectAfterLogin || window.location.origin;
4557-
window.location.href = `${t}/app/profile?return_to=${encodeURIComponent(o)}`;
4562+
const t = this.loginUrl || this.hankoUrl, o = this.redirectAfterLogin || window.location.origin;
4563+
window.location.href = `${t}/profile?return_to=${encodeURIComponent(o)}`;
45584564
} else if (e === "connect-osm") {
45594565
const i = window.location.pathname.includes("/app") ? window.location.origin : window.location.href, s = this.hankoUrl;
45604566
window.location.href = `${s}/app?return_to=${encodeURIComponent(

auth-libs/web-component/dist/hanko-auth.iife.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

auth-libs/web-component/dist/hanko-auth.umd.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

auth-libs/web-component/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@hotosm/hanko-auth",
3-
"version": "0.3.1",
3+
"version": "0.3.2",
44
"description": "Web component for HOTOSM SSO authentication with Hanko and OSM integration",
55
"type": "module",
66
"main": "dist/hanko-auth.umd.js",

auth-libs/web-component/src/hanko-auth.ts

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,10 +1292,16 @@ export class HankoAuth extends LitElement {
12921292
"✅ Logout complete - component will re-render with updated state",
12931293
);
12941294

1295-
// Redirect after logout if configured
1295+
// Redirect after logout if configured (but not if already there)
12961296
if (this.redirectAfterLogout) {
1297-
this.log("🔄 Redirecting after logout to:", this.redirectAfterLogout);
1298-
window.location.href = this.redirectAfterLogout;
1297+
const currentUrl = window.location.href.replace(/\/$/, "");
1298+
const targetUrl = this.redirectAfterLogout.replace(/\/$/, "");
1299+
if (currentUrl !== targetUrl && !currentUrl.startsWith(targetUrl + "#")) {
1300+
this.log("🔄 Redirecting after logout to:", this.redirectAfterLogout);
1301+
window.location.href = this.redirectAfterLogout;
1302+
} else {
1303+
this.log("⏭️ Already on logout target, skipping redirect");
1304+
}
12991305
}
13001306
// Otherwise let Lit's reactivity handle the re-render
13011307
}
@@ -1384,13 +1390,19 @@ export class HankoAuth extends LitElement {
13841390

13851391
this.log("✅ Session cleanup complete");
13861392

1387-
// Redirect after session expired if configured
1393+
// Redirect after session expired if configured (but not if already there)
13881394
if (this.redirectAfterLogout) {
1389-
this.log(
1390-
"🔄 Redirecting after session expired to:",
1391-
this.redirectAfterLogout,
1392-
);
1393-
window.location.href = this.redirectAfterLogout;
1395+
const currentUrl = window.location.href.replace(/\/$/, ""); // Remove trailing slash
1396+
const targetUrl = this.redirectAfterLogout.replace(/\/$/, "");
1397+
if (currentUrl !== targetUrl && !currentUrl.startsWith(targetUrl + "#")) {
1398+
this.log(
1399+
"🔄 Redirecting after session expired to:",
1400+
this.redirectAfterLogout,
1401+
);
1402+
window.location.href = this.redirectAfterLogout;
1403+
} else {
1404+
this.log("⏭️ Already on logout target, skipping redirect");
1405+
}
13941406
}
13951407
// Otherwise component will re-render and show login button
13961408
}
@@ -1406,11 +1418,11 @@ export class HankoAuth extends LitElement {
14061418
this.log("🎯 Dropdown item selected:", selectedValue);
14071419

14081420
if (selectedValue === "profile") {
1409-
// Profile page lives on the login site
1410-
// Pass return URL so profile can navigate back to the app
1411-
const baseUrl = this.hankoUrl;
1421+
// Profile page lives on the login site (or standalone app's login page)
1422+
// Use loginUrl if set (standalone mode), otherwise hankoUrl
1423+
const baseUrl = this.loginUrl || this.hankoUrl;
14121424
const returnTo = this.redirectAfterLogin || window.location.origin;
1413-
window.location.href = `${baseUrl}/app/profile?return_to=${encodeURIComponent(returnTo)}`;
1425+
window.location.href = `${baseUrl}/profile?return_to=${encodeURIComponent(returnTo)}`;
14141426
} else if (selectedValue === "connect-osm") {
14151427
// Smart return_to: if already on a login page, redirect to home instead
14161428
const currentPath = window.location.pathname;

0 commit comments

Comments
 (0)