From 1c915d1713b00e8fc5ead0c701c0217a635dc2fb Mon Sep 17 00:00:00 2001 From: Daniel McCrystal Date: Fri, 15 Aug 2025 15:27:24 -0500 Subject: [PATCH] some proper auth --- packages/client/package.json | 3 ++ packages/client/src/api.ts | 4 +-- packages/client/src/app.tsx | 35 +++++++++++++++--- packages/client/src/routes/[game]/index.tsx | 8 +---- packages/server/db/schema.prisma | 4 +-- packages/server/src/api.ts | 39 ++++++++++++++------- packages/server/src/games/simple.ts | 37 +++++++++---------- packages/server/src/index.ts | 7 +++- pnpm-lock.yaml | 29 +++++++++++++++ 9 files changed, 117 insertions(+), 49 deletions(-) diff --git a/packages/client/package.json b/packages/client/package.json index a2a7deb..74e1fc5 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -8,12 +8,15 @@ }, "dependencies": { "@elysiajs/eden": "^1.3.2", + "@solid-primitives/scheduled": "^1.5.2", "@solidjs/router": "^0.15.3", + "js-cookie": "^3.0.5", "object-hash": "^3.0.0", "solid-js": "^1.9.5" }, "devDependencies": { "@iconify-json/solar": "^1.2.4", + "@types/js-cookie": "^3.0.6", "@unocss/preset-icons": "^66.4.2", "@unocss/preset-wind4": "^66.4.2", "unocss": "^66.4.2", diff --git a/packages/client/src/api.ts b/packages/client/src/api.ts index 1b739e7..ca532c2 100644 --- a/packages/client/src/api.ts +++ b/packages/client/src/api.ts @@ -2,8 +2,6 @@ import { type Api } from "../../server/src/api"; import { treaty } from "@elysiajs/eden"; const { api } = treaty("http://localhost:5001", { - headers: { - human: "daniel", - }, + fetch: { credentials: "include" }, }); export default api; diff --git a/packages/client/src/app.tsx b/packages/client/src/app.tsx index 97afe4a..b303190 100644 --- a/packages/client/src/app.tsx +++ b/packages/client/src/app.tsx @@ -1,20 +1,47 @@ -import "./style.css"; import { Route, Router } from "@solidjs/router"; import { lazy, Suspense } from "solid-js"; -import pkg from "../package.json"; import { render } from "solid-js/web"; -import Root from "./routes/index"; import "virtual:uno.css"; +import pkg from "../package.json"; +import "./style.css"; +import api from "./api"; + +const Profile = () => { + let dialogRef!: HTMLDialogElement; + + return ( + <> +
dialogRef.showModal()} + class="i-solar-user-circle-bold button s-10 m-2 cursor-pointer fixed tr" + /> + + +
+ Name:{" "} + + api.setName.post({ name: e.target.value }) + } + class="bg-emerald-200 border-1.5 rounded-full px-4" + /> +
+
+ + ); +}; const App = () => ( ( <> {props.children} + + + {/* Version */} {"v" + pkg.version} -
)} > diff --git a/packages/client/src/routes/[game]/index.tsx b/packages/client/src/routes/[game]/index.tsx index e5b2bac..80588ef 100644 --- a/packages/client/src/routes/[game]/index.tsx +++ b/packages/client/src/routes/[game]/index.tsx @@ -17,13 +17,7 @@ export default () => {

{param.game}

diff --git a/packages/server/db/schema.prisma b/packages/server/db/schema.prisma index 89c8a87..a5f916f 100644 --- a/packages/server/db/schema.prisma +++ b/packages/server/db/schema.prisma @@ -17,8 +17,8 @@ model Game { } model Human { - key String @id - name String + key String @id @default(cuid(2)) + name String @default("") Instance Instance[] } diff --git a/packages/server/src/api.ts b/packages/server/src/api.ts index a3b7e7f..b7896ca 100644 --- a/packages/server/src/api.ts +++ b/packages/server/src/api.ts @@ -4,19 +4,33 @@ import { Prisma } from "@prisma/client"; import { simpleApi } from "./games/simple"; const api = new Elysia({ prefix: "/api" }) - // [wip] - .group("/prisma", (app) => - app - .post("/game", ({ body }: { body: Prisma.GameFindManyArgs }) => - prisma.game.findMany(body) - ) - .post( - "/instance", - ({ body }: { body: Prisma.InstanceFindManyArgs }) => - prisma.instance.findMany(body) - ) + .onBeforeHandle(async ({ cookie: { token } }) => { + if (token.value == null) { + console.log("CREATING NEW USER"); + const newHuman = await prisma.human.create({ + data: {}, + }); + token.value = newHuman.key; + } + }) + .guard({ cookie: t.Object({ token: t.String() }) }) + .post( + "/setName", + ({ cookie: { token: humanKey }, body: { name } }) => + prisma.human.update({ + where: { + key: humanKey.value, + }, + data: { + name, + }, + }), + { + body: t.Object({ + name: t.String(), + }), + } ) - .get("/games", () => prisma.game.findMany()) .get("/instances", ({ query: { game } }) => @@ -31,6 +45,7 @@ const api = new Elysia({ prefix: "/api" }) }, }) ) + .use(simpleApi); export default api; diff --git a/packages/server/src/games/simple.ts b/packages/server/src/games/simple.ts index c8431cb..ef855a0 100644 --- a/packages/server/src/games/simple.ts +++ b/packages/server/src/games/simple.ts @@ -111,24 +111,21 @@ export const resolveAction = ( }; export const simpleApi = new Elysia({ prefix: "/simple" }) - // .guard({ headers: t.Object({ Human: t.String() }) }) - .post( - "/newGame", - (args: { body: { players: string[] }; headers: { human: string } }) => { - return prisma.instance.create({ - data: { - gameState: newGame(args.body.players), - gameKey: "simple", - createdByKey: args.headers.human, - }, - }); - } - ) + .guard({ cookie: t.Object({ token: t.String() }) }) + .post("/newGame", ({ cookie: { token: humanKey } }) => { + return prisma.instance.create({ + data: { + gameState: newGame([humanKey.value]), + gameKey: "simple", + createdByKey: humanKey.value, + }, + }); + }) .group("/:instanceId", (app) => app .get( "/", - ({ params: { instanceId }, headers: { human: humanId } }) => + ({ params: { instanceId }, cookie: { token: humanKey } }) => prisma.instance .findUnique({ where: { @@ -139,9 +136,9 @@ export const simpleApi = new Elysia({ prefix: "/simple" }) getView( getKnowledge( game!.gameState as GameState, - humanId! + humanKey.value ), - humanId! + humanKey.value ) ) ) @@ -150,7 +147,7 @@ export const simpleApi = new Elysia({ prefix: "/simple" }) ({ params: { instanceId }, body: { action }, - headers: { human: humanId }, + cookie: { token: humanKey }, }) => prisma.instance .findUniqueOrThrow({ @@ -161,7 +158,7 @@ export const simpleApi = new Elysia({ prefix: "/simple" }) .then(async (game) => { const newState = resolveAction( game.gameState as GameState, - humanId!, + humanKey.value, action ); await prisma.instance.update({ @@ -171,8 +168,8 @@ export const simpleApi = new Elysia({ prefix: "/simple" }) }, }); return getView( - getKnowledge(newState, humanId!), - humanId! + getKnowledge(newState, humanKey.value), + humanKey.value ); }), { diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index d861b62..ff3b70a 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -6,7 +6,12 @@ import { staticPlugin } from "@elysiajs/static"; const port = env.PORT || 5001; const app = new Elysia() - .use(cors()) + .use( + cors({ + origin: "http://localhost:3000", + credentials: true, + }) + ) .onRequest(({ request }) => { console.log(request.method, request.url); }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5745604..0c44f2e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,9 +20,15 @@ importers: '@elysiajs/eden': specifier: ^1.3.2 version: 1.3.2(elysia@1.3.8(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2)) + '@solid-primitives/scheduled': + specifier: ^1.5.2 + version: 1.5.2(solid-js@1.9.8) '@solidjs/router': specifier: ^0.15.3 version: 0.15.3(solid-js@1.9.8) + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 object-hash: specifier: ^3.0.0 version: 3.0.0 @@ -33,6 +39,9 @@ importers: '@iconify-json/solar': specifier: ^1.2.4 version: 1.2.4 + '@types/js-cookie': + specifier: ^3.0.6 + version: 3.0.6 '@unocss/preset-icons': specifier: ^66.4.2 version: 66.4.2 @@ -387,6 +396,11 @@ packages: '@sinclair/typebox@0.34.38': resolution: {integrity: sha512-HpkxMmc2XmZKhvaKIZZThlHmx1L0I/V1hWK1NubtlFnr6ZqdiOpV72TKudZUNQjZNsyDBay72qFEhEvb+bcwcA==} + '@solid-primitives/scheduled@1.5.2': + resolution: {integrity: sha512-/j2igE0xyNaHhj6kMfcUQn5rAVSTLbAX+CDEBm25hSNBmNiHLu2lM7Usj2kJJ5j36D67bE8wR1hBNA8hjtvsQA==} + peerDependencies: + solid-js: ^1.6.12 + '@solidjs/router@0.15.3': resolution: {integrity: sha512-iEbW8UKok2Oio7o6Y4VTzLj+KFCmQPGEpm1fS3xixwFBdclFVBvaQVeibl1jys4cujfAK5Kn6+uG2uBm3lxOMw==} peerDependencies: @@ -417,6 +431,9 @@ packages: '@types/bun@1.2.20': resolution: {integrity: sha512-dX3RGzQ8+KgmMw7CsW4xT5ITBSCrSbfHc36SNT31EOUg/LA9JWq0VDdEXDRSe1InVWpd2yLUM1FUF/kEOyTzYA==} + '@types/js-cookie@3.0.6': + resolution: {integrity: sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==} + '@types/node@24.2.0': resolution: {integrity: sha512-3xyG3pMCq3oYCNg7/ZP+E1ooTaGB4cG8JWRsqqOYQdbWNY4zbaV0Ennrd7stjiJEFZCaybcIgpTjJWHRfBSIDw==} @@ -812,6 +829,10 @@ packages: resolution: {integrity: sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==} hasBin: true + js-cookie@3.0.5: + resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} + engines: {node: '>=14'} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -1486,6 +1507,10 @@ snapshots: '@sinclair/typebox@0.34.38': optional: true + '@solid-primitives/scheduled@1.5.2(solid-js@1.9.8)': + dependencies: + solid-js: 1.9.8 + '@solidjs/router@0.15.3(solid-js@1.9.8)': dependencies: solid-js: 1.9.8 @@ -1529,6 +1554,8 @@ snapshots: transitivePeerDependencies: - '@types/react' + '@types/js-cookie@3.0.6': {} + '@types/node@24.2.0': dependencies: undici-types: 7.10.0 @@ -1978,6 +2005,8 @@ snapshots: jiti@2.5.1: {} + js-cookie@3.0.5: {} + js-tokens@4.0.0: {} jsesc@3.1.0: {}