Add logout function and ADMIN_PASSWORD environment validation
This commit is contained in:
@@ -151,6 +151,17 @@ export default function AdminPage() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleLogout = () => {
|
||||||
|
localStorage.removeItem('hoerdle_admin_auth');
|
||||||
|
setIsAuthenticated(false);
|
||||||
|
setPassword('');
|
||||||
|
// Reset all state
|
||||||
|
setSongs([]);
|
||||||
|
setGenres([]);
|
||||||
|
setSpecials([]);
|
||||||
|
setDailyPuzzles([]);
|
||||||
|
};
|
||||||
|
|
||||||
// Helper function to add auth headers to requests
|
// Helper function to add auth headers to requests
|
||||||
const getAuthHeaders = () => {
|
const getAuthHeaders = () => {
|
||||||
const authToken = localStorage.getItem('hoerdle_admin_auth');
|
const authToken = localStorage.getItem('hoerdle_admin_auth');
|
||||||
@@ -779,7 +790,24 @@ export default function AdminPage() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="admin-container">
|
<div className="admin-container">
|
||||||
<h1 className="title" style={{ marginBottom: '2rem' }}>Hördle Admin Dashboard</h1>
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '2rem' }}>
|
||||||
|
<h1 className="title" style={{ margin: 0 }}>Hördle Admin Dashboard</h1>
|
||||||
|
<button
|
||||||
|
onClick={handleLogout}
|
||||||
|
className="btn-secondary"
|
||||||
|
style={{
|
||||||
|
padding: '0.5rem 1rem',
|
||||||
|
backgroundColor: '#dc3545',
|
||||||
|
color: 'white',
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: '4px',
|
||||||
|
cursor: 'pointer',
|
||||||
|
fontSize: '0.9rem'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
🚪 Logout
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Special Management */}
|
{/* Special Management */}
|
||||||
<div className="admin-card" style={{ marginBottom: '2rem' }}>
|
<div className="admin-card" style={{ marginBottom: '2rem' }}>
|
||||||
|
|||||||
10
lib/auth.ts
10
lib/auth.ts
@@ -22,6 +22,16 @@ export async function requireAdminAuth(request: NextRequest): Promise<NextRespon
|
|||||||
*/
|
*/
|
||||||
export async function verifyAdminPassword(password: string): Promise<boolean> {
|
export async function verifyAdminPassword(password: string): Promise<boolean> {
|
||||||
const bcrypt = await import('bcryptjs');
|
const bcrypt = await import('bcryptjs');
|
||||||
|
|
||||||
|
// Validate that ADMIN_PASSWORD is set (security best practice)
|
||||||
|
if (!process.env.ADMIN_PASSWORD) {
|
||||||
|
console.error('SECURITY WARNING: ADMIN_PASSWORD environment variable is not set!');
|
||||||
|
// Fallback to default hash only in development
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
throw new Error('ADMIN_PASSWORD environment variable is required in production');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const adminPasswordHash = process.env.ADMIN_PASSWORD || '$2b$10$SHOt9G1qUNIvHoWre7499.eEtp5PtOII0daOQGNV.dhDEuPmOUdsq';
|
const adminPasswordHash = process.env.ADMIN_PASSWORD || '$2b$10$SHOt9G1qUNIvHoWre7499.eEtp5PtOII0daOQGNV.dhDEuPmOUdsq';
|
||||||
return bcrypt.compare(password, adminPasswordHash);
|
return bcrypt.compare(password, adminPasswordHash);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user