Skip to content
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

Upgrade SolidStart to v1 #35

Open
wants to merge 7 commits 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
3 changes: 3 additions & 0 deletions package.json

Choose a reason for hiding this comment

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

Why was Typescript added as a dependency to the root project?

Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,8 @@
"prettier": "^3.0.3",
"prettier-plugin-astro": "^0.12.0",
"prettier-plugin-svelte": "^3.0.3"
},
"dependencies": {
"typescript": "^5.4.5"
}
}
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"
});
22 changes: 10 additions & 12 deletions solidstart/github-oauth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,18 @@
"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.0.1",
"oslo": "^1.0.3",
"solid-js": "^1.8.7",
"vinxi": "0.0.54"
"@lucia-auth/adapter-sqlite": "^3.0.1",
"@solidjs/router": "^0.13.3",
"@solidjs/start": "^1.0.0",
"@types/better-sqlite3": "^7.6.10",

Choose a reason for hiding this comment

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

Why were types moved to regular dependencies?

"arctic": "^1.9.0",
"better-sqlite3": "^10.0.0",
"lucia": "^3.2.0",
"oslo": "^1.2.0",
"solid-js": "^1.8.17",
"vinxi": "0.3.11"
},
"engines": {
"node": ">=18"
},
"devDependencies": {
"@types/better-sqlite3": "^7.6.8"
}
}
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
4 changes: 3 additions & 1 deletion solidstart/github-oauth/src/entry-client.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// @refresh reload
import { mount, StartClient } from "@solidjs/start/client";

mount(() => <StartClient />, document.getElementById("app"));
const root = document.getElementById("app");
if (root) mount(() => <StartClient />, root);
1 change: 1 addition & 0 deletions solidstart/github-oauth/src/entry-server.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @refresh reload
import { createHandler, StartServer } from "@solidjs/start/server";

export default createHandler(() => (
Expand Down
9 changes: 9 additions & 0 deletions solidstart/github-oauth/src/global.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
/// <reference types="@solidjs/start/env" />

import { User, Session } from "lucia";

declare module "@solidjs/start/server" {
export interface RequestEventLocals {
user?: User | null;
session?: Session | null;
}
}
3 changes: 2 additions & 1 deletion solidstart/github-oauth/src/lib/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { db } from "./db";
import { GitHub } from "arctic";

import type { DatabaseUser } from "./db";
import { isDev } from "solid-js/web";

// import { webcrypto } from "crypto";
// globalThis.crypto = webcrypto as Crypto;
Expand All @@ -16,7 +17,7 @@ const adapter = new BetterSqlite3Adapter(db, {
export const lucia = new Lucia(adapter, {
sessionCookie: {
attributes: {
secure: import.meta.env.PROD
secure: !isDev
}
},
getUserAttributes: (attributes) => {
Expand Down
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");
42 changes: 16 additions & 26 deletions solidstart/github-oauth/src/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,30 @@
import { createMiddleware, appendHeader, getCookie, getHeader } from "@solidjs/start/server";
import { Session, User, verifyRequestOrigin } from "lucia";
import { createMiddleware } from "@solidjs/start/middleware";
import { getCookie, setCookie } from "vinxi/http";
import { lucia } from "./lib/auth";

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

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

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

if (session?.fresh) {
const cookie = lucia.createSessionCookie(session.id);

setCookie(cookie.name, cookie.value, cookie.attributes);
}

if (!session) {
appendHeader(event, "Set-Cookie", lucia.createBlankSessionCookie().serialize());
const cookie = lucia.createBlankSessionCookie();

setCookie(cookie.name, cookie.value, cookie.attributes);
}
event.context.session = session;
event.context.user = user;
}
});

declare module "vinxi/server" {
interface H3EventContext {
user: User | null;
session: Session | null;
e.locals.user = user;
e.locals.session = session;
}
}
});
12 changes: 7 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 { setCookie } 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,12 @@ 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);
const cookie = lucia.createSessionCookie(event.locals.session.id);

setCookie(cookie.name, cookie.value, cookie.attributes);
throw redirect("/login");
});
26 changes: 11 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,16 @@
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 { createError, getCookie, getQuery, setCookie } from "vinxi/http";

