Compare commits

..
7 changed files with 31 additions and 71 deletions

View file

@ -36,13 +36,6 @@ if (verbose) {
app.commandLine.appendSwitch("log-level", "0"); app.commandLine.appendSwitch("log-level", "0");
} }
if (
process.platform === "linux" &&
!app.commandLine.hasSwitch("password-store")
) {
app.commandLine.appendSwitch("password-store", "gnome-libsecret");
}
if ( if (
process.platform === "linux" && process.platform === "linux" &&
process.env.XDG_SESSION_TYPE === "wayland" && process.env.XDG_SESSION_TYPE === "wayland" &&

View file

@ -34,6 +34,10 @@ function validateValue(value: unknown): asserts value is string {
} }
export function getSecureStorageStatus(): DesktopSecureStorageStatus { export function getSecureStorageStatus(): DesktopSecureStorageStatus {
if (!safeStorage.isEncryptionAvailable()) {
return { available: false, backend: null };
}
const backend = const backend =
process.platform === "linux" process.platform === "linux"
? safeStorage.getSelectedStorageBackend() ? safeStorage.getSelectedStorageBackend()
@ -44,9 +48,7 @@ export function getSecureStorageStatus(): DesktopSecureStorageStatus {
: null; : null;
return { return {
available: available: process.platform !== "linux" || backend !== "basic_text",
safeStorage.isEncryptionAvailable() &&
(process.platform !== "linux" || backend !== "basic_text"),
backend, backend,
}; };
} }

View file

@ -1,18 +1,16 @@
import { useState, useCallback, useEffect } from "react"; import { useState, useCallback, useEffect } from "react";
import { useStorage } from "@tensamin/storage/context"; import { useStorage } from "@tensamin/storage/context";
import { import { Button } from "@tensamin/ui";
Button, import { Checkbox } from "@tensamin/ui";
Checkbox,
CreateScreen,
ErrorScreen,
Label,
Link,
Spinner,
} from "@tensamin/ui";
import { z } from "zod"; import { z } from "zod";
import { ErrorScreen } from "@tensamin/ui";
import { legalDocsSchema } from "@tensamin/shared/features/legal/schema"; import { legalDocsSchema } from "@tensamin/shared/features/legal/schema";
import { log } from "@tensamin/shared/log"; import { log } from "@tensamin/shared/log";
import { Link } from "@tensamin/ui";
import { Label } from "@tensamin/ui";
import { CreateScreen } from "@tensamin/ui";
// Prevents the user from using Tensamin without accepting the privacy policy and terms of service. // Prevents the user from using Tensamin without accepting the privacy policy and terms of service.
export default function Screen(props: { children: React.ReactNode }) { export default function Screen(props: { children: React.ReactNode }) {
@ -29,7 +27,6 @@ export default function Screen(props: { children: React.ReactNode }) {
>(undefined); >(undefined);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [showLoading, setShowLoading] = useState(false);
const [acceptedPP, acceptPP] = useState(false); const [acceptedPP, acceptPP] = useState(false);
const [acceptedTOS, acceptTOS] = useState(false); const [acceptedTOS, acceptTOS] = useState(false);
@ -52,7 +49,6 @@ export default function Screen(props: { children: React.ReactNode }) {
useEffect(() => { useEffect(() => {
let active = true; let active = true;
let loadingTimer: ReturnType<typeof setTimeout> | undefined;
void (async () => { void (async () => {
try { try {
@ -67,17 +63,22 @@ export default function Screen(props: { children: React.ReactNode }) {
return; return;
} }
loadingTimer = setTimeout(() => { const current = await fetch("https://legal.tensamin.net/api/current")
if (active) setShowLoading(true); .then((res) => res.json())
}, 200); .catch((err) => {
const response = await fetch("https://legal.tensamin.net/api/current");
if (!response.ok) {
throw new Error(`Legal documents request failed: ${response.status}`);
}
const current: unknown = await response.json();
if (!active) { if (!active) {
return undefined;
}
setError("Failed to load legal documents");
setErrorDescription(
"An error occurred while fetching the legal documents from the server. Please try again later.",
);
log(0, "Legal", "red", "Failed to fetch legal documents", err);
return undefined;
});
if (!active || current === undefined) {
return; return;
} }
@ -121,16 +122,7 @@ export default function Screen(props: { children: React.ReactNode }) {
!!currentLocalDocs && !!currentLocalDocs &&
currentLocalDocs.tos.hash === safeCurrent.data.tos.hash, currentLocalDocs.tos.hash === safeCurrent.data.tos.hash,
); );
} catch (err) {
if (!active) return;
setError("Failed to load legal documents");
setErrorDescription(
"An error occurred while fetching the legal documents from the server. Please try again later.",
);
log(0, "Legal", "red", "Failed to fetch legal documents", err);
} finally { } finally {
clearTimeout(loadingTimer);
if (active) { if (active) {
setLoading(false); setLoading(false);
} }
@ -139,7 +131,6 @@ export default function Screen(props: { children: React.ReactNode }) {
return () => { return () => {
active = false; active = false;
clearTimeout(loadingTimer);
}; };
}, [load]); }, [load]);
@ -148,22 +139,7 @@ export default function Screen(props: { children: React.ReactNode }) {
} }
if (loading || userId === undefined) { if (loading || userId === undefined) {
if (!showLoading) return null; return null;
return (
<CreateScreen>
<div className="flex flex-col items-center gap-3">
<Spinner className="size-8" />
<p className="text-sm text-muted-foreground">
Fetching legal documents...
</p>
<Link
label="status.methanium.net"
link="https://status.methanium.net"
/>
</div>
</CreateScreen>
);
} }
const docsMatch = const docsMatch =

View file

@ -53,7 +53,6 @@
libglvnd libglvnd
libnotify libnotify
libpulseaudio libpulseaudio
libsecret
libuuid libuuid
libxkbcommon libxkbcommon
mesa mesa
@ -105,8 +104,7 @@
cp -r usr/* "$out/" cp -r usr/* "$out/"
mkdir -p "$out/bin" mkdir -p "$out/bin"
makeWrapper "$out/opt/Tensamin/tensamin" "$out/bin/tensamin" \ makeWrapper "$out/opt/Tensamin/tensamin" "$out/bin/tensamin"
--prefix LD_LIBRARY_PATH : "${pkgs.lib.makeLibraryPath electronRuntimeLibs}"
substituteInPlace "$out/share/applications/Tensamin.desktop" \ substituteInPlace "$out/share/applications/Tensamin.desktop" \
--replace-fail "Exec=/opt/Tensamin/tensamin" "Exec=tensamin" --replace-fail "Exec=/opt/Tensamin/tensamin" "Exec=tensamin"
@ -174,7 +172,6 @@
libglvnd libglvnd
libnotify libnotify
libpulseaudio libpulseaudio
libsecret
libuuid libuuid
libxkbcommon libxkbcommon
mesa mesa

View file

@ -14,7 +14,6 @@
"build": "tsc -p tsconfig.json --noEmit" "build": "tsc -p tsconfig.json --noEmit"
}, },
"dependencies": { "dependencies": {
"@tauri-apps/api": "^2",
"@tensamin/cache": "workspace:*", "@tensamin/cache": "workspace:*",
"@tensamin/shared": "workspace:*", "@tensamin/shared": "workspace:*",
"@tensamin/mtp": "workspace:*", "@tensamin/mtp": "workspace:*",

View file

@ -1,10 +1,8 @@
import type {} from "@tensamin/shared/desktopMedia"; import type {} from "@tensamin/shared/desktopMedia";
import { isTauri } from "@tauri-apps/api/core";
import { getDatabaseEntry, setDatabaseEntry } from "@tensamin/shared/indexedDb"; import { getDatabaseEntry, setDatabaseEntry } from "@tensamin/shared/indexedDb";
export type SecureStorageStatus = { export type SecureStorageStatus = {
backend: backend: "electron-keyring" | "webcrypto" | "indexeddb";
"electron-keyring" | "application-storage" | "webcrypto" | "indexeddb";
secure: boolean; secure: boolean;
reason?: string; reason?: string;
}; };
@ -86,7 +84,6 @@ export function isSecureEnvelope(value: unknown): value is SecureEnvelope {
} }
export async function encodeSecureValue(value: unknown): Promise<unknown> { export async function encodeSecureValue(value: unknown): Promise<unknown> {
if (isTauri()) return value;
const key = await getKey(); const key = await getKey();
if (!key) return value; if (!key) return value;
const iv = crypto.getRandomValues(new Uint8Array(12)); const iv = crypto.getRandomValues(new Uint8Array(12));
@ -130,7 +127,6 @@ export async function getSecureStorageStatus(): Promise<SecureStorageStatus> {
: "Electron secure storage is unavailable.", : "Electron secure storage is unavailable.",
}; };
} }
if (isTauri()) return { backend: "application-storage", secure: true };
return (await getKey()) return (await getKey())
? { backend: "webcrypto", secure: true } ? { backend: "webcrypto", secure: true }
: { : {

3
pnpm-lock.yaml generated
View file

@ -818,9 +818,6 @@ importers:
packages/storage: packages/storage:
dependencies: dependencies:
'@tauri-apps/api':
specifier: ^2
version: 2.11.1
'@tensamin/cache': '@tensamin/cache':
specifier: workspace:* specifier: workspace:*
version: link:../cache version: link:../cache