Begin undo #303
This commit is contained in:
@@ -422,11 +422,6 @@ const migrateSchema = () => {
|
||||
addColumnIfNotExists("users", "totp_enabled", "INTEGER NOT NULL DEFAULT 0");
|
||||
addColumnIfNotExists("users", "totp_backup_codes", "TEXT");
|
||||
|
||||
// Password recovery fields (UX compromise - breaks zero-trust for usability)
|
||||
addColumnIfNotExists("users", "recovery_dek", "TEXT");
|
||||
addColumnIfNotExists("users", "backup_encrypted_dek", "TEXT");
|
||||
addColumnIfNotExists("users", "zero_trust_mode", "INTEGER NOT NULL DEFAULT 0");
|
||||
|
||||
addColumnIfNotExists("ssh_data", "name", "TEXT");
|
||||
addColumnIfNotExists("ssh_data", "folder", "TEXT");
|
||||
addColumnIfNotExists("ssh_data", "tags", "TEXT");
|
||||
|
||||
@@ -23,13 +23,6 @@ export const users = sqliteTable("users", {
|
||||
.notNull()
|
||||
.default(false),
|
||||
totp_backup_codes: text("totp_backup_codes"),
|
||||
|
||||
// Password recovery fields (breaks zero-trust for UX)
|
||||
recovery_dek: text("recovery_dek"), // Recovery DEK stored in plaintext
|
||||
backup_encrypted_dek: text("backup_encrypted_dek"), // DEK encrypted with recovery DEK
|
||||
zero_trust_mode: integer("zero_trust_mode", { mode: "boolean" })
|
||||
.notNull()
|
||||
.default(false), // false=compromise mode, true=zero-trust mode
|
||||
});
|
||||
|
||||
export const settings = sqliteTable("settings", {
|
||||
|
||||
@@ -558,7 +558,7 @@ export const Terminal = forwardRef<any, SSHTerminalProps>(function SSHTerminal(
|
||||
scrollback: 10000,
|
||||
fontSize: 14,
|
||||
fontFamily:
|
||||
'"JetBrains Mono Nerd Font", "MesloLGS NF", "FiraCode Nerd Font", "Cascadia Code", "JetBrains Mono", Consolas, "Courier New", monospace',
|
||||
'"JetBrains Mono Nerd Font", "MesloLGS NF", "FiraCode Nerd Font", "Cascadia Code", "JetBrains Mono", "SF Mono", Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
|
||||
theme: { background: "#18181b", foreground: "#f7f7f7" },
|
||||
allowTransparency: true,
|
||||
convertEol: true,
|
||||
@@ -791,7 +791,7 @@ const style = document.createElement("style");
|
||||
style.innerHTML = `
|
||||
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap');
|
||||
|
||||
/* Load NerdFonts locally */
|
||||
/* Load NerdFonts locally with fallback handling */
|
||||
@font-face {
|
||||
font-family: 'JetBrains Mono Nerd Font';
|
||||
src: url('./fonts/JetBrainsMonoNerdFont-Regular.ttf') format('truetype');
|
||||
@@ -816,6 +816,15 @@ style.innerHTML = `
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
/* Fallback fonts for when custom fonts fail to load */
|
||||
@font-face {
|
||||
font-family: 'Terminal Fallback';
|
||||
src: local('SF Mono'), local('Monaco'), local('Consolas'), local('Liberation Mono'), local('Courier New');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
.xterm .xterm-viewport::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
background: transparent;
|
||||
@@ -840,7 +849,7 @@ style.innerHTML = `
|
||||
}
|
||||
|
||||
.xterm .xterm-screen {
|
||||
font-family: 'JetBrains Mono Nerd Font', 'MesloLGS NF', 'FiraCode Nerd Font', 'Cascadia Code', 'JetBrains Mono', Consolas, "Courier New", monospace !important;
|
||||
font-family: 'JetBrains Mono Nerd Font', 'MesloLGS NF', 'FiraCode Nerd Font', 'Cascadia Code', 'JetBrains Mono', 'SF Mono', Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace !important;
|
||||
font-variant-ligatures: contextual;
|
||||
}
|
||||
|
||||
|
||||
@@ -226,7 +226,7 @@ export const Terminal = forwardRef<any, SSHTerminalProps>(function SSHTerminal(
|
||||
scrollback: 10000,
|
||||
fontSize: 14,
|
||||
fontFamily:
|
||||
'"JetBrains Mono Nerd Font", "MesloLGS NF", "FiraCode Nerd Font", "Cascadia Code", "JetBrains Mono", Consolas, "Courier New", monospace',
|
||||
'"JetBrains Mono Nerd Font", "MesloLGS NF", "FiraCode Nerd Font", "Cascadia Code", "JetBrains Mono", "SF Mono", Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
|
||||
theme: { background: "#09090b", foreground: "#f7f7f7" },
|
||||
allowTransparency: true,
|
||||
convertEol: true,
|
||||
@@ -402,7 +402,7 @@ const style = document.createElement("style");
|
||||
style.innerHTML = `
|
||||
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap');
|
||||
|
||||
/* Load NerdFonts locally */
|
||||
/* Load NerdFonts locally with fallback handling */
|
||||
@font-face {
|
||||
font-family: 'JetBrains Mono Nerd Font';
|
||||
src: url('./fonts/JetBrainsMonoNerdFont-Regular.ttf') format('truetype');
|
||||
@@ -427,6 +427,15 @@ style.innerHTML = `
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
/* Fallback fonts for when custom fonts fail to load */
|
||||
@font-face {
|
||||
font-family: 'Terminal Fallback';
|
||||
src: local('SF Mono'), local('Monaco'), local('Consolas'), local('Liberation Mono'), local('Courier New');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
.xterm .xterm-viewport::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
background: transparent;
|
||||
@@ -451,7 +460,7 @@ style.innerHTML = `
|
||||
}
|
||||
|
||||
.xterm .xterm-screen {
|
||||
font-family: 'JetBrains Mono Nerd Font', 'MesloLGS NF', 'FiraCode Nerd Font', 'Cascadia Code', 'JetBrains Mono', Consolas, "Courier New", monospace !important;
|
||||
font-family: 'JetBrains Mono Nerd Font', 'MesloLGS NF', 'FiraCode Nerd Font', 'Cascadia Code', 'JetBrains Mono', 'SF Mono', Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace !important;
|
||||
font-variant-ligatures: contextual;
|
||||
}
|
||||
|
||||
|
||||
@@ -1604,49 +1604,6 @@ export async function getUserCount(): Promise<UserCount> {
|
||||
}
|
||||
}
|
||||
|
||||
// ===== New Recovery API functions (UX compromise) =====
|
||||
|
||||
export async function requestRecoveryCode(username: string): Promise<any> {
|
||||
try {
|
||||
const response = await authApi.post("/users/recovery/request", { username });
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
handleApiError(error, "request recovery code");
|
||||
}
|
||||
}
|
||||
|
||||
export async function verifyRecoveryCode(
|
||||
username: string,
|
||||
code: string,
|
||||
): Promise<any> {
|
||||
try {
|
||||
const response = await authApi.post("/users/recovery/verify", {
|
||||
username,
|
||||
code,
|
||||
});
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
handleApiError(error, "verify recovery code");
|
||||
}
|
||||
}
|
||||
|
||||
export async function loginWithRecovery(
|
||||
username: string,
|
||||
tempToken: string,
|
||||
): Promise<any> {
|
||||
try {
|
||||
const response = await authApi.post("/users/recovery/login", {
|
||||
username,
|
||||
tempToken,
|
||||
});
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
handleApiError(error, "recovery login");
|
||||
}
|
||||
}
|
||||
|
||||
// ===== Legacy password reset functions (deprecated) =====
|
||||
|
||||
export async function initiatePasswordReset(username: string): Promise<any> {
|
||||
try {
|
||||
const response = await authApi.post("/users/initiate-reset", { username });
|
||||
|
||||
Reference in New Issue
Block a user