parent
b3f2644d07
commit
aadc84ea70
2 changed files with 112 additions and 0 deletions
@ -0,0 +1,108 @@ |
|||||||
|
import assert from 'assert'; |
||||||
|
import { RequestHandler } from 'express'; |
||||||
|
|
||||||
|
import { REP_PEACEFUL_STRING } from '../../consts/REG_EXP_PATTERNS'; |
||||||
|
|
||||||
|
import { dbQuery, sub } from '../../accessModule'; |
||||||
|
import { sanitize } from '../../sanitize'; |
||||||
|
import { stderr } from '../../shell'; |
||||||
|
|
||||||
|
export const login: RequestHandler<unknown, unknown, AuthLoginRequestBody> = ( |
||||||
|
request, |
||||||
|
response, |
||||||
|
) => { |
||||||
|
const { |
||||||
|
body: { password: rawPassword, username: rawUsername }, |
||||||
|
} = request; |
||||||
|
|
||||||
|
const password = sanitize(rawPassword, 'string'); |
||||||
|
const username = sanitize(rawUsername, 'string', { modifierType: 'sql' }); |
||||||
|
|
||||||
|
try { |
||||||
|
assert( |
||||||
|
REP_PEACEFUL_STRING.test(username), |
||||||
|
`Username must be a peaceful string; got [${username}]`, |
||||||
|
); |
||||||
|
|
||||||
|
assert( |
||||||
|
REP_PEACEFUL_STRING.test(password), |
||||||
|
`Password must be a peaceful string; got [${password}]`, |
||||||
|
); |
||||||
|
} catch (assertError) { |
||||||
|
stderr( |
||||||
|
`Assertion failed when attempting to authenticate; CAUSE: ${assertError}`, |
||||||
|
); |
||||||
|
|
||||||
|
response.status(400).send(); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
let rows: [ |
||||||
|
userUuid: string, |
||||||
|
userPasswordHash: string, |
||||||
|
userSalt: string, |
||||||
|
userAlgorithm: string, |
||||||
|
userHashCount: string, |
||||||
|
][]; |
||||||
|
|
||||||
|
try { |
||||||
|
rows = dbQuery(` |
||||||
|
SELECT |
||||||
|
user_uuid, |
||||||
|
user_password_hash, |
||||||
|
user_salt, |
||||||
|
user_algorithm, |
||||||
|
user_hash_count |
||||||
|
FROM users |
||||||
|
WHERE user_algorithm != 'DELETED' |
||||||
|
AND user_name = '${username}'`).stdout;
|
||||||
|
} catch (queryError) { |
||||||
|
stderr(`Failed to get user ${username}; CAUSE: ${queryError}`); |
||||||
|
response.status(500).send(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (rows.length === 0) { |
||||||
|
stderr(`No entry for user ${username} found`); |
||||||
|
response.status(404).send(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
const { |
||||||
|
0: { 1: userPasswordHash, 2: userSalt, 3: userAlgorithm, 4: userHashCount }, |
||||||
|
} = rows; |
||||||
|
|
||||||
|
let encryptResult: { |
||||||
|
user_password_hash: string; |
||||||
|
user_salt: string; |
||||||
|
user_hash_count: number; |
||||||
|
user_algorithm: string; |
||||||
|
}; |
||||||
|
|
||||||
|
try { |
||||||
|
encryptResult = sub('encrypt_password', { |
||||||
|
subModuleName: 'Account', |
||||||
|
subParams: { |
||||||
|
algorithm: userAlgorithm, |
||||||
|
hash_count: userHashCount, |
||||||
|
password, |
||||||
|
salt: userSalt, |
||||||
|
}, |
||||||
|
}).stdout; |
||||||
|
} catch (subError) { |
||||||
|
stderr(`Failed to login with username ${username}; CAUSE: ${subError}`); |
||||||
|
response.status(500).send(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
const { user_password_hash: inputPasswordHash } = encryptResult; |
||||||
|
|
||||||
|
if (inputPasswordHash !== userPasswordHash) { |
||||||
|
stderr(`Input and recorded password mismatched.`); |
||||||
|
response.status(400).send(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
response.status(200).send(); |
||||||
|
}; |
@ -0,0 +1,4 @@ |
|||||||
|
type AuthLoginRequestBody = { |
||||||
|
username: string; |
||||||
|
password: string; |
||||||
|
}; |
Loading…
Reference in new issue