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": {
"@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",

View File

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

View File

@@ -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 (
<>
<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 = () => (
<Router
root={(props) => (
<>
<Suspense>{props.children}</Suspense>
<Profile />
{/* Version */}
<span class="fixed br m-2 font-mono text-xs">
{"v" + pkg.version}
</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>
<button
class="px-2 py-1.5 m-4 button rounded"
onClick={() =>
api.simple.newGame
.post({
players: ["daniel"],
})
.then(refetch)
}
onClick={() => api.simple.newGame.post().then(refetch)}
>
New Game
</button>

View File

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

View File

@@ -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;

View File

@@ -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
);
}),
{

View File

@@ -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);
})

29
pnpm-lock.yaml generated
View File

@@ -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: {}