You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
3.5 KiB

package routes
import (
"context"
"fmt"
"log"
"net/http"
"github.com/jacobmveber-01839764/BudgetBuddy/db"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/mongo/readpref"
"golang.org/x/crypto/bcrypt"
)
func ChangePassword(w http.ResponseWriter, r *http.Request) {
log.Println("* /auth/changepassword")
// get session key from request
session := r.Header.Get("x-session-key")
// prepare DB
err := db.Client.Ping(context.Background(), readpref.Primary())
if err != nil {
db.Connect()
}
var userCollection = db.Client.Database("budgetbuddy").Collection("users")
// var v contains POST credentials
r.ParseForm()
newpass := r.FormValue("new")
oldpass := r.FormValue("old")
if newpass == "" {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, "{\"error\":\"password must be provided\"}")
return
}
// cmp struct will be compared with v to verify credentials
var cmp db.UserSchema
found := userCollection.FindOne(r.Context(), bson.D{primitive.E{Key: "session", Value: session}})
if found.Err() != nil {
w.WriteHeader(http.StatusUnauthorized)
fmt.Fprintf(w, "{\"error\":\"invalid session key\"}")
return
}
err = found.Decode(&cmp)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
err = bcrypt.CompareHashAndPassword([]byte(cmp.Password), []byte(oldpass))
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
fmt.Fprintf(w, "{\"error\":\"invalid password\"}")
return
}
if len(newpass) < 8 || len(newpass) > 255 {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprint(w, "{\"error\":\"password must be 8 characters or greater\"}")
return
}
// hash and store the user's hashed password
hashedPass, err := bcrypt.GenerateFromPassword([]byte(newpass), 8)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, "{\"error\":\"internal server error, please try again later\"}")
}
filter := bson.D{primitive.E{Key: "session", Value: session}}
opts := options.Update().SetUpsert(true)
update := bson.D{primitive.E{Key: "$set", Value: bson.D{primitive.E{Key: "password", Value: string(hashedPass)}}}}
_, err = userCollection.UpdateOne(context.TODO(), filter, update, opts)
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
fmt.Fprintf(w, "{\"error\":\"invalid session key\"}")
return
}
w.Write([]byte("{\"status\": 200}"))
}
func ChangeName(w http.ResponseWriter, r *http.Request) {
log.Println("* /auth/changename")
// get session key from request
session := r.Header.Get("x-session-key")
// get collection handle from db
var userCollection = db.Client.Database("budgetbuddy").Collection("users")
r.ParseForm()
if r.FormValue("name") == "" {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, "{\"error\":\"name cannot be blank\"}")
return
}
found := userCollection.FindOne(r.Context(), bson.D{primitive.E{Key: "session", Value: session}})
if found.Err() != nil {
w.WriteHeader(http.StatusUnauthorized)
fmt.Fprintf(w, "{\"error\":\"invalid session key\"}")
return
}
filter := bson.D{primitive.E{Key: "session", Value: session}}
opts := options.Update().SetUpsert(true)
update := bson.D{primitive.E{Key: "$set", Value: bson.D{primitive.E{Key: "name", Value: r.FormValue("name")}}}}
_, err := userCollection.UpdateOne(context.TODO(), filter, update, opts)
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
fmt.Fprintf(w, "{\"error\":\"invalid session key\"}")
return
}
w.Write([]byte("{\"status\": 200}"))
}