Yuki / context /AuthContext.tsx
Severian's picture
Upload 43 files
be02369 verified
import React, { createContext, useState, useEffect, useCallback } from 'react';
import type { UserProfile } from '../types';
import { KOFI_LOGIN_NAME, KOFI_SECRET_PASSWORD } from '../config';
// Keys for localStorage
const CUSTOM_NAME_KEY = 'yuki-app-login-name';
const CUSTOM_SECRET_KEY = 'yuki-app-login-secret';
const SESSION_KEY = 'yuki-user-session';
interface IAuthContext {
user: UserProfile | null;
isLoading: boolean;
login: (name: string, secret: string) => boolean;
logout: () => void;
updateCredentials: (currentSecret: string, newName: string, newSecret: string) => { success: boolean; message: string };
}
export const AuthContext = createContext<IAuthContext>({
user: null,
isLoading: true,
login: () => false,
logout: () => {},
updateCredentials: () => ({ success: false, message: 'Not implemented' }),
});
const createAuthenticatedUser = (name: string): UserProfile => ({
id: `user-${name}`,
name: "Bonsai Master",
email: '', // Not needed for this auth model
picture: '', // Not needed for this auth model
});
export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [user, setUser] = useState<UserProfile | null>(null);
const [isLoading, setIsLoading] = useState(true);
const storageKey = 'yuki-user-session'; // Keep existing name for session for backward compatibility
useEffect(() => {
try {
const session = window.localStorage.getItem(storageKey);
if (session) {
const sessionUser = JSON.parse(session);
setUser(sessionUser);
}
} catch (error) {
console.error("Failed to parse user session:", error);
window.localStorage.removeItem(storageKey);
} finally {
setIsLoading(false);
}
}, [storageKey]);
const login = useCallback((name: string, secret: string): boolean => {
const customName = window.localStorage.getItem(CUSTOM_NAME_KEY);
const customSecret = window.localStorage.getItem(CUSTOM_SECRET_KEY);
const effectiveName = customName || KOFI_LOGIN_NAME;
const effectiveSecret = customSecret || KOFI_SECRET_PASSWORD;
if (name === effectiveName && secret === effectiveSecret) {
const authenticatedUser = createAuthenticatedUser(name);
try {
window.localStorage.setItem(storageKey, JSON.stringify(authenticatedUser));
setUser(authenticatedUser);
return true;
} catch (error) {
console.error("Failed to save user session:", error);
return false;
}
}
return false;
}, [storageKey]);
const logout = useCallback(() => {
try {
window.localStorage.removeItem(storageKey);
setUser(null);
} catch (error) {
console.error("Failed to clear user session:", error);
}
}, [storageKey]);
const updateCredentials = useCallback((currentSecret: string, newName: string, newSecret: string): { success: boolean; message: string } => {
const customSecret = window.localStorage.getItem(CUSTOM_SECRET_KEY);
const effectiveSecret = customSecret || KOFI_SECRET_PASSWORD;
if (currentSecret !== effectiveSecret) {
return { success: false, message: "Current secret password is incorrect." };
}
if (!newName.trim() || !newSecret.trim()) {
return { success: false, message: "New login name and secret cannot be empty." };
}
try {
window.localStorage.setItem(CUSTOM_NAME_KEY, newName);
window.localStorage.setItem(CUSTOM_SECRET_KEY, newSecret);
return { success: true, message: "Credentials updated successfully! You will need to use these next time you log in." };
} catch (error) {
console.error("Failed to update credentials:", error);
return { success: false, message: "Failed to save new credentials due to a storage error." };
}
}, []);
return (
<AuthContext.Provider value={{ user, isLoading, login, logout, updateCredentials }}>
{children}
</AuthContext.Provider>
);
};