added server, db, auth system
This commit is contained in:
parent
4d3395fa1c
commit
199dab69f9
28 changed files with 989 additions and 192 deletions
122
server/db.ts
Normal file
122
server/db.ts
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
import { SQL } from "bun"
|
||||
|
||||
const db = new SQL({
|
||||
adapter: "sqlite",
|
||||
filename: "./leo-typing.db",
|
||||
create: true,
|
||||
strict: true,
|
||||
})
|
||||
|
||||
export async function initDb() {
|
||||
await db`
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username TEXT NOT NULL UNIQUE,
|
||||
created_at TEXT DEFAULT (datetime('now'))
|
||||
)
|
||||
`
|
||||
await db`
|
||||
CREATE TABLE IF NOT EXISTS credentials (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id),
|
||||
public_key TEXT NOT NULL,
|
||||
counter INTEGER NOT NULL DEFAULT 0,
|
||||
transports TEXT,
|
||||
created_at TEXT DEFAULT (datetime('now'))
|
||||
)
|
||||
`
|
||||
await db`
|
||||
CREATE TABLE IF NOT EXISTS sessions (
|
||||
token TEXT PRIMARY KEY,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id),
|
||||
expires_at TEXT NOT NULL,
|
||||
created_at TEXT DEFAULT (datetime('now'))
|
||||
)
|
||||
`
|
||||
}
|
||||
|
||||
// ---- User queries ----
|
||||
|
||||
export async function createUser(username: string): Promise<{ id: number; username: string }> {
|
||||
const [user] = await db`
|
||||
INSERT INTO users (username) VALUES (${username})
|
||||
RETURNING id, username
|
||||
`
|
||||
return user as { id: number; username: string }
|
||||
}
|
||||
|
||||
export async function getUserByUsername(username: string) {
|
||||
const [user] = await db`SELECT id, username FROM users WHERE username = ${username}`
|
||||
return user as { id: number; username: string } | undefined
|
||||
}
|
||||
|
||||
export async function getUserById(id: number) {
|
||||
const [user] = await db`SELECT id, username FROM users WHERE id = ${id}`
|
||||
return user as { id: number; username: string } | undefined
|
||||
}
|
||||
|
||||
// ---- Credential queries ----
|
||||
|
||||
export async function storeCredential(
|
||||
credentialId: string,
|
||||
userId: number,
|
||||
publicKey: string,
|
||||
counter: number,
|
||||
transports?: string[],
|
||||
) {
|
||||
await db`
|
||||
INSERT INTO credentials (id, user_id, public_key, counter, transports)
|
||||
VALUES (${credentialId}, ${userId}, ${publicKey}, ${counter}, ${transports ? JSON.stringify(transports) : null})
|
||||
`
|
||||
}
|
||||
|
||||
export async function getCredentialById(credentialId: string) {
|
||||
const [cred] = await db`SELECT * FROM credentials WHERE id = ${credentialId}`
|
||||
return cred as {
|
||||
id: string
|
||||
user_id: number
|
||||
public_key: string
|
||||
counter: number
|
||||
transports: string | null
|
||||
} | undefined
|
||||
}
|
||||
|
||||
export async function getCredentialsByUserId(userId: number) {
|
||||
const creds = await db`SELECT * FROM credentials WHERE user_id = ${userId}`
|
||||
return creds as Array<{
|
||||
id: string
|
||||
user_id: number
|
||||
public_key: string
|
||||
counter: number
|
||||
transports: string | null
|
||||
}>
|
||||
}
|
||||
|
||||
export async function updateCredentialCounter(credentialId: string, counter: number) {
|
||||
await db`UPDATE credentials SET counter = ${counter} WHERE id = ${credentialId}`
|
||||
}
|
||||
|
||||
// ---- Session queries ----
|
||||
|
||||
export async function createSession(userId: number): Promise<string> {
|
||||
const token = crypto.randomUUID()
|
||||
const expires = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString()
|
||||
await db`
|
||||
INSERT INTO sessions (token, user_id, expires_at)
|
||||
VALUES (${token}, ${userId}, ${expires})
|
||||
`
|
||||
return token
|
||||
}
|
||||
|
||||
export async function getSession(token: string) {
|
||||
const [session] = await db`
|
||||
SELECT s.token, s.user_id, s.expires_at, u.username
|
||||
FROM sessions s JOIN users u ON s.user_id = u.id
|
||||
WHERE s.token = ${token} AND s.expires_at > datetime('now')
|
||||
`
|
||||
return session as { token: string; user_id: number; username: string; expires_at: string } | undefined
|
||||
}
|
||||
|
||||
export async function deleteSession(token: string) {
|
||||
await db`DELETE FROM sessions WHERE token = ${token}`
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue