1+
2+ const { InvalidPropertyError } = require ( "../../interface-adapters/config/validators-errors/errors" ) ;
3+ const bcrypt = require ( "bcrypt" ) ;
4+
5+
6+
7+ /**
8+ * Validates the format of an email address.
9+ *
10+ * @param {string } email - The email address to validate.
11+ * @return {boolean } Indicates whether the email address is in a valid format.
12+ */
13+ function validateEmail ( email ) {
14+ const re = / ^ ( ( [ ^ < > ( ) [ \] \\ . , ; : \s @ " ] + ( \. [ ^ < > ( ) [ \] \\ . , ; : \s @ " ] + ) * ) | ( " .+ " ) ) @ ( ( \[ [ 0 - 9 ] { 1 , 3 } \. [ 0 - 9 ] { 1 , 3 } \. [ 0 - 9 ] { 1 , 3 } \. [ 0 - 9 ] { 1 , 3 } \] ) | ( ( [ a - z A - Z \- 0 - 9 ] + \. ) + [ a - z A - Z ] { 2 , } ) ) $ / i;
15+ if ( ! re . test ( String ( email ) . toLowerCase ( ) ) ) {
16+ throw new InvalidPropertyError ( " Invalid Email " )
17+ } ;
18+
19+ return email ;
20+ }
21+
22+ /**
23+ * Validates the name and replaces any '<' characters with '<'.
24+ *
25+ * @param {string } name - The name to be validated.
26+ * @throws {InvalidPropertyError } If the name is less than 2 characters long.
27+ * @return {string } The validated name with '<' characters replaced, or 'No Name' if the name is falsy.
28+ */
29+ function validateName ( name ) {
30+ if ( name . length < 2 ) {
31+ throw new InvalidPropertyError (
32+ `A user's name must be at least 2 characters long.`
33+ )
34+ }
35+
36+ return name . replace ( / < / g, "<" ) || "No Name" ;
37+ }
38+
39+ /**
40+ * Validates a phone number.
41+ *
42+ * @param {string } phone - The phone number to validate.
43+ * @throws {InvalidPropertyError } If the phone number is invalid.
44+ */
45+ function validatePhone ( phone ) {
46+ const phoneRegex = / ^ \( ? ( [ 0 - 9 ] { 3 } ) \) ? [ - . ] ? ( [ 0 - 9 ] { 3 } ) [ - . ] ? ( [ 0 - 9 ] { 3 } ) $ / ;
47+
48+ // TODO : optimize phone number validation
49+ if ( ! phoneRegex . test ( phone ) || phone . length < 11 ) {
50+ throw new InvalidPropertyError ( `A user's phone number is not valid.` ) ;
51+ }
52+
53+ return phone ;
54+ }
55+
56+ /**
57+ * Normalizes user data by capitalizing the first letter of first and last names, and converting email to lowercase.
58+ *
59+ * @param {string } firstName - The first name of the user.
60+ * @param {string } lastName - The last name of the user.
61+ * @param {string } email - The email address of the user.
62+ * @param {...Object } otherInfo - Additional user information.
63+ * @return {Object } The normalized user data.
64+ */
65+ function normalise ( { firstName, lastName, email, ...otherInfo } ) {
66+ return {
67+ ...otherInfo ,
68+ firstName : firstName . charAt ( 0 ) . toUpperCase ( ) + firstName . slice ( 1 ) ,
69+ lastName : lastName . charAt ( 0 ) . toUpperCase ( ) + lastName . slice ( 1 ) ,
70+ email : email . toLowerCase ( )
71+ }
72+ }
73+
74+
75+ async function validatePassword ( password ) {
76+ if ( password . length < 8 ) {
77+ throw new InvalidPropertyError (
78+ `A user's password must be at least 8 characters long.`
79+ )
80+ }
81+ const hashPw = await bcrypt . hash ( password , 10 ) ; //generate salt and encrypt
82+ return hashPw ;
83+ }
84+
85+ /**
86+ * Validates user data by calling individual validation functions for each field.
87+ *
88+ * @param {Object } userData - An object containing the user's data.
89+ * @param {string } userData.firstName - The user's first name.
90+ * @param {string } userData.lastName - The user's last name.
91+ * @param {string } userData.email - The user's email address.
92+ * @param {string } userData.mobile - The user's mobile number.
93+ * @param {string } userData.password - The user's password.
94+ * @return {Object } An object containing the validation results for each field.
95+ * - firstName: The result of validating the first name.
96+ * - lastName: The result of validating the last name.
97+ * - email: The result of validating the email address.
98+ * - mobile: The result of validating the mobile number.
99+ * - password: The result of validating the password.
100+ */
101+ async function validateUserData ( {
102+ firstName,
103+ lastName,
104+ email,
105+ mobile,
106+ password
107+ } ) {
108+
109+ if ( ! firstName && ! lastName ) {
110+ return res . status ( 400 ) . json ( { msg : 'user must have at least one name.' } )
111+ }
112+
113+ if ( ! email ) {
114+ return res . status ( 400 ) . json ( { msg : 'user must have an email.' } )
115+ }
116+
117+ if ( ! password ) {
118+ return res . status ( 400 ) . json ( { msg : 'user must have a password.' } )
119+ }
120+
121+ return {
122+ email : validateEmail ( email ) ,
123+ mobile : validatePhone ( mobile ) ,
124+ password : await validatePassword ( password ) ,
125+ firstName : validateName ( firstName ) ,
126+ lastName : validateName ( lastName ) ,
127+ } ;
128+ }
129+
130+
131+
132+ module . exports = { validateUserData, normalise} ;
0 commit comments