diff --git a/src/controllers/userController.ts b/src/controllers/userController.ts index 711c4ab..7776350 100644 --- a/src/controllers/userController.ts +++ b/src/controllers/userController.ts @@ -24,6 +24,7 @@ import { saveSession, } from "../utils/utils"; import Store from "../models/store"; +import Session from "../models/session"; export async function SignUp(req: Request, res: Response) { try { @@ -102,7 +103,7 @@ export async function SignUp(req: Request, res: Response) { account_name: accountName, username: username, password: hashedPassword, - language: language, + language: language, analytics_enabled: USER_ANALYTICS_ENABLED_DEFAULT, }) .then((user) => { @@ -329,7 +330,7 @@ export async function GetUserProfileSettings(req: Request, res: Response) { where: { user_id: session.user_id, }, - attributes: ["language", "analytics_enabled"], + attributes: ["language", "analytics_enabled", "username", "account_name"], }); res.status(200).json(user); @@ -341,9 +342,14 @@ export async function GetUserProfileSettings(req: Request, res: Response) { export async function UpdateUserProfileSettings(req: Request, res: Response) { try { - const { language, analyticsEnabled } = req.body; + const { language, analyticsEnabled, username, accountName } = req.body; - if (!language && analyticsEnabled === undefined) { + if ( + !language && + analyticsEnabled === undefined && + !username && + !accountName + ) { return res.status(400).send({ err: "invalid request" }); } @@ -371,6 +377,22 @@ export async function UpdateUserProfileSettings(req: Request, res: Response) { user.analytics_enabled = analyticsEnabled; } + if (username) { + if (!isUsernameValid(username)) { + return res.status(400).send({ err: "invalid request" }); + } + + user.username = username; + } + + if (accountName) { + if (!isAccountNameValid(accountName)) { + return res.status(400).send({ err: "invalid request" }); + } + + user.account_name = accountName; + } + await user.save(); res.status(200).send({ msg: "user profile settings updated" }); @@ -379,3 +401,72 @@ export async function UpdateUserProfileSettings(req: Request, res: Response) { res.status(500).send({ err: "invalid request" }); } } + +export async function UpdateUserProfilePassword(req: Request, res: Response) { + try { + const { currentPassword, newPassword } = req.body; + + if (!currentPassword || !newPassword) { + return res.status(400).send({ err: "invalid request" }); + } + + const session = await getUserSession(req); + + if (!session) { + return res.status(401).send({ err: "unauthorized" }); + } + + const user = await User.findOne({ + where: { + user_id: session.user_id, + }, + attributes: ["password"], + }); + + if (!user) { + return res.status(401).send({ err: "unauthorized" }); + } + + const decodedCurrentPassword = decodeBase64(currentPassword); + + const match = await matchPassword(decodedCurrentPassword, user.password); + + if (!match) { + return res.status(400).send({ err: "invalid request" }); + } + + const decodedPassword = decodeBase64(newPassword); + + if (!isPasswordValid(decodedPassword)) { + return res.status(400).send({ err: "invalid request" }); + } + + const hashedPassword = await hashPassword(decodedPassword); + + // update user password + + await User.update( + { + password: hashedPassword, + }, + { + where: { + user_id: session.user_id, + }, + } + ); + + // delete all sessions of this user by deleting all sessions with this user_id + + await Session.destroy({ + where: { + user_id: session.user_id, + }, + }); + + res.status(200).send({ msg: "user password updated" }); + } catch (error) { + logger.error(error); + res.status(500).send({ err: "invalid request" }); + } +} diff --git a/src/routes/calendarRoutes.ts b/src/routes/calendarRoutes.ts index 7b83308..23b8364 100644 --- a/src/routes/calendarRoutes.ts +++ b/src/routes/calendarRoutes.ts @@ -65,13 +65,12 @@ router.get( pass: process.env.TERMIN_PLANNER_AUTHORIZATION_PASSWORD as string, } ) - .then(() => { - res.redirect(process.env.PASSPORT_SUCCESS_REDIRECT_URL as string); - }) + .then(() => {}) .catch((err) => { logger.info("err %s", err); - res.redirect(process.env.PASSPORT_FAILURE_REDIRECT_URL as string); }); + + res.redirect(process.env.PASSPORT_SUCCESS_REDIRECT_URL as string); }) .catch((err) => { logger.error(err); diff --git a/src/routes/userRoutes.ts b/src/routes/userRoutes.ts index 00c7e17..d21772d 100644 --- a/src/routes/userRoutes.ts +++ b/src/routes/userRoutes.ts @@ -19,5 +19,10 @@ router.post( sessionProtection, userController.UpdateUserProfileSettings ); +router.post( + "/profile/password", + sessionProtection, + userController.UpdateUserProfilePassword +); export default router; diff --git a/src/utils/constants.ts b/src/utils/constants.ts index e424e24..89782e1 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -42,6 +42,7 @@ export const USER_ANALYTICS_ENABLED_DEFAULT = true; export const VALID_LANGUAGE_CODES = ["en", "de"]; +// TODO: outdated export const Roles = { // admin of the whole system independent of stores Admin: "admin",