aboutsummaryrefslogtreecommitdiffstats
path: root/backend/src/routes/auth.ts
diff options
context:
space:
mode:
authorPinapelz <yukais@pinapelz.com>2025-06-30 00:58:56 -0700
committerPinapelz <yukais@pinapelz.com>2025-06-30 00:58:56 -0700
commitfae6914acace1a3b470f9d243fe8a2ba0f141388 (patch)
treecc2ac24b97b464189c220d6c5abe7d48e92f28aa /backend/src/routes/auth.ts
parent722df5105c098f404e09e884a817acf92d939648 (diff)
add basic batch manual score upload route
Diffstat (limited to 'backend/src/routes/auth.ts')
-rw-r--r--backend/src/routes/auth.ts116
1 files changed, 116 insertions, 0 deletions
diff --git a/backend/src/routes/auth.ts b/backend/src/routes/auth.ts
new file mode 100644
index 0000000..4c6c374
--- /dev/null
+++ b/backend/src/routes/auth.ts
@@ -0,0 +1,116 @@
+import { prisma } from '../config/db';
+import express from 'express';
+import { createSession } from '../utils/session'
+import bcrypt from 'bcrypt';
+import crypto from 'crypto';
+
+export const handleRegistration = async (req: express.Request, res: express.Response) => {
+ try {
+ const { username, password, email } = req.body;
+
+ if (!username || !password || !email) {
+ return res.status(400).json({ error: 'All fields are required' });
+ }
+
+ const existingUser = await prisma.user.findFirst({
+ where: {
+ OR: [
+ { username },
+ { email }
+ ]
+ }
+ });
+
+ if (existingUser) {
+ return res.status(400).json({ error: 'Username or email already exists' });
+ }
+
+ const salt = crypto.randomBytes(16).toString('hex');
+ const hashedPassword = await bcrypt.hash(password + salt, 12);
+
+ const user = await prisma.user.create({
+ data: {
+ username,
+ password: hashedPassword,
+ salt,
+ email,
+ }
+ });
+
+ // Create session for the new user
+ req.session.userId = user.id;
+ const sessionId = await createSession(user.id);
+
+ res.status(201).json({
+ id: user.id,
+ username: user.username,
+ email: user.email,
+ sessionId
+ });
+ } catch (error) {
+ console.error('Registration error:', error);
+ res.status(500).json({ error: 'Internal server error' });
+ }
+}
+
+export const handleAuthentication = async (req: express.Request, res: express.Response) => {
+ try {
+ const { username, password } = req.body;
+
+ if (!username || !password) {
+ return res.status(400).json({ error: 'Username and password are required' });
+ }
+
+ const user = await prisma.user.findUnique({
+ where: { username }
+ });
+
+ if (!user) {
+ return res.status(401).json({ error: 'Invalid credentials' });
+ }
+
+ const isValidPassword = await bcrypt.compare(password + user.salt, user.password);
+ if (!isValidPassword) {
+ return res.status(401).json({ error: 'Invalid credentials' });
+ }
+
+ // Create session
+ req.session.userId = user.id;
+ const sessionId = await createSession(user.id);
+
+ res.json({
+ id: user.id,
+ username: user.username,
+ email: user.email,
+ sessionId
+ });
+ } catch (error) {
+ console.error('Login error:', error);
+ res.status(500).json({ error: 'Internal server error' });
+ }
+}
+
+export const handleLogout = async (req: express.Request, res: express.Response,) => {
+ try {
+ const userId = req.session.userId;
+
+ // Remove all sessions for this user from database
+ await prisma.session.deleteMany({
+ where: { userId }
+ });
+
+ // Destroy the session
+ req.session.destroy((err) => {
+ if (err) {
+ console.error('Session destroy error:', err);
+ return res.status(500).json({ error: 'Logout failed' });
+ }
+
+ res.clearCookie('connect.sid'); // Clear the session cookie
+ res.json({ message: 'Logged out successfully' });
+ });
+ } catch (error) {
+ console.error('Logout error:', error);
+ res.status(500).json({ error: 'Internal server error' });
+ }
+}
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage