Implement login
This commit is contained in:
parent
39cf332500
commit
290ab487a1
16
web/package-lock.json
generated
16
web/package-lock.json
generated
@ -15,6 +15,7 @@
|
||||
"diff2html": "^3.4.35",
|
||||
"highlight.js": "^11.7.0",
|
||||
"prisma": "^4.13.0",
|
||||
"uuid": "^9.0.0",
|
||||
"zod": "^3.21.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -22,6 +23,7 @@
|
||||
"@sveltejs/kit": "^1.15.9",
|
||||
"@types/bootstrap": "^5.2.6",
|
||||
"@types/diff": "^5.0.3",
|
||||
"@types/uuid": "^9.0.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.1",
|
||||
"@typescript-eslint/parser": "^5.59.1",
|
||||
"eslint": "^8.39.0",
|
||||
@ -826,6 +828,12 @@
|
||||
"integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/uuid": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.1.tgz",
|
||||
"integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||
"version": "5.59.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.1.tgz",
|
||||
@ -3105,6 +3113,14 @@
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
|
||||
"integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "4.3.3",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-4.3.3.tgz",
|
||||
|
@ -16,6 +16,7 @@
|
||||
"@sveltejs/kit": "^1.15.9",
|
||||
"@types/bootstrap": "^5.2.6",
|
||||
"@types/diff": "^5.0.3",
|
||||
"@types/uuid": "^9.0.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.1",
|
||||
"@typescript-eslint/parser": "^5.59.1",
|
||||
"eslint": "^8.39.0",
|
||||
@ -38,6 +39,7 @@
|
||||
"diff2html": "^3.4.35",
|
||||
"highlight.js": "^11.7.0",
|
||||
"prisma": "^4.13.0",
|
||||
"uuid": "^9.0.0",
|
||||
"zod": "^3.21.4"
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,14 @@ model User {
|
||||
id Int @id @default(autoincrement())
|
||||
username String @unique
|
||||
password String
|
||||
sessions Session[]
|
||||
}
|
||||
|
||||
model Session {
|
||||
token String @id
|
||||
createdAt DateTime @default(now())
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
userId Int
|
||||
}
|
||||
|
||||
enum SubmissionState {
|
||||
|
57
web/src/hooks.server.ts
Normal file
57
web/src/hooks.server.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import { redirect, type Handle } from '@sveltejs/kit';
|
||||
import { db } from '$lib/server/prisma';
|
||||
import type { Session } from '@prisma/client';
|
||||
|
||||
const sessionExpireMilliseconds = 1000 * 60 * 60 * 24; // 24 hours
|
||||
|
||||
function isSessionExpired(session: Session): boolean {
|
||||
return session.createdAt.valueOf() + sessionExpireMilliseconds < new Date().valueOf();
|
||||
}
|
||||
|
||||
async function removeExpiredSessions(userId: number) {
|
||||
const sessions: Session[] = await db.session.findMany({ where: { userId: userId } });
|
||||
sessions.forEach(async (session) => {
|
||||
if (isSessionExpired(session)) {
|
||||
await db.session.delete({ where: { token: session.token } });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const handle = (async ({ event, resolve }) => {
|
||||
if (event.url.pathname.startsWith('/login')) {
|
||||
if (event.cookies.get('token')) {
|
||||
const session = await db.session.findUnique({ where: { token: event.cookies.get('token') } });
|
||||
if (session) {
|
||||
removeExpiredSessions(session.userId);
|
||||
if (!isSessionExpired(session)) {
|
||||
throw redirect(302, '/admin/reviews');
|
||||
} else {
|
||||
event.cookies.delete('token');
|
||||
}
|
||||
} else {
|
||||
const res = resolve(event);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (event.url.pathname.startsWith('/admin')) {
|
||||
if (event.cookies.get('token')) {
|
||||
const session = await db.session.findUnique({ where: { token: event.cookies.get('token') } });
|
||||
if (session) {
|
||||
removeExpiredSessions(session.userId);
|
||||
if (!isSessionExpired(session)) {
|
||||
const res = await resolve(event);
|
||||
return res;
|
||||
} else {
|
||||
event.cookies.delete('token');
|
||||
}
|
||||
} else {
|
||||
throw redirect(302, '/login');
|
||||
}
|
||||
} else {
|
||||
throw redirect(302, '/login');
|
||||
}
|
||||
}
|
||||
const res = await resolve(event);
|
||||
return res;
|
||||
}) satisfies Handle;
|
@ -6,6 +6,8 @@
|
||||
|
||||
<h1 class="mb-4">Reviews</h1>
|
||||
|
||||
<a href="/logout" class="mb-2 btn btn-outline-primary">Logout</a>
|
||||
|
||||
<ul class="list-group">
|
||||
{#each data.reviewList as review}
|
||||
<a href="/admin/diff" class="list-group-item list-group-item-action">{review}</a>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import type { Actions } from '@sveltejs/kit';
|
||||
import { db } from '$lib/server/prisma';
|
||||
import * as UUID from 'uuid';
|
||||
|
||||
export const actions = {
|
||||
login: async ({ cookies, request }) => {
|
||||
@ -14,6 +15,9 @@ export const actions = {
|
||||
return { success: false };
|
||||
}
|
||||
if (user.password === password) {
|
||||
const uuid: string = UUID.v4();
|
||||
await db.session.create({ data: { token: uuid, userId: user.id } });
|
||||
cookies.set('token', uuid);
|
||||
return { success: true };
|
||||
}
|
||||
return { success: false };
|
||||
|
16
web/src/routes/logout/+page.server.ts
Normal file
16
web/src/routes/logout/+page.server.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { redirect } from '@sveltejs/kit';
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { db } from '$lib/server/prisma';
|
||||
|
||||
export const load = (async ({ cookies }) => {
|
||||
if (!cookies.get('token')) {
|
||||
throw redirect(302, '/login');
|
||||
}
|
||||
try {
|
||||
await db.session.delete({ where: { token: cookies.get('token') } });
|
||||
} catch {
|
||||
throw redirect(302, '/login');
|
||||
}
|
||||
cookies.delete('token');
|
||||
throw redirect(302, '/login');
|
||||
}) satisfies PageServerLoad;
|
1
web/src/routes/logout/+page.svelte
Normal file
1
web/src/routes/logout/+page.svelte
Normal file
@ -0,0 +1 @@
|
||||
<h1>Logging Out</h1>
|
Loading…
Reference in New Issue
Block a user