main
Netcup Gituser 2023-12-09 21:54:34 +01:00
parent ff0699e61f
commit 6cf57df008
8 changed files with 131 additions and 19 deletions

View File

@ -1,6 +1,7 @@
import express, { Express } from "express";
import dotenv from "dotenv";
import bodyParser = require("body-parser");
import bodyParser from "body-parser";
import morgan from "morgan";
dotenv.config();
@ -42,16 +43,22 @@ const options = {
};
app.use(bodyParser.json());
app.use(morgan("combined"));
app.use("/api/v1/user", userRoutes);
app.use("/api/v1/users", usersRoutes);
app.use("/api/v1/admin", adminRoutes);
app.use("/api/v1/events", eventsRoutes);
app.use("/api/v1/appstart", (req, res, next) => {
console.log("appstart");
res.status(200).json({ status: "ok" });
});
const specs = swaggerJsDoc(options);
app.use("/api-docs", swaggerUI.serve, swaggerUI.setup(specs));
app.use((req, res, next) => {
console.log("req", req);
res.status(404).send("not found");
});

61
package-lock.json generated
View File

@ -14,12 +14,14 @@
"dotenv": "^16.3.1",
"express": "^4.18.2",
"mongoose": "^8.0.2",
"morgan": "^1.10.0",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-express": "^5.0.0"
},
"devDependencies": {
"@types/bcrypt": "^5.0.2",
"@types/express": "^4.17.21",
"@types/morgan": "^1.9.9",
"@types/node": "^20.10.2",
"@types/swagger-jsdoc": "^6.0.4",
"@types/swagger-ui-express": "^4.1.6",
@ -195,6 +197,15 @@
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
"dev": true
},
"node_modules/@types/morgan": {
"version": "1.9.9",
"resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.9.tgz",
"integrity": "sha512-iRYSDKVaC6FkGSpEVVIvrRGw0DfJMiQzIn3qr2G5B3C//AWkulhXgaBd7tS9/J79GWSYMTHGs7PfI5b3Y8m+RQ==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/node": {
"version": "20.10.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.2.tgz",
@ -383,6 +394,22 @@
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"node_modules/basic-auth": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
"integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
"dependencies": {
"safe-buffer": "5.1.2"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/basic-auth/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"node_modules/bcrypt": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz",
@ -1513,6 +1540,32 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"node_modules/morgan": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz",
"integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==",
"dependencies": {
"basic-auth": "~2.0.1",
"debug": "2.6.9",
"depd": "~2.0.0",
"on-finished": "~2.3.0",
"on-headers": "~1.0.2"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/morgan/node_modules/on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
"integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
"dependencies": {
"ee-first": "1.1.1"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/mpath": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz",
@ -1743,6 +1796,14 @@
"node": ">= 0.8"
}
},
"node_modules/on-headers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
"integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",

View File

@ -17,12 +17,14 @@
"dotenv": "^16.3.1",
"express": "^4.18.2",
"mongoose": "^8.0.2",
"morgan": "^1.10.0",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-express": "^5.0.0"
},
"devDependencies": {
"@types/bcrypt": "^5.0.2",
"@types/express": "^4.17.21",
"@types/morgan": "^1.9.9",
"@types/node": "^20.10.2",
"@types/swagger-jsdoc": "^6.0.4",
"@types/swagger-ui-express": "^4.1.6",

View File

@ -20,7 +20,7 @@ export async function SignUp(req: Request, res: Response) {
}
const existingUser = await User.findOne({ accountName })
.select(`accountName ${MONGODB_IGNORED_FIELDS}`)
.select(MONGODB_IGNORED_FIELDS)
.lean();
if (existingUser) {
@ -42,7 +42,7 @@ export async function SignUp(req: Request, res: Response) {
user
.save()
.then(() => saveSession(res, accountName))
.then(() => saveSession(res, accountName, username))
.catch((err) => {
console.log(err);
res.status(500).json({ status: "err" });
@ -55,14 +55,14 @@ export async function SignUp(req: Request, res: Response) {
export async function Login(req: Request, res: Response) {
try {
if (!req.body.accountName || !req.body.password) {
const { AccountName, Password } = req.body;
if (!AccountName || !Password) {
return res.status(400).json({ status: "err" });
}
const { accountName, password } = req.body;
const user = await User.findOne({ accountName })
.select(MONGODB_IGNORED_FIELDS)
const user = await User.findOne({ accountName: AccountName })
.select(`accountName username password -_id`)
.lean();
if (!user) {
@ -78,14 +78,14 @@ export async function Login(req: Request, res: Response) {
return res.status(401).json({ status: "err" });
}
const decodedPassword = decodeBase64(password);
const decodedPassword = decodeBase64(Password);
const isPasswordValid = await matchPassword(decodedPassword, user.password);
if (!isPasswordValid) {
return res.status(401).json({ status: "err" });
}
saveSession(res, user.accountName);
saveSession(res, user.accountName, user.username);
} catch (error) {
console.error("error on login:", error);
res.status(500).json({ status: "err" });
@ -179,3 +179,20 @@ export async function ChangePassword(req: Request, res: Response) {
res.status(500).json({ status: "err" });
}
}
export async function Logout(req: Request, res: Response) {
try {
const session = await getUserSession(req);
if (!session) {
return res.status(401).json({ status: "err" });
}
await Session.deleteOne({ sessionId: session.sessionId });
res.status(200).json({ status: "ok" });
} catch (error) {
console.error("error on logout", error);
res.status(500).json({ status: "err" });
}
}

View File

@ -129,7 +129,6 @@ router.post("/login", userController.Login);
router.post("/username", sessionProtection, userController.ChangeUsername);
router.post("/password", sessionProtection, userController.ChangePassword);
//router.post("/logout", sessionProtection, userController.Logout);
router.post("/logout", sessionProtection, userController.Logout);
export default router;

View File

@ -12,15 +12,15 @@ export const MONGODB_IGNORED_FIELDS_USER: string =
// Header name for the session ID
export const HEADER_X_AUTHORIZATION: string = "x-authorization";
export const USERNAME_MIN_LENGTH: number = 3;
export const USERNAME_MAX_LENGTH: number = 20;
export const USERNAME_MIN_LENGTH: number = 2;
export const USERNAME_MAX_LENGTH: number = 24;
export const USERNAME_REGEX: RegExp = /^[a-zA-Z0-9_]+$/; // Alphanumeric and underscore
export const PASSWORD_MIN_LENGTH: number = 8;
export const PASSWORD_MIN_LENGTH: number = 6;
export const PASSWORD_MAX_LENGTH: number = 64;
export const PASSWORD_REGEX: RegExp =
/^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$/;
export const ACCOUNT_NAME_MIN_LENGTH: number = 3;
export const ACCOUNT_NAME_MAX_LENGTH: number = 20;
export const ACCOUNT_NAME_MIN_LENGTH: number = 4;
export const ACCOUNT_NAME_MAX_LENGTH: number = 24;
// alphanumerics, numbers, underscores, and dashes
export const ACCOUNT_NAME_REGEX: RegExp = /^[a-zA-Z0-9_-]+$/;

View File

@ -4,7 +4,11 @@ import { Request, Response } from "express";
import bcrypt from "bcrypt";
import { HEADER_X_AUTHORIZATION } from "./constants";
export async function saveSession(res: Response, accountName: string) {
export async function saveSession(
res: Response,
accountName: string,
username: string
) {
try {
// Generate a random session ID
const sessionId = crypto.randomBytes(32).toString("hex");
@ -19,7 +23,7 @@ export async function saveSession(res: Response, accountName: string) {
await session.save();
// Respond with the session ID
res.status(200).json({ sessionId });
res.status(200).json({ XAuthorization: sessionId, Username: username });
} catch (error) {
console.error("Error saving session:", error);
res.status(500).json({ status: "err" });

22
test.js Normal file
View File

@ -0,0 +1,22 @@
function decimalToCharEncoder(decimalNumber) {
const characters =
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const base = characters.length;
if (decimalNumber === 0) {
return characters[0];
}
let result = "";
while (decimalNumber > 0) {
const remainder = decimalNumber % base;
result = characters[remainder] + result;
decimalNumber = Math.floor(decimalNumber / base);
}
return result;
}
const decimalNumber = 10002;
const encodedString = decimalToCharEncoder(decimalNumber);
console.log(`Decimal: ${decimalNumber}, Encoded: ${encodedString}`);