@hotosm/hanko-auth 0.3.1 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hotosm/hanko-auth",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "Web component for HOTOSM SSO authentication with Hanko and OSM integration",
5
5
  "type": "module",
6
6
  "main": "dist/hanko-auth.umd.js",
package/src/hanko-auth.ts CHANGED
@@ -607,10 +607,17 @@ export class HankoAuth extends LitElement {
607
607
  // Configure cookie domain for cross-subdomain SSO
608
608
  const hostname = window.location.hostname;
609
609
  const isLocalhost = hostname === "localhost" || hostname === "127.0.0.1";
610
+
611
+ // Extract base domain for cookie (e.g., "login.hotosm.org" -> ".hotosm.org")
612
+ // Handles both production (.hotosm.org) and dev (.hotosm.test)
613
+ const parts = hostname.split(".");
614
+ const baseDomain =
615
+ parts.length >= 2 ? `.${parts.slice(-2).join(".")}` : hostname;
616
+
610
617
  const cookieOptions = isLocalhost
611
618
  ? {}
612
619
  : {
613
- cookieDomain: ".hotosm.org",
620
+ cookieDomain: baseDomain,
614
621
  cookieName: "hanko",
615
622
  cookieSameSite: "lax",
616
623
  };
@@ -818,6 +825,12 @@ export class HankoAuth extends LitElement {
818
825
  }
819
826
 
820
827
  private async checkOSMConnection() {
828
+ // Skip OSM check if not required
829
+ if (!this.osmRequired) {
830
+ this.log("⏭️ OSM not required, skipping connection check");
831
+ return;
832
+ }
833
+
821
834
  if (this.osmConnected) {
822
835
  this.log("⏭️ Already connected to OSM, skipping check");
823
836
  return;
@@ -1292,10 +1305,16 @@ export class HankoAuth extends LitElement {
1292
1305
  "✅ Logout complete - component will re-render with updated state",
1293
1306
  );
1294
1307
 
1295
- // Redirect after logout if configured
1308
+ // Redirect after logout if configured (but not if already there)
1296
1309
  if (this.redirectAfterLogout) {
1297
- this.log("🔄 Redirecting after logout to:", this.redirectAfterLogout);
1298
- window.location.href = this.redirectAfterLogout;
1310
+ const currentUrl = window.location.href.replace(/\/$/, "");
1311
+ const targetUrl = this.redirectAfterLogout.replace(/\/$/, "");
1312
+ if (currentUrl !== targetUrl && !currentUrl.startsWith(targetUrl + "#")) {
1313
+ this.log("🔄 Redirecting after logout to:", this.redirectAfterLogout);
1314
+ window.location.href = this.redirectAfterLogout;
1315
+ } else {
1316
+ this.log("⏭️ Already on logout target, skipping redirect");
1317
+ }
1299
1318
  }
1300
1319
  // Otherwise let Lit's reactivity handle the re-render
1301
1320
  }
@@ -1344,8 +1363,16 @@ export class HankoAuth extends LitElement {
1344
1363
  this.log("📊 Current state:", {
1345
1364
  user: this.user,
1346
1365
  osmConnected: this.osmConnected,
1366
+ loading: this.loading,
1347
1367
  });
1348
1368
 
1369
+ // If still loading, wait for session check to complete before acting
1370
+ // The SDK may fire this event for old/stale sessions during init
1371
+ if (this.loading) {
1372
+ this.log("⏳ Still loading, ignoring session expired event during init");
1373
+ return;
1374
+ }
1375
+
1349
1376
  // If we have an active user, the session is still valid
1350
1377
  // The SDK may fire this event for old/stale sessions while a new session exists
1351
1378
  if (this.user) {
@@ -1384,13 +1411,19 @@ export class HankoAuth extends LitElement {
1384
1411
 
1385
1412
  this.log("✅ Session cleanup complete");
1386
1413
 
1387
- // Redirect after session expired if configured
1414
+ // Redirect after session expired if configured (but not if already there)
1388
1415
  if (this.redirectAfterLogout) {
1389
- this.log(
1390
- "🔄 Redirecting after session expired to:",
1391
- this.redirectAfterLogout,
1392
- );
1393
- window.location.href = this.redirectAfterLogout;
1416
+ const currentUrl = window.location.href.replace(/\/$/, ""); // Remove trailing slash
1417
+ const targetUrl = this.redirectAfterLogout.replace(/\/$/, "");
1418
+ if (currentUrl !== targetUrl && !currentUrl.startsWith(targetUrl + "#")) {
1419
+ this.log(
1420
+ "🔄 Redirecting after session expired to:",
1421
+ this.redirectAfterLogout,
1422
+ );
1423
+ window.location.href = this.redirectAfterLogout;
1424
+ } else {
1425
+ this.log("⏭️ Already on logout target, skipping redirect");
1426
+ }
1394
1427
  }
1395
1428
  // Otherwise component will re-render and show login button
1396
1429
  }
@@ -1406,11 +1439,11 @@ export class HankoAuth extends LitElement {
1406
1439
  this.log("🎯 Dropdown item selected:", selectedValue);
1407
1440
 
1408
1441
  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;
1442
+ // Profile page lives on the login site (or standalone app's login page)
1443
+ // Use loginUrl if set (standalone mode), otherwise hankoUrl
1444
+ const baseUrl = this.loginUrl || this.hankoUrl;
1412
1445
  const returnTo = this.redirectAfterLogin || window.location.origin;
1413
- window.location.href = `${baseUrl}/app/profile?return_to=${encodeURIComponent(returnTo)}`;
1446
+ window.location.href = `${baseUrl}/profile?return_to=${encodeURIComponent(returnTo)}`;
1414
1447
  } else if (selectedValue === "connect-osm") {
1415
1448
  // Smart return_to: if already on a login page, redirect to home instead
1416
1449
  const currentPath = window.location.pathname;