94 lines
2.9 KiB
TypeScript
94 lines
2.9 KiB
TypeScript
// routes/auth/login.ts
|
|
import { deleteCookie, getCookies, setCookie } from "$std/http/cookie.ts";
|
|
import { define } from "../../utils.ts";
|
|
import { generateNonce } from "../../services/stateMiddleware.ts";
|
|
|
|
const authority = Deno.env.get("AUTHORITY")!;
|
|
const clientId = Deno.env.get("CLIENT_ID")!;
|
|
const redirectUri = Deno.env.get("REDIRECT_URI")!;
|
|
|
|
export const handler = define.handlers({
|
|
GET(ctx) {
|
|
const nonce = generateNonce();
|
|
const authTraceId = crypto.randomUUID();
|
|
const cookies = getCookies(ctx.req.headers);
|
|
const _hasSession = !!cookies["session"];
|
|
const _hasState = !!cookies["xx_state_id"];
|
|
|
|
if (!authority || !clientId || !redirectUri) {
|
|
console.error("Missing environment variables");
|
|
return new Response("", {
|
|
status: 302,
|
|
headers: {
|
|
"Location": "/",
|
|
},
|
|
});
|
|
}
|
|
|
|
// Get return_path from query params (if user was redirected from a protected route)
|
|
const returnPath = ctx.url.searchParams.get("return_path") || "/";
|
|
|
|
const loginUrl =
|
|
`${authority}?client_id=${clientId}&scope=openid profile email&nonce=${nonce}&response_type=code&prompt=login&redirect_uri=${redirectUri}&state=${
|
|
encodeURIComponent(returnPath)
|
|
}`;
|
|
|
|
const response = new Response("", {
|
|
status: 302,
|
|
headers: {
|
|
"Location": loginUrl,
|
|
},
|
|
});
|
|
|
|
// Always clear stale auth cookies before initiating a fresh OAuth flow.
|
|
// This prevents "successful login" UX from an old session when callback fails.
|
|
deleteCookie(response.headers, "session", { path: "/" });
|
|
deleteCookie(response.headers, "xx_state_id", { path: "/" });
|
|
|
|
// Set return_path cookie for retrieval after OAuth callback
|
|
setCookie(response.headers, {
|
|
name: "return_path",
|
|
value: returnPath,
|
|
httpOnly: true,
|
|
expires: new Date(Date.now() + 10 * 60 * 1000), // 10 minutes expiry
|
|
secure: ctx.req.url.startsWith("https://"),
|
|
sameSite: "Lax",
|
|
path: "/",
|
|
});
|
|
|
|
setCookie(response.headers, {
|
|
name: "auth_trace_id",
|
|
value: authTraceId,
|
|
httpOnly: true,
|
|
expires: new Date(Date.now() + 10 * 60 * 1000),
|
|
secure: ctx.req.url.startsWith("https://"),
|
|
sameSite: "Lax",
|
|
path: "/",
|
|
});
|
|
|
|
return response;
|
|
},
|
|
// async POST(ctx) {
|
|
// const nonce = generateNonce();
|
|
// if (!authority || !clientId || !redirectUri) {
|
|
// console.error("Missing environment variables");
|
|
// return new Response("", {
|
|
// status: 302,
|
|
// headers: {
|
|
// "Location": "/",
|
|
// },
|
|
// });
|
|
// }
|
|
|
|
// const loginUrl =
|
|
// `${authority}?client_id=${clientId}&scope=openid&nonce=${nonce}&response_type=code&prompt=login&redirect_uri=${redirectUri}`;
|
|
|
|
// return new Response("", {
|
|
// status: 302,
|
|
// headers: {
|
|
// "Location": loginUrl,
|
|
// },
|
|
// });
|
|
// },
|
|
});
|