paths in mail
This commit is contained in:
+50
-13
@@ -1,6 +1,6 @@
|
||||
import { api } from "@rustpad/api";
|
||||
import * as sessionStore from "@rustpad/session";
|
||||
import { askInput, showMessage } from "@rustpad/modal";
|
||||
import { askConfirm, askInput, showMessage } from "@rustpad/modal";
|
||||
|
||||
const { getAuthToken, setAuthSession, setNickname } = sessionStore;
|
||||
const clearAuthSession = sessionStore.clearAuthSession || (() => {
|
||||
@@ -319,28 +319,44 @@ export async function logoutCurrentSession() {
|
||||
}
|
||||
|
||||
|
||||
export async function handleAccountConfirmationToken() {
|
||||
function mailActionToken(pathPrefix, legacyQueryName) {
|
||||
const url = new URL(location.href);
|
||||
const prefix = `${pathPrefix}/`;
|
||||
let token = null;
|
||||
|
||||
if (url.pathname.startsWith(prefix)) {
|
||||
const encodedToken = url.pathname.slice(prefix.length).split("/", 1)[0];
|
||||
try { token = decodeURIComponent(encodedToken); } catch { token = null; }
|
||||
}
|
||||
if (!token) token = url.searchParams.get(legacyQueryName);
|
||||
return token?.trim() || null;
|
||||
}
|
||||
|
||||
function clearMailActionUrl() {
|
||||
const url = new URL(location.href);
|
||||
const token = url.searchParams.get("confirm_token");
|
||||
if (!token) return;
|
||||
url.searchParams.delete("confirm_token");
|
||||
history.replaceState({}, "", `${url.pathname}${url.search}${url.hash}`);
|
||||
url.searchParams.delete("reset_token");
|
||||
url.searchParams.delete("account_action_token");
|
||||
history.replaceState({}, "", `/${url.search}${url.hash}`);
|
||||
}
|
||||
|
||||
export async function handleAccountConfirmationToken() {
|
||||
const token = mailActionToken("/auth/confirm", "confirm_token");
|
||||
if (!token) return false;
|
||||
clearMailActionUrl();
|
||||
try {
|
||||
const result = await api("/api/auth/confirm-account", { method: "POST", body: JSON.stringify({ token }) });
|
||||
await showMessage(result.message, { title: "Account confirmed" });
|
||||
} catch (error) {
|
||||
await showMessage(error.message, { title: "Account confirmation failed" });
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export async function handleResetToken() {
|
||||
const url = new URL(location.href);
|
||||
const token = url.searchParams.get("reset_token");
|
||||
if (!token) return;
|
||||
|
||||
// Remove the token immediately. Refreshing or navigating back must not reopen the reset dialog.
|
||||
url.searchParams.delete("reset_token");
|
||||
history.replaceState({}, "", `${url.pathname}${url.search}${url.hash}`);
|
||||
const token = mailActionToken("/auth/reset-password", "reset_token");
|
||||
if (!token) return false;
|
||||
clearMailActionUrl();
|
||||
|
||||
const password = await askInput({
|
||||
title: "Set a new password",
|
||||
@@ -352,11 +368,32 @@ export async function handleResetToken() {
|
||||
confirmText: "Change password",
|
||||
bitwardenIgnore: true,
|
||||
});
|
||||
if (!password) return;
|
||||
if (!password) return true;
|
||||
try {
|
||||
await api("/api/auth/password-reset/confirm", { method: "POST", body: JSON.stringify({ token, password }) });
|
||||
await showMessage("Password changed. The reset link has been used and cannot be opened again.", { title: "Password changed" });
|
||||
} catch (error) {
|
||||
await showMessage(error.message, { title: "Password reset failed" });
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export async function handleAccountActionToken() {
|
||||
const token = mailActionToken("/auth/account-action", "account_action_token");
|
||||
if (!token) return false;
|
||||
clearMailActionUrl();
|
||||
|
||||
const confirmed = await askConfirm(
|
||||
"Confirm the requested account action. If you did not request it, cancel and ignore the e-mail.",
|
||||
{ title: "Confirm account action", confirmText: "Confirm action", danger: true },
|
||||
);
|
||||
if (!confirmed) return true;
|
||||
try {
|
||||
const result = await api("/api/auth/account-action/confirm", { method: "POST", body: JSON.stringify({ token }) });
|
||||
await showMessage(result.message, { title: "Account action confirmed" });
|
||||
} catch (error) {
|
||||
await showMessage(error.message, { title: "Account action failed" });
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+2
-5
@@ -1,7 +1,7 @@
|
||||
import { installGlobalDiagnostics, logInfo } from "@rustpad/logger";
|
||||
installGlobalDiagnostics();
|
||||
|
||||
import { bindIdentityDialog, handleAccountConfirmationToken, handleResetToken, logoutCurrentSession, validateCurrentSession } from "@rustpad/auth-ui";
|
||||
import { bindIdentityDialog, handleAccountActionToken, handleAccountConfirmationToken, handleResetToken, logoutCurrentSession, validateCurrentSession } from "@rustpad/auth-ui";
|
||||
import { getAuthToken, setAccessToken } from "@rustpad/session";
|
||||
import { api } from "@rustpad/api";
|
||||
import { copyText } from "@rustpad/clipboard";
|
||||
@@ -83,10 +83,7 @@ document.querySelector("#workspace-form").addEventListener("submit", async (even
|
||||
}
|
||||
});
|
||||
|
||||
handleAccountConfirmationToken();
|
||||
handleResetToken();
|
||||
|
||||
{ const params=new URLSearchParams(location.search); const token=params.get("account_action_token"); if(token){ api("/api/auth/account-action/confirm",{method:"POST",body:JSON.stringify({token})}).then(r=>toast(r.message)).catch(e=>toast(e.message)).finally(()=>{params.delete("account_action_token");history.replaceState({},"",`${location.pathname}${params.size?`?${params}`:""}${location.hash}`);}); } }
|
||||
await handleAccountConfirmationToken() || await handleResetToken() || await handleAccountActionToken();
|
||||
|
||||
const identityDialog = document.querySelector("#identity-dialog");
|
||||
const guestAccount = document.querySelector("#footer-account-guest");
|
||||
|
||||
Reference in New Issue
Block a user