feat(striker-ui-api): apply session handler and add /auth/login

This commit is contained in:
Tsu-ba-me 2023-04-13 22:44:21 -04:00
parent 38181ac301
commit 1c8050caa9
5 changed files with 29 additions and 100 deletions

View File

@ -1,15 +1,26 @@
import cors from 'cors';
import express from 'express';
import express, { json } from 'express';
import passport from './passport';
import routes from './routes';
import { rrouters } from './lib/rrouters';
import sessionHandler from './session';
const app = express();
app.use(express.json());
app.use(json());
app.use(cors());
// Add session handler to the chain **after** adding other handlers that do
// not depend on session(s).
app.use(sessionHandler);
app.use(passport.initialize());
app.use(passport.authenticate('session'));
rrouters(app, routes, { key: 'api' });
rrouters(app, routes, { key: 'auth' });
rrouters(app, routes, { key: 'echo' });
export default app;

View File

@ -0,0 +1 @@
export * from './login';

View File

@ -1,108 +1,13 @@
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';
import { stdout } 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;
}
stdout(`session=${JSON.stringify(request.session, null, 2)}`);
stdout(`user=${JSON.stringify(request.user, null, 2)}`);
response.status(200).send();
};

View File

@ -0,0 +1,10 @@
import express from 'express';
import { login } from '../lib/request_handlers/auth';
import passport from '../passport';
const router = express.Router();
router.post('/login', passport.authenticate('login'), login);
export default router;

View File

@ -1,4 +1,5 @@
import anvilRouter from './anvil';
import authRouter from './auth';
import commandRouter from './command';
import echoRouter from './echo';
import fenceRouter from './fence';
@ -27,6 +28,7 @@ const routes = {
ups: upsRouter,
user: userRouter,
},
auth: authRouter,
echo: echoRouter,
};