From faf76e96ee8dbff749af8464ab939c4071620a12 Mon Sep 17 00:00:00 2001 From: ScriptSorcerer20 Date: Wed, 16 Apr 2025 16:54:51 +0200 Subject: [PATCH] started login --- gambling.js | 108 +++++++++++++++++++++++++++++++++++--- generate_secret.js | 5 ++ package.json | 2 + swagger.json | 126 ++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 233 insertions(+), 8 deletions(-) create mode 100644 generate_secret.js diff --git a/gambling.js b/gambling.js index 29d2dba..e22131e 100644 --- a/gambling.js +++ b/gambling.js @@ -1,16 +1,112 @@ const express = require("express"); const app = express(); -const swaggerUi = require('swagger-ui-express'); -const swaggerDocument = require('./swagger.json'); +const swaggerUi = require("swagger-ui-express"); +const swaggerDocument = require("./swagger.json"); + const path = require("path"); +const fs = require("fs"); +const dotenv = require("dotenv").config(); +const jwt = require("jsonwebtoken"); const port = 3000; -app.use('/swagger-ui', swaggerUi.serve, swaggerUi.setup(swaggerDocument)); +app.use(express.json()); +app.use("/swagger-ui", swaggerUi.serve, swaggerUi.setup(swaggerDocument)); -app.get("/", (request, respond) => { - respond.sendFile(path.join(__dirname, 'structure.png')); +function get_data() { + const dataPath = path.join(__dirname, "data.json"); + if (!fs.existsSync(dataPath)) { + fs.writeFileSync(dataPath, JSON.stringify([])); + } + const data = fs.readFileSync(dataPath); + return JSON.parse(data); +} + +function save_data(data) { + fs.writeFileSync(path.join(__dirname, "data.json"), JSON.stringify(data, null, 2)); +} + +function saveUser(user) { + const users = get_data(); + users.push(user); + save_data(users); +} + +function generateAccessToken(user) { + return jwt.sign(user, process.env.TOKEN_SECRET, { expiresIn: "1800s" }); +} + +function authenticateToken(request, response, next) { + const authHeader = request.headers["authorization"]; + const token = authHeader && authHeader.split(" ")[1]; + + if (token == null) return response.sendStatus(401); + + jwt.verify(token, process.env.TOKEN_SECRET, (err, user) => { + if (err) return response.sendStatus(403); + + const users = get_data(); + const foundUser = users.find(u => u.username === user.username); + if (!foundUser || foundUser.token !== token) { + return response.status(403).json({ error: "Token has been revoked or is invalid" }); + } + + request.user = user; + next(); + }); +} + +app.post("/register", (request, response) => { + const { username } = request.body; + if (!username) + return response.status(400).json({ error: "Username is required" }); + + const users = get_data(); + if (users.some(u => u.username === username)) { + return response.status(400).json({ error: "Username already exists" }); + } + + const token = generateAccessToken({ username }); + saveUser({ username, token }); + + response.json({ username, token }); +}); + +app.post("/login", (request, response) => { + const { username } = request.body; + if (!username) + return response.status(400).json({ error: "Username is required" }); + + const users = get_data(); + const user = users.find(u => u.username === username); + if (!user) return response.status(401).json({ error: "Invalid credentials" }); + + + const token = generateAccessToken({ username }); + user.token = token; + save_data(users); + + response.json({ username, token }); +}); + +app.get("/", authenticateToken, (request, response) => { + response.sendFile(path.join(__dirname, "structure.png")); +}); + +app.post("/verify", authenticateToken, (request, response) => { + response.json({ valid: true, user: request.user }); +}); + +app.delete("/logout", authenticateToken, (request, response) => { + const username = request.user.username; + const users = get_data(); + const user = users.find(u => u.username === username); + if (user) { + delete user.token; + save_data(users); + } + response.json({ message: "Logged out successfully." }); }); app.listen(port, () => { console.log("Server is running on port " + port); -}) \ No newline at end of file +}); diff --git a/generate_secret.js b/generate_secret.js new file mode 100644 index 0000000..2293b89 --- /dev/null +++ b/generate_secret.js @@ -0,0 +1,5 @@ +const crypto = require("crypto"); + +const secret = crypto.randomBytes(64).toString('hex') + +console.log(secret) \ No newline at end of file diff --git a/package.json b/package.json index 24f47b1..d805e5f 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,9 @@ }, "private": true, "dependencies": { + "dotenv": "^16.5.0", "express": "^5.1.0", + "jsonwebtoken": "^9.0.2", "swagger-ui-express": "^5.0.1" }, "devDependencies": { diff --git a/swagger.json b/swagger.json index b03412c..f07eb11 100644 --- a/swagger.json +++ b/swagger.json @@ -11,12 +11,134 @@ } ], "paths": { - "/": { - "get": { + "/register": { + "post": { "description": "", "responses": { "200": { "description": "OK" + }, + "400": { + "description": "Bad Request" + } + }, + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "username": { + "example": "any" + } + } + } + } + } + } + } + }, + "/login": { + "post": { + "description": "", + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + }, + "401": { + "description": "Unauthorized" + } + }, + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "username": { + "example": "any" + } + } + } + } + } + } + } + }, + "/": { + "get": { + "description": "", + "parameters": [ + { + "name": "authorization", + "in": "header", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + } + } + } + }, + "/verify": { + "post": { + "description": "", + "parameters": [ + { + "name": "authorization", + "in": "header", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + } + } + } + }, + "/logout": { + "delete": { + "description": "", + "parameters": [ + { + "name": "authorization", + "in": "header", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" } } }