diff --git a/controllers/updateController.go b/controllers/updateController.go index 423f957..5e69feb 100644 --- a/controllers/updateController.go +++ b/controllers/updateController.go @@ -258,7 +258,7 @@ func UpdateStudentPassword(c *fiber.Ctx) error { claims := token.Claims.(*jwt.StandardClaims) var student models.Student - findErr := studentCollection.FindOne(context.TODO(), bson.M{"schooldata.sid": claims.Issuer}).Decode(&student) + findErr := studentCollection.FindOne(ctx, bson.M{"schooldata.sid": claims.Issuer}).Decode(&student) if findErr != nil { cancel() return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ @@ -292,6 +292,14 @@ func UpdateStudentPassword(c *fiber.Ctx) error { }) } + if student.UsedPassword(data["newpassword1"]) { + cancel() + return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ + "success": false, + "message": "Your new password cannot be the same as a previous password", + }) + } + update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339)) update := bson.M{ "$set": bson.M{ @@ -299,6 +307,9 @@ func UpdateStudentPassword(c *fiber.Ctx) error { "accountdata.temppassword": false, // If it were a temp password, its not now "updated_at": update_time, }, + "$push": bson.M{ + "accountdata.hashhistory": student.HashPassword(data["newpassword1"]), + }, } result, updateErr := studentCollection.UpdateOne( diff --git a/models/studentModel.go b/models/studentModel.go index d1db5d1..dd00f89 100644 --- a/models/studentModel.go +++ b/models/studentModel.go @@ -45,16 +45,26 @@ type Student struct { Photo string `json:"photo"` } `json:"schooldata"` AccountData struct { - SchoolEmail string `json:"schoolemail"` - Password string `json:"-" validate:"min=10,max=32"` - AccountDisabled bool `bson:"accountdisabled"` - TempPassword bool `json:"temppassword"` - Attempts int `json:"attempts"` // login attempts max 5 + SchoolEmail string `json:"schoolemail"` + Password string `json:"-" validate:"min=10,max=32"` + AccountDisabled bool `bson:"accountdisabled"` + TempPassword bool `json:"temppassword"` + Attempts int `json:"attempts"` // login attempts max 5 + HashHistory []string `json:"-"` // List of old hashed passwords (not including auto generated passwords) } `json:"accountdata"` Created_at time.Time `json:"created_at"` Updated_at time.Time `json:"updated_at"` } +func (s *Student) UsedPassword(password string) bool { + for _, oldHash := range s.AccountData.HashHistory { + if oldHash == s.HashPassword(password) { + return true + } + } + return false +} + func (s *Student) HashPassword(password string) string { hash, _ := bcrypt.GenerateFromPassword([]byte(password), 14) return string(hash)