Versions

  • v16

    8/10/2024
    Open: Version
    Changes from v15 to v16
    +14
    -27
    ⦚ 7 unchanged lines ⦚
    import { Lucia, Session, User } from "npm:lucia@3.0.1";
    import { renderToString } from "npm:react-dom/server";

    const userTable = "user";
    ⦚ 21 unchanged lines ⦚
    }

    function getCookie(req: Request, name: string): string | null {
    const cookieString = req.headers.get("Cookie");
    if (!cookieString) return null;
    const cookies = cookieString.split(";").map(cookie => cookie.trim().split("="));
    const cookie = cookies.find(([key]) => key === name);
    return cookie ? decodeURIComponent(cookie[1]) : null;
    }

    function setCookie(res: Response, name: string, value: string, options: Record<string, string> = {}): Response {
    const cookieString = `${name}=${encodeURIComponent(value)}${
    Object.entries(options).map(([key, val]) => `; ${key}=${val}`).join("")
    }`;
    const newHeaders = new Headers(res.headers);
    newHeaders.append("Set-Cookie", cookieString);
    return new Response(res.body, {
    status: res.status,
    statusText: res.statusText,
    headers: newHeaders
    });
    }

    // Helper function for redirects
    function redirect(url: string, status = 302): Response {
    ⦚ 7 unchanged lines ⦚
    return async (req: Request) => {
    ⦚ 7 unchanged lines ⦚
    import { Lucia, Session, User } from "npm:lucia@3.0.1";
    import { renderToString } from "npm:react-dom/server";
    import { CookieJar } from "https://deno.land/x/cookies/mod.ts";

    const userTable = "user";
    ⦚ 21 unchanged lines ⦚
    }

    // Helper function for redirects
    function redirect(url: string, status = 302): Response {
    ⦚ 7 unchanged lines ⦚
    return async (req: Request) => {
    const url = new URL(req.url);
    const cookies = new CookieJar(req);
    const sessionId = cookies.get(lucia.sessionCookieName) ?? null;
    let user: User | null = null;
    let session: Session | null = null;
    ⦚ 59 unchanged lines ⦚
    const session = await lucia.createSession(userID, {});
    response = redirect("/");
    const cookieJar = new CookieJar(req, response);
    const sessionCookie = lucia.createSessionCookie(session.id);
    cookieJar.set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
    console.log("Created user", userID);
    } catch (err) {
    ⦚ 46 unchanged lines ⦚
    const session = await lucia.createSession(user.id, {});
    response = redirect("/");
    const cookieJar = new CookieJar(req, response);
    const sessionCookie = lucia.createSessionCookie(session.id);
    cookieJar.set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
  • v15

    8/10/2024
    Open: Version
    Changes from v14 to v15
    +5
    -5
    ⦚ 128 unchanged lines ⦚
    const session = await lucia.createSession(userID, {});
    response = redirect("/");
    response = setCookie(response, lucia.sessionCookieName, session.id, lucia.createSessionCookie(session.id).attributes);
    console.log("Created user", userID);
    } catch (err) {
    ⦚ 47 unchanged lines ⦚
    response = redirect("/");
    const sessionCookie = lucia.createSessionCookie(session.id);
    response = setCookie(response, sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
    } else if (url.pathname === "/auth/logout") {
    if (session) {
    await lucia.invalidateSession(session.id);
    }
    response = redirect("/");
    const sessionCookie = lucia.createBlankSessionCookie();
    response = setCookie(response, sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
    } else {
    const clonedReq = new Request(req.url, {
    ⦚ 10 unchanged lines ⦚
    if (session && session.fresh) {
    const sessionCookie = lucia.createSessionCookie(session.id);
    response = setCookie(response, sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
    }

    if (!session) {
    const sessionCookie = lucia.createBlankSessionCookie();
    response = setCookie(response, sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
    }

    ⦚ 19 unchanged lines ⦚
    ⦚ 128 unchanged lines ⦚
    const session = await lucia.createSession(userID, {});
    response = redirect("/");
    response = setCookie(response, lucia.sessionCookieName, session.id, lucia.createSessionCookie(session.id).attributes as Record<string, string>);
    console.log("Created user", userID);
    } catch (err) {
    ⦚ 47 unchanged lines ⦚
    response = redirect("/");
    const sessionCookie = lucia.createSessionCookie(session.id);
    response = setCookie(response, sessionCookie.name, sessionCookie.value, sessionCookie.attributes as Record<string, string>);
    } else if (url.pathname === "/auth/logout") {
    if (session) {
    await lucia.invalidateSession(session.id);
    }
    response = redirect("/");
    const sessionCookie = lucia.createBlankSessionCookie();
    response = setCookie(response, sessionCookie.name, sessionCookie.value, sessionCookie.attributes as Record<string, string>);
    } else {
    const clonedReq = new Request(req.url, {
    ⦚ 10 unchanged lines ⦚
    if (session && session.fresh) {
    const sessionCookie = lucia.createSessionCookie(session.id);
    response = setCookie(response, sessionCookie.name, sessionCookie.value, sessionCookie.attributes as Record<string, string>);
    }

    if (!session) {
    const sessionCookie = lucia.createBlankSessionCookie();
    response = setCookie(response, sessionCookie.name, sessionCookie.value, sessionCookie.attributes as Record<string, string>);
    }

    ⦚ 19 unchanged lines ⦚
  • v14

    8/10/2024
    Open: Version
    Changes from v13 to v14
    +8
    -4
    ⦚ 179 unchanged lines ⦚
    const session = await lucia.createSession(user.id, {});
    response = redirect("/");
    response = setCookie(response, lucia.sessionCookieName, session.id, lucia.createSessionCookie(session.id).attributes);
    } else if (url.pathname === "/auth/logout") {
    if (session) {
    await lucia.invalidateSession(session.id);
    }
    response = redirect("/");
    response = setCookie(response, lucia.sessionCookieName, "", lucia.createBlankSessionCookie().attributes);
    } else {
    const clonedReq = new Request(req.url, {
    ⦚ 9 unchanged lines ⦚

    if (session && session.fresh) {
    response = setCookie(response, lucia.sessionCookieName, session.id, lucia.createSessionCookie(session.id).attributes);
    }

    if (!session) {
    response = setCookie(response, lucia.sessionCookieName, "", lucia.createBlankSessionCookie().attributes);
    }

    ⦚ 19 unchanged lines ⦚
    ⦚ 179 unchanged lines ⦚
    const session = await lucia.createSession(user.id, {});
    response = redirect("/");
    const sessionCookie = lucia.createSessionCookie(session.id);
    response = setCookie(response, sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
    } else if (url.pathname === "/auth/logout") {
    if (session) {
    await lucia.invalidateSession(session.id);
    }
    response = redirect("/");
    const sessionCookie = lucia.createBlankSessionCookie();
    response = setCookie(response, sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
    } else {
    const clonedReq = new Request(req.url, {
    ⦚ 9 unchanged lines ⦚

    if (session && session.fresh) {
    const sessionCookie = lucia.createSessionCookie(session.id);
    response = setCookie(response, sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
    }

    if (!session) {
    const sessionCookie = lucia.createBlankSessionCookie();
    response = setCookie(response, sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
    }

    ⦚ 19 unchanged lines ⦚
  • v13

    8/10/2024
    Open: Version
    +227
    -0

    // This approach uses the Lucia authentication library with a custom ValTownAdapter.
    // It provides signup, login, and logout functionality with session management.
    // The main tradeoff is the complexity of setting up Lucia, but it offers robust auth features.

    /** @jsxImportSource https://esm.sh/react */
    import { ValTownAdapter } from "https://esm.town/v/stevekrouse/lucia_adapter";
    import { createUser, getUser, verifyPassword } from "https://esm.town/v/stevekrouse/lucia_sqlite";
    import { Lucia, Session, User } from "npm:lucia@3.0.1";
    import { renderToString } from "npm:react-dom/server";

    const userTable = "user";
    const sessionTable = "session";

    const adapter = new ValTownAdapter({ userTable, sessionTable });

    export const lucia = new Lucia(adapter, {
    getUserAttributes: (attributes) => {
    return {
    username: attributes.username,
    };
    },
    });

    declare module "npm:lucia" {
    interface Register {
    Lucia: typeof lucia;
    DatabaseUserAttributes: DatabaseUserAttributes;
    }
    }

    interface DatabaseUserAttributes {
    username: string;
    }

    function getCookie(req: Request, name: string): string | null {
    const cookieString = req.headers.get("Cookie");