Add username and password validation

This commit is contained in:
Maciej Ziarkowski 2019-09-11 16:28:05 +01:00
parent 456514ec51
commit 31efae3885
4 changed files with 39 additions and 5 deletions

View File

@ -5,6 +5,7 @@ import express from 'express';
import * as userService from '../services/user'; import * as userService from '../services/user';
import * as passwordResetService from '../services/passwordReset'; import * as passwordResetService from '../services/passwordReset';
import { TokenVerificationError } from '../services/passwordReset'; import { TokenVerificationError } from '../services/passwordReset';
import { ValidationError } from '../validation';
function createUser(req, res) { function createUser(req, res) {
const user = req.body; const user = req.body;
@ -87,6 +88,8 @@ async function resetPassword(req: express.Request, res: express.Response) {
} catch (err) { } catch (err) {
if (err instanceof TokenVerificationError) { if (err instanceof TokenVerificationError) {
return res.send({ error: 'Could not verify token' }); return res.send({ error: 'Could not verify token' });
} else if (err instanceof ValidationError) {
return res.send({ error: err.message});
} }
throw err; throw err;

View File

@ -5,6 +5,7 @@ import nodemailer from 'nodemailer';
import db from '../../db'; import db from '../../db';
import * as userService from './user'; import * as userService from './user';
import { transporter } from './email'; import { transporter } from './email';
import { validatePassword } from '../validation';
/** /**
@ -24,6 +25,7 @@ export async function sendPasswordResetToken(email: string, siteOrigin: string):
} }
export async function resetPassword(passwordResetToken: string, newPassword: string): Promise<void> { export async function resetPassword(passwordResetToken: string, newPassword: string): Promise<void> {
validatePassword(newPassword);
const userId = await verifyPasswordResetToken(passwordResetToken); const userId = await verifyPasswordResetToken(passwordResetToken);
if (userId != undefined) { if (userId != undefined) {
await updatePasswordForUser(userId, newPassword); await updatePasswordForUser(userId, newPassword);

View File

@ -3,14 +3,18 @@
* *
*/ */
import db from '../../db'; import db from '../../db';
import { validateUsername, ValidationError, validatePassword } from '../validation';
function createUser(user) { function createUser(user) {
if (!user.password || user.password.length < 8) { try {
return Promise.reject({ error: 'Password must be at least 8 characters' }) validateUsername(user.username);
} validatePassword(user.password);
if (user.password.length > 70) { } catch(err) {
return Promise.reject({ error: 'Password must be at most 70 characters' }) if (err instanceof ValidationError) {
return Promise.reject({ error: err.message });
} else throw err;
} }
return db.one( return db.one(
`INSERT `INSERT
INTO users ( INTO users (

25
app/src/api/validation.ts Normal file
View File

@ -0,0 +1,25 @@
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = 'ValidationError';
}
}
function validateUsername(username: string): void {
if (username == undefined) throw new ValidationError('Username is required');
if (!username.match(/^\w+$/)) throw new ValidationError('Username can only contain alphanumeric characters and underscore');
if (username.length < 4) throw new ValidationError('Username must be at least 4 characters long');
if (username.length > 30) throw new ValidationError('Username must be at most 30 characters long');
}
function validatePassword(password: string): void {
if (password == undefined) throw new ValidationError('Password is required');
if (password.length < 8) throw new ValidationError('Password must be at least 8 characters long');
if (password.length > 70) throw new ValidationError('Password must be at most 70 characters long');
}
export {
ValidationError,
validateUsername,
validatePassword
};