export async function GET(event: APIEvent) {
const query = getQuery(event);
export async function GET() {
const query = getQuery();
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 +31,9 @@ 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, "/");
const cookie = lucia.createSessionCookie(session.id);

setCookie(cookie.name, cookie.value, cookie.attributes);

Choose a reason for hiding this comment

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

You should be returning here, otherwise you throw an error because you try to add the user to the database again

}

const userId = generateId(15);
Expand All @@ -49,8 +43,10 @@ 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, "/");
const cookie = lucia.createSessionCookie(session.id);

setCookie(cookie.name, cookie.value, cookie.attributes);
return Response.redirect("/");

Choose a reason for hiding this comment

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

This is throwing a type error because it can't parse the URL. Instead you should probably use redirect from @solidjs/router

} 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,19 +1,19 @@
import { sendRedirect, setCookie } from "@solidjs/start/server";
import { generateState } from "arctic";
import { github } from "~/lib/auth";

import type { APIEvent } from "@solidjs/start/server";
import { setCookie } from "vinxi/http";

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 Response.redirect(url.toString());
}
5 changes: 5 additions & 0 deletions solidstart/username-and-password/app.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { defineConfig } from "@solidjs/start/config";

export default defineConfig({
middleware: "./src/middleware.ts",
});
20 changes: 9 additions & 11 deletions solidstart/username-and-password/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,17 @@
"start": "node ./.output/server/index.mjs"
},
"dependencies": {
"@lucia-auth/adapter-sqlite": "^3.0.0",
"@solidjs/router": "^0.10.5",
"@solidjs/start": "^0.4.2",
"better-sqlite3": "^9.2.2",
"lucia": "^3.0.1",
"oslo": "^1.0.3",
"solid-js": "^1.8.7",
"vinxi": "0.0.54"
"@lucia-auth/adapter-sqlite": "^3.0.1",
"@solidjs/router": "^0.13.3",
"@solidjs/start": "^1.0.0",
"@types/better-sqlite3": "^7.6.10",

Choose a reason for hiding this comment

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

Again, why are types in regular dependencies? They're not required at runtime, only during development.

"better-sqlite3": "^9.4.3",
"lucia": "^3.2.0",
"oslo": "^1.2.0",
"solid-js": "^1.8.17",
"vinxi": "0.3.11"
},
"engines": {
"node": ">=18"
},
"devDependencies": {
"@types/better-sqlite3": "^7.6.8"
}
}
2 changes: 1 addition & 1 deletion solidstart/username-and-password/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
4 changes: 3 additions & 1 deletion solidstart/username-and-password/src/entry-client.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// @refresh reload
import { mount, StartClient } from "@solidjs/start/client";

mount(() => <StartClient />, document.getElementById("app"));
const root = document.getElementById("app");
if (root) mount(() => <StartClient />, root);
2 changes: 2 additions & 0 deletions solidstart/username-and-password/src/entry-server.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// @refresh reload

import { createHandler, StartServer } from "@solidjs/start/server";

export default createHandler(() => (
Expand Down
9 changes: 9 additions & 0 deletions solidstart/username-and-password/src/global.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
/// <reference types="@solidjs/start/env" />

import { User, Session } from "lucia";

declare module "@solidjs/start/server" {
export interface RequestEventLocals {
user?: User | null;
session?: Session | null;
}
}
3 changes: 2 additions & 1 deletion solidstart/username-and-password/src/lib/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { BetterSqlite3Adapter } from "@lucia-auth/adapter-sqlite";
import { db } from "./db";

import type { DatabaseUser } from "./db";
import { isDev } from "solid-js/web";

// import { webcrypto } from "crypto";
// globalThis.crypto = webcrypto as Crypto;
Expand All @@ -15,7 +16,7 @@ const adapter = new BetterSqlite3Adapter(db, {
export const lucia = new Lucia(adapter, {
sessionCookie: {
attributes: {
secure: process.env.NODE_ENV === "production"
secure: !isDev
}
},
getUserAttributes: (attributes) => {
Expand Down
4 changes: 2 additions & 2 deletions solidstart/username-and-password/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");
Loading