implement bookmark delete
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { type User, DEMO_USER } from "@markone/core/user"
|
||||
import { DEMO_USER, type User } from "@markone/core/user"
|
||||
import { type } from "arktype"
|
||||
import dayjs from "dayjs"
|
||||
import { ulid } from "ulid"
|
||||
@@ -6,6 +6,7 @@ import { db } from "~/database.ts"
|
||||
import { HttpError } from "~/error.ts"
|
||||
import { httpHandler } from "~/http-handler.ts"
|
||||
import { createUser, findUserById, findUserByUsername } from "~/user/user.ts"
|
||||
import { hashPassword, verifyPassword } from "./password.ts"
|
||||
import { createSessionForUser, extendSession, forgetAllSessions, saveSession, verifySession } from "./session.ts"
|
||||
|
||||
const SignUpRequest = type({
|
||||
@@ -18,20 +19,13 @@ const LoginRequest = type({
|
||||
password: "string",
|
||||
})
|
||||
|
||||
const createAuthTokenQuery = db.query(
|
||||
"INSERT INTO auth_tokens(id, token, user_id, expires_at_unix_ms) VALUES ($id, $token, $userId, $expiresAt)",
|
||||
)
|
||||
|
||||
const deleteAuthTokenQuery = db.query("DELETE FROM auth_tokens WHERE id = $id")
|
||||
|
||||
const deleteAllAuthTokensQuery = db.query("DELETE FROM auth_tokens WHERE user_id = $userId")
|
||||
|
||||
function authenticated<Route extends string>(
|
||||
handler: (request: Bun.BunRequest<Route>, user: User) => Promise<Response>,
|
||||
) {
|
||||
return httpHandler<Route>((request) => {
|
||||
const session = verifySession(request.cookies)
|
||||
if (!session) {
|
||||
console.log("session not found!")
|
||||
throw new HttpError(401)
|
||||
}
|
||||
|
||||
@@ -42,6 +36,8 @@ function authenticated<Route extends string>(
|
||||
|
||||
const authTokenCookie = request.cookies.get("auth-token")
|
||||
if (authTokenCookie) {
|
||||
const deleteAuthTokenQuery = db.query("DELETE FROM auth_tokens WHERE id = $id")
|
||||
|
||||
// biome-ignore lint/style/noNonNullAssertion: the cookie has already been verified by verifySession previously, therefore the cookie must be in the correct format <token-id>:<token-signature>
|
||||
const tokenId = authTokenCookie.split(":")[0]!
|
||||
deleteAuthTokenQuery.run({ id: tokenId })
|
||||
@@ -69,6 +65,10 @@ function rememberLoginForUser(user: User, cookies: Bun.CookieMap) {
|
||||
|
||||
const expiryDate = dayjs().add(1, "month")
|
||||
|
||||
const createAuthTokenQuery = db.query(
|
||||
"INSERT INTO auth_tokens(id, token, user_id, expires_at_unix_ms) VALUES ($id, $token, $userId, $expiresAt)",
|
||||
)
|
||||
|
||||
createAuthTokenQuery.run({
|
||||
id: tokenId,
|
||||
token: hashedToken,
|
||||
@@ -78,6 +78,7 @@ function rememberLoginForUser(user: User, cookies: Bun.CookieMap) {
|
||||
|
||||
cookies.set("auth-token", `${tokenId}:${authToken.toBase64({ alphabet: "base64url" })}`, {
|
||||
maxAge: 30 * 24 * 60 * 60 * 1000,
|
||||
path: "/api",
|
||||
httpOnly: true,
|
||||
})
|
||||
}
|
||||
@@ -93,7 +94,7 @@ async function signUp(request: Bun.BunRequest<"/api/sign-up">) {
|
||||
}
|
||||
|
||||
const { username, password } = signUpRequest
|
||||
const hashedPassword = await Bun.password.hash(password, "argon2id")
|
||||
const hashedPassword = await hashPassword(password)
|
||||
const user = createUser(username, hashedPassword)
|
||||
|
||||
await createSessionForUser(user, request.cookies)
|
||||
@@ -116,10 +117,10 @@ async function login(request: Bun.BunRequest<"/api/login">) {
|
||||
password: true,
|
||||
})
|
||||
if (!foundUser) {
|
||||
throw new HttpError(400)
|
||||
throw new HttpError(401)
|
||||
}
|
||||
|
||||
const ok = await Bun.password.verify(loginRequest.password, foundUser.password, "argon2id").catch(() => {
|
||||
const ok = await verifyPassword(loginRequest.password, foundUser.password).catch(() => {
|
||||
throw new HttpError(401)
|
||||
})
|
||||
if (!ok) {
|
||||
@@ -131,8 +132,8 @@ async function login(request: Bun.BunRequest<"/api/login">) {
|
||||
username: foundUser.username,
|
||||
}
|
||||
|
||||
if (user.id === DEMO_USER.id) {
|
||||
await createSessionForUser(user, request.cookies)
|
||||
await createSessionForUser(user, request.cookies)
|
||||
if (user.id !== DEMO_USER.id) {
|
||||
rememberLoginForUser(user, request.cookies)
|
||||
}
|
||||
|
||||
@@ -140,6 +141,8 @@ async function login(request: Bun.BunRequest<"/api/login">) {
|
||||
}
|
||||
|
||||
async function logout(request: Bun.BunRequest<"/api/logout">, user: User): Promise<Response> {
|
||||
const deleteAllAuthTokensQuery = db.query("DELETE FROM auth_tokens WHERE user_id = $userId")
|
||||
|
||||
forgetAllSessions(user)
|
||||
deleteAllAuthTokensQuery.run({ userId: user.id })
|
||||
return new Response(undefined, { status: 200 })
|
||||
|
Reference in New Issue
Block a user