diff --git a/backend/src/controllers/v1/authController.ts b/backend/src/controllers/v1/authController.ts index 882db688f..19850680e 100644 --- a/backend/src/controllers/v1/authController.ts +++ b/backend/src/controllers/v1/authController.ts @@ -12,6 +12,8 @@ import { JWT_AUTH_SECRET, JWT_REFRESH_SECRET } from '../../config'; +import LoginSRPDetail from '../../models/LoginSRPDetail'; +import { BadRequestError } from '../../utils/errors'; declare module 'jsonwebtoken' { export interface UserIDJwtPayload extends jwt.JwtPayload { @@ -19,8 +21,6 @@ declare module 'jsonwebtoken' { } } -const clientPublicKeys: any = {}; - /** * Log in user step 1: Return [salt] and [serverPublicKey] as part of step 1 of SRP protocol * @param req @@ -46,13 +46,15 @@ export const login1 = async (req: Request, res: Response) => { salt: user.salt, verifier: user.verifier }, - () => { + async () => { // generate server-side public key const serverPublicKey = server.getPublicKey(); - clientPublicKeys[email] = { - clientPublicKey, - serverBInt: bigintConversion.bigintToBuf(server.bInt) - }; + + await LoginSRPDetail.findOneAndReplace({ email: email }, { + email: email, + clientPublicKey: clientPublicKey, + serverBInt: bigintConversion.bigintToBuf(server.bInt), + }, { upsert: true, returnNewDocument: false }) return res.status(200).send({ serverPublicKey, @@ -85,15 +87,21 @@ export const login2 = async (req: Request, res: Response) => { if (!user) throw new Error('Failed to find user'); + const loginSRPDetailFromDB = await LoginSRPDetail.findOneAndDelete({ email: email }) + + if (!loginSRPDetailFromDB) { + return BadRequestError(Error("It looks like some details from the first login are not found. Please try login one again")) + } + const server = new jsrp.server(); server.init( { salt: user.salt, verifier: user.verifier, - b: clientPublicKeys[email].serverBInt + b: loginSRPDetailFromDB.serverBInt }, async () => { - server.setClientPublicKey(clientPublicKeys[email].clientPublicKey); + server.setClientPublicKey(loginSRPDetailFromDB.clientPublicKey); // compare server and client shared keys if (server.checkClientProof(clientProof)) { diff --git a/backend/src/models/LoginSRPDetail.ts b/backend/src/models/LoginSRPDetail.ts new file mode 100644 index 000000000..f65e779c3 --- /dev/null +++ b/backend/src/models/LoginSRPDetail.ts @@ -0,0 +1,23 @@ +import mongoose, { Schema, model } from 'mongoose'; + +const LoginSRPDetailSchema = new Schema( + { + clientPublicKey: { + type: String, + required: true + }, + email: { + type: String, + required: true, + unique: true + }, + serverBInt: { type: mongoose.Schema.Types.Buffer }, + expireAt: { type: Date } + } +); + +const LoginSRPDetail = model('LoginSRPDetail', LoginSRPDetailSchema); + +// LoginSRPDetailSchema.index({ "expireAt": 1 }, { expireAfterSeconds: 0 }); + +export default LoginSRPDetail;