67 lines
2 KiB
JavaScript
67 lines
2 KiB
JavaScript
/**
|
|
* Netlify Function for secure login
|
|
* Password is stored as environment variable on server, never exposed to frontend
|
|
*/
|
|
|
|
exports.handler = async (event) => {
|
|
// Only allow POST requests
|
|
if (event.httpMethod !== 'POST') {
|
|
return {
|
|
statusCode: 405,
|
|
body: JSON.stringify({ error: 'Method not allowed' })
|
|
};
|
|
}
|
|
|
|
try {
|
|
// Parse request body
|
|
const body = JSON.parse(event.body);
|
|
const submittedPassword = body.password;
|
|
|
|
if (!submittedPassword) {
|
|
return {
|
|
statusCode: 400,
|
|
body: JSON.stringify({ error: 'Password required' })
|
|
};
|
|
}
|
|
|
|
// Get correct password from environment variable (set in Netlify UI)
|
|
const correctPassword = process.env.SMARTCANE_PASSWORD;
|
|
|
|
if (!correctPassword) {
|
|
console.error('SMARTCANE_PASSWORD environment variable not set');
|
|
return {
|
|
statusCode: 500,
|
|
body: JSON.stringify({ error: 'Server configuration error' })
|
|
};
|
|
}
|
|
|
|
// Compare passwords
|
|
if (submittedPassword === correctPassword) {
|
|
return {
|
|
statusCode: 200,
|
|
headers: {
|
|
'Set-Cookie': `auth_token=smartcane_${Date.now()}; Path=/; SameSite=Strict; Secure; HttpOnly`
|
|
},
|
|
body: JSON.stringify({
|
|
success: true,
|
|
message: 'Login successful'
|
|
})
|
|
};
|
|
} else {
|
|
// Add delay to prevent brute force
|
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
|
|
return {
|
|
statusCode: 401,
|
|
body: JSON.stringify({ error: 'Invalid password' })
|
|
};
|
|
}
|
|
} catch (error) {
|
|
console.error('Login error:', error);
|
|
return {
|
|
statusCode: 500,
|
|
body: JSON.stringify({ error: 'Server error' })
|
|
};
|
|
}
|
|
};
|