diff --git a/back-end-practice/cook-site/config/passport-config.js b/back-end-practice/cook-site/config/passport-config.js deleted file mode 100644 index ad52f3e..0000000 --- a/back-end-practice/cook-site/config/passport-config.js +++ /dev/null @@ -1,30 +0,0 @@ -const passport = require('passport'); -const LocalStrategy = require('passport-local').Strategy; -const { UserModel } = require('../models/user.model'); -const bcrypt = require('bcrypt'); - -passport.use( - new LocalStrategy(async (givenEmail, password, done) => { - const user = await UserModel.findOne({ email: givenEmail }); - - if (!user) return done('user not found', null); - - const matchedPassword = await bcrypt.compare(password, user.password); - - if (!matchedPassword) { - return done('user not match password', null); - } - - done(null, user); - }) -); - -passport.serializeUser((user, done) => { - done(null, user._id); -}); - -passport.deserializeUser((id, done) => { - const user = UserModel.findById(id); - if (!user) done('user not found', null); - else done(null, user); -}); diff --git a/back-end-practice/cook-site/config/passport-config.ts b/back-end-practice/cook-site/config/passport-config.ts new file mode 100644 index 0000000..c79c35f --- /dev/null +++ b/back-end-practice/cook-site/config/passport-config.ts @@ -0,0 +1,32 @@ +import passport from 'passport'; +import { Strategy as LocalStrategy } from 'passport-local'; +import bcrypt from 'bcrypt'; +import { UserModel } from '../models/user.model'; +import { findUserByEmail } from '../services/users.services'; +import { passportConfigUser } from '../interfaces/user.interface'; + +passport.use( + new LocalStrategy(async (userEmail, password, done) => { + const user = await findUserByEmail(userEmail); + + if (!user) return done('user not found', null); + + const matchedPassword = await bcrypt.compare(password, user.password); + + if (!matchedPassword) { + return done('user not match password', null); + } + + done(null, user); + }) +); + +passport.serializeUser((user: passportConfigUser | null, done: Function) => { + done(null, user?._id); +}); + +passport.deserializeUser(async (id: string, done: Function) => { + const user = await UserModel.findById(id); + if (!user) done('user not found', null); + else done(null, user); +}); diff --git a/back-end-practice/cook-site/interfaces/recipe.interface.ts b/back-end-practice/cook-site/interfaces/recipe.interface.ts new file mode 100644 index 0000000..a8e6c6e --- /dev/null +++ b/back-end-practice/cook-site/interfaces/recipe.interface.ts @@ -0,0 +1,7 @@ +export interface IRecipe { + name: string; + creator: string; + ingredients: string; + cookingTime: string; + difficulityLevel: string; +} diff --git a/back-end-practice/cook-site/interfaces/user.interface.ts b/back-end-practice/cook-site/interfaces/user.interface.ts index 559eda8..2a9c658 100644 --- a/back-end-practice/cook-site/interfaces/user.interface.ts +++ b/back-end-practice/cook-site/interfaces/user.interface.ts @@ -6,21 +6,6 @@ export interface IUser { fullName: string; } -/* -export interface IDogQuery { - status?: number; - gender?: string; - race?: string[]; - minAge?: number; - maxAge?: number; - name?: string; - page: number; // offset - itemsPerPage: number; // limit - sortByStatus?: number; - sortByGender?: number; - sortByRace?: number; - sortByAge?: number; - sortByName?: number; - sortByLastUpdated?: number; -} - */ +export type passportConfigUser = { + _id?: number; +}; diff --git a/back-end-practice/cook-site/models/recipe.model.js b/back-end-practice/cook-site/models/recipe.model.ts similarity index 77% rename from back-end-practice/cook-site/models/recipe.model.js rename to back-end-practice/cook-site/models/recipe.model.ts index d1252e6..f80d581 100644 --- a/back-end-practice/cook-site/models/recipe.model.js +++ b/back-end-practice/cook-site/models/recipe.model.ts @@ -1,4 +1,4 @@ -const mongoose = require('mongoose'); +import mongoose from 'mongoose'; const Schema = mongoose.Schema; const recipeSchema = new Schema( @@ -11,11 +11,11 @@ const recipeSchema = new Schema( creator: { type: String, default: 'anonymous', - }, + }, //todo : change to id ingredients: { type: String, required: [true, 'missing ingredients to the recipe'], - }, + }, //todo : change to array of strings (string[]) cookingTime: { type: String, required: [true, 'you forgot to mention the cooking time!'], @@ -25,4 +25,4 @@ const recipeSchema = new Schema( { timestamps: true } ); -module.exports.RecipeModel = mongoose.model('recipe', recipeSchema); +export const RecipeModel = mongoose.model('recipe', recipeSchema); diff --git a/back-end-practice/cook-site/models/user.model.js b/back-end-practice/cook-site/models/user.model.ts similarity index 85% rename from back-end-practice/cook-site/models/user.model.js rename to back-end-practice/cook-site/models/user.model.ts index d57b7d5..0a66a9c 100644 --- a/back-end-practice/cook-site/models/user.model.js +++ b/back-end-practice/cook-site/models/user.model.ts @@ -1,6 +1,6 @@ -const mongoose = require('mongoose'); +import mongoose from 'mongoose'; +import bcrypt from 'bcrypt'; const Schema = mongoose.Schema; -const bcrypt = require('bcrypt'); const userSchema = new Schema( { @@ -33,4 +33,4 @@ userSchema.pre('save', async function (done) { done(); }); -module.exports.UserModel = mongoose.model('user', userSchema); +export const UserModel = mongoose.model('user', userSchema); diff --git a/back-end-practice/cook-site/services/users.services.ts b/back-end-practice/cook-site/services/users.services.ts index 842fdcd..a1c2068 100644 --- a/back-end-practice/cook-site/services/users.services.ts +++ b/back-end-practice/cook-site/services/users.services.ts @@ -10,21 +10,30 @@ export async function registerUser(user: IUser): Promise { return result.toJSON(); } -export async function updateUserData(data: IUser): Promise { +export async function updateUserData( + userData: IUser +): Promise { + if (userData.password !== undefined) { + const salt = bcrypt.genSaltSync(10); + userData.password = bcrypt.hashSync(userData.password, salt); + } + const result: any = await UserModel.findOneAndUpdate( - { _id: data._id }, + { _id: userData._id }, { - password: data.password - ? bcrypt.hashSync(data.password, bcrypt.genSaltSync(10)) - : password, + email: userData.email, + password: userData.password, + phoneNumber: userData.phoneNumber, + fullName: userData.fullName, }, - ...(data.fullName!==undefined && fullName:data.fullName), - { phoneNumber: data.phoneNumber ? data.phoneNumber : phoneNumber }, - { - returnOriginal: false, - } - //fix me + { new: true, omitUndefined: true } ); return result; } + +export async function findUserByEmail(userEmail: string) { + const userDoc = await UserModel.findOne({ email: userEmail }); + + return userDoc; +} diff --git a/nodemon.json b/nodemon.json index 5acb3a3..ffc9476 100644 --- a/nodemon.json +++ b/nodemon.json @@ -1,5 +1,5 @@ { - "watch": "for-fun-!/police-officer.ts", + "watch": "back-end-practice/cook-site/**/*.ts", "execMap": { "ts": "ts-node" } diff --git a/package-lock.json b/package-lock.json index 7702d4f..5637efb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,6 +32,8 @@ "yarn": "^1.22.19" }, "devDependencies": { + "@types/bcrypt": "^5.0.0", + "@types/passport-local": "^1.0.34", "jest": "^27.5.1", "jest-html-reporters": "^3.0.5", "prettier": "^2.7.1", @@ -1042,6 +1044,15 @@ "@babel/types": "^7.3.0" } }, + "node_modules/@types/bcrypt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.0.tgz", + "integrity": "sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/body-parser": { "version": "1.19.2", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", @@ -1139,6 +1150,27 @@ "@types/express": "*" } }, + "node_modules/@types/passport-local": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/@types/passport-local/-/passport-local-1.0.34.tgz", + "integrity": "sha512-PSc07UdYx+jhadySxxIYWuv6sAnY5e+gesn/5lkPKfBeGuIYn9OPR+AAEDq73VRUh6NBTpvE/iPE62rzZUslog==", + "dev": true, + "dependencies": { + "@types/express": "*", + "@types/passport": "*", + "@types/passport-strategy": "*" + } + }, + "node_modules/@types/passport-strategy": { + "version": "0.2.35", + "resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.35.tgz", + "integrity": "sha512-o5D19Jy2XPFoX2rKApykY15et3Apgax00RRLf0RUotPDUsYrQa7x4howLYr9El2mlUApHmCMv5CZ1IXqKFQ2+g==", + "dev": true, + "dependencies": { + "@types/express": "*", + "@types/passport": "*" + } + }, "node_modules/@types/prettier": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.4.tgz", @@ -6725,6 +6757,15 @@ "@babel/types": "^7.3.0" } }, + "@types/bcrypt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.0.tgz", + "integrity": "sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/body-parser": { "version": "1.19.2", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", @@ -6822,6 +6863,27 @@ "@types/express": "*" } }, + "@types/passport-local": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/@types/passport-local/-/passport-local-1.0.34.tgz", + "integrity": "sha512-PSc07UdYx+jhadySxxIYWuv6sAnY5e+gesn/5lkPKfBeGuIYn9OPR+AAEDq73VRUh6NBTpvE/iPE62rzZUslog==", + "dev": true, + "requires": { + "@types/express": "*", + "@types/passport": "*", + "@types/passport-strategy": "*" + } + }, + "@types/passport-strategy": { + "version": "0.2.35", + "resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.35.tgz", + "integrity": "sha512-o5D19Jy2XPFoX2rKApykY15et3Apgax00RRLf0RUotPDUsYrQa7x4howLYr9El2mlUApHmCMv5CZ1IXqKFQ2+g==", + "dev": true, + "requires": { + "@types/express": "*", + "@types/passport": "*" + } + }, "@types/prettier": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.4.tgz", diff --git a/package.json b/package.json index 04917bb..e98276c 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,8 @@ "author": "Hadriel", "license": "ISC", "devDependencies": { + "@types/bcrypt": "^5.0.0", + "@types/passport-local": "^1.0.34", "jest": "^27.5.1", "jest-html-reporters": "^3.0.5", "prettier": "^2.7.1", diff --git a/tsconfig.json b/tsconfig.json index cdb4997..9ccce3d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "ts-node": { "files": true }, - "files": ["for-fun-!/police-officer.ts"], + "files": ["cook-site/app.ts"], "compilerOptions": { /* Visit https://aka.ms/tsconfig to read more about this file */