(request, env)
| 228 | |
| 229 | export default { |
| 230 | async fetch(request, env): Promise<Response> { |
| 231 | try { |
| 232 | const url = new URL(request.url); |
| 233 | const method = request.method; |
| 234 | const isRead = method === 'GET' || method === 'HEAD'; |
| 235 | |
| 236 | // --- unauthenticated surface: exactly these three routes --------------- |
| 237 | if (isRead && url.pathname === '/robots.txt') { |
| 238 | return new Response(ROBOTS_TXT, { headers: { 'content-type': 'text/plain; charset=utf-8' } }); |
| 239 | } |
| 240 | if (url.pathname === '/login') { |
| 241 | if (isRead) return await handleLoginPage(env, request, url); |
| 242 | if (method === 'POST') return await handleLoginSubmit(env, request); |
| 243 | return new Response('method not allowed\n', { status: 405, headers: { allow: 'GET, POST' } }); |
| 244 | } |
| 245 | if (url.pathname === '/logout') { |
| 246 | if (method !== 'POST') { |
| 247 | return new Response('method not allowed\n', { status: 405, headers: { allow: 'POST' } }); |
| 248 | } |
| 249 | if (!isSameOriginPost(request)) return new Response('bad request\n', { status: 400 }); |
| 250 | return redirect('/login', { headers: { 'set-cookie': clearedSessionCookie() } }); |
| 251 | } |
| 252 | |
| 253 | // --- everything else needs a session ----------------------------------- |
| 254 | const isApi = url.pathname === '/api' || url.pathname.startsWith('/api/'); |
| 255 | if (!(await hasValidSession(env, request))) { |
| 256 | return isApi ? json({ error: 'unauthorized' }, { status: 401 }) : loginRedirect(url); |
| 257 | } |
| 258 | |
| 259 | if (isApi) { |
| 260 | if (!isRead) { |
| 261 | return json({ error: 'method not allowed' }, { status: 405, headers: { allow: 'GET' } }); |
| 262 | } |
| 263 | return await apiResponse(env, url); |
| 264 | } |
| 265 | |
| 266 | if (!isRead) { |
| 267 | return new Response('method not allowed\n', { status: 405, headers: { allow: 'GET' } }); |
| 268 | } |
| 269 | return await serveAsset(env, request); |
| 270 | } catch (err) { |
| 271 | console.error(JSON.stringify({ msg: 'unhandled error', err: String(err) })); |
| 272 | return new Response('internal error\n', { status: 500 }); |
| 273 | } |
| 274 | }, |
| 275 | } satisfies ExportedHandler<Env>; |
no test coverage detected