change modal on error
This commit is contained in:
Generated
+1
-1
@@ -2581,7 +2581,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustpad"
|
||||
version = "0.2.39"
|
||||
version = "0.2.40"
|
||||
dependencies = [
|
||||
"argon2",
|
||||
"aws-config",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rustpad"
|
||||
version = "0.2.39"
|
||||
version = "0.2.40"
|
||||
edition = "2024"
|
||||
rust-version = "1.94"
|
||||
description = "Collaborative Markdown notepad built with Axum, WebSockets and SQLite, PostgreSQL and MySQL"
|
||||
|
||||
@@ -27,6 +27,7 @@ import { bindNoteFiles } from "@rustpad/note-files";
|
||||
import { currentShareUrl, readEditorState, writeEditorState } from "@rustpad/url-state";
|
||||
import { toast } from "@rustpad/toast";
|
||||
import { getTheme } from "@rustpad/theme";
|
||||
import { isResourceAccessError } from "@rustpad/security";
|
||||
|
||||
export function startNoteEditor(adapter) {
|
||||
const editor = document.querySelector("#editor"), preview = document.querySelector("#preview"), editorWorkspace = document.querySelector("#editor-workspace"), gutter = document.querySelector("#line-gutter"), ownerLabels = document.querySelector("#owner-labels"), authorshipLayer = document.querySelector("#authorship-layer");
|
||||
@@ -1353,7 +1354,6 @@ export function startNoteEditor(adapter) {
|
||||
onError: message => {
|
||||
hideConnectionNotice();
|
||||
const friendly = /read-only access/i.test(message) ? "This note is read only. Enter the password or ask the owner to grant write access." : message;
|
||||
document.querySelector("#password-error").textContent = friendly;
|
||||
if (/read-only access/i.test(message)) {
|
||||
toast(friendly);
|
||||
accessLevel.textContent = "Access: read only";
|
||||
@@ -1368,9 +1368,17 @@ export function startNoteEditor(adapter) {
|
||||
if (saveState.textContent === "Saving…") saveState.textContent = "Save failed";
|
||||
if (/nickname|session|account/i.test(message)) {
|
||||
if (!identityDialog.open) identityDialog.showModal();
|
||||
} else if (info?.protected && !passwordDialog.open) {
|
||||
passwordDialog.showModal();
|
||||
return;
|
||||
}
|
||||
if (info?.protected && isResourceAccessError(message)) {
|
||||
resourceUnlocked = false;
|
||||
setDocumentReadOnly(true, "Password required");
|
||||
document.querySelector("#password-error").textContent = friendly;
|
||||
if (!passwordDialog.open) passwordDialog.showModal();
|
||||
document.querySelector("#open-password")?.focus();
|
||||
return;
|
||||
}
|
||||
toast(friendly);
|
||||
},
|
||||
});
|
||||
socket.connect();
|
||||
|
||||
@@ -7,6 +7,14 @@
|
||||
* See LICENSE file in repository root for details.
|
||||
*/
|
||||
|
||||
const RESOURCE_ACCESS_ERROR_PATTERN = /(?:invalid password|password required|authentication required|access expired or revoked)/i;
|
||||
|
||||
export function isResourceAccessError(error) {
|
||||
const status = Number(error?.status);
|
||||
const message = typeof error === "string" ? error : error?.message;
|
||||
return status === 401 || RESOURCE_ACCESS_ERROR_PATTERN.test(String(message || ""));
|
||||
}
|
||||
|
||||
export function safeAppUrl(value, fallback = "/") {
|
||||
try {
|
||||
const url = new URL(String(value || ""), location.origin);
|
||||
|
||||
@@ -15,7 +15,7 @@ import { copyText } from "@rustpad/clipboard";
|
||||
import { getNickname, getAccessToken, getAuthToken, getGuestId, setAccessToken } from "@rustpad/session";
|
||||
import { bindIdentityDialog, validateCurrentSession } from "@rustpad/auth-ui";
|
||||
import { askConfirm } from "@rustpad/modal";
|
||||
import { safeAppUrl } from "@rustpad/security";
|
||||
import { isResourceAccessError, safeAppUrl } from "@rustpad/security";
|
||||
import { toast } from "@rustpad/toast";
|
||||
|
||||
const parts = location.pathname.split("/").filter(Boolean);
|
||||
@@ -116,7 +116,8 @@ function connectWorkspaceWatch() {
|
||||
if (message.type === "error") {
|
||||
workspaceWatchIntentionalClose = true;
|
||||
socket.close();
|
||||
if (/password/i.test(message.message || "")) lockWorkspaceForPassword(message.message);
|
||||
if (isResourceAccessError(message.message)) lockWorkspaceForPassword(message.message);
|
||||
else document.querySelector("#workspace-error").textContent = message.message || "Workspace connection error";
|
||||
}
|
||||
});
|
||||
socket.addEventListener("close", () => {
|
||||
@@ -234,7 +235,7 @@ async function openWorkspace() {
|
||||
if (dialog.open) dialog.close();
|
||||
connectWorkspaceWatch();
|
||||
} catch (e) {
|
||||
if (info?.protected || e.message.toLowerCase().includes("password")) {
|
||||
if (info?.protected && isResourceAccessError(e)) {
|
||||
lockWorkspaceForPassword(e.message);
|
||||
} else if (e.status === 403 || e.status === 404) {
|
||||
await showSystemNotFound();
|
||||
|
||||
Reference in New Issue
Block a user