fix: Cleanup PR
This commit is contained in:
1
.github/workflows/electron.yml
vendored
1
.github/workflows/electron.yml
vendored
@@ -746,7 +746,6 @@ jobs:
|
||||
mkdir -p homebrew-submission/Casks/t
|
||||
|
||||
cp homebrew/termix.rb homebrew-submission/Casks/t/termix.rb
|
||||
cp homebrew/README.md homebrew-submission/
|
||||
|
||||
sed -i '' "s/VERSION_PLACEHOLDER/$VERSION/g" homebrew-submission/Casks/t/termix.rb
|
||||
sed -i '' "s/CHECKSUM_PLACEHOLDER/$CHECKSUM/g" homebrew-submission/Casks/t/termix.rb
|
||||
|
||||
@@ -59,29 +59,9 @@ class DatabaseFileEncryption {
|
||||
dataSize: encrypted.length,
|
||||
};
|
||||
|
||||
databaseLogger.debug("Starting atomic encryption write", {
|
||||
operation: "database_buffer_encryption_start",
|
||||
targetPath,
|
||||
tmpPath,
|
||||
originalSize: buffer.length,
|
||||
encryptedSize: encrypted.length,
|
||||
keyFingerprint,
|
||||
ivPrefix: metadata.iv.substring(0, 8),
|
||||
tagPrefix: metadata.tag.substring(0, 8),
|
||||
});
|
||||
|
||||
fs.writeFileSync(tmpPath, encrypted);
|
||||
fs.writeFileSync(tmpMetadataPath, JSON.stringify(metadata, null, 2));
|
||||
|
||||
databaseLogger.debug(
|
||||
"Temporary files written, performing atomic rename",
|
||||
{
|
||||
operation: "database_buffer_encryption_rename",
|
||||
tmpPath,
|
||||
targetPath,
|
||||
},
|
||||
);
|
||||
|
||||
if (fs.existsSync(targetPath)) {
|
||||
fs.unlinkSync(targetPath);
|
||||
}
|
||||
@@ -92,13 +72,6 @@ class DatabaseFileEncryption {
|
||||
}
|
||||
fs.renameSync(tmpMetadataPath, metadataPath);
|
||||
|
||||
databaseLogger.debug("Database buffer encrypted with atomic write", {
|
||||
operation: "database_buffer_encryption_atomic",
|
||||
targetPath,
|
||||
encryptedSize: encrypted.length,
|
||||
keyFingerprint,
|
||||
});
|
||||
|
||||
return targetPath;
|
||||
} catch (error) {
|
||||
try {
|
||||
@@ -177,29 +150,9 @@ class DatabaseFileEncryption {
|
||||
dataSize: encrypted.length,
|
||||
};
|
||||
|
||||
databaseLogger.debug("Starting atomic file encryption", {
|
||||
operation: "database_file_encryption_start",
|
||||
sourcePath,
|
||||
encryptedPath,
|
||||
tmpPath,
|
||||
originalSize: sourceData.length,
|
||||
encryptedSize: encrypted.length,
|
||||
keyFingerprint,
|
||||
ivPrefix: metadata.iv.substring(0, 8),
|
||||
});
|
||||
|
||||
fs.writeFileSync(tmpPath, encrypted);
|
||||
fs.writeFileSync(tmpMetadataPath, JSON.stringify(metadata, null, 2));
|
||||
|
||||
databaseLogger.debug(
|
||||
"Temporary files written, performing atomic rename",
|
||||
{
|
||||
operation: "database_file_encryption_rename",
|
||||
tmpPath,
|
||||
encryptedPath,
|
||||
},
|
||||
);
|
||||
|
||||
if (fs.existsSync(encryptedPath)) {
|
||||
fs.unlinkSync(encryptedPath);
|
||||
}
|
||||
@@ -267,31 +220,9 @@ class DatabaseFileEncryption {
|
||||
const dataFileStats = fs.statSync(encryptedPath);
|
||||
const metaFileStats = fs.statSync(metadataPath);
|
||||
|
||||
databaseLogger.debug("Starting database decryption", {
|
||||
operation: "database_buffer_decryption_start",
|
||||
encryptedPath,
|
||||
metadataPath,
|
||||
dataFileSize: dataFileStats.size,
|
||||
dataFileMtime: dataFileStats.mtime.toISOString(),
|
||||
metaFileMtime: metaFileStats.mtime.toISOString(),
|
||||
dataDir: process.env.DATA_DIR || "./db/data",
|
||||
});
|
||||
|
||||
const metadataContent = fs.readFileSync(metadataPath, "utf8");
|
||||
const metadata: EncryptedFileMetadata = JSON.parse(metadataContent);
|
||||
|
||||
databaseLogger.debug("Metadata loaded", {
|
||||
operation: "database_metadata_loaded",
|
||||
version: metadata.version,
|
||||
algorithm: metadata.algorithm,
|
||||
keySource: metadata.keySource,
|
||||
fingerprint: metadata.fingerprint,
|
||||
hasDataSize: !!metadata.dataSize,
|
||||
expectedDataSize: metadata.dataSize,
|
||||
ivPrefix: metadata.iv?.substring(0, 8),
|
||||
tagPrefix: metadata.tag?.substring(0, 8),
|
||||
});
|
||||
|
||||
const encryptedData = fs.readFileSync(encryptedPath);
|
||||
|
||||
if (metadata.dataSize && encryptedData.length !== metadata.dataSize) {
|
||||
@@ -342,15 +273,6 @@ class DatabaseFileEncryption {
|
||||
.digest("hex")
|
||||
.substring(0, 16);
|
||||
|
||||
databaseLogger.debug("Starting decryption with loaded key", {
|
||||
operation: "database_decryption_attempt",
|
||||
keyFingerprint,
|
||||
algorithm: metadata.algorithm,
|
||||
ivPrefix: metadata.iv.substring(0, 8),
|
||||
tagPrefix: metadata.tag.substring(0, 8),
|
||||
dataSize: encryptedData.length,
|
||||
});
|
||||
|
||||
const decipher = crypto.createDecipheriv(
|
||||
metadata.algorithm,
|
||||
key,
|
||||
@@ -363,14 +285,6 @@ class DatabaseFileEncryption {
|
||||
decipher.final(),
|
||||
]);
|
||||
|
||||
databaseLogger.debug("Database decryption successful", {
|
||||
operation: "database_buffer_decryption_success",
|
||||
encryptedPath,
|
||||
encryptedSize: encryptedData.length,
|
||||
decryptedSize: decryptedBuffer.length,
|
||||
keyFingerprint,
|
||||
});
|
||||
|
||||
return decryptedBuffer;
|
||||
} catch (error) {
|
||||
const errorMessage =
|
||||
|
||||
@@ -51,17 +51,8 @@ class SystemCrypto {
|
||||
},
|
||||
);
|
||||
}
|
||||
} catch (fileError) {
|
||||
databaseLogger.warn("Failed to read .env file for JWT secret", {
|
||||
operation: "jwt_init_file_read_failed",
|
||||
error:
|
||||
fileError instanceof Error ? fileError.message : "Unknown error",
|
||||
});
|
||||
}
|
||||
} catch (fileError) {}
|
||||
|
||||
databaseLogger.warn("Generating new JWT secret", {
|
||||
operation: "jwt_generating_new_secret",
|
||||
});
|
||||
await this.generateAndGuideUser();
|
||||
} catch (error) {
|
||||
databaseLogger.error("Failed to initialize JWT secret", error, {
|
||||
@@ -92,23 +83,9 @@ class SystemCrypto {
|
||||
.digest("hex")
|
||||
.substring(0, 16);
|
||||
|
||||
databaseLogger.info("DATABASE_KEY loaded from environment variable", {
|
||||
operation: "db_key_loaded_from_env",
|
||||
keyFingerprint,
|
||||
keyLength: envKey.length,
|
||||
dataDir,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
databaseLogger.debug(
|
||||
"DATABASE_KEY not found in environment, checking .env file",
|
||||
{
|
||||
operation: "db_key_checking_file",
|
||||
envPath,
|
||||
},
|
||||
);
|
||||
|
||||
try {
|
||||
const envContent = await fs.readFile(envPath, "utf8");
|
||||
const dbKeyMatch = envContent.match(/^DATABASE_KEY=(.+)$/m);
|
||||
@@ -122,34 +99,10 @@ class SystemCrypto {
|
||||
.digest("hex")
|
||||
.substring(0, 16);
|
||||
|
||||
databaseLogger.info("DATABASE_KEY loaded from .env file", {
|
||||
operation: "db_key_loaded_from_file",
|
||||
keyFingerprint,
|
||||
keyLength: dbKeyMatch[1].length,
|
||||
envPath,
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
databaseLogger.warn(
|
||||
"DATABASE_KEY found in .env but invalid or too short",
|
||||
{
|
||||
operation: "db_key_invalid_in_file",
|
||||
envPath,
|
||||
hasMatch: !!dbKeyMatch,
|
||||
keyLength: dbKeyMatch?.[1]?.length || 0,
|
||||
requiredLength: 64,
|
||||
},
|
||||
);
|
||||
}
|
||||
} catch (fileError) {
|
||||
databaseLogger.warn("Failed to read .env file for DATABASE_KEY", {
|
||||
operation: "db_key_file_read_failed",
|
||||
envPath,
|
||||
error:
|
||||
fileError instanceof Error ? fileError.message : "Unknown error",
|
||||
willGenerateNew: true,
|
||||
});
|
||||
}
|
||||
} catch (fileError) {}
|
||||
|
||||
await this.generateAndGuideDatabaseKey();
|
||||
} catch (error) {
|
||||
|
||||
@@ -24,11 +24,20 @@ import {
|
||||
verifyTOTPLogin,
|
||||
getServerConfig,
|
||||
isElectron,
|
||||
logoutUser,
|
||||
} from "../../main-axios.ts";
|
||||
import { ElectronServerConfig as ServerConfigComponent } from "@/ui/desktop/authentication/ElectronServerConfig.tsx";
|
||||
import { ElectronLoginForm } from "@/ui/desktop/authentication/ElectronLoginForm.tsx";
|
||||
|
||||
function getCookie(name: string): string | undefined {
|
||||
const value = `; ${document.cookie}`;
|
||||
const parts = value.split(`; ${name}=`);
|
||||
if (parts.length === 2) return parts.pop()?.split(";").shift();
|
||||
}
|
||||
|
||||
interface ExtendedWindow extends Window {
|
||||
IS_ELECTRON_WEBVIEW?: boolean;
|
||||
}
|
||||
|
||||
interface AuthProps extends React.ComponentProps<"div"> {
|
||||
setLoggedIn: (loggedIn: boolean) => void;
|
||||
setIsAdmin: (isAdmin: boolean) => void;
|
||||
@@ -37,7 +46,6 @@ interface AuthProps extends React.ComponentProps<"div"> {
|
||||
loggedIn: boolean;
|
||||
authLoading: boolean;
|
||||
setDbError: (error: string | null) => void;
|
||||
dbError?: string | null;
|
||||
onAuthSuccess: (authData: {
|
||||
isAdmin: boolean;
|
||||
username: string | null;
|
||||
@@ -54,21 +62,20 @@ export function Auth({
|
||||
loggedIn,
|
||||
authLoading,
|
||||
setDbError,
|
||||
dbError,
|
||||
onAuthSuccess,
|
||||
...props
|
||||
}: AuthProps) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const isInElectronWebView = () => {
|
||||
if ((window as any).IS_ELECTRON_WEBVIEW) {
|
||||
if ((window as ExtendedWindow).IS_ELECTRON_WEBVIEW) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
if (window.self !== window.top) {
|
||||
return true;
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (_e) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
@@ -126,7 +133,7 @@ export function Auth({
|
||||
userId: meRes.userId || null,
|
||||
});
|
||||
toast.success(t("messages.loginSuccess"));
|
||||
} catch (err) {
|
||||
} catch (_err) {
|
||||
toast.error(t("errors.failedUserInfo"));
|
||||
}
|
||||
}, [
|
||||
@@ -206,7 +213,7 @@ export function Auth({
|
||||
.finally(() => {
|
||||
setDbHealthChecking(false);
|
||||
});
|
||||
}, [setDbError, firstUserToastShown, showServerConfig]);
|
||||
}, [setDbError, firstUserToastShown, showServerConfig, t]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!registrationAllowed && !internalLoggedIn) {
|
||||
@@ -282,9 +289,9 @@ export function Auth({
|
||||
);
|
||||
setWebviewAuthSuccess(true);
|
||||
setTimeout(() => window.location.reload(), 100);
|
||||
setLoading(false);
|
||||
return;
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
console.error("Error posting auth success message:", e);
|
||||
}
|
||||
}
|
||||
|
||||
const [meRes] = await Promise.all([getUserInfo()]);
|
||||
@@ -461,7 +468,9 @@ export function Auth({
|
||||
setTimeout(() => window.location.reload(), 100);
|
||||
setTotpLoading(false);
|
||||
return;
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
console.error("Error posting auth success message:", e);
|
||||
}
|
||||
}
|
||||
|
||||
setInternalLoggedIn(true);
|
||||
@@ -569,7 +578,9 @@ export function Auth({
|
||||
setTimeout(() => window.location.reload(), 100);
|
||||
setOidcLoading(false);
|
||||
return;
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
console.error("Error posting auth success message:", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -607,7 +618,16 @@ export function Auth({
|
||||
setOidcLoading(false);
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
}, [
|
||||
onAuthSuccess,
|
||||
setDbError,
|
||||
setIsAdmin,
|
||||
setLoggedIn,
|
||||
setUserId,
|
||||
setUsername,
|
||||
t,
|
||||
isInElectronWebView,
|
||||
]);
|
||||
|
||||
const Spinner = (
|
||||
<svg
|
||||
|
||||
Reference in New Issue
Block a user