From 82ea8ce0a3e0958aafe006f90696c78cdef41fcb Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Mon, 30 Dec 2019 08:36:55 +0100 Subject: [PATCH] Can check security answers --- src/controllers/AccountController.ts | 30 ++++++++++++++++++++++++++++ src/controllers/Routes.ts | 2 ++ src/helpers/AccountHelper.ts | 26 ++++++++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/src/controllers/AccountController.ts b/src/controllers/AccountController.ts index 94d146e..8817346 100644 --- a/src/controllers/AccountController.ts +++ b/src/controllers/AccountController.ts @@ -115,4 +115,34 @@ export class AccountController { ] }) } + + /** + * Check the answer given by the user + * + * @param h Request handler + */ + public static async CheckSecurityAnswers(h: RequestHandler) { + const userID = await h.postUserIdFromEmail("email"); + const settings = await UserHelper.GetUserInfo(userID); + + if(!settings.hasSecurityQuestions) + h.error(401, "Specified user has not setup security questions !"); + + // Get the answers of the user + const answers = h.postString("answers", 3).split("&") + .map((e) => decodeURIComponent(e).toLowerCase().trim()); + + if(answers.length != 2) + h.error(401, "Please specify two security answers !"); + + // Check the answers + if(answers[0] != settings.security_answer_1.toLowerCase().trim() || + answers[1] != settings.security_answer_2.toLowerCase().trim()) + h.error(401, "Specified ecurity answers are invalid!"); + + // If we get there, security answers are valid, we can create a password reset token + h.send({ + reset_token: await AccountHelper.GenerateNewPasswordResetToken(userID) + }); + } } \ No newline at end of file diff --git a/src/controllers/Routes.ts b/src/controllers/Routes.ts index 0533ab0..af15265 100644 --- a/src/controllers/Routes.ts +++ b/src/controllers/Routes.ts @@ -49,6 +49,8 @@ export const Routes : Route[] = [ {path: "/account/get_security_questions", cb: (h) => AccountController.GetSecurityQuestions(h), needLogin: false}, + {path: "/account/check_security_answers", cb: (h) => AccountController.CheckSecurityAnswers(h), needLogin: false}, + // User controller {path: "/user/getInfo", cb: (h) => UserController.GetSingle(h), needLogin: false}, diff --git a/src/helpers/AccountHelper.ts b/src/helpers/AccountHelper.ts index b4dd985..ae36928 100644 --- a/src/helpers/AccountHelper.ts +++ b/src/helpers/AccountHelper.ts @@ -3,6 +3,7 @@ import { APIClient } from "../entities/APIClient"; import { UserLoginTokens } from "../entities/UserLoginTokens"; import { DatabaseHelper } from "./DatabaseHelper"; import { UserHelper } from "./UserHelper"; +import { time } from "../utils/DateUtils"; /** * Account helper @@ -205,4 +206,29 @@ export class AccountHelper { return foundUser < 1 || userID == foundUser; } + + /** + * Generate a new token to reset an account password + * + * @param userID Target user ID + * @returns Generated token + */ + public static async GenerateNewPasswordResetToken(userID: number) : Promise { + + // Generate a token + const token = randomStr(255); + + await DatabaseHelper.UpdateRows({ + table: USER_TABLE, + where: { + ID: userID + }, + set: { + password_reset_token: token, + password_reset_token_time_create: time() + } + }); + + return token; + } } \ No newline at end of file