Migrate from electron-store to OS-level secure storage (getSecureStorage)
- Replace `electron-store` with OS-level encrypted storage for secure token, userId, and language management in `LocalSystem` and `keyManager`. - Add `init-user` IPC handler to initialize user data and manage encryption keys. - Update login process to handle encrypted storage saving with fallback for macOS issues. - Add offline warning component to `login/page.tsx` to handle first-time sync requirements. - Remove `electron-store` and associated dependencies from `package.json` and `package-lock.json`.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
'use client'
|
||||
import {useContext} from 'react';
|
||||
import {useContext, useEffect, useState} from 'react';
|
||||
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
||||
import {faEnvelope} from "@fortawesome/free-solid-svg-icons";
|
||||
import {faEnvelope, faWifi, faCloudArrowUp} from "@fortawesome/free-solid-svg-icons";
|
||||
import LoginForm from "@/app/login/login/LoginForm";
|
||||
import SocialForm from "@/app/login/login/SocialForm";
|
||||
import {useTranslations} from "next-intl";
|
||||
@@ -11,13 +11,67 @@ import System from "@/lib/models/System";
|
||||
export default function LoginPage() {
|
||||
const t = useTranslations();
|
||||
const {lang, setLang} = useContext(LangContext);
|
||||
|
||||
const [showOfflineWarning, setShowOfflineWarning] = useState(false);
|
||||
const [isOnline, setIsOnline] = useState(true);
|
||||
|
||||
const toggleLanguage = () => {
|
||||
const newLang = lang === 'fr' ? 'en' : 'fr';
|
||||
setLang(newLang);
|
||||
System.setCookie('lang', newLang, 365);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
async function checkFirstConnectionAndNetwork() {
|
||||
// Check if we're in Electron
|
||||
if (!window.electron) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Check if token exists (first connection)
|
||||
const token = await window.electron.getToken();
|
||||
const hasToken = !!token;
|
||||
|
||||
// Check network status
|
||||
const online = navigator.onLine;
|
||||
setIsOnline(online);
|
||||
|
||||
// Show warning if first connection AND offline
|
||||
if (!hasToken && !online) {
|
||||
setShowOfflineWarning(true);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error checking first connection:', error);
|
||||
}
|
||||
}
|
||||
|
||||
checkFirstConnectionAndNetwork();
|
||||
|
||||
// Listen for online/offline events
|
||||
const handleOnline = () => {
|
||||
setIsOnline(true);
|
||||
setShowOfflineWarning(false);
|
||||
};
|
||||
const handleOffline = async () => {
|
||||
setIsOnline(false);
|
||||
// Check if token exists
|
||||
if (window.electron) {
|
||||
const token = await window.electron.getToken();
|
||||
if (!token) {
|
||||
setShowOfflineWarning(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('online', handleOnline);
|
||||
window.addEventListener('offline', handleOffline);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('online', handleOnline);
|
||||
window.removeEventListener('offline', handleOffline);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<main className="flex min-h-screen flex-col items-center justify-center bg-background text-textPrimary p-4">
|
||||
<div className="w-full max-w-md px-4 py-10">
|
||||
@@ -32,6 +86,29 @@ export default function LoginPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Offline warning notification */}
|
||||
{showOfflineWarning && (
|
||||
<div className="mb-6 bg-gradient-to-r from-orange-500/20 to-amber-500/20 border border-orange-500/40 rounded-xl p-4 shadow-lg shadow-orange-500/10">
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="flex-shrink-0 mt-0.5">
|
||||
<div className="relative">
|
||||
<FontAwesomeIcon icon={faWifi} className="w-5 h-5 text-orange-400" />
|
||||
<div className="absolute inset-0 w-6 h-0.5 bg-orange-400 rotate-45 top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<h3 className="font-semibold text-orange-200 mb-1 flex items-center gap-2">
|
||||
<FontAwesomeIcon icon={faCloudArrowUp} className="w-4 h-4" />
|
||||
{t('loginPage.offlineWarning.title')}
|
||||
</h3>
|
||||
<p className="text-sm text-orange-300/90 leading-relaxed">
|
||||
{t('loginPage.offlineWarning.message')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
className="bg-tertiary rounded-2xl overflow-hidden shadow-xl shadow-primary/10 w-full relative">
|
||||
<button
|
||||
|
||||
Reference in New Issue
Block a user