Compare commits

...

2 commits

Author SHA1 Message Date
8d65c5821a email validator added and implemented 2023-06-11 13:43:02 +03:00
d583fb78e8 README + changed schema of user 2023-06-11 13:35:09 +03:00
5 changed files with 63 additions and 11 deletions

View file

@ -39,6 +39,7 @@ added the required error handling for the application.
- Docker (docker-compose) - Docker (docker-compose)
- bcrypt - bcrypt
- JWT - JWT
- deep-email-validator
## How to Run ## How to Run
@ -218,4 +219,17 @@ status 404
message: message:
"Cart not found." "Cart not found."
} }
```
# Database Schema
## User
```
{
name: string,
email: string,
password: string,
cart: {
productId: number
}
}
``` ```

35
package-lock.json generated
View file

@ -12,6 +12,7 @@
"@sendgrid/mail": "^7.7.0", "@sendgrid/mail": "^7.7.0",
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
"cookie-parser": "^1.4.6", "cookie-parser": "^1.4.6",
"deep-email-validator": "^0.1.21",
"dotenv": "^16.1.4", "dotenv": "^16.1.4",
"express": "^4.18.2", "express": "^4.18.2",
"jsonwebtoken": "^9.0.0", "jsonwebtoken": "^9.0.0",
@ -95,6 +96,11 @@
"@types/express": "*" "@types/express": "*"
} }
}, },
"node_modules/@types/disposable-email-domains": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@types/disposable-email-domains/-/disposable-email-domains-1.0.4.tgz",
"integrity": "sha512-AmKPD8vBZzvey/jeg+YAIH/xJE3D6edOXz+YUooSCcHesGzFyzke83kj1j4d0LUR9nkSHIRklUVdcAMleuWLpg=="
},
"node_modules/@types/express": { "node_modules/@types/express": {
"version": "4.17.17", "version": "4.17.17",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz",
@ -420,6 +426,25 @@
"ms": "2.0.0" "ms": "2.0.0"
} }
}, },
"node_modules/deep-email-validator": {
"version": "0.1.21",
"resolved": "https://registry.npmjs.org/deep-email-validator/-/deep-email-validator-0.1.21.tgz",
"integrity": "sha512-DBAmMzbr+MAubXQ+TS9tZuPwLcdKscb8YzKZiwoLqF3NmaeEgXvSSHhZ0EXOFeKFE2FNWC4mNXCyiQ/JdFXUwg==",
"dependencies": {
"@types/disposable-email-domains": "^1.0.1",
"axios": "^0.24.0",
"disposable-email-domains": "^1.0.59",
"mailcheck": "^1.1.1"
}
},
"node_modules/deep-email-validator/node_modules/axios": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz",
"integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
"dependencies": {
"follow-redirects": "^1.14.4"
}
},
"node_modules/deepmerge": { "node_modules/deepmerge": {
"version": "4.3.1", "version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
@ -445,6 +470,11 @@
"npm": "1.2.8000 || >= 1.4.16" "npm": "1.2.8000 || >= 1.4.16"
} }
}, },
"node_modules/disposable-email-domains": {
"version": "1.0.62",
"resolved": "https://registry.npmjs.org/disposable-email-domains/-/disposable-email-domains-1.0.62.tgz",
"integrity": "sha512-LBQvhRw7mznQTPoyZbsmYeNOZt1pN5aCsx4BAU/3siVFuiM9f2oyKzUaB8v1jbxFjE3aYqYiMo63kAL4pHgfWQ=="
},
"node_modules/dotenv": { "node_modules/dotenv": {
"version": "16.1.4", "version": "16.1.4",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.1.4.tgz", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.1.4.tgz",
@ -837,6 +867,11 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/mailcheck": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/mailcheck/-/mailcheck-1.1.1.tgz",
"integrity": "sha512-3WjL8+ZDouZwKlyJBMp/4LeziLFXgleOdsYu87piGcMLqhBzCsy2QFdbtAwv757TFC/rtqd738fgJw1tFQCSgA=="
},
"node_modules/media-typer": { "node_modules/media-typer": {
"version": "0.3.0", "version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",

View file

@ -6,14 +6,15 @@
"scripts": { "scripts": {
"dev": "nodemon dist/index.js", "dev": "nodemon dist/index.js",
"start": "node dist/index.js", "start": "node dist/index.js",
"build": "tsc -p ." "build": "tsc -p ."
}, },
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@sendgrid/mail": "^7.7.0", "@sendgrid/mail": "^7.7.0",
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
"cookie-parser": "^1.4.6", "cookie-parser": "^1.4.6",
"deep-email-validator": "^0.1.21",
"dotenv": "^16.1.4", "dotenv": "^16.1.4",
"express": "^4.18.2", "express": "^4.18.2",
"jsonwebtoken": "^9.0.0", "jsonwebtoken": "^9.0.0",

View file

@ -3,12 +3,18 @@ import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken'; import jwt from 'jsonwebtoken';
import { User, IUser } from '../mongoose/Schema'; import { User, IUser } from '../mongoose/Schema';
import { clearJwtCookie, setJwtCookie } from '../middlewares/checkAuth'; import { clearJwtCookie, setJwtCookie } from '../middlewares/checkAuth';
import validate from 'deep-email-validator';
export async function createUser(req: Request, res: Response) { export async function createUser(req: Request, res: Response) {
try { try {
const { firstName, lastName, email, password, address } = req.body; const { email, password, address } = req.body;
const isValidEmail = await validate(email);
if (!(email && password && firstName && lastName && address)) { if (!isValidEmail.valid) {
console.error('Email is invalid:', isValidEmail.validators);
return res.status(400).json({ error: 'Email is invalid' });
}
if (!(password && address)) {
return res.status(400).json({ error: 'All inputs are required' }); return res.status(400).json({ error: 'All inputs are required' });
} }
// checkIfUserExists return true if the user exists // checkIfUserExists return true if the user exists
@ -20,8 +26,6 @@ export async function createUser(req: Request, res: Response) {
const hashedPassword = await bcrypt.hash(password, 10); const hashedPassword = await bcrypt.hash(password, 10);
const user: IUser = await User.create({ const user: IUser = await User.create({
firstName,
lastName,
email, email,
password: hashedPassword, password: hashedPassword,
address, address,
@ -43,12 +47,14 @@ export async function login(req: Request, res: Response) {
// Check if the user exists // Check if the user exists
const user: IUser | null = await User.findOne({ email }); const user: IUser | null = await User.findOne({ email });
if (!user) { if (!user) {
console.error('User not found');
return res.status(401).json({ error: 'Invalid email or password' }); return res.status(401).json({ error: 'Invalid email or password' });
} }
// Compare the provided password with the stored password // Compare the provided password with the stored password
const isPasswordCorrect = await bcrypt.compare(password, user.password); const isPasswordCorrect = await bcrypt.compare(password, user.password);
if (!isPasswordCorrect) { if (!isPasswordCorrect) {
console.error('Invalid password');
return res.status(401).json({ error: 'Invalid email or password' }); return res.status(401).json({ error: 'Invalid email or password' });
} }

View file

@ -1,8 +1,6 @@
import mongoose, { Schema, Document } from 'mongoose'; import mongoose, { Schema, Document } from 'mongoose';
export interface IUser extends Document { export interface IUser extends Document {
firstName: string;
lastName: string;
email: string; email: string;
password: string; password: string;
address: string; address: string;
@ -35,8 +33,6 @@ export interface IOrder extends Document {
} }
const UserSchema: Schema = new Schema({ const UserSchema: Schema = new Schema({
firstName: { type: String, required: true },
lastName: { type: String, required: true },
email: { type: String, required: true, unique: true }, email: { type: String, required: true, unique: true },
password: { type: String, required: true }, password: { type: String, required: true },
address: { type: String, required: true }, address: { type: String, required: true },