diff --git a/.env.example b/.env.example
index 0b33b40..0a9db32 100644
--- a/.env.example
+++ b/.env.example
@@ -1 +1,7 @@
-PORT =
\ No newline at end of file
+DBNAME=database
+DBUSER=postgres
+DBPASSWORD=password
+PORT=5432
+DBHOST=127.0.0.1
+SECRETKEY=any_secret
+JWT_SECRET=
diff --git a/.gitignore b/.gitignore
index 1606528..03ccdab 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,6 +16,9 @@ pids
*.seed
*.pid.lock
+# My DB config
+src/api/db/config/config.js
+
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
diff --git a/README.md b/README.md
index f7d562c..2da1500 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,62 @@
# Class Manager
-### Introduction
- More information coming soon ...
-
-### Installation Guide
-* Clone this repository [here](https://github.com/devcareer/class-manager.git).
-* The main branch is the most stable branch at any given time, ensure you're working from it.
-* Run npm install to install all dependencies
-* Create an .env file in your project root folder and add your variables. See .env.example for assistance.
-### Usage
-* Run npm watch:dev to start the application.
-### License
-This project is available for use under the MIT License.
\ No newline at end of file
+
+### The technologies used in creating this project are:
+Node.js, ExpressJs, Sequelize ORM, and PostgreSQL
+
+### :rocket: How to get started
+- Make sure to have Git and Node.js installed on your computer
+- Clone the project by running: `git clone https://https://github.com/devcareer/class-manager`
+- cd into the project and run `npm install`
+- create a `.env` file in the root folder and copy the content in the `.env.example`into it.
+- run `npm run migrate` to migrate to the database.
+- run `npm run migrate:undo` to undo migration.
+- run `npm run seed` to seed the database.
+- run `npm start` to start the project.
+
+These are the HTTP response codes used in this project:
+| Status Codes | Indication |
+| --- | --- |
+| `200` | This `OK` status code indicates that a request has succeeded |
+| `400` | This `bad request error` status code indicates that the request sent to the server is incorrect |
+| `404` | This `not found error` status code indicates that the resource is not found. |
+| `500` | This `internal server error` status code indicates that something has gone wrong on the web server |
+
+
+//
Congrats for sending test email with Mailtrap!
+//
Inspect it using the tabs you see above and learn how this email can be improved.
+//

+//
Now send your email using our fake SMTP server and integration of your choice!
+//
Good luck! Hope it works.
+//
+//
+//
+//
+//
+// `,
+// // attachments: [
+// // {
+// // filename: "welcome.png",
+// // content_id: "welcome.png",
+// // disposition: "inline",
+// // //content: welcomeImage,
+// // },
+// // ],
+// })
+// .then(
+// console.log('hjj'),
+// console.error('jkkjk')
+// ).catch(function () {
+// console.log("Promise Rejected");
+// });
\ No newline at end of file
diff --git a/src/services/emailServiceMailtrap.js b/src/services/emailServiceMailtrap.js
new file mode 100644
index 0000000..2ead188
--- /dev/null
+++ b/src/services/emailServiceMailtrap.js
@@ -0,0 +1,36 @@
+// import nodemailer from 'nodemailer';
+
+// class EmailSender{
+// static async sendMail(to, subject, text) {
+// const transporter = nodemailer.createTransport({
+// service: 'gmail', //'gmail',
+// host: "smtp.mailtrap.io",
+// port: 2525,
+// ssl: false,
+// tls: true,
+// auth: {
+// //Gmail user: 'mansuribrahimnok@gmail.com',
+// user: 'mansuribrahimnok@gmail.com',//8294e4f60324e9',
+// //Gmail pass: 'eugepkjqwvciaiap' // naturally, replace both with your real credentials or an application-specific password
+// pass: 'eugepkjqwvciaiap'//6ee4754d4902b5' // naturally, replace both with your real credentials or an application-specific password
+// }
+// });
+
+// const mailOptions = {
+// from: 'mansuribrahimnok@gmail.com',
+// to: to,//'princemi007@gmail.com',
+// subject: subject,//'Invoices due',
+// text: text//'Hey baby, Will you marry me.'
+// };
+
+// transporter.sendMail(mailOptions, function(error, info){
+// if (error) {
+// console.log(error);
+// } else {
+// console.log('Email sent: ' + info.response);
+// }
+// });
+// }
+// }
+// //EmailSender.sendMail('princemi007@gmail.com', 'subject', 'text')
+// export default EmailSender;
\ No newline at end of file
diff --git a/src/services/studentService.js b/src/services/studentService.js
index 7465da9..49a00d8 100644
--- a/src/services/studentService.js
+++ b/src/services/studentService.js
@@ -1,18 +1,14 @@
+/* eslint-disable no-useless-catch */
import database from '../db/models/index.js';
+const role = database.Role.findOne({where:{slug: 'sl_student'}})
+console.log(role.slug)
class StudentService {
- static async getAllStudents() {
- try {
- const result = await database.User.findAll();
- return result;
- } catch (error) {
- throw error;
- }
+ constructor() {
}
-
- static async addStudent(newStudent) {
+ static async getAllStudents() {
try {
- const result = await database.User.create(newStudent);
+ const result = await database.User.findAll({where:{roleId: role.id}});
return result;
} catch (error) {
throw error;
@@ -22,11 +18,11 @@ class StudentService {
static async updateStudent(id, updateStudent) {
try {
const studentToUpdate = await database.User.findOne({
- where: { id: id }
+ where: { id: id, roleId: role.id}
});
if (studentToUpdate) {
- await database.User.update(updateStudent, { where: { id: id } });
+ await database.User.update(updateStudent, { where: { id: id, roleId: role.id } });
return updateStudent;
}
@@ -39,7 +35,7 @@ class StudentService {
static async getAStudent(id) {
try {
const aStudent = await database.User.findOne({
- where: { id: id }
+ where: { id: id, roleId: role.id}
});
return aStudent;
@@ -50,11 +46,11 @@ class StudentService {
static async deleteStudent(id) {
try {
- const StudentToDelete = await database.User.findOne({ where: { id: id } });
+ const StudentToDelete = await database.User.findOne({ where: { id: id, roleId: role.id} });
if (StudentToDelete) {
const deletedStudent = await database.User.destroy({
- where: { id: id }
+ where: { id: id, roleId: role.id}
});
return deletedStudent;
}
diff --git a/src/services/userService.js b/src/services/userService.js
new file mode 100644
index 0000000..04293fd
--- /dev/null
+++ b/src/services/userService.js
@@ -0,0 +1,69 @@
+/* eslint-disable no-useless-catch */
+require("dotenv").config();
+import bcrypt from "bcrypt";
+import jwt from "jsonwebtoken";
+import database from '../db/models/index.js';
+
+const users = database.User;
+const JWT_SECRET = process.env.JWT_SECRET;
+ class UserService {
+
+ static async findUser ({id, email}) {
+
+ try {
+ if(id!= null){
+ const aUser = await users.findOne({
+ where: {id: id }
+ });
+
+ return aUser
+ }else if(email !=null){
+ const aUser = await users.findOne({
+ where: {email: email }
+ });
+ return aUser;
+ }
+ } catch (error) {
+ throw error;
+ }
+ };
+ static async authenticate ({ id, email, password }) {
+ const user = await this.findUser({id, email });
+ const isPasswordValid = await bcrypt.compare(password, user.password);
+
+ if(isPasswordValid){
+ const token = jwt.sign({ id: user.id }, JWT_SECRET, {
+ expiresIn: 24 * 60 * 60, // Expire tokens after a certain amount of time so users can't stay logged in forever
+ });
+
+ return { token };
+}
+};
+
+// Save the new user to the database and return an authorization token for the user
+ static async create ({firstName, lastName, secondName, email, roleId, password }) {
+
+ const newUser = {
+ firstName,
+ lastName,
+ secondName,
+ email,
+ roleId,
+ password: await bcrypt.hash(password, 10)
+
+ };
+ // save the new user to our database
+ const result = await users.create(newUser);
+ // Generate the JWT with jwt.sign. The return value is an
+ // authentication token
+ const token = jwt.sign({ id: result.id }, JWT_SECRET, {
+ expiresIn: 24 * 60 * 60, // Expire tokens after a certain amount of time so users can't stay logged in forever
+ });
+
+ return { token };
+};
+
+
+}
+export default UserService
+
diff --git a/src/services/verify.js b/src/services/verify.js
new file mode 100644
index 0000000..91207aa
--- /dev/null
+++ b/src/services/verify.js
@@ -0,0 +1,74 @@
+/* eslint-disable no-useless-catch */
+//import sendEmail from "../utils/email";
+const sendEmail = require( "./EmailServiceMailtrap.js");
+const db = require( "../db/models/index.js");
+const crypto = require('crypto');
+
+
+// const router = express.Router();
+//class Verify {
+
+const sendVerify = async (name, email)=>{
+ console.log(name);
+try {
+ //const { error } = validate(err);
+ // if (error) return res.status(400).send(error.details[0].message);
+ console.log(name);
+ let user = await db.User.findOne({
+ where: { email: email }
+ });
+ console.log(name);
+ if (user){
+ // return res.status(400).send("User with given email already exist!");
+
+ let token = await db.Token.create({
+ userId: user.id,
+ token: crypto.randomBytes(32).toString("hex"),
+ });
+ console.log(token);
+ const message = `${name} click this link to verify your email ${process.env.BASE_URL}/user/verify/${user.id}/${token.token}`;
+ console.log(token);
+ await sendEmail.sendMail(email, "Verify Email", message);
+ }else{
+ console.log(token);
+ return null
+ }
+ //res.send("An Email sent to your account please verify");
+ } catch (error) {
+ console.log(error);
+ //console.log("An error occured"); //res.status(400).send("An error occured");
+ }
+}
+
+// async verify(token, id) {
+// try {
+// const user = await db.User.findOne({where:{ id: id }});
+// //if (!user) return res.status(400).send("Invalid link");
+
+// const token = await db.Token.findOne({where:{
+// userId: user.id,
+// token: token,
+// }});
+// if (!token){
+// return false;
+// }else{
+// await db.User.updateOne({where:{ id: id, verified: true }});
+// await db.Token.destroy({
+// where: {
+// id: token.id
+// }
+// });
+
+// return true;
+// }
+// // res.send("email verified sucessfully");
+
+// } catch (error) {
+// return error;// res.status(400).send("An error occured");
+// }
+// };
+
+
+// }
+ sendVerify('name', 'princemi007@gmail.com')
+ // export default Verify
diff --git a/src/services/verifyService.js b/src/services/verifyService.js
new file mode 100644
index 0000000..5bf192e
--- /dev/null
+++ b/src/services/verifyService.js
@@ -0,0 +1,86 @@
+/* eslint-disable no-useless-catch */
+require("dotenv").config();
+import database from '../db/models/index.js';
+// import sendEmail from "./EmailServiceMailtrap.js";
+import sendEmail from '../utils/email'
+import crypto from 'crypto';
+import UserService from "./userService.js";
+
+const users = database.User;
+const tokens = database.Token;
+const url = process.env.BASE_URL;
+ class VerifyService {
+ static async sendMail (name, email) {
+ try {
+ let user = await this.findUser({ email })
+ if (user){
+ let token = await tokens.create({
+ userId: user.id,
+ token: crypto.randomBytes(32).toString("hex"),
+ });
+ const message = `${name} click this link to verify your email ${url}/user/verify/${user.id}/${token.token}`;
+ await sendEmail(email, "Verify Email", message);
+ }else{
+ return null
+ }
+
+ } catch (error) {
+ throw error;
+ }
+ };
+
+
+ static async findUser ({email}) {
+ try {
+
+ if(email !=null){
+ const aUser = await users.findOne({
+ where: {email: email }
+ });
+ return aUser;
+ }
+ } catch (error) {
+ throw error;
+ }
+ };
+
+
+ static async verify(token, id) {
+ try {
+ const user = await UserService.findUser({ id });
+ if(!user){
+ return false
+ }
+ const userToken = await tokens.findOne({where:{
+ userId: user.id,
+ token: token,
+ }});
+ if (!userToken){
+ return false;
+ }else{
+ await users.update({ verified: true }, {
+ where: {
+ id: id
+ }
+ });;
+ await tokens.destroy({
+ where: {
+ userId: userToken.userId
+ }
+ });
+
+ return true;
+ }
+ // res.send("email verified sucessfully");
+
+} catch (error) {
+ return error;// res.status(400).send("An error occured");
+ }
+ };
+
+// Save the new user to the database and return an authorization token for the user
+
+
+}
+export default VerifyService
+
diff --git a/src/utils/email.js b/src/utils/email.js
new file mode 100644
index 0000000..bcbd317
--- /dev/null
+++ b/src/utils/email.js
@@ -0,0 +1,30 @@
+const nodemailer = require("nodemailer");
+require('dotenv').config()
+const sendEmail = async (email, subject, text) => {
+ try {
+ const transporter = nodemailer.createTransport({
+ host: process.env.EMAIL_HOST,
+ service: process.env.EMAIL_SERVICE,
+ port: process.env.EMAIL_PORT,
+ //secure: true,
+ auth: {
+ user: process.env.EMAIL_USER,
+ pass: process.env.EMAIL_PASS,
+ },
+ });
+
+ await transporter.sendMail({
+ from: process.env.EMAIL_USER,
+ to: email,
+ subject: subject,
+ text: text,
+ });
+ console.log("email sent sucessfully");
+ } catch (error) {
+ console.log("email not sent");
+ console.log(error);
+ }
+};
+//sendEmail('princemi007@gmail.com', 'subject', 'text')
+
+ export default sendEmail;
\ No newline at end of file