diff --git a/controllers/authController.go b/controllers/authController.go index d3349ea..fd183b5 100644 --- a/controllers/authController.go +++ b/controllers/authController.go @@ -12,8 +12,6 @@ import ( "github.com/SowinskiBraeden/school-management-api/models" "github.com/howeyc/gopass" - "net/smtp" - "github.com/dgrijalva/jwt-go" "github.com/gofiber/fiber/v2" "github.com/google/uuid" @@ -207,11 +205,11 @@ func Enroll(c *fiber.Ctx) error { student.AccountData.TempPassword = true // Send student personal email temp password - message := []byte("Your temporary password is " + tempPass) - auth := smtp.PlainAuth("", systemEmail, systemPassword, "smtp.gmail.com") + subject := "Password Changed" + receiver := student.PersonalData.Email + r := NewRequest([]string{receiver}, subject) - err := smtp.SendMail("smtp.gmail.com:587", auth, systemEmail, []string{student.PersonalData.Email}, message) - if err != nil { + if err := r.Send("./templates/passwordChanged.html", map[string]string{"username": student.PersonalData.FirstName, "password": tempPass}); err { cancel() return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, @@ -342,15 +340,15 @@ func RegisterTeacher(c *fiber.Ctx) error { teacher.AccountData.TempPassword = true // Send teacher personal email temp password - message := []byte("Your temporary password is " + tempPass) - auth := smtp.PlainAuth("", systemEmail, systemPassword, "smtp.gmail.com") + subject := "Password Changed" + receiver := teacher.PersonalData.Email + r := NewRequest([]string{receiver}, subject) - err := smtp.SendMail("smtp.gmail.com:587", auth, systemEmail, []string{teacher.PersonalData.Email}, message) - if err != nil { + if err := r.Send("./templates/passwordChanged.html", map[string]string{"username": teacher.PersonalData.FirstName, "password": tempPass}); err { cancel() return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, - "message": "Could not send password to teacners email", + "message": "Could not send password to teachers email", "error": err, }) } @@ -430,15 +428,15 @@ func CreateAdmin(c *fiber.Ctx) error { admin.TempPassword = true // Send admin personal email temp password - message := []byte("Your temporary password is " + tempPass) - auth := smtp.PlainAuth("", systemEmail, systemPassword, "smtp.gmail.com") + subject := "Password Changed" + receiver := admin.Email + r := NewRequest([]string{receiver}, subject) - err := smtp.SendMail("smtp.gmail.com:587", auth, systemEmail, []string{admin.Email}, message) - if err != nil { + if err := r.Send("./templates/passwordChanged.html", map[string]string{"username": admin.FirstName, "password": tempPass}); err { cancel() return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, - "message": "Could not send password to admins email", + "message": "Could not send password to students email", "error": err, }) } @@ -537,6 +535,21 @@ func StudentLogin(c *fiber.Ctx) error { if localAccountDisabled || student.AccountData.AccountDisabled { cancel() + + // Send student email warning of disabled account + subject := "Account Disabled" + receiver := student.PersonalData.Email + r := NewRequest([]string{receiver}, subject) + + if err := r.Send("./templates/accountDisabled.html", map[string]string{"username": student.PersonalData.FirstName}); err { + cancel() + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "success": false, + "message": "Could not send password to students email", + "error": err, + }) + } + return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ "success": false, "message": "Account is Disabled, contact an Admin", diff --git a/controllers/idManager.go b/controllers/idController.go similarity index 100% rename from controllers/idManager.go rename to controllers/idController.go diff --git a/controllers/mailerController.go b/controllers/mailerController.go new file mode 100644 index 0000000..f82f787 --- /dev/null +++ b/controllers/mailerController.go @@ -0,0 +1,79 @@ +package controllers + +import ( + "bytes" + "fmt" + "html/template" + "log" + "net/smtp" + "os" +) + +type Config struct { + Server string + Port int + Email string + Password string +} + +var config Config = Config{ + Server: "smtp.gmail.com", + Port: 587, + Email: os.Getenv("SYSTEM_EMAIL"), + Password: os.Getenv("SYSTEM_PASSWORD"), +} + +type Request struct { + from string + to []string + subject string + body string +} + +const ( + MIME = "MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n" +) + +func NewRequest(to []string, subject string) *Request { + return &Request{ + to: to, + subject: subject, + } +} + +func (r *Request) parseTemplate(fileName string, data interface{}) error { + t, err := template.ParseFiles(fileName) + if err != nil { + return err + } + buffer := new(bytes.Buffer) + if err = t.Execute(buffer, data); err != nil { + return err + } + r.body = buffer.String() + return nil +} + +func (r *Request) sendMail() bool { + body := "To: " + r.to[0] + "\r\nSubject: " + r.subject + "\r\n" + MIME + "\r\n" + r.body + SMTP := fmt.Sprintf("%s:%d", config.Server, config.Port) + if err := smtp.SendMail(SMTP, smtp.PlainAuth("", config.Email, config.Password, config.Server), config.Email, r.to, []byte(body)); err != nil { + return false + } + return true +} + +func (r *Request) Send(templateName string, items interface{}) bool { + err := r.parseTemplate(templateName, items) + if err != nil { + log.Fatal(err) + return false + } + if ok := r.sendMail(); ok { + log.Printf("Email has been sent to %s\n", r.to) + return true + } else { + log.Printf("Failed to send the email to %s\n", r.to) + return false + } +} diff --git a/controllers/updateController.go b/controllers/updateController.go index 2cc5c0f..b5b2d2c 100644 --- a/controllers/updateController.go +++ b/controllers/updateController.go @@ -5,7 +5,6 @@ import ( "encoding/base64" "fmt" "io/ioutil" - "net/smtp" "os" "strings" "time" @@ -339,6 +338,12 @@ func UpdateStudentPassword(c *fiber.Ctx) error { } defer cancel() + // Alert email the password has changed + subject := "Password Changed" + receiver := student.PersonalData.Email + r := NewRequest([]string{receiver}, subject) + r.Send("./templates/selfPasswordChanged.html", map[string]string{"username": student.PersonalData.FirstName}) + return c.Status(fiber.StatusOK).JSON(fiber.Map{ "success": true, "message": "successfully updated student password", @@ -413,12 +418,11 @@ func ResetStudentPassword(c *fiber.Ctx) error { defer cancel() // Send student personal email temp password - message := []byte("Your temporary password is " + tempPass) - auth := smtp.PlainAuth("", systemEmail, systemPassword, "smtp.gmail.com") + subject := "Password Changed" + receiver := student.PersonalData.Email + r := NewRequest([]string{receiver}, subject) - err := smtp.SendMail("smtp.gmail.com:587", auth, systemEmail, []string{student.PersonalData.Email}, message) - if err != nil { - cancel() + if err := r.Send("./templates/passwordChanged.html", map[string]string{"username": student.PersonalData.FirstName, "password": tempPass}); err { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, "message": "Could not send password to students email", @@ -1263,6 +1267,18 @@ func UpdateTeacherPassword(c *fiber.Ctx) error { } defer cancel() + subject := "Password Changed" + receiver := teacher.PersonalData.Email + r := NewRequest([]string{receiver}, subject) + + if err := r.Send("./templates/selfPasswordChanged.html", map[string]string{"username": teacher.PersonalData.FirstName}); err { + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "success": false, + "message": "Could not send password to teachers email", + "error": err, + }) + } + return c.Status(fiber.StatusOK).JSON(fiber.Map{ "success": true, "message": "successfully updated teacher password", @@ -1335,13 +1351,12 @@ func ResetTeacherPassword(c *fiber.Ctx) error { } defer cancel() - // Send student personal email temp password - message := []byte("Your temporary password is " + tempPass) - auth := smtp.PlainAuth("", systemEmail, systemPassword, "smtp.gmail.com") + // Send teacher personal email temp password + subject := "Password Changed" + receiver := teacher.PersonalData.Email + r := NewRequest([]string{receiver}, subject) - err := smtp.SendMail("smtp.gmail.com:587", auth, systemEmail, []string{teacher.PersonalData.Email}, message) - if err != nil { - cancel() + if err := r.Send("./templates/passwordChanged.html", map[string]string{"username": teacher.PersonalData.FirstName, "password": tempPass}); err { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, "message": "Could not send password to teachers email", diff --git a/templates/accountDisabled.html b/templates/accountDisabled.html new file mode 100644 index 0000000..bd0cea6 --- /dev/null +++ b/templates/accountDisabled.html @@ -0,0 +1,83 @@ + + +
+ + +| + Uh Oh! Account Disabled! + | +
|
+
+ Hi {{ .username }}, |
+
| + This is an automated system email // DO NOT REPLY + | +
| + Password Change! + | +|
|
+
+ Hi {{ .username }}, |
+ |
+ Your new password is:+
|
+ |
| + This is an automated system email // DO NOT REPLY + | +
| + Password Change! + | +
|
+
+ Hi {{ .username }}, |
+
| + This is an automated system email // DO NOT REPLY + | +