some proper auth

This commit is contained in:
2025-08-15 15:27:24 -05:00
parent 4419dd7acc
commit 1c915d1713
9 changed files with 117 additions and 49 deletions

View File

@@ -8,12 +8,15 @@
}, },
"dependencies": { "dependencies": {
"@elysiajs/eden": "^1.3.2", "@elysiajs/eden": "^1.3.2",
"@solid-primitives/scheduled": "^1.5.2",
"@solidjs/router": "^0.15.3", "@solidjs/router": "^0.15.3",
"js-cookie": "^3.0.5",
"object-hash": "^3.0.0", "object-hash": "^3.0.0",
"solid-js": "^1.9.5" "solid-js": "^1.9.5"
}, },
"devDependencies": { "devDependencies": {
"@iconify-json/solar": "^1.2.4", "@iconify-json/solar": "^1.2.4",
"@types/js-cookie": "^3.0.6",
"@unocss/preset-icons": "^66.4.2", "@unocss/preset-icons": "^66.4.2",
"@unocss/preset-wind4": "^66.4.2", "@unocss/preset-wind4": "^66.4.2",
"unocss": "^66.4.2", "unocss": "^66.4.2",

View File

@@ -2,8 +2,6 @@ import { type Api } from "../../server/src/api";
import { treaty } from "@elysiajs/eden"; import { treaty } from "@elysiajs/eden";
const { api } = treaty<Api>("http://localhost:5001", { const { api } = treaty<Api>("http://localhost:5001", {
headers: { fetch: { credentials: "include" },
human: "daniel",
},
}); });
export default api; export default api;

View File

@@ -1,20 +1,47 @@
import "./style.css";
import { Route, Router } from "@solidjs/router"; import { Route, Router } from "@solidjs/router";
import { lazy, Suspense } from "solid-js"; import { lazy, Suspense } from "solid-js";
import pkg from "../package.json";
import { render } from "solid-js/web"; import { render } from "solid-js/web";
import Root from "./routes/index";
import "virtual:uno.css"; import "virtual:uno.css";
import pkg from "../package.json";
import "./style.css";
import api from "./api";
const Profile = () => {
let dialogRef!: HTMLDialogElement;
return (
<>
<div
onClick={() => dialogRef.showModal()}
class="i-solar-user-circle-bold button s-10 m-2 cursor-pointer fixed tr"
/>
<dialog ref={dialogRef} closedby="any">
<div class="fixed tr bg-emerald-100 m-2 p-4 rounded-xl border-2 shadow-md shadow-black">
Name:{" "}
<input
onChange={(e) =>
api.setName.post({ name: e.target.value })
}
class="bg-emerald-200 border-1.5 rounded-full px-4"
/>
</div>
</dialog>
</>
);
};
const App = () => ( const App = () => (
<Router <Router
root={(props) => ( root={(props) => (
<> <>
<Suspense>{props.children}</Suspense> <Suspense>{props.children}</Suspense>
<Profile />
{/* Version */}
<span class="fixed br m-2 font-mono text-xs"> <span class="fixed br m-2 font-mono text-xs">
{"v" + pkg.version} {"v" + pkg.version}
</span> </span>
<div class="i-solar-user-circle-bold fixed s-10 top-0 right-0 m-2 cursor-pointer" />
</> </>
)} )}
> >

View File

@@ -17,13 +17,7 @@ export default () => {
<p class="text-[40px]">{param.game}</p> <p class="text-[40px]">{param.game}</p>
<button <button
class="px-2 py-1.5 m-4 button rounded" class="px-2 py-1.5 m-4 button rounded"
onClick={() => onClick={() => api.simple.newGame.post().then(refetch)}
api.simple.newGame
.post({
players: ["daniel"],
})
.then(refetch)
}
> >
New Game New Game
</button> </button>

View File

@@ -17,8 +17,8 @@ model Game {
} }
model Human { model Human {
key String @id key String @id @default(cuid(2))
name String name String @default("")
Instance Instance[] Instance Instance[]
} }

View File

@@ -4,19 +4,33 @@ import { Prisma } from "@prisma/client";
import { simpleApi } from "./games/simple"; import { simpleApi } from "./games/simple";
const api = new Elysia({ prefix: "/api" }) const api = new Elysia({ prefix: "/api" })
// [wip] .onBeforeHandle(async ({ cookie: { token } }) => {
.group("/prisma", (app) => if (token.value == null) {
app console.log("CREATING NEW USER");
.post("/game", ({ body }: { body: Prisma.GameFindManyArgs }) => const newHuman = await prisma.human.create({
prisma.game.findMany(body) data: {},
) });
.post( token.value = newHuman.key;
"/instance", }
({ body }: { body: Prisma.InstanceFindManyArgs }) => })
prisma.instance.findMany(body) .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("/games", () => prisma.game.findMany())
.get("/instances", ({ query: { game } }) => .get("/instances", ({ query: { game } }) =>
@@ -31,6 +45,7 @@ const api = new Elysia({ prefix: "/api" })
}, },
}) })
) )
.use(simpleApi); .use(simpleApi);
export default api; export default api;

