From 41f2e761b05052c7c01fa6251df0afeb5f2664d2 Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Fri, 1 Jul 2022 22:38:51 +0200 Subject: [PATCH 01/33] add notification token on sign up --- src/APIs/controllers/Patient.controller.ts | 40 +++++++++--- src/APIs/controllers/Supervisor.controller.ts | 3 +- src/APIs/schema/Patient.schema.ts | 3 +- src/APIs/schema/Supervisior.schema.ts | 3 +- src/APIs/types/Patient.type.ts | 62 ++++++++++--------- src/APIs/types/Supervisor.type.ts | 1 + 6 files changed, 70 insertions(+), 42 deletions(-) diff --git a/src/APIs/controllers/Patient.controller.ts b/src/APIs/controllers/Patient.controller.ts index 048371e..97058c3 100644 --- a/src/APIs/controllers/Patient.controller.ts +++ b/src/APIs/controllers/Patient.controller.ts @@ -2,10 +2,15 @@ import * as PatientsServices from '../services/Patient.services' import { CreatePatientObjectType } from '../types/Patient.type' import { RequestHandler } from 'express' import mongoose from 'mongoose' +import { sendVerificationMail } from '../services/VerificationMail.services' -export const getAllPatientsBySupervisorId: RequestHandler = async ({ params }) => { +export const getAllPatientsBySupervisorId: RequestHandler = async ({ + params +}) => { const supervisorId = new mongoose.Types.ObjectId(params.id) - const response = await PatientsServices.getAllPatientsBySupervisorId(supervisorId) + const response = await PatientsServices.getAllPatientsBySupervisorId( + supervisorId + ) return { response: response, @@ -44,16 +49,26 @@ export const createPatient: RequestHandler = async ({ body, file }) => { gender: body.gender, height: Number(body.height), weight: Number(body.weight), - smoking: Boolean(body.smoking) + smoking: Boolean(body.smoking), + notificatio_token: body.notificatio_token } // @ts-ignore const profilePictureFileId = file.id === undefined ? '' : file.id - const response = await PatientsServices.createPatient(patientInfo, profilePictureFileId) + const response = await PatientsServices.createPatient( + patientInfo, + profilePictureFileId + ) + + await sendVerificationMail( + response?.email as string, + response?._id as mongoose.Types.ObjectId, + response?.name + ) return { response: response, - message: 'Patient created successfully' + message: 'Patient created successfully, and Verification Mail has been sent' } } @@ -69,7 +84,7 @@ export const deletePatient: RequestHandler = async ({ params }) => { export const updatePatient: RequestHandler = async ({ body, params }) => { const patientId = new mongoose.Types.ObjectId(params.id) - const updatePatientInput : CreatePatientObjectType = { + const updatePatientInput: CreatePatientObjectType = { patient_name: body.patient_name, email: body.email, address: body.address, @@ -84,11 +99,15 @@ export const updatePatient: RequestHandler = async ({ body, params }) => { profile_picture: body.profile_picture } - const response = await PatientsServices.updatePatient(patientId, updatePatientInput) + const response = await PatientsServices.updatePatient( + patientId, + updatePatientInput + ) return { response: response, - message: 'Patient updated successfully' + message: + 'Patient updated successfully' } } @@ -120,7 +139,10 @@ export const uploadMedicalRecord: RequestHandler = async ({ params, file }) => { } // @ts-ignore fileMedicalRecord = file.id - const response = await PatientsServices.uploadMedicalRecord(patientId, fileMedicalRecord) + const response = await PatientsServices.uploadMedicalRecord( + patientId, + fileMedicalRecord + ) return { response, diff --git a/src/APIs/controllers/Supervisor.controller.ts b/src/APIs/controllers/Supervisor.controller.ts index 8d2d603..35e2531 100644 --- a/src/APIs/controllers/Supervisor.controller.ts +++ b/src/APIs/controllers/Supervisor.controller.ts @@ -19,7 +19,8 @@ export const supervisiorSignUp: RequestHandler = async ({ body, file }) => { return { response: supervisor, - message: 'Successfully Registered' + message: + 'Supervisor created successfully, and Verification Mail has been sent' } } diff --git a/src/APIs/schema/Patient.schema.ts b/src/APIs/schema/Patient.schema.ts index 2b1eef6..3a5b180 100644 --- a/src/APIs/schema/Patient.schema.ts +++ b/src/APIs/schema/Patient.schema.ts @@ -62,7 +62,8 @@ const PatientSchema = new Schema({ profile_picture: { type: String }, - medical_history: [{ type: String }] + medical_history: [{ type: String }], + notificatio_token: { type: String } }) const Patient = model('Patient', PatientSchema) diff --git a/src/APIs/schema/Supervisior.schema.ts b/src/APIs/schema/Supervisior.schema.ts index e1b54b6..ac0153e 100644 --- a/src/APIs/schema/Supervisior.schema.ts +++ b/src/APIs/schema/Supervisior.schema.ts @@ -36,7 +36,8 @@ const SupervisiorSchema = new mongoose.Schema( isVerified: { type: Boolean, default: false - } + }, + notificatio_token: { type: String } }, { timestamps: { diff --git a/src/APIs/types/Patient.type.ts b/src/APIs/types/Patient.type.ts index 4add13b..89ff1c4 100644 --- a/src/APIs/types/Patient.type.ts +++ b/src/APIs/types/Patient.type.ts @@ -1,35 +1,37 @@ import mongoose from 'mongoose' -export interface IPatientModel{ - name: string - email: string - password: string - phone: number - emergency_number: number - address: string - gender: string - weight?: number - height?: number - dob: Date - smoking?: boolean - chair_serial_id?: string - supervisors? : [mongoose.Types.ObjectId], - profile_picture?: string - medical_history:[string], - isVerified:Boolean +export interface IPatientModel { + name: string; + email: string; + password: string; + phone: number; + emergency_number: number; + address: string; + gender: string; + weight?: number; + height?: number; + dob: Date; + smoking?: boolean; + chair_serial_id?: string; + supervisors?: [mongoose.Types.ObjectId]; + profile_picture?: string; + medical_history: [string]; + isVerified: Boolean; + notificatio_token: string; } export type CreatePatientObjectType = { - patient_name:string - email:string - password:string - phone:number - emergency_number:number - address:string - gender: string - weight:number - height:number - dob:Date - smoking:boolean, - profile_picture?:string -} + patient_name: string; + email: string; + password: string; + phone: number; + emergency_number: number; + address: string; + gender: string; + weight: number; + height: number; + dob: Date; + smoking: boolean; + profile_picture?: string; + notificatio_token?: string +}; diff --git a/src/APIs/types/Supervisor.type.ts b/src/APIs/types/Supervisor.type.ts index 0c20d58..dae613d 100644 --- a/src/APIs/types/Supervisor.type.ts +++ b/src/APIs/types/Supervisor.type.ts @@ -5,4 +5,5 @@ export type SupervisorObjectType = { phone: number; gender: string; profile_picture: string; + notificatio_token: string; }; From 7ea18083a0af15165aa96863138ed3cee3ab799e Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Fri, 1 Jul 2022 23:18:32 +0200 Subject: [PATCH 02/33] get all patient associated with supervisor with its id --- src/APIs/models/Patient.model.ts | 10 +++++++++- src/APIs/routes/PatientRoutes.route.ts | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/APIs/models/Patient.model.ts b/src/APIs/models/Patient.model.ts index 433dd53..d2959e9 100644 --- a/src/APIs/models/Patient.model.ts +++ b/src/APIs/models/Patient.model.ts @@ -10,13 +10,20 @@ import mongoose from 'mongoose' */ export const getAllPatientsBySupervisorId = async ( supervisorId: mongoose.Types.ObjectId -) => {} +) => { + const patients = await Patient.find({ + supervisors: supervisorId + }) + + return patients +} /** * * @param * @returns all patients data */ + export const getAllPatients = async () => { const patients = await Patient.find() @@ -127,6 +134,7 @@ export const updateVerificationStatus = async ( return patient } + /** * * @param patientId diff --git a/src/APIs/routes/PatientRoutes.route.ts b/src/APIs/routes/PatientRoutes.route.ts index b0936db..25e802a 100644 --- a/src/APIs/routes/PatientRoutes.route.ts +++ b/src/APIs/routes/PatientRoutes.route.ts @@ -35,7 +35,7 @@ router.get( ) router.get( - '/:id', + '/patient/:id', validatePatientId, checkAuthentication, (req: Request, res: Response, next: NextFunction) => { From c97e059dacea8034930d9611cefe4baa378d16bb Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Sat, 2 Jul 2022 13:26:23 +0200 Subject: [PATCH 03/33] associated users edit --- src/APIs/controllers/Patient.controller.ts | 2 +- src/APIs/controllers/Supervisor.controller.ts | 1 + src/APIs/models/Patient.model.ts | 4 ++-- src/APIs/models/Supervisor.model.ts | 2 +- src/APIs/routes/PatientRoutes.route.ts | 1 - src/APIs/routes/Supervisor.route.ts | 1 - src/APIs/schema/Patient.schema.ts | 4 ++-- src/APIs/schema/Supervisior.schema.ts | 4 ++-- src/APIs/types/Patient.type.ts | 6 +++--- src/APIs/types/Supervisor.type.ts | 2 +- 10 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/APIs/controllers/Patient.controller.ts b/src/APIs/controllers/Patient.controller.ts index 97058c3..3b98ba1 100644 --- a/src/APIs/controllers/Patient.controller.ts +++ b/src/APIs/controllers/Patient.controller.ts @@ -50,7 +50,7 @@ export const createPatient: RequestHandler = async ({ body, file }) => { height: Number(body.height), weight: Number(body.weight), smoking: Boolean(body.smoking), - notificatio_token: body.notificatio_token + notification_token: body.notification_token } // @ts-ignore diff --git a/src/APIs/controllers/Supervisor.controller.ts b/src/APIs/controllers/Supervisor.controller.ts index 35e2531..7eb2821 100644 --- a/src/APIs/controllers/Supervisor.controller.ts +++ b/src/APIs/controllers/Supervisor.controller.ts @@ -4,6 +4,7 @@ import mongoose from 'mongoose' import { sendVerificationMail } from '../services/VerificationMail.services' export const supervisiorSignUp: RequestHandler = async ({ body, file }) => { + console.log('Tessst') let profilePictureFileId // @ts-ignore becasue property id doesn't exist on type file as it's not supported by docs if (file.id === undefined) { diff --git a/src/APIs/models/Patient.model.ts b/src/APIs/models/Patient.model.ts index d2959e9..e7baf8a 100644 --- a/src/APIs/models/Patient.model.ts +++ b/src/APIs/models/Patient.model.ts @@ -110,8 +110,8 @@ export const linkSupervisor = async ( const patient = await Patient.findById( new mongoose.Types.ObjectId(patientID) ) - if (patient?.supervisors) { - patient.supervisors.push(supervisorID) + if (patient?.associated_users) { + patient.associated_users.push(supervisorID) const res = await patient.save() return res diff --git a/src/APIs/models/Supervisor.model.ts b/src/APIs/models/Supervisor.model.ts index eda5ede..7255329 100644 --- a/src/APIs/models/Supervisor.model.ts +++ b/src/APIs/models/Supervisor.model.ts @@ -63,7 +63,7 @@ export const linkPatient = async ( new mongoose.Types.ObjectId(supervisorID) ) - supervisor.associated_patients.push(patientID) + supervisor.associated_users.push(patientID) const res = await supervisor.save() return res diff --git a/src/APIs/routes/PatientRoutes.route.ts b/src/APIs/routes/PatientRoutes.route.ts index 25e802a..37ec1dc 100644 --- a/src/APIs/routes/PatientRoutes.route.ts +++ b/src/APIs/routes/PatientRoutes.route.ts @@ -56,7 +56,6 @@ router.post( '/', uploadPhotosMiddleware, validatePatientCreation, - checkAuthentication, (req: Request, res: Response, next: NextFunction) => { handler({ req, res, next, fn: PatientController.createPatient }) } diff --git a/src/APIs/routes/Supervisor.route.ts b/src/APIs/routes/Supervisor.route.ts index 2d98335..9cb2a4d 100644 --- a/src/APIs/routes/Supervisor.route.ts +++ b/src/APIs/routes/Supervisor.route.ts @@ -50,7 +50,6 @@ router.post( '/', uploadPhotosMiddleware, SupervisorValidator.validateSupervisorCreation, - checkAuthentication, (req: Request, res: Response, next: NextFunction) => handler({ req, res, next, fn: SupervisorController.supervisiorSignUp }) ) diff --git a/src/APIs/schema/Patient.schema.ts b/src/APIs/schema/Patient.schema.ts index 3a5b180..fdbbfde 100644 --- a/src/APIs/schema/Patient.schema.ts +++ b/src/APIs/schema/Patient.schema.ts @@ -55,7 +55,7 @@ const PatientSchema = new Schema({ chair_serial_id: { type: String }, - supervisors: { + associated_users: { type: [{ type: mongoose.Types.ObjectId, ref: 'Supervisor', default: [] }], default: [] }, @@ -63,7 +63,7 @@ const PatientSchema = new Schema({ type: String }, medical_history: [{ type: String }], - notificatio_token: { type: String } + notification_token: { type: String } }) const Patient = model('Patient', PatientSchema) diff --git a/src/APIs/schema/Supervisior.schema.ts b/src/APIs/schema/Supervisior.schema.ts index ac0153e..204bec8 100644 --- a/src/APIs/schema/Supervisior.schema.ts +++ b/src/APIs/schema/Supervisior.schema.ts @@ -29,7 +29,7 @@ const SupervisiorSchema = new mongoose.Schema( profile_picture: { type: String }, - associated_patients: { + associated_users: { type: [{ type: mongoose.Types.ObjectId, ref: 'Patient' }], default: [] }, @@ -37,7 +37,7 @@ const SupervisiorSchema = new mongoose.Schema( type: Boolean, default: false }, - notificatio_token: { type: String } + notification_token: { type: String } }, { timestamps: { diff --git a/src/APIs/types/Patient.type.ts b/src/APIs/types/Patient.type.ts index 89ff1c4..935653a 100644 --- a/src/APIs/types/Patient.type.ts +++ b/src/APIs/types/Patient.type.ts @@ -13,11 +13,11 @@ export interface IPatientModel { dob: Date; smoking?: boolean; chair_serial_id?: string; - supervisors?: [mongoose.Types.ObjectId]; + associated_users?: [mongoose.Types.ObjectId]; profile_picture?: string; medical_history: [string]; isVerified: Boolean; - notificatio_token: string; + notification_token: string; } export type CreatePatientObjectType = { @@ -33,5 +33,5 @@ export type CreatePatientObjectType = { dob: Date; smoking: boolean; profile_picture?: string; - notificatio_token?: string + notification_token?: string }; diff --git a/src/APIs/types/Supervisor.type.ts b/src/APIs/types/Supervisor.type.ts index dae613d..43ccb3b 100644 --- a/src/APIs/types/Supervisor.type.ts +++ b/src/APIs/types/Supervisor.type.ts @@ -5,5 +5,5 @@ export type SupervisorObjectType = { phone: number; gender: string; profile_picture: string; - notificatio_token: string; + notification_token: string; }; From 35073967f9db8cf6af4ad3d099b0472c3573e4d3 Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Sat, 2 Jul 2022 13:29:38 +0200 Subject: [PATCH 04/33] heroku --- Procfile | 1 + package.json | 4 ++++ tsconfig.json | 12 ++++++------ 3 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 Procfile diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..64631a4 --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: node ./build/app.js \ No newline at end of file diff --git a/package.json b/package.json index 7f8b898..383d90d 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,10 @@ "version": "1.0.0", "description": "Software Backend", "main": "index.js", + "engines": { + "node": "16.xx", + "npm": "8.xx" + }, "scripts": { "start": "nodemon ./src/app.ts", "test": "jest --runInBand --detectOpenHandles --forceExit" diff --git a/tsconfig.json b/tsconfig.json index 857c428..44454e9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,7 +12,7 @@ /* Language and Environment */ "esModuleInterop": true, - "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ @@ -25,7 +25,7 @@ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ /* Modules */ - "module": "commonjs", /* Specify what module code is generated. */ + "module": "commonjs" /* Specify what module code is generated. */, // "rootDir": "./", /* Specify the root folder within your source files. */ // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ @@ -48,7 +48,7 @@ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ - // "outDir": "./", /* Specify an output folder for all emitted files. */ + "outDir": "./build" /* Specify an output folder for all emitted files. */, // "removeComments": true, /* Disable emitting comments. */ // "noEmit": true, /* Disable emitting files from a compilation. */ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ @@ -71,10 +71,10 @@ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, /* Type Checking */ - "strict": true, /* Enable all strict type-checking options. */ + "strict": true /* Enable all strict type-checking options. */, // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ @@ -96,6 +96,6 @@ /* Completeness */ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ } } From 4ede632aed11a92dc0bd1c451971e67e06c65ce6 Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Sat, 2 Jul 2022 13:32:11 +0200 Subject: [PATCH 05/33] remove node version --- package.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/package.json b/package.json index 383d90d..fe5817f 100644 --- a/package.json +++ b/package.json @@ -3,10 +3,7 @@ "version": "1.0.0", "description": "Software Backend", "main": "index.js", - "engines": { - "node": "16.xx", - "npm": "8.xx" - }, + "scripts": { "start": "nodemon ./src/app.ts", "test": "jest --runInBand --detectOpenHandles --forceExit" From ca04f1ec732d7184b275c059b836ce48a5bdafc1 Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Sat, 2 Jul 2022 18:39:54 +0200 Subject: [PATCH 06/33] notification pushing --- package-lock.json | 68 +++++++++++++++++++ package.json | 2 +- .../controllers/Notifications.controller.ts | 9 +++ src/APIs/controllers/Patient.controller.ts | 2 +- src/APIs/controllers/Supervisor.controller.ts | 9 +-- src/APIs/models/Invitations.model.ts | 2 +- src/APIs/routes/Notifications.route.ts | 9 ++- src/APIs/services/Login.services.ts | 28 ++++++++ src/APIs/services/Notifications.services.ts | 44 +++++++++++- .../services/VerificationMail.services.ts | 2 +- src/APIs/types/Patient.type.ts | 1 + 11 files changed, 162 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3d4907f..0748d5e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "@typescript-eslint/eslint-plugin": "^5.29.0", "@typescript-eslint/parser": "^5.29.0", "aws-sdk": "^2.1162.0", + "axios": "^0.27.2", "bcryptjs": "^2.4.3", "config": "^3.3.7", "cors": "^2.8.5", @@ -2355,6 +2356,28 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, + "node_modules/axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "node_modules/axios/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", @@ -4958,6 +4981,25 @@ "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", "dev": true }, + "node_modules/follow-redirects": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", + "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -12160,6 +12202,27 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, + "axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "requires": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + }, + "dependencies": { + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } + } + }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", @@ -14170,6 +14233,11 @@ "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", "dev": true }, + "follow-redirects": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", + "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==" + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", diff --git a/package.json b/package.json index fe5817f..a73fd21 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,6 @@ "version": "1.0.0", "description": "Software Backend", "main": "index.js", - "scripts": { "start": "nodemon ./src/app.ts", "test": "jest --runInBand --detectOpenHandles --forceExit" @@ -41,6 +40,7 @@ "@typescript-eslint/eslint-plugin": "^5.29.0", "@typescript-eslint/parser": "^5.29.0", "aws-sdk": "^2.1162.0", + "axios": "^0.27.2", "bcryptjs": "^2.4.3", "config": "^3.3.7", "cors": "^2.8.5", diff --git a/src/APIs/controllers/Notifications.controller.ts b/src/APIs/controllers/Notifications.controller.ts index ee6a8d9..5883c58 100644 --- a/src/APIs/controllers/Notifications.controller.ts +++ b/src/APIs/controllers/Notifications.controller.ts @@ -40,3 +40,12 @@ export const editNotification: RequestHandler = async ({ body, params }) => { message: 'Notification has been edited successfully' } } + +export const pushNotification: RequestHandler = async ({ body }) => { + const response = await NotificationServices.push(body) + + return { + response: response, + message: 'Notification has been pushed successfully' + } +} diff --git a/src/APIs/controllers/Patient.controller.ts b/src/APIs/controllers/Patient.controller.ts index 3b98ba1..62c94a2 100644 --- a/src/APIs/controllers/Patient.controller.ts +++ b/src/APIs/controllers/Patient.controller.ts @@ -54,7 +54,7 @@ export const createPatient: RequestHandler = async ({ body, file }) => { } // @ts-ignore - const profilePictureFileId = file.id === undefined ? '' : file.id + const profilePictureFileId = file === undefined ? '' : file.id const response = await PatientsServices.createPatient( patientInfo, profilePictureFileId diff --git a/src/APIs/controllers/Supervisor.controller.ts b/src/APIs/controllers/Supervisor.controller.ts index 7eb2821..5c97fc1 100644 --- a/src/APIs/controllers/Supervisor.controller.ts +++ b/src/APIs/controllers/Supervisor.controller.ts @@ -4,14 +4,9 @@ import mongoose from 'mongoose' import { sendVerificationMail } from '../services/VerificationMail.services' export const supervisiorSignUp: RequestHandler = async ({ body, file }) => { - console.log('Tessst') - let profilePictureFileId - // @ts-ignore becasue property id doesn't exist on type file as it's not supported by docs - if (file.id === undefined) { - profilePictureFileId = '' - } // @ts-ignore - profilePictureFileId = file.id + const profilePictureFileId = file === undefined ? '' : file.id + const supervisor = await SupervisorServices.createSupervisor( body, profilePictureFileId diff --git a/src/APIs/models/Invitations.model.ts b/src/APIs/models/Invitations.model.ts index 74044b7..78b87f5 100644 --- a/src/APIs/models/Invitations.model.ts +++ b/src/APIs/models/Invitations.model.ts @@ -50,7 +50,7 @@ export const getPatientInvitations = async (patientID: string) => { export const getSupervisorInvitations = async (supervisorID: string) => { const invitations = await Invitations.find({ - from_id: new mongoose.Types.ObjectId(supervisorID) + to_id: new mongoose.Types.ObjectId(supervisorID) }) return invitations diff --git a/src/APIs/routes/Notifications.route.ts b/src/APIs/routes/Notifications.route.ts index 49539ed..f9482d5 100644 --- a/src/APIs/routes/Notifications.route.ts +++ b/src/APIs/routes/Notifications.route.ts @@ -36,12 +36,19 @@ router.put( handler({ req, res, next, fn: NotificationsController.editNotification }) ) +router.post( + '/push', + checkAuthentication, + (req: Request, res: Response, next: NextFunction) => + handler({ req, res, next, fn: NotificationsController.delteNotification }) +) + router.delete( '/:id', NotificationsValidator.validateNotificationID, checkAuthentication, (req: Request, res: Response, next: NextFunction) => - handler({ req, res, next, fn: NotificationsController.delteNotification }) + handler({ req, res, next, fn: NotificationsController.pushNotification }) ) export default router diff --git a/src/APIs/services/Login.services.ts b/src/APIs/services/Login.services.ts index 1b96755..601189d 100644 --- a/src/APIs/services/Login.services.ts +++ b/src/APIs/services/Login.services.ts @@ -1,9 +1,11 @@ import * as PatientModel from '../models/Patient.model' import * as SupervisorModel from '../models/Supervisor.model' import * as jwt from 'jsonwebtoken' +import { IPatientModel } from '../types/Patient.type' import { USER_ROLES } from '../types/User.types' import { UnprocessableError } from '../types/general.types' import bcyrpt from 'bcryptjs' +import mongoose from 'mongoose' export const login = async (email: string, password: string, role: string) => { let user @@ -28,10 +30,36 @@ export const login = async (email: string, password: string, role: string) => { if (!validPass) { throw new UnprocessableError('Password is invalid') } + const token = generateToken(user._id, email, password) + const associatedUsers: any = [] + + switch (role) { + case USER_ROLES.PATIENT: + await Promise.all( + user.associated_users.map(async (user: mongoose.Types.ObjectId) => { + const { name, address, profile_picture, _id } = + await SupervisorModel.getSupervisorById(user) + associatedUsers.push({ name, address, profile_picture, _id }) + }) + ) + break + case USER_ROLES.SUPERVISOR: + await Promise.all( + user.associated_users.map(async (user: mongoose.Types.ObjectId) => { + const { name, address, profile_picture, _id } = + (await PatientModel.getPatient(user)) as IPatientModel + associatedUsers.push({ name, address, profile_picture, _id }) + }) + ) + break + default: + break + } return { ...user._doc, + associatedUsers, token: token } } diff --git a/src/APIs/services/Notifications.services.ts b/src/APIs/services/Notifications.services.ts index f242431..c6dc310 100644 --- a/src/APIs/services/Notifications.services.ts +++ b/src/APIs/services/Notifications.services.ts @@ -1,6 +1,10 @@ import * as NotificationModel from '../models/Notifications.model' import { NotificationObjectType } from '../types/Notifications.type' +import { USER_ROLES } from '../types/User.types' import { UnprocessableError } from '../types/general.types' +import { UserVariations } from './VerificationMail.services' +import mongoose from 'mongoose' +import axios from 'axios' export const createNotification = ( notificationObject: NotificationObjectType @@ -21,11 +25,47 @@ export const getUserNotifications = (id: string) => { return response } -export const editNotification = async (notificationID: string, newNotificationObject: NotificationObjectType) => { - const newNotitication = await NotificationModel.editNotification(notificationID, newNotificationObject) +export const editNotification = async ( + notificationID: string, + newNotificationObject: NotificationObjectType +) => { + const newNotitication = await NotificationModel.editNotification( + notificationID, + newNotificationObject + ) if (!newNotitication) { throw new UnprocessableError('Notification not found') } return newNotitication } + +export const push = async ({ + body, + title, + _id, + userRole +}: { + body: string; + title: string; + _id: string; + userRole: USER_ROLES; +}) => { + const { notification_token } = await UserVariations( + new mongoose.Types.ObjectId(_id), + userRole, + 'get' + ) + + if (!notification_token) { + throw new UnprocessableError('User doesn\'t have a notification token ') + } + + const res = await axios.post('https://exp.host/--/api/v2/push/send', { + to: notification_token, + title: title, + body: body + }) + + return res +} diff --git a/src/APIs/services/VerificationMail.services.ts b/src/APIs/services/VerificationMail.services.ts index dfa0323..e237857 100644 --- a/src/APIs/services/VerificationMail.services.ts +++ b/src/APIs/services/VerificationMail.services.ts @@ -59,7 +59,7 @@ export const verifyMail = async ( return updatedUser } -const UserVariations = async ( +export const UserVariations = async ( id: mongoose.Types.ObjectId, userType: USER_ROLES, ToDo: 'get' | 'update' diff --git a/src/APIs/types/Patient.type.ts b/src/APIs/types/Patient.type.ts index 935653a..caf78f9 100644 --- a/src/APIs/types/Patient.type.ts +++ b/src/APIs/types/Patient.type.ts @@ -1,6 +1,7 @@ import mongoose from 'mongoose' export interface IPatientModel { + _id?: mongoose.Types.ObjectId, name: string; email: string; password: string; From 2b02d295d730227a0b21ba311e684710df6b8cdb Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Mon, 11 Jul 2022 16:12:23 +0200 Subject: [PATCH 07/33] Include from and to names => Reminders --- src/APIs/services/Notifications.services.ts | 2 +- src/APIs/services/Reminders.services.ts | 60 +++++++++++++++---- .../services/VerificationMail.services.ts | 1 - 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/APIs/services/Notifications.services.ts b/src/APIs/services/Notifications.services.ts index c6dc310..01f97f4 100644 --- a/src/APIs/services/Notifications.services.ts +++ b/src/APIs/services/Notifications.services.ts @@ -3,8 +3,8 @@ import { NotificationObjectType } from '../types/Notifications.type' import { USER_ROLES } from '../types/User.types' import { UnprocessableError } from '../types/general.types' import { UserVariations } from './VerificationMail.services' -import mongoose from 'mongoose' import axios from 'axios' +import mongoose from 'mongoose' export const createNotification = ( notificationObject: NotificationObjectType diff --git a/src/APIs/services/Reminders.services.ts b/src/APIs/services/Reminders.services.ts index aea8e3f..ee25a84 100644 --- a/src/APIs/services/Reminders.services.ts +++ b/src/APIs/services/Reminders.services.ts @@ -1,27 +1,44 @@ import * as RemindersModel from '../models/Reminder.model' -import { CreateReminderObjectType, UpdateReminderObjectType } from '../types/Reminder.type' +import { + CreateReminderObjectType, + UpdateReminderObjectType +} from '../types/Reminder.type' import { UnprocessableError } from '../types/general.types' +import { getPatient } from '../models/Patient.model' +import { getSupervisorById } from '../models/Supervisor.model' import mongoose from 'mongoose' -export const getAllRemindersByPatientId = (patientId: mongoose.Types.ObjectId) => { - const reminders = RemindersModel.getAllRemindersByPatientId(patientId) +export const getAllRemindersByPatientId = async ( + patientId: mongoose.Types.ObjectId +) => { + const reminders = await RemindersModel.getAllRemindersByPatientId(patientId) if (!reminders) { throw new UnprocessableError('Could not fetch reminders using patientId') } - return reminders + const AllReminders = await getReminderUserNames(reminders as []) + + return AllReminders } -export const getAllRemindersBySupervisorId = (supervisorId: mongoose.Types.ObjectId) => { - const reminders = RemindersModel.getAllRemindersBySupervisorId(supervisorId) +export const getAllRemindersBySupervisorId = async ( + supervisorId: mongoose.Types.ObjectId +) => { + const reminders = await RemindersModel.getAllRemindersBySupervisorId( + supervisorId + ) if (!reminders) { - throw new UnprocessableError('Could not fetch reminders using supervisorId') + throw new UnprocessableError( + 'Could not fetch reminders using supervisorId' + ) } - return reminders + const AllReminders = await getReminderUserNames(reminders as []) + + return AllReminders } -export const getReminder = (reminderId:mongoose.Types.ObjectId) => { +export const getReminder = (reminderId: mongoose.Types.ObjectId) => { const reminder = RemindersModel.getReminder(reminderId) if (!reminder) { throw new UnprocessableError('Could not fetch reminder') @@ -43,7 +60,9 @@ export const deleteReminder = (reminderId: mongoose.Types.ObjectId) => { return reminder } -export const updateReminder = (reminderUpdateInput: UpdateReminderObjectType) => { +export const updateReminder = ( + reminderUpdateInput: UpdateReminderObjectType +) => { const reminder = RemindersModel.updateReminder(reminderUpdateInput) if (!reminder) { throw new UnprocessableError('Could not update reminder') @@ -51,3 +70,24 @@ export const updateReminder = (reminderUpdateInput: UpdateReminderObjectType) => return reminder } + +const getReminderUserNames = async (reminders: []) => { + const AllReminders: any = [] + await Promise.all( + reminders.map(async (reminder) => { + const { patient_id, supervisor_id } = reminder + const patient = await getPatient(new mongoose.Types.ObjectId(patient_id)) + const supervisor = await getSupervisorById( + new mongoose.Types.ObjectId(supervisor_id) + ) + + AllReminders.push({ + reminder, + patientName: patient?.name, + supervisorName: supervisor.name + }) + }) + ) + + return AllReminders +} diff --git a/src/APIs/services/VerificationMail.services.ts b/src/APIs/services/VerificationMail.services.ts index e237857..a9826b8 100644 --- a/src/APIs/services/VerificationMail.services.ts +++ b/src/APIs/services/VerificationMail.services.ts @@ -103,7 +103,6 @@ export const resendVerificationMail = async ( } const newToken = await generateToken(id, email) - console.log(newToken) const data = await sendMail({ userMail: [email], From ea6d5ee7b84ee70b3760fae9f2110511a841171b Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Mon, 11 Jul 2022 16:18:39 +0200 Subject: [PATCH 08/33] fix note type typo --- src/APIs/models/Note.model.ts | 6 +----- src/APIs/types/Note.type.ts | 2 +- test/services/NoteService.test.ts | 2 +- test/utilities/seed.ts | 6 +++--- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/APIs/models/Note.model.ts b/src/APIs/models/Note.model.ts index ac3b0d0..5ddd7c4 100644 --- a/src/APIs/models/Note.model.ts +++ b/src/APIs/models/Note.model.ts @@ -30,11 +30,7 @@ export const getNote = async (noteId: mongoose.Types.ObjectId) => { * @returns id of the newly created input */ export const createNote = async (noteInput: CreateNoteObjectType) => { - const response = await Note.create({ - user_id: new mongoose.Types.ObjectId(noteInput.userId), - title: noteInput.title, - description: noteInput.description - }) + const response = await Note.create(noteInput) return response } diff --git a/src/APIs/types/Note.type.ts b/src/APIs/types/Note.type.ts index 90e80b8..db77403 100644 --- a/src/APIs/types/Note.type.ts +++ b/src/APIs/types/Note.type.ts @@ -10,7 +10,7 @@ export interface INoteModel { } export type CreateNoteObjectType = { - userId: string + user_id: string title:string description: string } diff --git a/test/services/NoteService.test.ts b/test/services/NoteService.test.ts index eb88a17..fd52c61 100644 --- a/test/services/NoteService.test.ts +++ b/test/services/NoteService.test.ts @@ -27,7 +27,7 @@ describe('Testing Note Service', () => { test('Create note', async () => { const noteInput:CreateNoteObjectType = { - userId: '6263ce0577164ec6745e3bd7', + user_id: '6263ce0577164ec6745e3bd7', title: 'Hello', description: 'world!' } diff --git a/test/utilities/seed.ts b/test/utilities/seed.ts index 0efb81e..bb005c7 100644 --- a/test/utilities/seed.ts +++ b/test/utilities/seed.ts @@ -4,17 +4,17 @@ import * as ReminderModel from '../../src/APIs/models/Reminder.model' import { CreateNoteObjectType } from '../../src/APIs/types/Note.type' import { CreatePatientObjectType } from '../../src/APIs/types/Patient.type' import { CreateReminderObjectType } from '../../src/APIs/types/Reminder.type' -import mongoose from 'mongoose' import { UnprocessableError } from '../../src/APIs/types/general.types' +import mongoose from 'mongoose' export const createNote = async ():Promise => { const note:CreateNoteObjectType = { - userId: '6263ce0577164ec6745e3bd7', + user_id: '6263ce0577164ec6745e3bd7', title: 'Hello', description: 'world!' } const note2:CreateNoteObjectType = { - userId: '6263ce0577164ec6745e3bd7', + user_id: '6263ce0577164ec6745e3bd7', title: 'Hello2', description: 'world2!' } From 65893d5f6f64e8695d22de78148b3de48991aaa4 Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Mon, 11 Jul 2022 18:05:09 +0200 Subject: [PATCH 09/33] get invitation details front wants --- src/APIs/services/Invitations.services.ts | 43 ++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/src/APIs/services/Invitations.services.ts b/src/APIs/services/Invitations.services.ts index 4ff526b..966b900 100644 --- a/src/APIs/services/Invitations.services.ts +++ b/src/APIs/services/Invitations.services.ts @@ -5,8 +5,9 @@ import { } from '../types/Invitation.types' import { USER_ROLES } from '../types/User.types' import { UnprocessableError } from '../types/general.types' -import { linkPatient } from '../models/Supervisor.model' -import { linkSupervisor } from '../models/Patient.model' +import { getSupervisorById, linkPatient } from '../models/Supervisor.model' +import { getPatient, linkSupervisor } from '../models/Patient.model' +import mongoose from 'mongoose' export const sendInvitationService = async ( invitation: CreateInvitationObjectType @@ -39,16 +40,23 @@ export const getInvitation = async (id: string) => InvitationModels.getInvitation(id) export const getInvitations = async (userID: string, userType: USER_ROLES) => { + let invitations = [] switch (userType) { case USER_ROLES.PATIENT: - return await InvitationModels.getPatientInvitations(userID) + invitations = await InvitationModels.getPatientInvitations(userID) + break case USER_ROLES.SUPERVISOR: - return await InvitationModels.getSupervisorInvitations(userID) + invitations = await InvitationModels.getSupervisorInvitations(userID) + break default: throw new UnprocessableError('User type doesn\'t exist') } + + const AllInvitations = await getInvitationDetails(invitations as []) + + console.log(AllInvitations) } export const acceptInvitation = async (inivitationID: string) => { @@ -77,3 +85,30 @@ export const rejectInvitation = async (inivitationID: string) => { return response } + +const getInvitationDetails = async (invitations: []) => { + const AllInvitations: any = [] + await Promise.all( + invitations.map(async (invitation) => { + const { from_id, to_id } = invitation + const patient = await getPatient(new mongoose.Types.ObjectId(from_id)) + const supervisor = await getSupervisorById( + new mongoose.Types.ObjectId(to_id) + ) + + AllInvitations.push({ + invitation, + patient: { + name: patient?.name, + photo: patient?.profile_picture, + gender: patient?.gender, + birthDate: patient?.dob + }, + supervisorName: supervisor.name, + supervisorPhoto: supervisor.profile_picture + }) + }) + ) + + return AllInvitations +} From ff9f7ce59abfb1e833452a103c26d3a0d6eb2668 Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Mon, 11 Jul 2022 21:08:23 +0200 Subject: [PATCH 10/33] push notifications to user on creation --- src/APIs/services/Notifications.services.ts | 15 +++++++++++++-- src/APIs/types/Notifications.type.ts | 2 ++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/APIs/services/Notifications.services.ts b/src/APIs/services/Notifications.services.ts index 01f97f4..fce0d45 100644 --- a/src/APIs/services/Notifications.services.ts +++ b/src/APIs/services/Notifications.services.ts @@ -6,9 +6,20 @@ import { UserVariations } from './VerificationMail.services' import axios from 'axios' import mongoose from 'mongoose' -export const createNotification = ( +export const createNotification = async ( notificationObject: NotificationObjectType -) => NotificationModel.createNotification(notificationObject) +) => { + const res = await NotificationModel.createNotification(notificationObject) + const { description, title, user_id, userRole } = notificationObject + await push({ + body: description, + title, + _id: user_id.toString(), + userRole + }) + + return res +} export const deleteNotification = async (id: string) => { const response = await NotificationModel.deleteNotification(id) diff --git a/src/APIs/types/Notifications.type.ts b/src/APIs/types/Notifications.type.ts index f9a4fdb..a41d67e 100644 --- a/src/APIs/types/Notifications.type.ts +++ b/src/APIs/types/Notifications.type.ts @@ -1,3 +1,4 @@ +import { USER_ROLES } from './User.types' import mongoose from 'mongoose' export interface NotificationObjectType { @@ -7,4 +8,5 @@ export interface NotificationObjectType { description: string; isRead: boolean; type: string; + userRole: USER_ROLES } From a902932108e18d30210e874b4431f760e2699f21 Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Tue, 12 Jul 2022 17:22:39 +0200 Subject: [PATCH 11/33] verify mail and sending mail get url from front + notification issue --- src/APIs/controllers/Patient.controller.ts | 9 +++++---- src/APIs/controllers/Supervisor.controller.ts | 7 ++++++- src/APIs/controllers/Users.controller.ts | 3 ++- src/APIs/models/Patient.model.ts | 3 ++- .../HelperFunctions/generateMailTempelate.ts | 4 ++-- src/APIs/services/Patient.services.ts | 17 ++++++++++++----- src/APIs/services/VerificationMail.services.ts | 15 ++++++++++----- src/APIs/types/Patient.type.ts | 2 +- src/APIs/types/sendingMail.types.ts | 1 + 9 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/APIs/controllers/Patient.controller.ts b/src/APIs/controllers/Patient.controller.ts index 62c94a2..82396c5 100644 --- a/src/APIs/controllers/Patient.controller.ts +++ b/src/APIs/controllers/Patient.controller.ts @@ -63,12 +63,14 @@ export const createPatient: RequestHandler = async ({ body, file }) => { await sendVerificationMail( response?.email as string, response?._id as mongoose.Types.ObjectId, - response?.name + response?.name, + body.url ) return { response: response, - message: 'Patient created successfully, and Verification Mail has been sent' + message: + 'Patient created successfully, and Verification Mail has been sent' } } @@ -106,8 +108,7 @@ export const updatePatient: RequestHandler = async ({ body, params }) => { return { response: response, - message: - 'Patient updated successfully' + message: 'Patient updated successfully' } } diff --git a/src/APIs/controllers/Supervisor.controller.ts b/src/APIs/controllers/Supervisor.controller.ts index 5c97fc1..04c4b4f 100644 --- a/src/APIs/controllers/Supervisor.controller.ts +++ b/src/APIs/controllers/Supervisor.controller.ts @@ -11,7 +11,12 @@ export const supervisiorSignUp: RequestHandler = async ({ body, file }) => { body, profilePictureFileId ) - await sendVerificationMail(supervisor.email, supervisor._id, supervisor.name) + await sendVerificationMail( + supervisor.email, + supervisor._id, + supervisor.name, + body.url + ) return { response: supervisor, diff --git a/src/APIs/controllers/Users.controller.ts b/src/APIs/controllers/Users.controller.ts index 439f0bd..60f1943 100644 --- a/src/APIs/controllers/Users.controller.ts +++ b/src/APIs/controllers/Users.controller.ts @@ -39,7 +39,8 @@ export const resendVerificationMailController: RequestHandler = async ({ const response = await resendVerificationMail( new mongoose.Types.ObjectId(body.user_id), body.email, - body.userName || undefined + body.userName || undefined, + body.url ) return { diff --git a/src/APIs/models/Patient.model.ts b/src/APIs/models/Patient.model.ts index e7baf8a..dc0fc6f 100644 --- a/src/APIs/models/Patient.model.ts +++ b/src/APIs/models/Patient.model.ts @@ -70,7 +70,8 @@ export const createPatient = async (patientInput: CreatePatientObjectType) => { height: patientInput.height, dob: patientInput.dob, smoking: patientInput.smoking, - profile_picture: patientInput.profile_picture + profile_picture: patientInput.profile_picture, + notification_token: patientInput.notification_token }) return response diff --git a/src/APIs/services/HelperFunctions/generateMailTempelate.ts b/src/APIs/services/HelperFunctions/generateMailTempelate.ts index 3c5d74f..080f844 100644 --- a/src/APIs/services/HelperFunctions/generateMailTempelate.ts +++ b/src/APIs/services/HelperFunctions/generateMailTempelate.ts @@ -1,7 +1,7 @@ import { MailObject } from '../../types/sendingMail.types' const generateMailTempelate = (mailData: MailObject) => { - const { userMail, userName, mailBody, subject } = mailData + const { userMail, userName, mailBody, subject, url } = mailData return { Destination: { @@ -13,7 +13,7 @@ const generateMailTempelate = (mailData: MailObject) => { Body: { Html: { Charset: 'UTF-8', - Data: `

Hello ${userName}

${mailBody}

Best Wishes

Wheel.E Team

` + Data: `

Hello ${userName}

${mailBody}

Open Link

Best Wishes

Wheel.E Team

` }, Text: { Charset: 'UTF-8', diff --git a/src/APIs/services/Patient.services.ts b/src/APIs/services/Patient.services.ts index 9b6d8ad..e530f43 100644 --- a/src/APIs/services/Patient.services.ts +++ b/src/APIs/services/Patient.services.ts @@ -34,14 +34,16 @@ export const getPatient = (patientId: mongoose.Types.ObjectId) => { return patient } -export const getPatientMedicalRecords = async (patientId: mongoose.Types.ObjectId) => { +export const getPatientMedicalRecords = async ( + patientId: mongoose.Types.ObjectId +) => { const patient = await PatientModel.getPatient(patientId) if (!patient) { throw new UnprocessableError('Could not fetch patient') } const { medical_history } = patient - const medicalRecords : string[] = [] + const medicalRecords: string[] = [] for (let i = 0; i < medical_history.length; i++) { const file = await FileModel.getMedicalRecord(medical_history[i]) @@ -91,7 +93,7 @@ export const updatePatient = ( return patient } -export const getPatientProfilePicture = async (patientId:string) => { +export const getPatientProfilePicture = async (patientId: string) => { const patientID = new mongoose.Types.ObjectId(patientId) const patient = await PatientModel.getPatient(patientID) if (!patient) { @@ -112,9 +114,14 @@ export const uploadMedicalRecord = async ( patientId: mongoose.Types.ObjectId, healthRecord: string ) => { - const patient = await PatientModel.uploadMedicalRecord(patientId, healthRecord) + const patient = await PatientModel.uploadMedicalRecord( + patientId, + healthRecord + ) if (!patient) { - throw new UnprocessableError('Could not add medical record to the patient profile') + throw new UnprocessableError( + 'Could not add medical record to the patient profile' + ) } return patient diff --git a/src/APIs/services/VerificationMail.services.ts b/src/APIs/services/VerificationMail.services.ts index a9826b8..5a531d7 100644 --- a/src/APIs/services/VerificationMail.services.ts +++ b/src/APIs/services/VerificationMail.services.ts @@ -24,14 +24,16 @@ const generateToken = async (id: mongoose.Types.ObjectId, email: string) => { export const sendVerificationMail = async ( email: string, id: mongoose.Types.ObjectId, - userName: string | undefined + userName: string | undefined, + url: string ) => { const token = await generateToken(id, email) const data = await sendMail({ userMail: [email], subject: 'Verification Mail', userName: userName || 'My Friend', - mailBody: `Please Open this link to Verify you appliction, ${token}` + mailBody: `Please Open this link to Verify you appliction`, + url: `${url}:${token}` }) return { token, data } @@ -88,7 +90,8 @@ export const UserVariations = async ( export const resendVerificationMail = async ( id: mongoose.Types.ObjectId, email: string, - userName: string | undefined + userName: string | undefined, + url: string ) => { const verificationToken = await VerificationMailModel.findTokenByUserID(id) if (verificationToken) { @@ -96,7 +99,8 @@ export const resendVerificationMail = async ( userMail: [email], subject: 'Verification Mail', userName: userName || 'My Friend', - mailBody: `Please Open this link to Verify you appliction, ${verificationToken}` + mailBody: `Please Open this link to Verify you appliction`, + url: `${url}:${verificationToken}` }) return { verificationToken, data } @@ -108,7 +112,8 @@ export const resendVerificationMail = async ( userMail: [email], subject: 'Verification Mail', userName: userName || 'My Friend', - mailBody: `Please Open this link to Verify you appliction, ${newToken}` + mailBody: `Please Open this link to Verify you appliction`, + url: `${url}:${newToken}` }) return { newToken, data } diff --git a/src/APIs/types/Patient.type.ts b/src/APIs/types/Patient.type.ts index caf78f9..03bae32 100644 --- a/src/APIs/types/Patient.type.ts +++ b/src/APIs/types/Patient.type.ts @@ -34,5 +34,5 @@ export type CreatePatientObjectType = { dob: Date; smoking: boolean; profile_picture?: string; - notification_token?: string + notification_token?: string, }; diff --git a/src/APIs/types/sendingMail.types.ts b/src/APIs/types/sendingMail.types.ts index aa3b7cc..a20d057 100644 --- a/src/APIs/types/sendingMail.types.ts +++ b/src/APIs/types/sendingMail.types.ts @@ -3,4 +3,5 @@ export interface MailObject { mailBody: string; subject: string; userName: string; + url: string, } From 91a40ad33c338672d76a843a74cd73647e02316a Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Tue, 12 Jul 2022 18:56:52 +0200 Subject: [PATCH 12/33] fix notification push route --- src/APIs/routes/Notifications.route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/APIs/routes/Notifications.route.ts b/src/APIs/routes/Notifications.route.ts index f9482d5..7a35a5c 100644 --- a/src/APIs/routes/Notifications.route.ts +++ b/src/APIs/routes/Notifications.route.ts @@ -40,7 +40,7 @@ router.post( '/push', checkAuthentication, (req: Request, res: Response, next: NextFunction) => - handler({ req, res, next, fn: NotificationsController.delteNotification }) + handler({ req, res, next, fn: NotificationsController.pushNotification }) ) router.delete( From ad91b12504d218c3b661d2cf6fbb534853cf3434 Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Tue, 12 Jul 2022 19:06:23 +0200 Subject: [PATCH 13/33] fix send mail issue --- src/APIs/services/HelperFunctions/generateMailTempelate.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/APIs/services/HelperFunctions/generateMailTempelate.ts b/src/APIs/services/HelperFunctions/generateMailTempelate.ts index 080f844..d1b0a72 100644 --- a/src/APIs/services/HelperFunctions/generateMailTempelate.ts +++ b/src/APIs/services/HelperFunctions/generateMailTempelate.ts @@ -13,7 +13,10 @@ const generateMailTempelate = (mailData: MailObject) => { Body: { Html: { Charset: 'UTF-8', - Data: `

Hello ${userName}

${mailBody}

Open Link

Best Wishes

Wheel.E Team

` + Data: + url === '' + ? `

Hello ${userName}

${mailBody}

Best Wishes

Wheel.E Team

` + : `

Hello ${userName}

${mailBody}

Open Link

Best Wishes

Wheel.E Team

` }, Text: { Charset: 'UTF-8', From 8ac23373bbb29afe6299e7b516440a4fa7beb1e6 Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Wed, 13 Jul 2022 14:15:07 +0200 Subject: [PATCH 14/33] fix resend verification token issue --- src/APIs/services/VerificationMail.services.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/APIs/services/VerificationMail.services.ts b/src/APIs/services/VerificationMail.services.ts index 5a531d7..aa39c89 100644 --- a/src/APIs/services/VerificationMail.services.ts +++ b/src/APIs/services/VerificationMail.services.ts @@ -100,10 +100,10 @@ export const resendVerificationMail = async ( subject: 'Verification Mail', userName: userName || 'My Friend', mailBody: `Please Open this link to Verify you appliction`, - url: `${url}:${verificationToken}` + url: `${url}/${verificationToken.token}` }) - return { verificationToken, data } + return { verificationToken: verificationToken.token, data } } const newToken = await generateToken(id, email) From 099560ea5d44b92bdf80da1a11832bc9e8a92b5e Mon Sep 17 00:00:00 2001 From: Alaa Date: Fri, 15 Jul 2022 21:39:03 +0200 Subject: [PATCH 15/33] change port number --- .env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env b/.env index 856b86f..e7432f4 100644 --- a/.env +++ b/.env @@ -1,3 +1,3 @@ DB="mongodb+srv://wheeler:1234@backend-cluster.qrm0u.mongodb.net/test" HOST=localhost -PORT=3000 \ No newline at end of file +PORT=8080 \ No newline at end of file From 5ea991c183b1e22d5a1188b354c435e801841306 Mon Sep 17 00:00:00 2001 From: Alaa Date: Sun, 17 Jul 2022 02:19:08 +0200 Subject: [PATCH 16/33] fixing supervisor sign up using form data --- package-lock.json | 48 +++++++++---------- package.json | 6 +-- src/APIs/controllers/Supervisor.controller.ts | 15 +++++- src/APIs/routes/Supervisor.route.ts | 2 +- 4 files changed, 39 insertions(+), 32 deletions(-) diff --git a/package-lock.json b/package-lock.json index ee83c97..45e8565 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1780,7 +1780,7 @@ "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, "array-includes": { "version": "3.1.4", @@ -2425,7 +2425,7 @@ "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true }, "collect-v8-coverage": { @@ -2582,7 +2582,7 @@ "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "core-js": { "version": "2.6.12", @@ -2738,7 +2738,7 @@ "dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", "dev": true }, "deep-eql": { @@ -2953,7 +2953,7 @@ "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "electron-to-chromium": { "version": "1.4.172", @@ -2975,7 +2975,7 @@ "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" }, "end-of-stream": { "version": "1.4.4", @@ -3061,7 +3061,7 @@ "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "escape-string-regexp": { "version": "4.0.0", @@ -3537,7 +3537,7 @@ "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" }, "events": { "version": "1.1.1", @@ -3572,7 +3572,7 @@ "exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true }, "expect": { @@ -3786,7 +3786,7 @@ "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" }, "fs-constants": { "version": "1.0.0", @@ -3807,8 +3807,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { "version": "2.3.2", @@ -3892,7 +3891,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4290,7 +4288,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -4338,7 +4335,7 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, "is-bigint": { @@ -5794,7 +5791,7 @@ "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" }, "memory-pager": { "version": "1.5.0", @@ -5805,7 +5802,7 @@ "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "merge-stream": { "version": "2.0.0", @@ -5821,7 +5818,7 @@ "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" }, "micromatch": { "version": "4.0.5", @@ -6130,7 +6127,7 @@ "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, "node-releases": { @@ -6247,7 +6244,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-inspect": { "version": "1.12.0", @@ -6413,8 +6410,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-key": { "version": "3.1.1", @@ -6431,7 +6427,7 @@ "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "path-type": { "version": "4.0.0", @@ -6777,7 +6773,7 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, "require-from-string": { @@ -7611,7 +7607,7 @@ "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" }, "update-browserslist-db": { "version": "1.0.4", @@ -7694,7 +7690,7 @@ "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" }, "uuid": { "version": "8.0.0", diff --git a/package.json b/package.json index ef98bf0..72bd6e6 100644 --- a/package.json +++ b/package.json @@ -60,8 +60,8 @@ "ts-node": "^10.7.0", "typescript": "^4.7.4" }, - "engines" : { - "npm" : ">=6.0.0", - "node" : ">=14.0.0" + "engines": { + "npm": ">=6.0.0", + "node": ">=14.0.0" } } diff --git a/src/APIs/controllers/Supervisor.controller.ts b/src/APIs/controllers/Supervisor.controller.ts index 8d2d603..7e93e89 100644 --- a/src/APIs/controllers/Supervisor.controller.ts +++ b/src/APIs/controllers/Supervisor.controller.ts @@ -2,8 +2,9 @@ import * as SupervisorServices from '../services/Supervisors.services' import { RequestHandler } from 'express' import mongoose from 'mongoose' import { sendVerificationMail } from '../services/VerificationMail.services' +import { SupervisorObjectType } from '../types/Supervisor.type' -export const supervisiorSignUp: RequestHandler = async ({ body, file }) => { +export const supervisorSignUp: RequestHandler = async ({ body, file }) => { let profilePictureFileId // @ts-ignore becasue property id doesn't exist on type file as it's not supported by docs if (file.id === undefined) { @@ -11,8 +12,18 @@ export const supervisiorSignUp: RequestHandler = async ({ body, file }) => { } // @ts-ignore profilePictureFileId = file.id + + const supervisorData : SupervisorObjectType ={ + name:body.name, + email:body.email, + password: body.password, + phone: Number(body.phone), + gender: body.gender, + profile_picture:"" + } + const supervisor = await SupervisorServices.createSupervisor( - body, + supervisorData, profilePictureFileId ) await sendVerificationMail(supervisor.email, supervisor._id, supervisor.name) diff --git a/src/APIs/routes/Supervisor.route.ts b/src/APIs/routes/Supervisor.route.ts index 9cb2a4d..1f80fc1 100644 --- a/src/APIs/routes/Supervisor.route.ts +++ b/src/APIs/routes/Supervisor.route.ts @@ -51,7 +51,7 @@ router.post( uploadPhotosMiddleware, SupervisorValidator.validateSupervisorCreation, (req: Request, res: Response, next: NextFunction) => - handler({ req, res, next, fn: SupervisorController.supervisiorSignUp }) + handler({ req, res, next, fn: SupervisorController.supervisorSignUp }) ) router.put( From fd3e5de553a2c08c7516bfdc1081db1b1dbb0a8d Mon Sep 17 00:00:00 2001 From: Alaa Date: Sun, 17 Jul 2022 02:30:43 +0200 Subject: [PATCH 17/33] updating environment --- .env | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.env b/.env index e7432f4..6d57e2c 100644 --- a/.env +++ b/.env @@ -1,3 +1,4 @@ DB="mongodb+srv://wheeler:1234@backend-cluster.qrm0u.mongodb.net/test" HOST=localhost -PORT=8080 \ No newline at end of file +PORT=80 +JWT_SECRET=My_SECRET \ No newline at end of file From 64382d9fae87d2d8c27adf4e91595768ba5fab3c Mon Sep 17 00:00:00 2001 From: Alaa Date: Sun, 17 Jul 2022 14:38:25 +0200 Subject: [PATCH 18/33] updating patients routes --- src/APIs/routes/PatientRoutes.route.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/APIs/routes/PatientRoutes.route.ts b/src/APIs/routes/PatientRoutes.route.ts index ebc9dad..7aa6480 100644 --- a/src/APIs/routes/PatientRoutes.route.ts +++ b/src/APIs/routes/PatientRoutes.route.ts @@ -21,7 +21,7 @@ router.get( ) router.get( - '/:id', + '/supervisor/:id', validateSupervisorId, checkAuthentication, (req: Request, res: Response, next: NextFunction) => { @@ -35,7 +35,7 @@ router.get( ) router.get( - '/:id', + '/patient/:id', validatePatientId, checkAuthentication, (req: Request, res: Response, next: NextFunction) => { @@ -53,7 +53,7 @@ router.get( ) router.post( - '/', + '/signup', uploadPhotosMiddleware, validatePatientCreation, (req: Request, res: Response, next: NextFunction) => { From bc831d410ce481dd833bc7a8318023e7c4e9503f Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Fri, 1 Jul 2022 22:38:51 +0200 Subject: [PATCH 19/33] add notification token on sign up --- src/APIs/controllers/Patient.controller.ts | 40 +++++++++--- src/APIs/controllers/Supervisor.controller.ts | 3 +- src/APIs/schema/Patient.schema.ts | 3 +- src/APIs/schema/Supervisior.schema.ts | 3 +- src/APIs/types/Patient.type.ts | 62 ++++++++++--------- src/APIs/types/Supervisor.type.ts | 1 + 6 files changed, 70 insertions(+), 42 deletions(-) diff --git a/src/APIs/controllers/Patient.controller.ts b/src/APIs/controllers/Patient.controller.ts index 048371e..97058c3 100644 --- a/src/APIs/controllers/Patient.controller.ts +++ b/src/APIs/controllers/Patient.controller.ts @@ -2,10 +2,15 @@ import * as PatientsServices from '../services/Patient.services' import { CreatePatientObjectType } from '../types/Patient.type' import { RequestHandler } from 'express' import mongoose from 'mongoose' +import { sendVerificationMail } from '../services/VerificationMail.services' -export const getAllPatientsBySupervisorId: RequestHandler = async ({ params }) => { +export const getAllPatientsBySupervisorId: RequestHandler = async ({ + params +}) => { const supervisorId = new mongoose.Types.ObjectId(params.id) - const response = await PatientsServices.getAllPatientsBySupervisorId(supervisorId) + const response = await PatientsServices.getAllPatientsBySupervisorId( + supervisorId + ) return { response: response, @@ -44,16 +49,26 @@ export const createPatient: RequestHandler = async ({ body, file }) => { gender: body.gender, height: Number(body.height), weight: Number(body.weight), - smoking: Boolean(body.smoking) + smoking: Boolean(body.smoking), + notificatio_token: body.notificatio_token } // @ts-ignore const profilePictureFileId = file.id === undefined ? '' : file.id - const response = await PatientsServices.createPatient(patientInfo, profilePictureFileId) + const response = await PatientsServices.createPatient( + patientInfo, + profilePictureFileId + ) + + await sendVerificationMail( + response?.email as string, + response?._id as mongoose.Types.ObjectId, + response?.name + ) return { response: response, - message: 'Patient created successfully' + message: 'Patient created successfully, and Verification Mail has been sent' } } @@ -69,7 +84,7 @@ export const deletePatient: RequestHandler = async ({ params }) => { export const updatePatient: RequestHandler = async ({ body, params }) => { const patientId = new mongoose.Types.ObjectId(params.id) - const updatePatientInput : CreatePatientObjectType = { + const updatePatientInput: CreatePatientObjectType = { patient_name: body.patient_name, email: body.email, address: body.address, @@ -84,11 +99,15 @@ export const updatePatient: RequestHandler = async ({ body, params }) => { profile_picture: body.profile_picture } - const response = await PatientsServices.updatePatient(patientId, updatePatientInput) + const response = await PatientsServices.updatePatient( + patientId, + updatePatientInput + ) return { response: response, - message: 'Patient updated successfully' + message: + 'Patient updated successfully' } } @@ -120,7 +139,10 @@ export const uploadMedicalRecord: RequestHandler = async ({ params, file }) => { } // @ts-ignore fileMedicalRecord = file.id - const response = await PatientsServices.uploadMedicalRecord(patientId, fileMedicalRecord) + const response = await PatientsServices.uploadMedicalRecord( + patientId, + fileMedicalRecord + ) return { response, diff --git a/src/APIs/controllers/Supervisor.controller.ts b/src/APIs/controllers/Supervisor.controller.ts index 7e93e89..1aefdec 100644 --- a/src/APIs/controllers/Supervisor.controller.ts +++ b/src/APIs/controllers/Supervisor.controller.ts @@ -30,7 +30,8 @@ export const supervisorSignUp: RequestHandler = async ({ body, file }) => { return { response: supervisor, - message: 'Successfully Registered' + message: + 'Supervisor created successfully, and Verification Mail has been sent' } } diff --git a/src/APIs/schema/Patient.schema.ts b/src/APIs/schema/Patient.schema.ts index 2b1eef6..3a5b180 100644 --- a/src/APIs/schema/Patient.schema.ts +++ b/src/APIs/schema/Patient.schema.ts @@ -62,7 +62,8 @@ const PatientSchema = new Schema({ profile_picture: { type: String }, - medical_history: [{ type: String }] + medical_history: [{ type: String }], + notificatio_token: { type: String } }) const Patient = model('Patient', PatientSchema) diff --git a/src/APIs/schema/Supervisior.schema.ts b/src/APIs/schema/Supervisior.schema.ts index e1b54b6..ac0153e 100644 --- a/src/APIs/schema/Supervisior.schema.ts +++ b/src/APIs/schema/Supervisior.schema.ts @@ -36,7 +36,8 @@ const SupervisiorSchema = new mongoose.Schema( isVerified: { type: Boolean, default: false - } + }, + notificatio_token: { type: String } }, { timestamps: { diff --git a/src/APIs/types/Patient.type.ts b/src/APIs/types/Patient.type.ts index 4add13b..89ff1c4 100644 --- a/src/APIs/types/Patient.type.ts +++ b/src/APIs/types/Patient.type.ts @@ -1,35 +1,37 @@ import mongoose from 'mongoose' -export interface IPatientModel{ - name: string - email: string - password: string - phone: number - emergency_number: number - address: string - gender: string - weight?: number - height?: number - dob: Date - smoking?: boolean - chair_serial_id?: string - supervisors? : [mongoose.Types.ObjectId], - profile_picture?: string - medical_history:[string], - isVerified:Boolean +export interface IPatientModel { + name: string; + email: string; + password: string; + phone: number; + emergency_number: number; + address: string; + gender: string; + weight?: number; + height?: number; + dob: Date; + smoking?: boolean; + chair_serial_id?: string; + supervisors?: [mongoose.Types.ObjectId]; + profile_picture?: string; + medical_history: [string]; + isVerified: Boolean; + notificatio_token: string; } export type CreatePatientObjectType = { - patient_name:string - email:string - password:string - phone:number - emergency_number:number - address:string - gender: string - weight:number - height:number - dob:Date - smoking:boolean, - profile_picture?:string -} + patient_name: string; + email: string; + password: string; + phone: number; + emergency_number: number; + address: string; + gender: string; + weight: number; + height: number; + dob: Date; + smoking: boolean; + profile_picture?: string; + notificatio_token?: string +}; diff --git a/src/APIs/types/Supervisor.type.ts b/src/APIs/types/Supervisor.type.ts index 0c20d58..dae613d 100644 --- a/src/APIs/types/Supervisor.type.ts +++ b/src/APIs/types/Supervisor.type.ts @@ -5,4 +5,5 @@ export type SupervisorObjectType = { phone: number; gender: string; profile_picture: string; + notificatio_token: string; }; From 3e13f6f9c870e48e8a5b7bee504c96190408cd7c Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Fri, 1 Jul 2022 23:18:32 +0200 Subject: [PATCH 20/33] get all patient associated with supervisor with its id --- src/APIs/models/Patient.model.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/APIs/models/Patient.model.ts b/src/APIs/models/Patient.model.ts index 9836f57..2f291d4 100644 --- a/src/APIs/models/Patient.model.ts +++ b/src/APIs/models/Patient.model.ts @@ -10,13 +10,20 @@ import mongoose from 'mongoose' */ export const getAllPatientsBySupervisorId = async ( supervisorId: mongoose.Types.ObjectId -) => {} +) => { + const patients = await Patient.find({ + supervisors: supervisorId + }) + + return patients +} /** * * @param * @returns all patients data */ + export const getAllPatients = async () => { const patients = await Patient.find() @@ -141,6 +148,7 @@ export const updateVerificationStatus = async ( return patient } + /** * * @param patientId From e65a0e54768cfc59034a7df7e6fbf03cef489305 Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Sat, 2 Jul 2022 13:26:23 +0200 Subject: [PATCH 21/33] associated users edit --- src/APIs/controllers/Patient.controller.ts | 2 +- src/APIs/controllers/Supervisor.controller.ts | 11 ++++++----- src/APIs/models/Patient.model.ts | 4 ++-- src/APIs/models/Supervisor.model.ts | 2 +- src/APIs/schema/Patient.schema.ts | 4 ++-- src/APIs/schema/Supervisior.schema.ts | 4 ++-- src/APIs/types/Patient.type.ts | 6 +++--- src/APIs/types/Supervisor.type.ts | 2 +- 8 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/APIs/controllers/Patient.controller.ts b/src/APIs/controllers/Patient.controller.ts index 97058c3..3b98ba1 100644 --- a/src/APIs/controllers/Patient.controller.ts +++ b/src/APIs/controllers/Patient.controller.ts @@ -50,7 +50,7 @@ export const createPatient: RequestHandler = async ({ body, file }) => { height: Number(body.height), weight: Number(body.weight), smoking: Boolean(body.smoking), - notificatio_token: body.notificatio_token + notification_token: body.notification_token } // @ts-ignore diff --git a/src/APIs/controllers/Supervisor.controller.ts b/src/APIs/controllers/Supervisor.controller.ts index 1aefdec..b83f971 100644 --- a/src/APIs/controllers/Supervisor.controller.ts +++ b/src/APIs/controllers/Supervisor.controller.ts @@ -12,14 +12,15 @@ export const supervisorSignUp: RequestHandler = async ({ body, file }) => { } // @ts-ignore profilePictureFileId = file.id - - const supervisorData : SupervisorObjectType ={ - name:body.name, - email:body.email, + + const supervisorData : SupervisorObjectType = { + name: body.name, + email: body.email, password: body.password, phone: Number(body.phone), gender: body.gender, - profile_picture:"" + profile_picture: '', + notification_token: body.notification_token } const supervisor = await SupervisorServices.createSupervisor( diff --git a/src/APIs/models/Patient.model.ts b/src/APIs/models/Patient.model.ts index 2f291d4..f73c999 100644 --- a/src/APIs/models/Patient.model.ts +++ b/src/APIs/models/Patient.model.ts @@ -124,8 +124,8 @@ export const linkSupervisor = async ( const patient = await Patient.findById( new mongoose.Types.ObjectId(patientID) ) - if (patient?.supervisors) { - patient.supervisors.push(supervisorID) + if (patient?.associated_users) { + patient.associated_users.push(supervisorID) const res = await patient.save() return res diff --git a/src/APIs/models/Supervisor.model.ts b/src/APIs/models/Supervisor.model.ts index b859406..b12b122 100644 --- a/src/APIs/models/Supervisor.model.ts +++ b/src/APIs/models/Supervisor.model.ts @@ -63,7 +63,7 @@ export const linkPatient = async ( new mongoose.Types.ObjectId(supervisorID) ) - supervisor.associated_patients.push(patientID) + supervisor.associated_users.push(patientID) const res = await supervisor.save() return res diff --git a/src/APIs/schema/Patient.schema.ts b/src/APIs/schema/Patient.schema.ts index 3a5b180..fdbbfde 100644 --- a/src/APIs/schema/Patient.schema.ts +++ b/src/APIs/schema/Patient.schema.ts @@ -55,7 +55,7 @@ const PatientSchema = new Schema({ chair_serial_id: { type: String }, - supervisors: { + associated_users: { type: [{ type: mongoose.Types.ObjectId, ref: 'Supervisor', default: [] }], default: [] }, @@ -63,7 +63,7 @@ const PatientSchema = new Schema({ type: String }, medical_history: [{ type: String }], - notificatio_token: { type: String } + notification_token: { type: String } }) const Patient = model('Patient', PatientSchema) diff --git a/src/APIs/schema/Supervisior.schema.ts b/src/APIs/schema/Supervisior.schema.ts index ac0153e..204bec8 100644 --- a/src/APIs/schema/Supervisior.schema.ts +++ b/src/APIs/schema/Supervisior.schema.ts @@ -29,7 +29,7 @@ const SupervisiorSchema = new mongoose.Schema( profile_picture: { type: String }, - associated_patients: { + associated_users: { type: [{ type: mongoose.Types.ObjectId, ref: 'Patient' }], default: [] }, @@ -37,7 +37,7 @@ const SupervisiorSchema = new mongoose.Schema( type: Boolean, default: false }, - notificatio_token: { type: String } + notification_token: { type: String } }, { timestamps: { diff --git a/src/APIs/types/Patient.type.ts b/src/APIs/types/Patient.type.ts index 89ff1c4..935653a 100644 --- a/src/APIs/types/Patient.type.ts +++ b/src/APIs/types/Patient.type.ts @@ -13,11 +13,11 @@ export interface IPatientModel { dob: Date; smoking?: boolean; chair_serial_id?: string; - supervisors?: [mongoose.Types.ObjectId]; + associated_users?: [mongoose.Types.ObjectId]; profile_picture?: string; medical_history: [string]; isVerified: Boolean; - notificatio_token: string; + notification_token: string; } export type CreatePatientObjectType = { @@ -33,5 +33,5 @@ export type CreatePatientObjectType = { dob: Date; smoking: boolean; profile_picture?: string; - notificatio_token?: string + notification_token?: string }; diff --git a/src/APIs/types/Supervisor.type.ts b/src/APIs/types/Supervisor.type.ts index dae613d..43ccb3b 100644 --- a/src/APIs/types/Supervisor.type.ts +++ b/src/APIs/types/Supervisor.type.ts @@ -5,5 +5,5 @@ export type SupervisorObjectType = { phone: number; gender: string; profile_picture: string; - notificatio_token: string; + notification_token: string; }; From c9fc187015e1b76dff6a06db1a4eb978e8339da3 Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Sat, 2 Jul 2022 13:29:38 +0200 Subject: [PATCH 22/33] heroku --- Procfile | 1 + package.json | 4 ++++ tsconfig.json | 12 ++++++------ 3 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 Procfile diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..64631a4 --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: node ./build/app.js \ No newline at end of file diff --git a/package.json b/package.json index 72bd6e6..1d85a8a 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,10 @@ "version": "1.0.0", "description": "Software Backend", "main": "index.js", + "engines": { + "node": "16.xx", + "npm": "8.xx" + }, "scripts": { "start": "nodemon ./src/app.ts", "test": "jest --runInBand --detectOpenHandles --forceExit" diff --git a/tsconfig.json b/tsconfig.json index 857c428..44454e9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,7 +12,7 @@ /* Language and Environment */ "esModuleInterop": true, - "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ @@ -25,7 +25,7 @@ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ /* Modules */ - "module": "commonjs", /* Specify what module code is generated. */ + "module": "commonjs" /* Specify what module code is generated. */, // "rootDir": "./", /* Specify the root folder within your source files. */ // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ @@ -48,7 +48,7 @@ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ - // "outDir": "./", /* Specify an output folder for all emitted files. */ + "outDir": "./build" /* Specify an output folder for all emitted files. */, // "removeComments": true, /* Disable emitting comments. */ // "noEmit": true, /* Disable emitting files from a compilation. */ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ @@ -71,10 +71,10 @@ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, /* Type Checking */ - "strict": true, /* Enable all strict type-checking options. */ + "strict": true /* Enable all strict type-checking options. */, // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ @@ -96,6 +96,6 @@ /* Completeness */ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ } } From 8b71aeb537a1baeb83268a34404629f0749d350d Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Sat, 2 Jul 2022 13:32:11 +0200 Subject: [PATCH 23/33] remove node version --- package.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/package.json b/package.json index 1d85a8a..4c2dad8 100644 --- a/package.json +++ b/package.json @@ -3,10 +3,7 @@ "version": "1.0.0", "description": "Software Backend", "main": "index.js", - "engines": { - "node": "16.xx", - "npm": "8.xx" - }, + "scripts": { "start": "nodemon ./src/app.ts", "test": "jest --runInBand --detectOpenHandles --forceExit" From a9a421fabc5073181439258ef7621c07a8c845db Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Sat, 2 Jul 2022 18:39:54 +0200 Subject: [PATCH 24/33] notification pushing --- package-lock.json | 26 +++++++++++ package.json | 2 +- .../controllers/Notifications.controller.ts | 9 ++++ src/APIs/controllers/Patient.controller.ts | 2 +- src/APIs/models/Invitations.model.ts | 2 +- src/APIs/routes/Notifications.route.ts | 9 +++- src/APIs/services/Login.services.ts | 29 +++++++++++- src/APIs/services/Notifications.services.ts | 44 ++++++++++++++++++- .../services/VerificationMail.services.ts | 2 +- src/APIs/types/Patient.type.ts | 1 + 10 files changed, 118 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 45e8565..7dabdc7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1905,6 +1905,27 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, + "axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "requires": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + }, + "dependencies": { + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } + } + }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", @@ -3763,6 +3784,11 @@ "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", "dev": true }, + "follow-redirects": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", + "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==" + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", diff --git a/package.json b/package.json index 4c2dad8..34089e0 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,6 @@ "version": "1.0.0", "description": "Software Backend", "main": "index.js", - "scripts": { "start": "nodemon ./src/app.ts", "test": "jest --runInBand --detectOpenHandles --forceExit" @@ -41,6 +40,7 @@ "@typescript-eslint/eslint-plugin": "^5.29.0", "@typescript-eslint/parser": "^5.29.0", "aws-sdk": "^2.1162.0", + "axios": "^0.27.2", "bcryptjs": "^2.4.3", "config": "^3.3.7", "cors": "^2.8.5", diff --git a/src/APIs/controllers/Notifications.controller.ts b/src/APIs/controllers/Notifications.controller.ts index ee6a8d9..5883c58 100644 --- a/src/APIs/controllers/Notifications.controller.ts +++ b/src/APIs/controllers/Notifications.controller.ts @@ -40,3 +40,12 @@ export const editNotification: RequestHandler = async ({ body, params }) => { message: 'Notification has been edited successfully' } } + +export const pushNotification: RequestHandler = async ({ body }) => { + const response = await NotificationServices.push(body) + + return { + response: response, + message: 'Notification has been pushed successfully' + } +} diff --git a/src/APIs/controllers/Patient.controller.ts b/src/APIs/controllers/Patient.controller.ts index 3b98ba1..62c94a2 100644 --- a/src/APIs/controllers/Patient.controller.ts +++ b/src/APIs/controllers/Patient.controller.ts @@ -54,7 +54,7 @@ export const createPatient: RequestHandler = async ({ body, file }) => { } // @ts-ignore - const profilePictureFileId = file.id === undefined ? '' : file.id + const profilePictureFileId = file === undefined ? '' : file.id const response = await PatientsServices.createPatient( patientInfo, profilePictureFileId diff --git a/src/APIs/models/Invitations.model.ts b/src/APIs/models/Invitations.model.ts index 74044b7..78b87f5 100644 --- a/src/APIs/models/Invitations.model.ts +++ b/src/APIs/models/Invitations.model.ts @@ -50,7 +50,7 @@ export const getPatientInvitations = async (patientID: string) => { export const getSupervisorInvitations = async (supervisorID: string) => { const invitations = await Invitations.find({ - from_id: new mongoose.Types.ObjectId(supervisorID) + to_id: new mongoose.Types.ObjectId(supervisorID) }) return invitations diff --git a/src/APIs/routes/Notifications.route.ts b/src/APIs/routes/Notifications.route.ts index 49539ed..f9482d5 100644 --- a/src/APIs/routes/Notifications.route.ts +++ b/src/APIs/routes/Notifications.route.ts @@ -36,12 +36,19 @@ router.put( handler({ req, res, next, fn: NotificationsController.editNotification }) ) +router.post( + '/push', + checkAuthentication, + (req: Request, res: Response, next: NextFunction) => + handler({ req, res, next, fn: NotificationsController.delteNotification }) +) + router.delete( '/:id', NotificationsValidator.validateNotificationID, checkAuthentication, (req: Request, res: Response, next: NextFunction) => - handler({ req, res, next, fn: NotificationsController.delteNotification }) + handler({ req, res, next, fn: NotificationsController.pushNotification }) ) export default router diff --git a/src/APIs/services/Login.services.ts b/src/APIs/services/Login.services.ts index 08be49a..10eec45 100644 --- a/src/APIs/services/Login.services.ts +++ b/src/APIs/services/Login.services.ts @@ -2,8 +2,9 @@ import * as PatientModel from '../models/Patient.model' import * as ResetPasswordTokenModel from '../models/ResetPasswordTokens.model' import * as SupervisorModel from '../models/Supervisor.model' import * as jwt from 'jsonwebtoken' -import { MailObject } from '../types/sendingMail.types' +import { IPatientModel } from '../types/Patient.type' import { USER_ROLES } from '../types/User.types' +import { MailObject } from '../types/sendingMail.types' import { UnprocessableError } from '../types/general.types' import bcrypt from 'bcryptjs' import crypto from 'crypto' @@ -33,10 +34,36 @@ export const login = async (email: string, password: string, role: string) => { if (!validPass) { throw new UnprocessableError('Password is invalid') } + const token = generateToken(user._id, email, password) + const associatedUsers: any = [] + + switch (role) { + case USER_ROLES.PATIENT: + await Promise.all( + user.associated_users.map(async (user: mongoose.Types.ObjectId) => { + const { name, address, profile_picture, _id } = + await SupervisorModel.getSupervisorById(user) + associatedUsers.push({ name, address, profile_picture, _id }) + }) + ) + break + case USER_ROLES.SUPERVISOR: + await Promise.all( + user.associated_users.map(async (user: mongoose.Types.ObjectId) => { + const { name, address, profile_picture, _id } = + (await PatientModel.getPatient(user)) as IPatientModel + associatedUsers.push({ name, address, profile_picture, _id }) + }) + ) + break + default: + break + } return { ...user._doc, + associatedUsers, token: token } } diff --git a/src/APIs/services/Notifications.services.ts b/src/APIs/services/Notifications.services.ts index f242431..c6dc310 100644 --- a/src/APIs/services/Notifications.services.ts +++ b/src/APIs/services/Notifications.services.ts @@ -1,6 +1,10 @@ import * as NotificationModel from '../models/Notifications.model' import { NotificationObjectType } from '../types/Notifications.type' +import { USER_ROLES } from '../types/User.types' import { UnprocessableError } from '../types/general.types' +import { UserVariations } from './VerificationMail.services' +import mongoose from 'mongoose' +import axios from 'axios' export const createNotification = ( notificationObject: NotificationObjectType @@ -21,11 +25,47 @@ export const getUserNotifications = (id: string) => { return response } -export const editNotification = async (notificationID: string, newNotificationObject: NotificationObjectType) => { - const newNotitication = await NotificationModel.editNotification(notificationID, newNotificationObject) +export const editNotification = async ( + notificationID: string, + newNotificationObject: NotificationObjectType +) => { + const newNotitication = await NotificationModel.editNotification( + notificationID, + newNotificationObject + ) if (!newNotitication) { throw new UnprocessableError('Notification not found') } return newNotitication } + +export const push = async ({ + body, + title, + _id, + userRole +}: { + body: string; + title: string; + _id: string; + userRole: USER_ROLES; +}) => { + const { notification_token } = await UserVariations( + new mongoose.Types.ObjectId(_id), + userRole, + 'get' + ) + + if (!notification_token) { + throw new UnprocessableError('User doesn\'t have a notification token ') + } + + const res = await axios.post('https://exp.host/--/api/v2/push/send', { + to: notification_token, + title: title, + body: body + }) + + return res +} diff --git a/src/APIs/services/VerificationMail.services.ts b/src/APIs/services/VerificationMail.services.ts index dfa0323..e237857 100644 --- a/src/APIs/services/VerificationMail.services.ts +++ b/src/APIs/services/VerificationMail.services.ts @@ -59,7 +59,7 @@ export const verifyMail = async ( return updatedUser } -const UserVariations = async ( +export const UserVariations = async ( id: mongoose.Types.ObjectId, userType: USER_ROLES, ToDo: 'get' | 'update' diff --git a/src/APIs/types/Patient.type.ts b/src/APIs/types/Patient.type.ts index 935653a..caf78f9 100644 --- a/src/APIs/types/Patient.type.ts +++ b/src/APIs/types/Patient.type.ts @@ -1,6 +1,7 @@ import mongoose from 'mongoose' export interface IPatientModel { + _id?: mongoose.Types.ObjectId, name: string; email: string; password: string; From be2b71d71732a01baac9ebf6ecade8ab446e229d Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Mon, 11 Jul 2022 16:12:23 +0200 Subject: [PATCH 25/33] Include from and to names => Reminders --- src/APIs/services/Notifications.services.ts | 2 +- src/APIs/services/Reminders.services.ts | 60 +++++++++++++++---- .../services/VerificationMail.services.ts | 1 - 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/APIs/services/Notifications.services.ts b/src/APIs/services/Notifications.services.ts index c6dc310..01f97f4 100644 --- a/src/APIs/services/Notifications.services.ts +++ b/src/APIs/services/Notifications.services.ts @@ -3,8 +3,8 @@ import { NotificationObjectType } from '../types/Notifications.type' import { USER_ROLES } from '../types/User.types' import { UnprocessableError } from '../types/general.types' import { UserVariations } from './VerificationMail.services' -import mongoose from 'mongoose' import axios from 'axios' +import mongoose from 'mongoose' export const createNotification = ( notificationObject: NotificationObjectType diff --git a/src/APIs/services/Reminders.services.ts b/src/APIs/services/Reminders.services.ts index aea8e3f..ee25a84 100644 --- a/src/APIs/services/Reminders.services.ts +++ b/src/APIs/services/Reminders.services.ts @@ -1,27 +1,44 @@ import * as RemindersModel from '../models/Reminder.model' -import { CreateReminderObjectType, UpdateReminderObjectType } from '../types/Reminder.type' +import { + CreateReminderObjectType, + UpdateReminderObjectType +} from '../types/Reminder.type' import { UnprocessableError } from '../types/general.types' +import { getPatient } from '../models/Patient.model' +import { getSupervisorById } from '../models/Supervisor.model' import mongoose from 'mongoose' -export const getAllRemindersByPatientId = (patientId: mongoose.Types.ObjectId) => { - const reminders = RemindersModel.getAllRemindersByPatientId(patientId) +export const getAllRemindersByPatientId = async ( + patientId: mongoose.Types.ObjectId +) => { + const reminders = await RemindersModel.getAllRemindersByPatientId(patientId) if (!reminders) { throw new UnprocessableError('Could not fetch reminders using patientId') } - return reminders + const AllReminders = await getReminderUserNames(reminders as []) + + return AllReminders } -export const getAllRemindersBySupervisorId = (supervisorId: mongoose.Types.ObjectId) => { - const reminders = RemindersModel.getAllRemindersBySupervisorId(supervisorId) +export const getAllRemindersBySupervisorId = async ( + supervisorId: mongoose.Types.ObjectId +) => { + const reminders = await RemindersModel.getAllRemindersBySupervisorId( + supervisorId + ) if (!reminders) { - throw new UnprocessableError('Could not fetch reminders using supervisorId') + throw new UnprocessableError( + 'Could not fetch reminders using supervisorId' + ) } - return reminders + const AllReminders = await getReminderUserNames(reminders as []) + + return AllReminders } -export const getReminder = (reminderId:mongoose.Types.ObjectId) => { +export const getReminder = (reminderId: mongoose.Types.ObjectId) => { const reminder = RemindersModel.getReminder(reminderId) if (!reminder) { throw new UnprocessableError('Could not fetch reminder') @@ -43,7 +60,9 @@ export const deleteReminder = (reminderId: mongoose.Types.ObjectId) => { return reminder } -export const updateReminder = (reminderUpdateInput: UpdateReminderObjectType) => { +export const updateReminder = ( + reminderUpdateInput: UpdateReminderObjectType +) => { const reminder = RemindersModel.updateReminder(reminderUpdateInput) if (!reminder) { throw new UnprocessableError('Could not update reminder') @@ -51,3 +70,24 @@ export const updateReminder = (reminderUpdateInput: UpdateReminderObjectType) => return reminder } + +const getReminderUserNames = async (reminders: []) => { + const AllReminders: any = [] + await Promise.all( + reminders.map(async (reminder) => { + const { patient_id, supervisor_id } = reminder + const patient = await getPatient(new mongoose.Types.ObjectId(patient_id)) + const supervisor = await getSupervisorById( + new mongoose.Types.ObjectId(supervisor_id) + ) + + AllReminders.push({ + reminder, + patientName: patient?.name, + supervisorName: supervisor.name + }) + }) + ) + + return AllReminders +} diff --git a/src/APIs/services/VerificationMail.services.ts b/src/APIs/services/VerificationMail.services.ts index e237857..a9826b8 100644 --- a/src/APIs/services/VerificationMail.services.ts +++ b/src/APIs/services/VerificationMail.services.ts @@ -103,7 +103,6 @@ export const resendVerificationMail = async ( } const newToken = await generateToken(id, email) - console.log(newToken) const data = await sendMail({ userMail: [email], From 1952a94a4a49c5c13947461722a9c702903d3af1 Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Mon, 11 Jul 2022 16:18:39 +0200 Subject: [PATCH 26/33] fix note type typo --- src/APIs/models/Note.model.ts | 6 +----- src/APIs/types/Note.type.ts | 2 +- test/services/NoteService.test.ts | 2 +- test/utilities/seed.ts | 6 +++--- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/APIs/models/Note.model.ts b/src/APIs/models/Note.model.ts index ac3b0d0..5ddd7c4 100644 --- a/src/APIs/models/Note.model.ts +++ b/src/APIs/models/Note.model.ts @@ -30,11 +30,7 @@ export const getNote = async (noteId: mongoose.Types.ObjectId) => { * @returns id of the newly created input */ export const createNote = async (noteInput: CreateNoteObjectType) => { - const response = await Note.create({ - user_id: new mongoose.Types.ObjectId(noteInput.userId), - title: noteInput.title, - description: noteInput.description - }) + const response = await Note.create(noteInput) return response } diff --git a/src/APIs/types/Note.type.ts b/src/APIs/types/Note.type.ts index 90e80b8..db77403 100644 --- a/src/APIs/types/Note.type.ts +++ b/src/APIs/types/Note.type.ts @@ -10,7 +10,7 @@ export interface INoteModel { } export type CreateNoteObjectType = { - userId: string + user_id: string title:string description: string } diff --git a/test/services/NoteService.test.ts b/test/services/NoteService.test.ts index eb88a17..fd52c61 100644 --- a/test/services/NoteService.test.ts +++ b/test/services/NoteService.test.ts @@ -27,7 +27,7 @@ describe('Testing Note Service', () => { test('Create note', async () => { const noteInput:CreateNoteObjectType = { - userId: '6263ce0577164ec6745e3bd7', + user_id: '6263ce0577164ec6745e3bd7', title: 'Hello', description: 'world!' } diff --git a/test/utilities/seed.ts b/test/utilities/seed.ts index 0efb81e..bb005c7 100644 --- a/test/utilities/seed.ts +++ b/test/utilities/seed.ts @@ -4,17 +4,17 @@ import * as ReminderModel from '../../src/APIs/models/Reminder.model' import { CreateNoteObjectType } from '../../src/APIs/types/Note.type' import { CreatePatientObjectType } from '../../src/APIs/types/Patient.type' import { CreateReminderObjectType } from '../../src/APIs/types/Reminder.type' -import mongoose from 'mongoose' import { UnprocessableError } from '../../src/APIs/types/general.types' +import mongoose from 'mongoose' export const createNote = async ():Promise => { const note:CreateNoteObjectType = { - userId: '6263ce0577164ec6745e3bd7', + user_id: '6263ce0577164ec6745e3bd7', title: 'Hello', description: 'world!' } const note2:CreateNoteObjectType = { - userId: '6263ce0577164ec6745e3bd7', + user_id: '6263ce0577164ec6745e3bd7', title: 'Hello2', description: 'world2!' } From 34c6d2129bf0741280749b2323274c78d9627b68 Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Mon, 11 Jul 2022 18:05:09 +0200 Subject: [PATCH 27/33] get invitation details front wants --- src/APIs/services/Invitations.services.ts | 43 ++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/src/APIs/services/Invitations.services.ts b/src/APIs/services/Invitations.services.ts index 4ff526b..966b900 100644 --- a/src/APIs/services/Invitations.services.ts +++ b/src/APIs/services/Invitations.services.ts @@ -5,8 +5,9 @@ import { } from '../types/Invitation.types' import { USER_ROLES } from '../types/User.types' import { UnprocessableError } from '../types/general.types' -import { linkPatient } from '../models/Supervisor.model' -import { linkSupervisor } from '../models/Patient.model' +import { getSupervisorById, linkPatient } from '../models/Supervisor.model' +import { getPatient, linkSupervisor } from '../models/Patient.model' +import mongoose from 'mongoose' export const sendInvitationService = async ( invitation: CreateInvitationObjectType @@ -39,16 +40,23 @@ export const getInvitation = async (id: string) => InvitationModels.getInvitation(id) export const getInvitations = async (userID: string, userType: USER_ROLES) => { + let invitations = [] switch (userType) { case USER_ROLES.PATIENT: - return await InvitationModels.getPatientInvitations(userID) + invitations = await InvitationModels.getPatientInvitations(userID) + break case USER_ROLES.SUPERVISOR: - return await InvitationModels.getSupervisorInvitations(userID) + invitations = await InvitationModels.getSupervisorInvitations(userID) + break default: throw new UnprocessableError('User type doesn\'t exist') } + + const AllInvitations = await getInvitationDetails(invitations as []) + + console.log(AllInvitations) } export const acceptInvitation = async (inivitationID: string) => { @@ -77,3 +85,30 @@ export const rejectInvitation = async (inivitationID: string) => { return response } + +const getInvitationDetails = async (invitations: []) => { + const AllInvitations: any = [] + await Promise.all( + invitations.map(async (invitation) => { + const { from_id, to_id } = invitation + const patient = await getPatient(new mongoose.Types.ObjectId(from_id)) + const supervisor = await getSupervisorById( + new mongoose.Types.ObjectId(to_id) + ) + + AllInvitations.push({ + invitation, + patient: { + name: patient?.name, + photo: patient?.profile_picture, + gender: patient?.gender, + birthDate: patient?.dob + }, + supervisorName: supervisor.name, + supervisorPhoto: supervisor.profile_picture + }) + }) + ) + + return AllInvitations +} From a7c1f25ac925866e58d121b67e33ae3ef502a086 Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Mon, 11 Jul 2022 21:08:23 +0200 Subject: [PATCH 28/33] push notifications to user on creation --- src/APIs/services/Notifications.services.ts | 15 +++++++++++++-- src/APIs/types/Notifications.type.ts | 2 ++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/APIs/services/Notifications.services.ts b/src/APIs/services/Notifications.services.ts index 01f97f4..fce0d45 100644 --- a/src/APIs/services/Notifications.services.ts +++ b/src/APIs/services/Notifications.services.ts @@ -6,9 +6,20 @@ import { UserVariations } from './VerificationMail.services' import axios from 'axios' import mongoose from 'mongoose' -export const createNotification = ( +export const createNotification = async ( notificationObject: NotificationObjectType -) => NotificationModel.createNotification(notificationObject) +) => { + const res = await NotificationModel.createNotification(notificationObject) + const { description, title, user_id, userRole } = notificationObject + await push({ + body: description, + title, + _id: user_id.toString(), + userRole + }) + + return res +} export const deleteNotification = async (id: string) => { const response = await NotificationModel.deleteNotification(id) diff --git a/src/APIs/types/Notifications.type.ts b/src/APIs/types/Notifications.type.ts index f9a4fdb..a41d67e 100644 --- a/src/APIs/types/Notifications.type.ts +++ b/src/APIs/types/Notifications.type.ts @@ -1,3 +1,4 @@ +import { USER_ROLES } from './User.types' import mongoose from 'mongoose' export interface NotificationObjectType { @@ -7,4 +8,5 @@ export interface NotificationObjectType { description: string; isRead: boolean; type: string; + userRole: USER_ROLES } From e81b61c64297eb4206aeabbdcd268c08c275204c Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Tue, 12 Jul 2022 17:22:39 +0200 Subject: [PATCH 29/33] verify mail and sending mail get url from front + notification issue --- src/APIs/controllers/Patient.controller.ts | 9 +++++---- src/APIs/controllers/Supervisor.controller.ts | 7 ++++++- src/APIs/controllers/Users.controller.ts | 3 ++- src/APIs/models/Patient.model.ts | 3 ++- .../HelperFunctions/generateMailTempelate.ts | 4 ++-- src/APIs/services/Patient.services.ts | 17 ++++++++++++----- src/APIs/services/VerificationMail.services.ts | 15 ++++++++++----- src/APIs/types/Patient.type.ts | 2 +- src/APIs/types/sendingMail.types.ts | 1 + 9 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/APIs/controllers/Patient.controller.ts b/src/APIs/controllers/Patient.controller.ts index 62c94a2..82396c5 100644 --- a/src/APIs/controllers/Patient.controller.ts +++ b/src/APIs/controllers/Patient.controller.ts @@ -63,12 +63,14 @@ export const createPatient: RequestHandler = async ({ body, file }) => { await sendVerificationMail( response?.email as string, response?._id as mongoose.Types.ObjectId, - response?.name + response?.name, + body.url ) return { response: response, - message: 'Patient created successfully, and Verification Mail has been sent' + message: + 'Patient created successfully, and Verification Mail has been sent' } } @@ -106,8 +108,7 @@ export const updatePatient: RequestHandler = async ({ body, params }) => { return { response: response, - message: - 'Patient updated successfully' + message: 'Patient updated successfully' } } diff --git a/src/APIs/controllers/Supervisor.controller.ts b/src/APIs/controllers/Supervisor.controller.ts index b83f971..0aec043 100644 --- a/src/APIs/controllers/Supervisor.controller.ts +++ b/src/APIs/controllers/Supervisor.controller.ts @@ -27,7 +27,12 @@ export const supervisorSignUp: RequestHandler = async ({ body, file }) => { supervisorData, profilePictureFileId ) - await sendVerificationMail(supervisor.email, supervisor._id, supervisor.name) + await sendVerificationMail( + supervisor.email, + supervisor._id, + supervisor.name, + body.url + ) return { response: supervisor, diff --git a/src/APIs/controllers/Users.controller.ts b/src/APIs/controllers/Users.controller.ts index 5ca6c51..cd02f37 100644 --- a/src/APIs/controllers/Users.controller.ts +++ b/src/APIs/controllers/Users.controller.ts @@ -39,7 +39,8 @@ export const resendVerificationMailController: RequestHandler = async ({ const response = await resendVerificationMail( new mongoose.Types.ObjectId(body.user_id), body.email, - body.userName || undefined + body.userName || undefined, + body.url ) return { diff --git a/src/APIs/models/Patient.model.ts b/src/APIs/models/Patient.model.ts index f73c999..35481fc 100644 --- a/src/APIs/models/Patient.model.ts +++ b/src/APIs/models/Patient.model.ts @@ -70,7 +70,8 @@ export const createPatient = async (patientInput: CreatePatientObjectType) => { height: patientInput.height, dob: patientInput.dob, smoking: patientInput.smoking, - profile_picture: patientInput.profile_picture + profile_picture: patientInput.profile_picture, + notification_token: patientInput.notification_token }) return response diff --git a/src/APIs/services/HelperFunctions/generateMailTempelate.ts b/src/APIs/services/HelperFunctions/generateMailTempelate.ts index 3c5d74f..080f844 100644 --- a/src/APIs/services/HelperFunctions/generateMailTempelate.ts +++ b/src/APIs/services/HelperFunctions/generateMailTempelate.ts @@ -1,7 +1,7 @@ import { MailObject } from '../../types/sendingMail.types' const generateMailTempelate = (mailData: MailObject) => { - const { userMail, userName, mailBody, subject } = mailData + const { userMail, userName, mailBody, subject, url } = mailData return { Destination: { @@ -13,7 +13,7 @@ const generateMailTempelate = (mailData: MailObject) => { Body: { Html: { Charset: 'UTF-8', - Data: `

Hello ${userName}

${mailBody}

Best Wishes

Wheel.E Team

` + Data: `

Hello ${userName}

${mailBody}

Open Link

Best Wishes

Wheel.E Team

` }, Text: { Charset: 'UTF-8', diff --git a/src/APIs/services/Patient.services.ts b/src/APIs/services/Patient.services.ts index 9b6d8ad..e530f43 100644 --- a/src/APIs/services/Patient.services.ts +++ b/src/APIs/services/Patient.services.ts @@ -34,14 +34,16 @@ export const getPatient = (patientId: mongoose.Types.ObjectId) => { return patient } -export const getPatientMedicalRecords = async (patientId: mongoose.Types.ObjectId) => { +export const getPatientMedicalRecords = async ( + patientId: mongoose.Types.ObjectId +) => { const patient = await PatientModel.getPatient(patientId) if (!patient) { throw new UnprocessableError('Could not fetch patient') } const { medical_history } = patient - const medicalRecords : string[] = [] + const medicalRecords: string[] = [] for (let i = 0; i < medical_history.length; i++) { const file = await FileModel.getMedicalRecord(medical_history[i]) @@ -91,7 +93,7 @@ export const updatePatient = ( return patient } -export const getPatientProfilePicture = async (patientId:string) => { +export const getPatientProfilePicture = async (patientId: string) => { const patientID = new mongoose.Types.ObjectId(patientId) const patient = await PatientModel.getPatient(patientID) if (!patient) { @@ -112,9 +114,14 @@ export const uploadMedicalRecord = async ( patientId: mongoose.Types.ObjectId, healthRecord: string ) => { - const patient = await PatientModel.uploadMedicalRecord(patientId, healthRecord) + const patient = await PatientModel.uploadMedicalRecord( + patientId, + healthRecord + ) if (!patient) { - throw new UnprocessableError('Could not add medical record to the patient profile') + throw new UnprocessableError( + 'Could not add medical record to the patient profile' + ) } return patient diff --git a/src/APIs/services/VerificationMail.services.ts b/src/APIs/services/VerificationMail.services.ts index a9826b8..5a531d7 100644 --- a/src/APIs/services/VerificationMail.services.ts +++ b/src/APIs/services/VerificationMail.services.ts @@ -24,14 +24,16 @@ const generateToken = async (id: mongoose.Types.ObjectId, email: string) => { export const sendVerificationMail = async ( email: string, id: mongoose.Types.ObjectId, - userName: string | undefined + userName: string | undefined, + url: string ) => { const token = await generateToken(id, email) const data = await sendMail({ userMail: [email], subject: 'Verification Mail', userName: userName || 'My Friend', - mailBody: `Please Open this link to Verify you appliction, ${token}` + mailBody: `Please Open this link to Verify you appliction`, + url: `${url}:${token}` }) return { token, data } @@ -88,7 +90,8 @@ export const UserVariations = async ( export const resendVerificationMail = async ( id: mongoose.Types.ObjectId, email: string, - userName: string | undefined + userName: string | undefined, + url: string ) => { const verificationToken = await VerificationMailModel.findTokenByUserID(id) if (verificationToken) { @@ -96,7 +99,8 @@ export const resendVerificationMail = async ( userMail: [email], subject: 'Verification Mail', userName: userName || 'My Friend', - mailBody: `Please Open this link to Verify you appliction, ${verificationToken}` + mailBody: `Please Open this link to Verify you appliction`, + url: `${url}:${verificationToken}` }) return { verificationToken, data } @@ -108,7 +112,8 @@ export const resendVerificationMail = async ( userMail: [email], subject: 'Verification Mail', userName: userName || 'My Friend', - mailBody: `Please Open this link to Verify you appliction, ${newToken}` + mailBody: `Please Open this link to Verify you appliction`, + url: `${url}:${newToken}` }) return { newToken, data } diff --git a/src/APIs/types/Patient.type.ts b/src/APIs/types/Patient.type.ts index caf78f9..03bae32 100644 --- a/src/APIs/types/Patient.type.ts +++ b/src/APIs/types/Patient.type.ts @@ -34,5 +34,5 @@ export type CreatePatientObjectType = { dob: Date; smoking: boolean; profile_picture?: string; - notification_token?: string + notification_token?: string, }; diff --git a/src/APIs/types/sendingMail.types.ts b/src/APIs/types/sendingMail.types.ts index aa3b7cc..a20d057 100644 --- a/src/APIs/types/sendingMail.types.ts +++ b/src/APIs/types/sendingMail.types.ts @@ -3,4 +3,5 @@ export interface MailObject { mailBody: string; subject: string; userName: string; + url: string, } From 52cde1f84e44d239cee39f4daa40bac9c824f9a8 Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Tue, 12 Jul 2022 18:56:52 +0200 Subject: [PATCH 30/33] fix notification push route --- src/APIs/routes/Notifications.route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/APIs/routes/Notifications.route.ts b/src/APIs/routes/Notifications.route.ts index f9482d5..7a35a5c 100644 --- a/src/APIs/routes/Notifications.route.ts +++ b/src/APIs/routes/Notifications.route.ts @@ -40,7 +40,7 @@ router.post( '/push', checkAuthentication, (req: Request, res: Response, next: NextFunction) => - handler({ req, res, next, fn: NotificationsController.delteNotification }) + handler({ req, res, next, fn: NotificationsController.pushNotification }) ) router.delete( From 68a7e8c011a7dec434c5ef9ad1791af3c0de7ec3 Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Tue, 12 Jul 2022 19:06:23 +0200 Subject: [PATCH 31/33] fix send mail issue --- src/APIs/services/HelperFunctions/generateMailTempelate.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/APIs/services/HelperFunctions/generateMailTempelate.ts b/src/APIs/services/HelperFunctions/generateMailTempelate.ts index 080f844..d1b0a72 100644 --- a/src/APIs/services/HelperFunctions/generateMailTempelate.ts +++ b/src/APIs/services/HelperFunctions/generateMailTempelate.ts @@ -13,7 +13,10 @@ const generateMailTempelate = (mailData: MailObject) => { Body: { Html: { Charset: 'UTF-8', - Data: `

Hello ${userName}

${mailBody}

Open Link

Best Wishes

Wheel.E Team

` + Data: + url === '' + ? `

Hello ${userName}

${mailBody}

Best Wishes

Wheel.E Team

` + : `

Hello ${userName}

${mailBody}

Open Link

Best Wishes

Wheel.E Team

` }, Text: { Charset: 'UTF-8', From d29e9979eb1a6a0dd70d9b8ce4bf1acc79156fc2 Mon Sep 17 00:00:00 2001 From: MohammedHassan98 Date: Wed, 13 Jul 2022 14:15:07 +0200 Subject: [PATCH 32/33] fix resend verification token issue --- src/APIs/services/VerificationMail.services.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/APIs/services/VerificationMail.services.ts b/src/APIs/services/VerificationMail.services.ts index 5a531d7..aa39c89 100644 --- a/src/APIs/services/VerificationMail.services.ts +++ b/src/APIs/services/VerificationMail.services.ts @@ -100,10 +100,10 @@ export const resendVerificationMail = async ( subject: 'Verification Mail', userName: userName || 'My Friend', mailBody: `Please Open this link to Verify you appliction`, - url: `${url}:${verificationToken}` + url: `${url}/${verificationToken.token}` }) - return { verificationToken, data } + return { verificationToken: verificationToken.token, data } } const newToken = await generateToken(id, email) From e566cb690ce11f6d17a4850f23f391623b9d4bc1 Mon Sep 17 00:00:00 2001 From: Alaa Date: Sun, 17 Jul 2022 15:43:28 +0200 Subject: [PATCH 33/33] merging conflicts updates --- src/APIs/services/Login.services.ts | 64 ++++++++--------------------- 1 file changed, 17 insertions(+), 47 deletions(-) diff --git a/src/APIs/services/Login.services.ts b/src/APIs/services/Login.services.ts index e4fd966..624021e 100644 --- a/src/APIs/services/Login.services.ts +++ b/src/APIs/services/Login.services.ts @@ -3,10 +3,6 @@ import * as ResetPasswordTokenModel from '../models/ResetPasswordTokens.model' import * as SupervisorModel from '../models/Supervisor.model' import * as jwt from 'jsonwebtoken' import { IPatientModel } from '../types/Patient.type' -<<<<<<< HEAD -======= -import { MailObject } from '../types/sendingMail.types' ->>>>>>> 8ac23373bbb29afe6299e7b516440a4fa7beb1e6 import { USER_ROLES } from '../types/User.types' import { MailObject } from '../types/sendingMail.types' import { UnprocessableError } from '../types/general.types' @@ -86,17 +82,13 @@ const decideUser = async (email: string, role: string) => { case USER_ROLES.PATIENT: user = await PatientModel.getPatientByEmail(email) if (!user) { - throw new UnprocessableError( - 'Email not found in the database, can not recover password.' - ) + throw new UnprocessableError('Email not found in the database, can not recover password.') } break case USER_ROLES.SUPERVISOR: user = await SupervisorModel.getSupervisorByEmail(email) if (!user) { - throw new UnprocessableError( - 'Email not found in the database, can not recover password.' - ) + throw new UnprocessableError('Email not found in the database, can not recover password.') } break default: @@ -113,17 +105,13 @@ const decideUserUsingId = async (userId: string, role: string) => { case USER_ROLES.PATIENT: user = await PatientModel.getPatient(userMongoId) if (!user) { - throw new UnprocessableError( - 'Id not found in the database, can not reset password.' - ) + throw new UnprocessableError('Id not found in the database, can not reset password.') } break case USER_ROLES.SUPERVISOR: user = await SupervisorModel.getSupervisorById(userMongoId) if (!user) { - throw new UnprocessableError( - 'Id not found in the database, can not reset password.' - ) + throw new UnprocessableError('Id not found in the database, can not reset password.') } break default: @@ -133,11 +121,7 @@ const decideUserUsingId = async (userId: string, role: string) => { return user } -const updateUser = async ( - userId: mongoose.Types.ObjectId, - role: string, - newPassword: string -) => { +const updateUser = async (userId: mongoose.Types.ObjectId, role: string, newPassword:string) => { const hashedPass = await bcrypt.hash(newPassword, 10) let user switch (role) { @@ -167,16 +151,10 @@ const updateUser = async ( * @param role Patient or supervisor * @description Checks for the reset password token and sends an email to the user */ -export const recoverPassword = async ( - email: string, - url: string, - role: USER_ROLES -) => { +export const recoverPassword = async (email: string, url:string, role: USER_ROLES) => { const user = await decideUser(email, role) if (!user) { - throw new UnprocessableError( - `${role} was not found, please provide valid id` - ) + throw new UnprocessableError(`${role} was not found, please provide valid id`) } // check if there's an already registered token for the user if so delete it @@ -186,17 +164,15 @@ export const recoverPassword = async ( } const resetToken = crypto.randomBytes(32).toString('hex') - token = await ResetPasswordTokenModel.createResetPasswordToken( - user._id, - resetToken - ) - - const mailData: MailObject = { + token = await ResetPasswordTokenModel.createResetPasswordToken(user._id, resetToken) + // refactor URL to environment variable later + const link = `${url}${role}/${token.token}` + const mailData : MailObject = { userName: user.name, userMail: [email], - mailBody: `Please reset your password by opening the link below`, + mailBody: `Please reset your password using this URL: ${link}`, subject: 'resetting password for wheele', - url: `${url}:${token.token}` + url: link } await sendMail(mailData) @@ -209,11 +185,7 @@ export const recoverPassword = async ( * @param newPassword the updated password * @description Reset the user password and send confirmation email */ -export const resetPassword = async ( - role: string, - token: string, - newPassword: string -) => { +export const resetPassword = async (role:string, token:string, newPassword: string) => { const tokenrecord = await ResetPasswordTokenModel.findToken(token) if (!tokenrecord) { throw new UnprocessableError('Invalid or Expired Token') @@ -221,19 +193,17 @@ export const resetPassword = async ( const user = await decideUserUsingId(tokenrecord.user_id, role) if (!user) { - throw new UnprocessableError( - `${role} was not found, please provide valid id` - ) + throw new UnprocessableError(`${role} was not found, please provide valid id`) } await updateUser(user._id, role, newPassword) - const mailData: MailObject = { + const mailData : MailObject = { userName: user.name, userMail: [user.email], mailBody: `This is the confirmation mail showing the password for your wheele account under mail ${user.email} has been changed. Keep safe ans secure.`, subject: 'Your password has been changed', - url: '' + url: ' ' } await sendMail(mailData)