125 lines
3.8 KiB
TypeScript
125 lines
3.8 KiB
TypeScript
import { Injectable } from '@angular/core';
|
|
import Joi from '@hapi/joi';
|
|
import {AbstractControl} from '@angular/forms';
|
|
|
|
@Injectable({
|
|
providedIn: 'root'
|
|
})
|
|
export class ValidationService {
|
|
|
|
private vUsername = Joi.string()
|
|
.lowercase()
|
|
.pattern(new RegExp('^[a-z0-9-_.]+$'))
|
|
.min(1)
|
|
.max(128);
|
|
|
|
private vPassword = Joi.string()
|
|
.pattern(/^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!"#%&'()*+,-.\/:;<=>?@[\]^_`{|}~])(?=\S+$)[a-zA-Z0-9!"#%&'()*+,\-.\/:;<=>?@[\]^_`{|}~]{8,}$/)
|
|
.max(128);
|
|
|
|
constructor() { }
|
|
|
|
generate(method, args) { // generate a Validator function
|
|
return (control: AbstractControl): {[key: string]: any} | null => {
|
|
let ok;
|
|
let error;
|
|
if (args) {
|
|
({ok, error} = this[method](control.value, ...args));
|
|
}
|
|
else {
|
|
({ok, error} = this[method](control.value));
|
|
}
|
|
return ok ? null : { failure: error };
|
|
};
|
|
}
|
|
|
|
username(data) {
|
|
const {ignore, error} = this.vUsername.validate(data);
|
|
if (error) {
|
|
return {ok: false, error: 'username must only contain a-z0-9-_.'};
|
|
}
|
|
return {ok: true, error: ''};
|
|
}
|
|
|
|
password(data) {
|
|
const {ignore, error} = this.vPassword.validate(data);
|
|
if (error) {
|
|
if (Joi.string().min(8).validate(data).error) {
|
|
return {ok: false, error: 'password must have at least 8 characters'};
|
|
}
|
|
else if (Joi.string().pattern(/[a-z]+/).validate(data).error) {
|
|
return {ok: false, error: 'password must have at least one lowercase character'};
|
|
}
|
|
else if (Joi.string().pattern(/[A-Z]+/).validate(data).error) {
|
|
return {ok: false, error: 'password must have at least one uppercase character'};
|
|
}
|
|
else if (Joi.string().pattern(/[0-9]+/).validate(data).error) {
|
|
return {ok: false, error: 'password must have at least one number'};
|
|
}
|
|
else if (Joi.string().pattern(/[!"#%&'()*+,-.\/:;<=>?@[\]^_`{|}~]+/).validate(data).error) {
|
|
return {ok: false, error: 'password must have at least one of the following characters !"#%&\'()*+,-.\\/:;<=>?@[]^_`{|}~'};
|
|
}
|
|
else {
|
|
return {ok: false, error: 'password must only contain a-zA-Z0-9!"#%&\'()*+,-./:;<=>?@[]^_`{|}~'};
|
|
}
|
|
}
|
|
return {ok: true, error: ''};
|
|
}
|
|
|
|
string(data) {
|
|
const {ignore, error} = Joi.string().max(128).allow('').validate(data);
|
|
if (error) {
|
|
return {ok: false, error: 'must contain max 128 characters'};
|
|
}
|
|
return {ok: true, error: ''};
|
|
}
|
|
|
|
stringOf(data, list) {
|
|
const {ignore, error} = Joi.string().allow('').valid(...list.map(e => e.toString())).validate(data);
|
|
if (error) {
|
|
return {ok: false, error: 'must be one of ' + list.join(', ')};
|
|
}
|
|
return {ok: true, error: ''};
|
|
}
|
|
|
|
stringLength(data, length) {
|
|
const {ignore, error} = Joi.string().max(length).allow('').validate(data);
|
|
if (error) {
|
|
return {ok: false, error: 'must contain max ' + length + ' characters'};
|
|
}
|
|
return {ok: true, error: ''};
|
|
}
|
|
|
|
minMax(data, min, max) {
|
|
const {ignore, error} = Joi.number().allow('').min(min).max(max).validate(data);
|
|
if (error) {
|
|
return {ok: false, error: `must be between ${min} and ${max}`};
|
|
}
|
|
return {ok: true, error: ''};
|
|
}
|
|
|
|
min(data, min) {
|
|
const {ignore, error} = Joi.number().allow('').min(min).validate(data);
|
|
if (error) {
|
|
return {ok: false, error: `must not be below ${min}`};
|
|
}
|
|
return {ok: true, error: ''};
|
|
}
|
|
|
|
max(data, max) {
|
|
const {ignore, error} = Joi.number().allow('').min(max).validate(data);
|
|
if (error) {
|
|
return {ok: false, error: `must not be above ${max}`};
|
|
}
|
|
return {ok: true, error: ''};
|
|
}
|
|
|
|
unique(data, list) {
|
|
const {ignore, error} = Joi.string().allow('').invalid(...list.map(e => e.toString())).validate(data);
|
|
if (error) {
|
|
return {ok: false, error: `values must be unique`};
|
|
}
|
|
return {ok: true, error: ''};
|
|
}
|
|
}
|