Skip to content

fix: solidstart/github-oauth: update to current versions #51

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions solidstart/github-oauth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,20 @@
"start": "node ./.output/server/index.mjs"
},
"dependencies": {
"@lucia-auth/adapter-sqlite": "^3.0.0",
"@solidjs/router": "^0.10.5",
"@solidjs/start": "^0.4.2",
"arctic": "^0.10.2",
"better-sqlite3": "^9.2.2",
"lucia": "^3.2.0",
"solid-js": "^1.8.7",
"vinxi": "0.0.54"
"@lucia-auth/adapter-sqlite": "^3.0.2",
"@solidjs/router": "^0.14.10",
"@solidjs/start": "^1.0.9",
"arctic": "^1.9.2",
"better-sqlite3": "^9.6.0",
"lucia": "^3.2.1",
"solid-js": "^1.9.2",
"vinxi": "^0.4.3"
},
"engines": {
"node": ">=18"
},
"devDependencies": {
"@types/better-sqlite3": "^7.6.8"
"@types/better-sqlite3": "^7.6.8",
"typescript": "^5.6.3"
}
}
2 changes: 1 addition & 1 deletion solidstart/github-oauth/src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Router } from "@solidjs/router";
import { FileRoutes } from "@solidjs/start";
import { FileRoutes } from "@solidjs/start/router";
import { Suspense } from "solid-js";

