create event

main
Netcup Gituser 2023-12-06 20:27:55 +01:00
parent 02d7c6a1d4
commit ff0699e61f
14 changed files with 201 additions and 96 deletions

View File

@ -13,7 +13,8 @@ import swaggerUI from "swagger-ui-express";
import adminRoutes from "./src/routes/adminRoutes"; import adminRoutes from "./src/routes/adminRoutes";
import userRoutes from "./src/routes/userRoutes"; import userRoutes from "./src/routes/userRoutes";
import eventRoutes from "./src/routes/eventRoutes"; import usersRoutes from "./src/routes/usersRoutes";
import eventsRoutes from "./src/routes/eventsRoutes";
const options = { const options = {
definition: { definition: {
@ -43,8 +44,9 @@ const options = {
app.use(bodyParser.json()); app.use(bodyParser.json());
app.use("/api/v1/user", userRoutes); app.use("/api/v1/user", userRoutes);
app.use("/api/v1/users", usersRoutes);
app.use("/api/v1/admin", adminRoutes); app.use("/api/v1/admin", adminRoutes);
app.use("/api/v1/events", eventRoutes); app.use("/api/v1/events", eventsRoutes);
const specs = swaggerJsDoc(options); const specs = swaggerJsDoc(options);
app.use("/api-docs", swaggerUI.serve, swaggerUI.setup(specs)); app.use("/api-docs", swaggerUI.serve, swaggerUI.setup(specs));

View File

@ -2,7 +2,7 @@ import { Request, Response } from "express";
import { User } from "../models/user"; import { User } from "../models/user";
import { import {
ADMIN_MAX_USERS_PER_PAGE, ADMIN_MAX_USERS_PER_PAGE,
MONGODB_IGNORED_FIELDS, MONGODB_IGNORED_FIELDS_USER,
} from "../utils/constants"; } from "../utils/constants";
export async function GetAllUsers(req: Request, res: Response) { export async function GetAllUsers(req: Request, res: Response) {
@ -24,7 +24,7 @@ export async function GetAllUsers(req: Request, res: Response) {
// Query for the current page with limit and skip // Query for the current page with limit and skip
const users = await User.find({}) const users = await User.find({})
.lean() .lean()
.select(MONGODB_IGNORED_FIELDS) // Exclude password and other fields .select(MONGODB_IGNORED_FIELDS_USER)
.skip(skip) .skip(skip)
.limit(pageSize); .limit(pageSize);

View File

@ -0,0 +1,43 @@
import { Request, Response } from "express";
import { Event } from "../models/event";
import { MONGODB_IGNORED_FIELDS } from "../utils/constants";
export async function CreateEvent(req: Request, res: Response) {
try {
const { name, type, latitude, longitude } = req.body;
if (!name || type === null || !latitude || !longitude) {
console.log("missing fields");
return res.status(400).json({ status: "err" });
}
const event = new Event({
name: name,
type: type,
latitude: latitude,
longitude: longitude,
});
await event
.save()
.then(() => res.status(200).json({ status: "ok" }))
.catch((err) => {
console.log(err);
res.status(500).json({ status: "err" });
});
} catch (error) {
console.error("error on create event:", error);
res.status(500).json({ status: "err" });
}
}
export async function GetEvents(req: Request, res: Response) {
try {
const events = await Event.find().select(MONGODB_IGNORED_FIELDS).lean();
res.status(200).json({ events });
} catch (error) {
console.error("error on get events:", error);
res.status(500).json({ status: "err" });
}
}

View File

@ -5,46 +5,52 @@ import {
hashPassword, hashPassword,
decodeBase64, decodeBase64,
matchPassword, matchPassword,
getUserSession,
} from "../utils/utils"; } from "../utils/utils";
import { MONGODB_IGNORED_FIELDS } from "../utils/constants";
import { isUsernameValid, isPasswordValid } from "../validation/validation"; import { isUsernameValid, isPasswordValid } from "../validation/validation";
import { Session } from "../models/session"; import { Session } from "../models/session";
import { MONGODB_IGNORED_FIELDS } from "../utils/constants";
export async function SignUp(req: Request, res: Response) { export async function SignUp(req: Request, res: Response) {
const { accountName, username, password } = req.body; try {
const { accountName, username, password } = req.body;
if (!accountName || !username || !password) { if (!accountName || !username || !password) {
return res.status(400).json({ status: "err" }); return res.status(400).json({ status: "err" });
} }
const existingUser = await User.findOne({ accountName }) const existingUser = await User.findOne({ accountName })
.select("accountName -_id") .select(`accountName ${MONGODB_IGNORED_FIELDS}`)
.lean(); .lean();
if (existingUser) { if (existingUser) {
return res.status(400).json({ status: 1 }); return res.status(400).json({ status: 1 });
} }
if (!isPasswordValid(password)) { if (!isPasswordValid(password)) {
return res.status(400).json({ status: "err" }); return res.status(400).json({ status: "err" });
} }
const decodedPassword = decodeBase64(password); const decodedPassword = decodeBase64(password);
const hashedPassword = await hashPassword(decodedPassword); const hashedPassword = await hashPassword(decodedPassword);
const user = new User({ const user = new User({
accountName: accountName, accountName: accountName,
username: username, username: username,
password: hashedPassword, password: hashedPassword,
});
user
.save()
.then(() => saveSession(res, accountName))
.catch((err) => {
console.log(err);
res.status(500).json({ status: "err" });
}); });
user
.save()
.then(() => saveSession(res, accountName))
.catch((err) => {
console.log(err);
res.status(500).json({ status: "err" });
});
} catch (error) {
console.error("error on signup:", error);
res.status(500).json({ status: "err" });
}
} }
export async function Login(req: Request, res: Response) { export async function Login(req: Request, res: Response) {
@ -55,7 +61,9 @@ export async function Login(req: Request, res: Response) {
const { accountName, password } = req.body; const { accountName, password } = req.body;
const user = await User.findOne({ accountName }).lean(); const user = await User.findOne({ accountName })
.select(MONGODB_IGNORED_FIELDS)
.lean();
if (!user) { if (!user) {
return res.status(401).json({ status: "err" }); return res.status(401).json({ status: "err" });
@ -84,71 +92,65 @@ export async function Login(req: Request, res: Response) {
} }
} }
export async function GetUserProfile(req: Request, res: Response) { export async function ChangeUsername(req: Request, res: Response) {
try { try {
const user = await User.findOne({ const { newUsername } = req.body;
accountName: req.params.accountName,
})
.select(MONGODB_IGNORED_FIELDS)
.lean();
if (!user) { if (!newUsername || !isUsernameValid(newUsername)) {
return res.status(404).json({ status: "err" }); return res.status(400).json({ status: "err" });
} }
res.json({ const session = await getUserSession(req, "accountName");
accountName: user.accountName,
username: user.username,
});
} catch (error) {
console.error("error on get user profile:", error);
res.status(500).json({ status: "err" });
}
}
export async function ChangeUsername(req: Request, res: Response) { if (!session) {
const { accountName, newUsername } = req.body; return res.status(401).json({ status: "err" });
}
if (!accountName || !newUsername) {
return res.status(400).json({ status: "err" });
}
if (!isUsernameValid(newUsername)) {
return res.status(400).json({ status: "err" });
}
try {
await User.updateOne( await User.updateOne(
{ accountName: accountName }, { accountName: session.accountName },
{ $set: { username: newUsername } } { $set: { username: newUsername } }
); );
res.status(200).json({ status: "ok" }); res.status(200).json({ status: "ok" });
} catch (error) { } catch (error) {
console.error(error); console.error("error on changing username", error);
res.status(500).json({ status: "err" }); res.status(500).json({ status: "err" });
} }
} }
export async function ChangePassword(req: Request, res: Response) { export async function ChangePassword(req: Request, res: Response) {
const { accountName, currentPassword, newPassword } = req.body;
if (!accountName || !currentPassword || !newPassword) {
return res.status(400).json({ status: "err" });
}
try { try {
const decodedCurrentPassword = decodeBase64(currentPassword); // cp = current password
// np = new password
const { cp, np } = req.body;
const existingUser = await User.findOne({ accountName }) if (!cp || !np) {
.select("password -_id") return res.status(400).json({ status: "err" });
}
console.log(cp, np);
const session = await getUserSession(req, "accountName");
if (!session) {
return res.status(401).json({ status: "err" });
}
const accountName = session.accountName;
const decodedCurrentPassword = decodeBase64(cp);
const existingUser = await User.findOne({
accountName: accountName,
})
.select(`password -_id`)
.lean(); .lean();
if (!existingUser) { if (!existingUser) {
return res.status(400).json({ status: 1 }); return res.status(400).json({ status: 1 });
} }
const decodedNewPassword = decodeBase64(newPassword); const decodedNewPassword = decodeBase64(np);
if (!isPasswordValid(decodedCurrentPassword)) { if (!isPasswordValid(decodedCurrentPassword)) {
return res.status(400).json({ status: "err" }); return res.status(400).json({ status: "err" });
@ -173,7 +175,7 @@ export async function ChangePassword(req: Request, res: Response) {
// delete all sessions // delete all sessions
await Session.deleteMany({ accountName: accountName }); await Session.deleteMany({ accountName: accountName });
} catch (error) { } catch (error) {
console.error(error); console.error("error on changing password", error);
res.status(500).json({ status: "err" }); res.status(500).json({ status: "err" });
} }
} }

View File

@ -0,0 +1,22 @@
import { Request, Response } from "express";
import { User } from "../models/user";
import { MONGODB_IGNORED_FIELDS_USER } from "../utils/constants";
export async function GetUserProfile(req: Request, res: Response) {
try {
const user = await User.findOne({
accountName: req.params.accountName,
})
.select(`-accountName ${MONGODB_IGNORED_FIELDS_USER}`)
.lean();
if (!user) {
return res.status(404).json({ status: "err" });
}
res.json(user);
} catch (error) {
console.error("error on get user profile:", error);
res.status(500).json({ status: "err" });
}
}

View File

@ -2,17 +2,10 @@ import { Request } from "express";
import { Session } from "../models/session"; import { Session } from "../models/session";
import { User } from "../models/user"; import { User } from "../models/user";
import { HEADER_X_AUTHORIZATION } from "../utils/constants"; import { HEADER_X_AUTHORIZATION } from "../utils/constants";
import { getUserSession } from "../utils/utils";
export async function sessionProtection(req: Request, res: any, next: any) { export async function sessionProtection(req: Request, res: any, next: any) {
const xAuthorization = req.get(HEADER_X_AUTHORIZATION); const session = await getUserSession(req);
if (!xAuthorization) {
return res.status(401).json({ status: "err" });
}
const session = await Session.findOne({ sessionId: xAuthorization })
.select("sessionId -_id")
.lean();
if (!session) { if (!session) {
return res.status(401).json({ status: "err" }); return res.status(401).json({ status: "err" });

15
src/models/event.ts Normal file
View File

@ -0,0 +1,15 @@
import mongoose, { InferSchemaType, Schema } from "mongoose";
export const eventSchema = new Schema({
name: String,
type: Number,
description: String,
latitude: Number,
longitude: Number,
date: Date,
creator: String,
});
export type Event = InferSchemaType<typeof eventSchema>;
export const Event = mongoose.model<Event>("Event", eventSchema);

View File

@ -1,4 +0,0 @@
import express from "express";
const router = express.Router();
export default router;

View File

@ -0,0 +1,9 @@
import express from "express";
import { sessionProtection } from "../middleware/authMiddleware";
const router = express.Router();
import * as eventsController from "../controllers/eventsController";
router.post("/", sessionProtection, eventsController.CreateEvent);
router.get("/", sessionProtection, eventsController.GetEvents);
export default router;

View File

@ -1,4 +1,4 @@
import express, { Router } from "express"; import express from "express";
const router = express.Router(); const router = express.Router();
import * as userController from "../controllers/userController"; import * as userController from "../controllers/userController";
import { sessionProtection } from "../middleware/authMiddleware"; import { sessionProtection } from "../middleware/authMiddleware";
@ -127,12 +127,6 @@ router.post("/signup", userController.SignUp);
*/ */
router.post("/login", userController.Login); router.post("/login", userController.Login);
router.get(
"/profile/:accountName",
sessionProtection,
userController.GetUserProfile
);
router.post("/username", sessionProtection, userController.ChangeUsername); router.post("/username", sessionProtection, userController.ChangeUsername);
router.post("/password", sessionProtection, userController.ChangePassword); router.post("/password", sessionProtection, userController.ChangePassword);

View File

@ -0,0 +1,8 @@
import express from "express";
const router = express.Router();
import * as usersController from "../controllers/usersController";
import { sessionProtection } from "../middleware/authMiddleware";
router.get("/:accountName", sessionProtection, usersController.GetUserProfile);
export default router;

View File

@ -5,7 +5,9 @@ export const DEFAULT_SESSION_EXPIRATION: number = 7 * 24 * 60 * 60 * 1000;
export const ADMIN_MAX_USERS_PER_PAGE: number = 10; export const ADMIN_MAX_USERS_PER_PAGE: number = 10;
// Fields to ignore when querying MongoDB // Fields to ignore when querying MongoDB
export const MONGODB_IGNORED_FIELDS: string = "-password -_id -__v"; export const MONGODB_IGNORED_FIELDS: string = "-_id -__v";
export const MONGODB_IGNORED_FIELDS_USER: string =
MONGODB_IGNORED_FIELDS + " -password -isAdmin";
// Header name for the session ID // Header name for the session ID
export const HEADER_X_AUTHORIZATION: string = "x-authorization"; export const HEADER_X_AUTHORIZATION: string = "x-authorization";

View File

@ -1,7 +1,8 @@
import crypto from "crypto"; import crypto from "crypto";
import { Session } from "../models/session"; import { Session } from "../models/session";
import { Response } from "express"; import { Request, Response } from "express";
import bcrypt from "bcrypt"; 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) {
try { try {
@ -36,3 +37,21 @@ export async function hashPassword(password: string) {
export function decodeBase64(value: string) { export function decodeBase64(value: string) {
return Buffer.from(value, "base64").toString("utf-8"); return Buffer.from(value, "base64").toString("utf-8");
} }
export async function getUserSession(req: Request, select?: string) {
const sessionId = req.get(HEADER_X_AUTHORIZATION);
if (!sessionId) {
return null;
}
const session = await Session.findOne({ sessionId })
.select(`sessionId -_id ${select}`)
.lean();
if (!session) {
return null;
}
return session;
}