Working one-time message encryption and decryption

This commit is contained in:
2025-12-03 16:40:26 +03:00
Unverified
parent d4b1e261d7
commit fcb3dff2c9
18 changed files with 1392 additions and 336 deletions
+10 -3
View File
@@ -1,12 +1,13 @@
import { AuthContainer } from "./Auth";
import { useState, useEffect, useRef, useLayoutEffect, useCallback, type RefObject } from "react";
import { useNavigate, useSearchParams } from "react-router-dom";
import { useNavigate, useSearchParams, Navigate } from "react-router-dom";
import { motion, AnimatePresence } from "motion/react";
import useDownloadAppScreen from "@/core/hooks/useDownloadAppScreen";
import { LoginForm } from "./LoginForm";
import { RegisterForm } from "./RegisterForm";
import type { Variants, Transition } from "motion/react";
import styles from "./auth.module.scss";
import { useUserStore } from "@/state/user";
const slideVariants: Variants = {
enter: (direction: number) => ({
@@ -37,9 +38,9 @@ const slideTransition: Transition = {
export default function AuthPage() {
const [searchParams] = useSearchParams();
const { navigate: navigateDownloadApp } = useDownloadAppScreen();
if (navigateDownloadApp) return navigateDownloadApp;
const navigate = useNavigate();
const { user } = useUserStore();
const [direction, setDirection] = useState(0);
const prevMode = useRef(searchParams.get("mode") || "login");
const containerRef = useRef<HTMLDivElement>(null);
@@ -90,6 +91,12 @@ export default function AuthPage() {
}
};
}, [currentMode]);
// Now we can do conditional returns after all hooks are called
if (navigateDownloadApp) return navigateDownloadApp;
if (user.authToken && user.currentUser) {
return <Navigate to="/chat" replace />;
}
function switchMode(newMode: "login" | "register") {
navigate(`/auth?mode=${newMode}`, { replace: true });
+23 -7
View File
@@ -93,14 +93,30 @@ export function LoginForm({ onSwitchMode }: LoginFormProps) {
try {
await api.user.auth.ensureKeysOnLogin(password, data.token);
// Initialize Signal Protocol after keys are set up
// Initialize Signal Protocol after keys are set up (non-blocking)
if (data.user?.id) {
const { SignalProtocolService } = await import("@/utils/crypto/signalProtocol");
const { uploadPreKeyBundle } = await import("@/core/api/crypto");
const signalService = new SignalProtocolService(data.user.id.toString());
await signalService.initialize();
const bundle = await signalService.getPreKeyBundle();
await uploadPreKeyBundle(bundle, data.token);
// Run Signal Protocol initialization in background to avoid blocking navigation
(async () => {
try {
const { SignalProtocolService } = await import("@/utils/crypto/signalProtocol");
const { uploadPreKeyBundle, uploadAllPreKeys } = await import("@/core/api/crypto/prekeys");
const signalService = new SignalProtocolService(data.user!.id.toString());
await signalService.initialize();
// Upload base bundle with one prekey (for backward compatibility)
const bundle = await signalService.getPreKeyBundle();
await uploadPreKeyBundle(bundle, data.token);
// Upload all prekeys for server-side rotation
const baseBundle = await signalService.getBaseBundle();
const prekeys = await signalService.getAllPreKeys();
await uploadAllPreKeys(baseBundle, prekeys, data.token);
console.log(`Uploaded ${prekeys.length} prekeys to server`);
} catch (e) {
console.error("Key setup failed:", e);
}
})();
}
} catch (e) {
console.error("Key setup failed:", e);