export default function App() {
Expand Down
2 changes: 1 addition & 1 deletion solidstart/github-oauth/src/entry-client.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { mount, StartClient } from "@solidjs/start/client";

mount(() => <StartClient />, document.getElementById("app"));
mount(() => <StartClient />, document.getElementById("app")!);
4 changes: 2 additions & 2 deletions solidstart/github-oauth/src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { getRequestEvent } from "solid-js/web";
export const getAuthenticatedUser = cache(async () => {
"use server";
const event = getRequestEvent()!;
if (!event.context.user) {
if (!event.locals.user) {
throw redirect("/login");
}
return event.context.user;
return event.locals.user;
}, "user");
34 changes: 18 additions & 16 deletions solidstart/github-oauth/src/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,41 @@
import { createMiddleware, appendHeader, getCookie, getHeader } from "@solidjs/start/server";
import { createMiddleware} from "@solidjs/start/middleware";
import { Session, User, verifyRequestOrigin } from "lucia";
import { lucia } from "./lib/auth";
import { appendHeader, getCookie, getHeader } from "vinxi/http";
import { FetchEvent } from "@solidjs/start/server";

export default createMiddleware({
onRequest: async (event) => {
if (event.node.req.method !== "GET") {
const originHeader = getHeader(event, "Origin") ?? null;
const hostHeader = getHeader(event, "Host") ?? null;
onRequest: [ async (event: FetchEvent) => {
if (event.request.method !== "GET") {
const originHeader = getHeader("Origin") ?? null;
const hostHeader = getHeader( "Host") ?? null;
if (!originHeader || !hostHeader || !verifyRequestOrigin(originHeader, [hostHeader])) {
event.node.res.writeHead(403).end();
event.response.status = 403;
return;
}
}

const sessionId = getCookie(event, lucia.sessionCookieName) ?? null;
const sessionId = getCookie(lucia.sessionCookieName) ?? null;
if (!sessionId) {
event.context.session = null;
event.context.user = null;
event.locals.session = null;
event.locals.user = null;
return;
}

const { session, user } = await lucia.validateSession(sessionId);
if (session && session.fresh) {
appendHeader(event, "Set-Cookie", lucia.createSessionCookie(session.id).serialize());
appendHeader("Set-Cookie", lucia.createSessionCookie(session.id).serialize());
}
if (!session) {
appendHeader(event, "Set-Cookie", lucia.createBlankSessionCookie().serialize());
appendHeader("Set-Cookie", lucia.createBlankSessionCookie().serialize());
}
event.context.session = session;
event.context.user = user;
}
event.locals.session = session;
event.locals.user = user;
}]
});

declare module "vinxi/server" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is context.Locals typed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In createMiddleware, I updated the code to add a type declaration to the event: FetchEvent so that the types will be more clear to anyone looking at the code.

To answer your question, event.locals is of type RequestEventLocals, which is of type:

export interface RequestEventLocals {
    [key: string | symbol]: any;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there no way to override the RequestEventLocals type?

Copy link
Author

@greglearns greglearns Oct 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code added to overide/clarify the RequestEventLocals type addition.

(Oh my gosh...on a different, funny tangential note, re-reading this thread before I submit my comment... I suddenly had a surreal feeling just now that this thread sounds a little like a ChatGPT code interaction :-) Then I thought, "I am not a LLM!", but then I though, "Would anyone know if I were?" Like a reverse Turing test! I really am a human.)(And since text doesn't communicate emotion or intention, I'm laughing as I write this!) (By the way, this is a great chance for me to thank you for Artic, Oslo, and your re-purposing Lucia as an education opportunity. I really appreciate it, and I thank you. I agree with your decision about Lucia, and it has benefited me. I'm glad that I'm able to give back in this little way of providing some code back to you.).

interface H3EventContext {
declare module "@solidjs/start/server" {
interface RequestEventLocals {
user: User | null;
session: Session | null;
}
Expand Down
10 changes: 5 additions & 5 deletions solidstart/github-oauth/src/routes/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { action, createAsync, redirect } from "@solidjs/router";
import { getRequestEvent } from "solid-js/web";
import { appendHeader } from "@solidjs/start/server";
import { appendHeader } from "vinxi/http";
import { lucia } from "~/lib/auth";
import { getAuthenticatedUser } from "~/lib/utils";

export default function Index() {
const user = createAsync(getAuthenticatedUser);
const user = createAsync(() => getAuthenticatedUser());
return (
<>
<h1>Hi, {user()?.username}!</h1>
Expand All @@ -20,10 +20,10 @@ export default function Index() {
const logout = action(async () => {
"use server";
const event = getRequestEvent()!;
if (!event.context.session) {
if (!event.locals.session) {
return new Error("Unauthorized");
}
await lucia.invalidateSession(event.context.session.id);
appendHeader(event, "Set-Cookie", lucia.createBlankSessionCookie().serialize());
await lucia.invalidateSession(event.locals.session.id);
appendHeader("Set-Cookie", lucia.createBlankSessionCookie().serialize());
throw redirect("/login");
});
22 changes: 7 additions & 15 deletions solidstart/github-oauth/src/routes/login/github/callback.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
import {
getQuery,
createError,
getCookie,
appendHeader,
sendRedirect
} from "@solidjs/start/server";
import { OAuth2RequestError } from "arctic";
import { generateId } from "lucia";
import { github, lucia } from "~/lib/auth";
import { db } from "~/lib/db";

import type { APIEvent } from "@solidjs/start/server";
import type { DatabaseUser } from "~/lib/db";
import { appendHeader, createError, getCookie, getQuery, HTTPEvent, sendRedirect } from "vinxi/http";

export async function GET(event: APIEvent) {
export async function GET(event: HTTPEvent) {
const query = getQuery(event);
const code = query.code?.toString() ?? null;
const state = query.state?.toString() ?? null;
const storedState = getCookie(event, "github_oauth_state") ?? null;
const storedState = getCookie("github_oauth_state") ?? null;
if (!code || !state || !storedState || state !== storedState) {
throw createError({
status: 400
Expand All @@ -38,8 +30,8 @@ export async function GET(event: APIEvent) {

if (existingUser) {
const session = await lucia.createSession(existingUser.id, {});
appendHeader(event, "Set-Cookie", lucia.createSessionCookie(session.id).serialize());
return sendRedirect(event, "/");
appendHeader("Set-Cookie", lucia.createSessionCookie(session.id).serialize());
return sendRedirect("/");
}

const userId = generateId(15);
Expand All @@ -49,8 +41,8 @@ export async function GET(event: APIEvent) {
githubUser.login
);
const session = await lucia.createSession(userId, {});
appendHeader(event, "Set-Cookie", lucia.createSessionCookie(session.id).serialize());
return sendRedirect(event, "/");
appendHeader("Set-Cookie", lucia.createSessionCookie(session.id).serialize());
return sendRedirect("/");
} catch (e) {
if (e instanceof OAuth2RequestError && e.message === "bad_verification_code") {
// invalid code
Expand Down
6 changes: 3 additions & 3 deletions solidstart/github-oauth/src/routes/login/github/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { sendRedirect, setCookie } from "@solidjs/start/server";
import { sendRedirect, setCookie } from "vinxi/http";
import { generateState } from "arctic";
import { github } from "~/lib/auth";

Expand All @@ -8,12 +8,12 @@ export async function GET(event: APIEvent) {
const state = generateState();
const url = await github.createAuthorizationURL(state);

setCookie(event, "github_oauth_state", state, {
setCookie("github_oauth_state", state, {
path: "/",
secure: process.env.NODE_ENV === "production",
httpOnly: true,
maxAge: 60 * 10,
sameSite: "lax"
});
return sendRedirect(event, url.toString());
return sendRedirect(url.toString());
}
4 changes: 1 addition & 3 deletions solidstart/github-oauth/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { defineConfig } from "@solidjs/start/config";

export default defineConfig({
start: {
middleware: "./src/middleware.ts"
}
middleware: "./src/middleware.ts"
});