Make backend login stateless

This commit is contained in:
Maidul Islam
2023-01-25 20:03:43 -08:00
parent be2945c445
commit ae0ee727fa
2 changed files with 40 additions and 9 deletions

View File

@@ -12,6 +12,8 @@ import {
JWT_AUTH_SECRET, JWT_AUTH_SECRET,
JWT_REFRESH_SECRET JWT_REFRESH_SECRET
} from '../../config'; } from '../../config';
import LoginSRPDetail from '../../models/LoginSRPDetail';
import { BadRequestError } from '../../utils/errors';
declare module 'jsonwebtoken' { declare module 'jsonwebtoken' {
export interface UserIDJwtPayload extends jwt.JwtPayload { 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 * Log in user step 1: Return [salt] and [serverPublicKey] as part of step 1 of SRP protocol
* @param req * @param req
@@ -46,13 +46,15 @@ export const login1 = async (req: Request, res: Response) => {
salt: user.salt, salt: user.salt,
verifier: user.verifier verifier: user.verifier
}, },
() => { async () => {
// generate server-side public key // generate server-side public key
const serverPublicKey = server.getPublicKey(); const serverPublicKey = server.getPublicKey();
clientPublicKeys[email] = {
clientPublicKey, await LoginSRPDetail.findOneAndReplace({ email: email }, {
serverBInt: bigintConversion.bigintToBuf(server.bInt) email: email,
}; clientPublicKey: clientPublicKey,
serverBInt: bigintConversion.bigintToBuf(server.bInt),
}, { upsert: true, returnNewDocument: false })
return res.status(200).send({ return res.status(200).send({
serverPublicKey, serverPublicKey,
@@ -85,15 +87,21 @@ export const login2 = async (req: Request, res: Response) => {
if (!user) throw new Error('Failed to find user'); 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(); const server = new jsrp.server();
server.init( server.init(
{ {
salt: user.salt, salt: user.salt,
verifier: user.verifier, verifier: user.verifier,
b: clientPublicKeys[email].serverBInt b: loginSRPDetailFromDB.serverBInt
}, },
async () => { async () => {
server.setClientPublicKey(clientPublicKeys[email].clientPublicKey); server.setClientPublicKey(loginSRPDetailFromDB.clientPublicKey);
// compare server and client shared keys // compare server and client shared keys
if (server.checkClientProof(clientProof)) { if (server.checkClientProof(clientProof)) {

View File

@@ -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;