diff --git a/frontend/src/index.ts b/frontend/src/index.ts
index 2936abfcfc..153ccd3be6 100644
--- a/frontend/src/index.ts
+++ b/frontend/src/index.ts
@@ -13,7 +13,7 @@ import type { NotifyEvent, NavigateEvent } from "./utils/LiteElement";
import LiteElement, { html } from "./utils/LiteElement";
import APIRouter from "./utils/APIRouter";
import AuthService, { AuthState } from "./utils/AuthService";
-import type { LoggedInEvent } from "./utils/AuthService";
+import type { LoggedInEvent, NeedLoginEvent } from "./utils/AuthService";
import type { ViewState } from "./utils/APIRouter";
import type { CurrentUser, UserOrg } from "./types/user";
import type { AuthStorageEventData } from "./utils/AuthService";
@@ -107,6 +107,7 @@ export class App extends LiteElement {
}
super.connectedCallback();
+ window.addEventListener("need-login", this.onNeedLogin);
window.addEventListener("popstate", () => {
this.syncViewState();
});
@@ -585,7 +586,8 @@ export class App extends LiteElement {
@logged-in=${this.onLoggedIn}
.authState=${this.authService.authState}
.viewState=${this.viewState}
- redirectUrl=${this.viewState.params.redirectUrl}
+ redirectUrl=${this.viewState.params.redirectUrl ||
+ this.viewState.data?.redirectUrl}
>`;
case "resetPassword":
@@ -616,7 +618,6 @@ export class App extends LiteElement {
return html``;
@@ -632,7 +633,6 @@ export class App extends LiteElement {
return html` {
e.stopPropagation();
this.updateUserInfo();
@@ -653,7 +653,6 @@ export class App extends LiteElement {
class="w-full max-w-screen-lg mx-auto p-2 md:py-8 box-border"
@navigate="${this.onNavigateTo}"
@logged-in=${this.onLoggedIn}
- @need-login="${this.onNeedLogin}"
.authState="${this.authService.authState}"
.userInfo="${this.userInfo}"
>`;
@@ -665,7 +664,6 @@ export class App extends LiteElement {
class="w-full max-w-screen-lg mx-auto p-2 md:py-8 box-border"
@navigate="${this.onNavigateTo}"
@logged-in=${this.onLoggedIn}
- @need-login="${this.onNeedLogin}"
.authState="${this.authService.authState}"
.userInfo="${this.userInfo}"
>`;
@@ -684,7 +682,6 @@ export class App extends LiteElement {
return html` {
+ e.stopPropagation();
+
this.clearUser();
- this.navigate(ROUTES.login);
- }
+ const redirectUrl = (e as NeedLoginEvent).detail?.redirectUrl;
+ this.navigate(ROUTES.login, {
+ redirectUrl,
+ });
+ this.onNotify(
+ new CustomEvent("notify", {
+ detail: {
+ message: msg("Please log in to continue."),
+ variant: "warning" as any,
+ icon: "exclamation-triangle",
+ },
+ })
+ );
+ };
onNavigateTo(event: NavigateEvent) {
event.stopPropagation();
diff --git a/frontend/src/pages/org/index.ts b/frontend/src/pages/org/index.ts
index ae51e902e7..deccbb720f 100644
--- a/frontend/src/pages/org/index.ts
+++ b/frontend/src/pages/org/index.ts
@@ -124,7 +124,7 @@ export class Org extends LiteElement {
}
async willUpdate(changedProperties: Map) {
- if (changedProperties.has("orgId") && this.orgId) {
+ if (changedProperties.has("orgId") && this.orgId && this.authState) {
try {
this.org = await this.getOrg(this.orgId);
this.checkStorageQuota();
diff --git a/frontend/src/utils/AuthService.ts b/frontend/src/utils/AuthService.ts
index b32d357511..9c7a104002 100644
--- a/frontend/src/utils/AuthService.ts
+++ b/frontend/src/utils/AuthService.ts
@@ -1,3 +1,4 @@
+import { ROUTES } from "../routes";
import { APIError } from "./api";
export type Auth = {
@@ -27,6 +28,14 @@ export interface LoggedInEvent extends CustomEvent {
readonly detail: T;
}
+export interface NeedLoginEvent extends CustomEvent {
+ readonly bubbles: boolean;
+ readonly composed: boolean;
+ readonly detail: {
+ redirectUrl?: string;
+ };
+}
+
type AuthRequestEventData = {
name: "requesting_auth";
};
@@ -51,6 +60,7 @@ export default class AuthService {
static storageKey = "btrix.auth";
static unsupportedAuthErrorCode = "UNSUPPORTED_AUTH_TYPE";
static loggedInEvent = "logged-in";
+ static needLoginEvent = "need-login";
static broadcastChannel = new BroadcastChannel(AuthService.storageKey);
static storage = {
@@ -85,6 +95,14 @@ export default class AuthService {
return new CustomEvent(AuthService.loggedInEvent, { detail });
};
+ static createNeedLoginEvent = (redirectUrl?: string): NeedLoginEvent => {
+ return new CustomEvent(AuthService.needLoginEvent, {
+ bubbles: true,
+ composed: true,
+ detail: { redirectUrl },
+ });
+ };
+
static async login({
email,
password,
@@ -307,6 +325,14 @@ export default class AuthService {
}, FRESHNESS_TIMER_INTERVAL);
} catch (e) {
console.debug(e);
+
+ this.logout();
+ const { pathname, search, hash } = window.location;
+ const redirectUrl =
+ pathname !== ROUTES.login && pathname !== ROUTES.home
+ ? `${pathname}${search}${hash}`
+ : "";
+ window.dispatchEvent(AuthService.createNeedLoginEvent(redirectUrl));
}
}
}
diff --git a/frontend/src/utils/LiteElement.ts b/frontend/src/utils/LiteElement.ts
index 5220403a2e..5d56bc79f3 100644
--- a/frontend/src/utils/LiteElement.ts
+++ b/frontend/src/utils/LiteElement.ts
@@ -3,6 +3,7 @@ import type { TemplateResult } from "lit";
import { msg } from "@lit/localize";
import type { Auth } from "../utils/AuthService";
+import AuthService from "../utils/AuthService";
import { APIError } from "./api";
export interface NavigateEvent extends CustomEvent {
@@ -147,7 +148,7 @@ export default class LiteElement extends LitElement {
switch (resp.status) {
case 401: {
- this.dispatchEvent(new CustomEvent("need-login"));
+ this.dispatchEvent(AuthService.createNeedLoginEvent());
errorMessage = msg("Need login");
break;
}
diff --git a/frontend/src/utils/auth.ts b/frontend/src/utils/auth.ts
index 3b6e591b53..8bc1435bca 100644
--- a/frontend/src/utils/auth.ts
+++ b/frontend/src/utils/auth.ts
@@ -1,6 +1,6 @@
import LiteElement from "../utils/LiteElement";
import type { AuthState } from "../utils/AuthService";
-import type { CurrentUser } from "../types/user";
+import AuthService from "../utils/AuthService";
/**
* Block rendering and dispatch event if user is not logged in
@@ -27,7 +27,11 @@ export function needLogin(
if (this.authState) {
super.update(changedProperties);
} else {
- this.dispatchEvent(new CustomEvent("need-login"));
+ this.dispatchEvent(
+ AuthService.createNeedLoginEvent(
+ `${window.location.pathname}${window.location.search}${window.location.hash}`
+ )
+ );
}
}
};