View File

@@ -111,24 +111,21 @@ export const resolveAction = (
}; };
export const simpleApi = new Elysia({ prefix: "/simple" }) export const simpleApi = new Elysia({ prefix: "/simple" })
// .guard({ headers: t.Object({ Human: t.String() }) }) .guard({ cookie: t.Object({ token: t.String() }) })
.post( .post("/newGame", ({ cookie: { token: humanKey } }) => {
"/newGame", return prisma.instance.create({
(args: { body: { players: string[] }; headers: { human: string } }) => { data: {
return prisma.instance.create({ gameState: newGame([humanKey.value]),
data: { gameKey: "simple",
gameState: newGame(args.body.players), createdByKey: humanKey.value,
gameKey: "simple", },
createdByKey: args.headers.human, });
}, })
});
}
)
.group("/:instanceId", (app) => .group("/:instanceId", (app) =>
app app
.get( .get(
"/", "/",
({ params: { instanceId }, headers: { human: humanId } }) => ({ params: { instanceId }, cookie: { token: humanKey } }) =>
prisma.instance prisma.instance
.findUnique({ .findUnique({
where: { where: {
@@ -139,9 +136,9 @@ export const simpleApi = new Elysia({ prefix: "/simple" })
getView( getView(
getKnowledge( getKnowledge(
game!.gameState as GameState, game!.gameState as GameState,
humanId! humanKey.value
), ),
humanId! humanKey.value
) )
) )
) )
@@ -150,7 +147,7 @@ export const simpleApi = new Elysia({ prefix: "/simple" })
({ ({
params: { instanceId }, params: { instanceId },
body: { action }, body: { action },
headers: { human: humanId }, cookie: { token: humanKey },
}) => }) =>
prisma.instance prisma.instance
.findUniqueOrThrow({ .findUniqueOrThrow({
@@ -161,7 +158,7 @@ export const simpleApi = new Elysia({ prefix: "/simple" })
.then(async (game) => { .then(async (game) => {
const newState = resolveAction( const newState = resolveAction(
game.gameState as GameState, game.gameState as GameState,
humanId!, humanKey.value,
action action
); );
await prisma.instance.update({ await prisma.instance.update({
@@ -171,8 +168,8 @@ export const simpleApi = new Elysia({ prefix: "/simple" })
}, },
}); });
return getView( return getView(
getKnowledge(newState, humanId!), getKnowledge(newState, humanKey.value),
humanId! humanKey.value
); );
}), }),
{ {

View File

@@ -6,7 +6,12 @@ import { staticPlugin } from "@elysiajs/static";
const port = env.PORT || 5001; const port = env.PORT || 5001;
const app = new Elysia() const app = new Elysia()
.use(cors()) .use(
cors({
origin: "http://localhost:3000",
credentials: true,
})
)
.onRequest(({ request }) => { .onRequest(({ request }) => {
console.log(request.method, request.url); console.log(request.method, request.url);
}) })

29
pnpm-lock.yaml generated
View File

@@ -20,9 +20,15 @@ importers:
'@elysiajs/eden': '@elysiajs/eden':
specifier: ^1.3.2 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)) 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': '@solidjs/router':
specifier: ^0.15.3 specifier: ^0.15.3
version: 0.15.3(solid-js@1.9.8) version: 0.15.3(solid-js@1.9.8)
js-cookie:
specifier: ^3.0.5
version: 3.0.5
object-hash: object-hash:
specifier: ^3.0.0 specifier: ^3.0.0
version: 3.0.0 version: 3.0.0
@@ -33,6 +39,9 @@ importers:
'@iconify-json/solar': '@iconify-json/solar':
specifier: ^1.2.4 specifier: ^1.2.4
version: 1.2.4 version: 1.2.4
'@types/js-cookie':
specifier: ^3.0.6
version: 3.0.6
'@unocss/preset-icons': '@unocss/preset-icons':
specifier: ^66.4.2 specifier: ^66.4.2
version: 66.4.2 version: 66.4.2
@@ -387,6 +396,11 @@ packages:
'@sinclair/typebox@0.34.38': '@sinclair/typebox@0.34.38':
resolution: {integrity: sha512-HpkxMmc2XmZKhvaKIZZThlHmx1L0I/V1hWK1NubtlFnr6ZqdiOpV72TKudZUNQjZNsyDBay72qFEhEvb+bcwcA==} 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': '@solidjs/router@0.15.3':
resolution: {integrity: sha512-iEbW8UKok2Oio7o6Y4VTzLj+KFCmQPGEpm1fS3xixwFBdclFVBvaQVeibl1jys4cujfAK5Kn6+uG2uBm3lxOMw==} resolution: {integrity: sha512-iEbW8UKok2Oio7o6Y4VTzLj+KFCmQPGEpm1fS3xixwFBdclFVBvaQVeibl1jys4cujfAK5Kn6+uG2uBm3lxOMw==}
peerDependencies: peerDependencies:
@@ -417,6 +431,9 @@ packages:
'@types/bun@1.2.20': '@types/bun@1.2.20':
resolution: {integrity: sha512-dX3RGzQ8+KgmMw7CsW4xT5ITBSCrSbfHc36SNT31EOUg/LA9JWq0VDdEXDRSe1InVWpd2yLUM1FUF/kEOyTzYA==} resolution: {integrity: sha512-dX3RGzQ8+KgmMw7CsW4xT5ITBSCrSbfHc36SNT31EOUg/LA9JWq0VDdEXDRSe1InVWpd2yLUM1FUF/kEOyTzYA==}
'@types/js-cookie@3.0.6':
resolution: {integrity: sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==}
'@types/node@24.2.0': '@types/node@24.2.0':
resolution: {integrity: sha512-3xyG3pMCq3oYCNg7/ZP+E1ooTaGB4cG8JWRsqqOYQdbWNY4zbaV0Ennrd7stjiJEFZCaybcIgpTjJWHRfBSIDw==} resolution: {integrity: sha512-3xyG3pMCq3oYCNg7/ZP+E1ooTaGB4cG8JWRsqqOYQdbWNY4zbaV0Ennrd7stjiJEFZCaybcIgpTjJWHRfBSIDw==}
@@ -812,6 +829,10 @@ packages:
resolution: {integrity: sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==} resolution: {integrity: sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==}
hasBin: true hasBin: true
js-cookie@3.0.5:
resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==}
engines: {node: '>=14'}
js-tokens@4.0.0: js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@@ -1486,6 +1507,10 @@ snapshots:
'@sinclair/typebox@0.34.38': '@sinclair/typebox@0.34.38':
optional: true 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)': '@solidjs/router@0.15.3(solid-js@1.9.8)':
dependencies: dependencies:
solid-js: 1.9.8 solid-js: 1.9.8
@@ -1529,6 +1554,8 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- '@types/react' - '@types/react'
'@types/js-cookie@3.0.6': {}
'@types/node@24.2.0': '@types/node@24.2.0':
dependencies: dependencies:
undici-types: 7.10.0 undici-types: 7.10.0
@@ -1978,6 +2005,8 @@ snapshots:
jiti@2.5.1: {} jiti@2.5.1: {}
js-cookie@3.0.5: {}
js-tokens@4.0.0: {} js-tokens@4.0.0: {}
jsesc@3.1.0: {} jsesc@3.1.0: {}