opensource
This commit is contained in:
177
src/auth.js
Normal file
177
src/auth.js
Normal file
@@ -0,0 +1,177 @@
|
||||
// src/auth.js
|
||||
const SESSION_COOKIE_NAME = 'session_id_89757';
|
||||
const SESSION_EXPIRATION_SECONDS = 60 * 60; // 1 hour
|
||||
|
||||
// Function to generate the login page HTML
|
||||
function generateLoginPage(redirectUrl) {
|
||||
return `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Login</title>
|
||||
<style>
|
||||
body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; background-color: #f4f4f4; margin: 0; }
|
||||
.login-container { background-color: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); width: 100%; max-width: 400px; text-align: center; }
|
||||
h2 { color: #333; margin-bottom: 20px; }
|
||||
.form-group { margin-bottom: 15px; text-align: left; }
|
||||
label { display: block; margin-bottom: 5px; color: #555; }
|
||||
input[type="text"], input[type="password"] { width: calc(100% - 20px); padding: 10px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box; }
|
||||
button { background-color: #007bff; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; width: 100%; }
|
||||
button:hover { background-color: #0056b3; }
|
||||
.error-message { color: red; margin-top: 10px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="login-container">
|
||||
<h2>Login</h2>
|
||||
<form id="loginForm" method="POST" action="/login">
|
||||
<div class="form-group">
|
||||
<label for="username">Username:</label>
|
||||
<input type="text" id="username" name="username" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password">Password:</label>
|
||||
<input type="password" id="password" name="password" required>
|
||||
</div>
|
||||
<input type="hidden" name="redirect" value="${redirectUrl}">
|
||||
<button type="submit">Login</button>
|
||||
<p id="errorMessage" class="error-message"></p>
|
||||
</form>
|
||||
<script>
|
||||
const form = document.getElementById('loginForm');
|
||||
const errorMessage = document.getElementById('errorMessage');
|
||||
form.addEventListener('submit', async (event) => {
|
||||
event.preventDefault();
|
||||
const formData = new FormData(form);
|
||||
const response = await fetch('/login', {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams(formData).toString(),
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
});
|
||||
if (response.ok) {
|
||||
const redirectUrl = response.headers.get('X-Redirect-Url');
|
||||
if (redirectUrl && redirectUrl !== '/') {
|
||||
window.location.href = redirectUrl;
|
||||
} else {
|
||||
window.location.href = '/getContentHtml'; // Fallback to home
|
||||
}
|
||||
} else {
|
||||
const errorText = await response.text();
|
||||
errorMessage.textContent = errorText || 'Login failed. Please try again.';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
}
|
||||
|
||||
// Function to set or renew the session cookie
|
||||
function setSessionCookie(sessionId) {
|
||||
const expirationDate = new Date(Date.now() + SESSION_EXPIRATION_SECONDS * 1000);
|
||||
return `${SESSION_COOKIE_NAME}=${sessionId}; Path=/; Expires=${expirationDate.toUTCString()}; HttpOnly; Secure; SameSite=Lax`;
|
||||
}
|
||||
|
||||
// Function to handle login requests
|
||||
async function handleLogin(request, env) {
|
||||
if (request.method === 'GET') {
|
||||
const url = new URL(request.url);
|
||||
const redirectUrl = url.searchParams.get('redirect') || '/getContentHtml';
|
||||
return new Response(generateLoginPage(redirectUrl), {
|
||||
headers: { 'Content-Type': 'text/html; charset=utf-8' },
|
||||
});
|
||||
} else if (request.method === 'POST') {
|
||||
const formData = await request.formData();
|
||||
const username = formData.get('username');
|
||||
const password = formData.get('password');
|
||||
const redirect = formData.get('redirect') || '/';
|
||||
|
||||
if (username === env.LOGIN_USERNAME && password === env.LOGIN_PASSWORD) {
|
||||
const sessionId = crypto.randomUUID(); // Generate a simple session ID
|
||||
|
||||
// Store sessionId in KV store for persistent sessions
|
||||
// await env.DATA_KV.put(`session:${sessionId}`, 'valid', { expirationTtl: SESSION_EXPIRATION_SECONDS });
|
||||
|
||||
const cookie = setSessionCookie(sessionId);
|
||||
|
||||
return new Response('Login successful', {
|
||||
status: 200,
|
||||
headers: {
|
||||
'Set-Cookie': cookie,
|
||||
'X-Redirect-Url': redirect, // Custom header for client-side redirect
|
||||
},
|
||||
});
|
||||
} else {
|
||||
return new Response('Invalid username or password', { status: 401 });
|
||||
}
|
||||
}
|
||||
return new Response('Method Not Allowed', { status: 405 });
|
||||
}
|
||||
|
||||
// Function to check and renew session cookie
|
||||
async function isAuthenticated(request, env) {
|
||||
const cookieHeader = request.headers.get('Cookie');
|
||||
if (!cookieHeader) {
|
||||
return { authenticated: false, cookie: null };
|
||||
}
|
||||
|
||||
const cookies = cookieHeader.split(';').map(c => c.trim());
|
||||
const sessionCookie = cookies.find(cookie => cookie.startsWith(`${SESSION_COOKIE_NAME}=`));
|
||||
|
||||
if (!sessionCookie) {
|
||||
return { authenticated: false, cookie: null };
|
||||
}
|
||||
|
||||
const sessionId = sessionCookie.split('=')[1];
|
||||
|
||||
// Validate sessionId against KV store
|
||||
// const storedSession = await env.DATA_KV.get(`session:${sessionId}`);
|
||||
// if (storedSession !== 'valid') {
|
||||
// return { authenticated: false, cookie: null };
|
||||
// }
|
||||
|
||||
// Renew the session cookie
|
||||
const newCookie = setSessionCookie(sessionId);
|
||||
return { authenticated: true, cookie: newCookie };
|
||||
}
|
||||
|
||||
// Function to handle logout requests
|
||||
async function handleLogout(request, env) {
|
||||
const cookieHeader = request.headers.get('Cookie');
|
||||
if (cookieHeader) {
|
||||
const cookies = cookieHeader.split(';').map(c => c.trim());
|
||||
const sessionCookie = cookies.find(cookie => cookie.startsWith(`${SESSION_COOKIE_NAME}=`));
|
||||
if (sessionCookie) {
|
||||
const sessionId = sessionCookie.split('=')[1];
|
||||
// Delete session from KV store
|
||||
// await env.DATA_KV.delete(`session:${sessionId}`);
|
||||
}
|
||||
}
|
||||
|
||||
const expiredDate = new Date(0); // Set expiration to a past date
|
||||
const cookie = `${SESSION_COOKIE_NAME}=; Path=/; Expires=${expiredDate.toUTCString()}; HttpOnly; Secure; SameSite=Lax`;
|
||||
|
||||
const url = new URL(request.url);
|
||||
const redirectUrl = url.searchParams.get('redirect') || '/login'; // Redirect to login page by default
|
||||
|
||||
return new Response('Logged out', {
|
||||
status: 302,
|
||||
headers: {
|
||||
'Set-Cookie': cookie,
|
||||
'Location': redirectUrl,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export {
|
||||
handleLogin,
|
||||
isAuthenticated,
|
||||
handleLogout,
|
||||
SESSION_COOKIE_NAME,
|
||||
SESSION_EXPIRATION_SECONDS,
|
||||
};
|
||||
Reference in New Issue
Block a user