finished with auth (besides oauth)
This commit is contained in:
parent
cd7f487b53
commit
0845eb1bbb
10 changed files with 134 additions and 21 deletions
BIN
bun.lockb
BIN
bun.lockb
Binary file not shown.
29
package.json
29
package.json
|
@ -1,21 +1,13 @@
|
||||||
{
|
{
|
||||||
"name": "talkomatic",
|
"name": "talkomatic",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"private": true,
|
|
||||||
"scripts": {
|
|
||||||
"dev": "vite dev",
|
|
||||||
"build": "vite build",
|
|
||||||
"preview": "vite preview",
|
|
||||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
||||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
||||||
"format": "prettier --write .",
|
|
||||||
"lint": "prettier --check ."
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@deno/kv": "^0.8.1",
|
"@deno/kv": "^0.8.1",
|
||||||
|
"@hono/zod-validator": "^0.2.2",
|
||||||
"@olli/kvdex": "npm:@jsr/olli__kvdex",
|
"@olli/kvdex": "npm:@jsr/olli__kvdex",
|
||||||
"@oxi/option": "npm:@jsr/oxi__option",
|
"@oxi/option": "npm:@jsr/oxi__option",
|
||||||
"@oxi/result": "npm:@jsr/oxi__result",
|
"@oxi/result": "npm:@jsr/oxi__result",
|
||||||
|
"@petamoriken/float16": "^3.8.7",
|
||||||
"@sveltejs/kit": "^2.0.0",
|
"@sveltejs/kit": "^2.0.0",
|
||||||
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
||||||
"@ts-rex/argon2": "npm:@jsr/ts-rex__argon2",
|
"@ts-rex/argon2": "npm:@jsr/ts-rex__argon2",
|
||||||
|
@ -35,11 +27,20 @@
|
||||||
"tailwindcss": "^3.4.10",
|
"tailwindcss": "^3.4.10",
|
||||||
"typescript": "^5.0.0",
|
"typescript": "^5.0.0",
|
||||||
"vite": "^5.0.3",
|
"vite": "^5.0.3",
|
||||||
"zod": "^3.23.8",
|
"zod": "^3.23.8"
|
||||||
"@petamoriken/float16": "^3.8.7"
|
},
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite dev",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||||
|
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||||
|
"format": "prettier --write .",
|
||||||
|
"lint": "prettier --check ."
|
||||||
},
|
},
|
||||||
"type": "module",
|
|
||||||
"trustedDependencies": [
|
"trustedDependencies": [
|
||||||
"svelte-preprocess"
|
"svelte-preprocess"
|
||||||
]
|
],
|
||||||
|
"type": "module"
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,6 @@ export const cookieController = new CookieController('auth_session', {
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
secure: true,
|
secure: true,
|
||||||
sameSite: "lax",
|
sameSite: "lax",
|
||||||
path: ".",
|
path: "/",
|
||||||
}, { expiresIn: cookieExpiration })
|
}, { expiresIn: cookieExpiration })
|
||||||
export { createSessionForUser, deleteSession, getUserAndSession }
|
export { createSessionForUser, deleteSession, getUserAndSession }
|
||||||
|
|
|
@ -19,6 +19,12 @@ export const session = z.object({
|
||||||
userId: z.string(),
|
userId: z.string(),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const chat = z.object({
|
||||||
|
name: z.string(),
|
||||||
|
creator: z.string().describe('id'),
|
||||||
|
createdAt: z.date()
|
||||||
|
})
|
||||||
|
|
||||||
export const kv = await openKv()
|
export const kv = await openKv()
|
||||||
export const db = kvdex(kv, {
|
export const db = kvdex(kv, {
|
||||||
user: collection(user, {
|
user: collection(user, {
|
||||||
|
@ -35,9 +41,10 @@ export const db = kvdex(kv, {
|
||||||
userId: 'secondary'
|
userId: 'secondary'
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
pfp: collection(model<Uint8Array>()),
|
|
||||||
chat: {
|
chat: {
|
||||||
boxes: collection(model<{ userID: string, text: string }>()),
|
boxes: collection(model<{ roomID: string, userID: string, text: string }>()),
|
||||||
users: collection(publicUser)
|
users: collection(publicUser),
|
||||||
|
updatekey: collection(model<true>()),
|
||||||
|
data: collection(chat)
|
||||||
}
|
}
|
||||||
})
|
})
|
|
@ -1,10 +1,32 @@
|
||||||
import { Hono } from "hono"
|
import { Hono } from "hono"
|
||||||
|
import { zValidator } from "@hono/zod-validator"
|
||||||
|
import z from "zod"
|
||||||
|
import { HTTPException } from 'hono/http-exception'
|
||||||
|
import { db } from "./db"
|
||||||
|
import { alphabet, generateRandomString } from "oslo/crypto"
|
||||||
|
import { text } from "@sveltejs/kit"
|
||||||
|
|
||||||
type Bindings = {
|
type Bindings = {
|
||||||
locals: App.Locals
|
locals: App.Locals
|
||||||
}
|
}
|
||||||
|
|
||||||
const api = new Hono<{ Bindings: Bindings }>()
|
const api = new Hono<{ Bindings: Bindings }>()
|
||||||
|
.use(async (ctx, next) => {
|
||||||
|
if(!ctx.env.locals.session) throw new HTTPException(401)
|
||||||
|
await next()
|
||||||
|
})
|
||||||
|
.post('/rooms/create', zValidator('json', z.object({
|
||||||
|
name: z.string()
|
||||||
|
})), async ({ req, env: { locals: { user } } }) => {
|
||||||
|
const body = req.valid('json')
|
||||||
|
const roomId = generateRandomString(10, alphabet('0-9', 'a-z'))
|
||||||
|
await db.chat.data.set(roomId, {
|
||||||
|
createdAt: new Date(),
|
||||||
|
creator: user?.id!,
|
||||||
|
name: body.name
|
||||||
|
})
|
||||||
|
return text(roomId)
|
||||||
|
})
|
||||||
export type api = typeof api
|
export type api = typeof api
|
||||||
|
|
||||||
export const hono = new Hono<{ Bindings: Bindings }>().route('/api', api)
|
export const hono = new Hono<{ Bindings: Bindings }>().route('/api', api)
|
|
@ -1,7 +1,12 @@
|
||||||
|
import { publicUser } from '$lib/db.js';
|
||||||
import { redirect } from '@sveltejs/kit';
|
import { redirect } from '@sveltejs/kit';
|
||||||
|
|
||||||
export async function load({ locals }) {
|
export async function load({ locals }) {
|
||||||
if(!locals.session) {
|
if(!locals.session) {
|
||||||
return redirect(302, "/auth")
|
return redirect(302, "/auth")
|
||||||
}
|
}
|
||||||
|
return publicUser.safeParse(locals.user).data!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const csr = true;
|
||||||
|
export const ssr = false;
|
71
src/routes/app/+layout.svelte
Normal file
71
src/routes/app/+layout.svelte
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
<script>
|
||||||
|
const { data, children } = $props()
|
||||||
|
let dropdownOpen = $state(false)
|
||||||
|
$inspect(dropdownOpen)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="h-[100vh] w-[100vw] flex flex-col">
|
||||||
|
<div class="px-4">
|
||||||
|
<div class="navbar bg-base-200 rounded-b-xl">
|
||||||
|
<div class="flex-1">
|
||||||
|
<button class="btn btn-ghost text-xl">spiel.place</button>
|
||||||
|
</div>
|
||||||
|
<div class="flex-none">
|
||||||
|
<details
|
||||||
|
class="dropdown dropdown-end"
|
||||||
|
ontoggle={({ newState }) => (dropdownOpen = newState === 'open')}>
|
||||||
|
<summary class="btn btn-circle btn-ghost m-1 swap swap-rotate">
|
||||||
|
<input type="checkbox" bind:checked={dropdownOpen} />
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="currentColor"
|
||||||
|
class="size-5 swap-off">
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M2 4.75A.75.75 0 0 1 2.75 4h14.5a.75.75 0 0 1 0 1.5H2.75A.75.75 0 0 1 2 4.75ZM2 10a.75.75 0 0 1 .75-.75h14.5a.75.75 0 0 1 0 1.5H2.75A.75.75 0 0 1 2 10Zm0 5.25a.75.75 0 0 1 .75-.75h14.5a.75.75 0 0 1 0 1.5H2.75a.75.75 0 0 1-.75-.75Z"
|
||||||
|
clip-rule="evenodd"></path>
|
||||||
|
</svg>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
class="size-5 swap-on stroke-2">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"></path>
|
||||||
|
</svg>
|
||||||
|
</summary>
|
||||||
|
<ul class="menu dropdown-content bg-base-100 rounded-box z-[1] w-52 p-2 shadow">
|
||||||
|
<li><a href="/app/settings">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M17.982 18.725A7.488 7.488 0 0 0 12 15.75a7.488 7.488 0 0 0-5.982 2.975m11.963 0a9 9 0 1 0-11.963 0m11.963 0A8.966 8.966 0 0 1 12 21a8.966 8.966 0 0 1-5.982-2.275M15 9.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
||||||
|
</svg>
|
||||||
|
{data.displayName}
|
||||||
|
</a></li>
|
||||||
|
<li>
|
||||||
|
<a href="/auth/signout">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
class="size-6">
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M15.75 9V5.25A2.25 2.25 0 0 0 13.5 3h-6a2.25 2.25 0 0 0-2.25 2.25v13.5A2.25 2.25 0 0 0 7.5 21h6a2.25 2.25 0 0 0 2.25-2.25V15m3 0 3-3m0 0-3-3m3 3H9"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
sign out</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</details>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex-grow">
|
||||||
|
{@render children()}
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -1,3 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
|
const { data } = $props()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<div class="">
|
||||||
|
|
||||||
|
</div>
|
3
src/routes/app/page2/+page.svelte
Normal file
3
src/routes/app/page2/+page.svelte
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<script>
|
||||||
|
const { data } = $props()
|
||||||
|
</script>
|
Loading…
Reference in a new issue