case 'request_otp':
if(isLoggedIn(ws)) {
ws.send(JSON.stringify({
response_ID: request_ID,
data: "already logged in"
}));
} else {
let token = await randomBytes(128);
if((await pool.query(`update usr set otp_expiry = now() + interval '5 minute', otp_hash = $2 where email = $1`, [parameters.email, crypto.createHash('BLAKE2b512').update(token).digest()])).rowCount === 1) {
sgMail.send({
to: parameters.email,
from: 'lobojane <support@lobojane.com>',
subject: `Click this link to finish logging in`,
html: `<a href="https://www.lobojane.com/user?otp=${token.toString('base64')}">idk</a><div>Alternatively, copy and paste <code>${token.toString('base64')}</code> into the input field</div>if this wasn't you, let us know by replying to this email.`
}).then(() => ws.send(JSON.stringify({
response_ID: request_ID
})), error => {
console.error(error);
ws.send(JSON.stringify({
response_ID: request_ID,
data: 'failed to send email'
}));
});
} else {
ws.send(JSON.stringify({
response_ID: request_ID,
data: 'user not found'
}))
}
}
break;
case 'login_otp'://if paste in code || click link && original tab still open(sharedworker active, preexisting connection)
if(isLoggedIn(ws)) {
ws.send(JSON.stringify({
response_ID: request_ID,
data: "already logged in"
}));
} else {
let token = await randomBytes(128);
let user = (await pool.query('update usr set otp_hash = null, token_hash = $1 where otp_hash = $2 and now() < otp_expiry returning user_id, email, type, comt, akt1, cyp2c9, cyp2c19_2, cyp2c19_3, cyp2c19_17', [crypto.createHash('BLAKE2b512').update(token).digest(), crypto.createHash('BLAKE2b512').update(Buffer.from(parameters.otp, 'base64')).digest()])).rows[0];//possible timing attack?
if(user === undefined) {
ws.send(JSON.stringify({
response_ID: request_ID,
data: 'invalid otp'
}));
} else {
ws.user_ID = user.user_id;
ws.user_type = user.type;
desensitize(user);
user.token = token.toString('base64');
ws.send(JSON.stringify({
response_ID: request_ID,
data: user
}));
//disallow multiple sockets with same credentials
let old = authenticated.get(user.user_id);
if(old !== undefined) {
delete old.user_ID;
delete old.user_type;
old.send('{"what":"logout"}');
}
authenticated.set(user.user_id, ws);
ws.publish('user/authenticated', JSON.stringify({
what: 'user/authenticated',//tbd
how: 'update',
data: authenticated.size
}));
}
}
break;