diff --git a/auth/jwt.go b/auth/jwt.go index 014d1d6..c09ae61 100644 --- a/auth/jwt.go +++ b/auth/jwt.go @@ -1,7 +1,6 @@ package auth import ( - "os" "time" "github.com/golang-jwt/jwt/v5" @@ -13,8 +12,6 @@ type Claims struct { jwt.RegisteredClaims } -var secret = os.Getenv("SHAP_JWT_SECRET") - func GenerateJWT(userID, role string, secret []byte) (string, error) { claims := Claims{ UserID: userID, diff --git a/handlers/account.go b/handlers/account.go index 164d945..7208379 100644 --- a/handlers/account.go +++ b/handlers/account.go @@ -236,7 +236,7 @@ func UserInfo(w http.ResponseWriter, r *http.Request) { err = json.NewEncoder(w).Encode(map[string]interface{}{ "id": user.ID, "name": user.Username, - "avatar_url": nil, + "avatar_url": "", }) if err != nil { log.Println("GET [api/userinfo] " + r.RemoteAddr + ": " + err.Error()) diff --git a/handlers/expenses.go b/handlers/expenses.go index a311f4a..56652b7 100644 --- a/handlers/expenses.go +++ b/handlers/expenses.go @@ -7,6 +7,7 @@ import ( "shap-planner-backend/models" "shap-planner-backend/storage" "shap-planner-backend/utils" + "strings" "time" ) @@ -21,7 +22,9 @@ func Expenses(w http.ResponseWriter, r *http.Request) { http.Error(w, "Something went wrong", http.StatusInternalServerError) return } - err = json.NewEncoder(w).Encode(expenses) + err = json.NewEncoder(w).Encode(map[string]interface{}{ + "expenses": expenses, + }) if err != nil { log.Println("GET [api/expense] " + r.RemoteAddr + ": " + err.Error()) return @@ -102,4 +105,56 @@ func Expenses(w http.ResponseWriter, r *http.Request) { http.Error(w, "Invalid request method", http.StatusMethodNotAllowed) } } +func ExpenseShares(w http.ResponseWriter, r *http.Request) { + switch r.Method { + case http.MethodGet: + query := r.URL.Query() + idParam := query.Get("id") + idTypeParam := strings.ToLower(query.Get("idType")) + if idTypeParam == models.IDTypeEXPENSE { + println(idParam) + shares, err := storage.GetSharesByExpenseId(idParam) + if err != nil { + log.Println("GET [api/shares] " + r.RemoteAddr + ": " + err.Error()) + http.Error(w, "Something went wrong", http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + err = json.NewEncoder(w).Encode(map[string]interface{}{ + "shares": shares, + }) + if err != nil { + log.Println("GET [api/shares] " + r.RemoteAddr + ": " + err.Error()) + return + } + log.Println("GET [api/shares] " + r.RemoteAddr + ": Successfully retrieved shares") + } else if idTypeParam == models.IDTypeSHARE || idTypeParam == "" { + share, err := storage.GetShareById(idParam) + if err != nil { + log.Println("GET [api/shares] " + r.RemoteAddr + ": " + err.Error()) + http.Error(w, "Something went wrong", http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + err = json.NewEncoder(w).Encode(map[string]interface{}{ + "id": share.ID, + "expense_id": share.ExpenseID, + "user_id": share.UserID, + "share_cents": share.ShareCents, + }) + if err != nil { + log.Println("GET [api/shares] " + r.RemoteAddr + ": " + err.Error()) + return + } + log.Println("GET [api/shares] " + r.RemoteAddr + ": Successfully retrieved shares") + } + break + case http.MethodPut: + break + case http.MethodDelete: + break + default: + http.Error(w, "Invalid request method", http.StatusMethodNotAllowed) + } +} func AdminPanel(w http.ResponseWriter, r *http.Request) {} diff --git a/models/constants.go b/models/constants.go new file mode 100644 index 0000000..f3cfc2d --- /dev/null +++ b/models/constants.go @@ -0,0 +1,14 @@ +package models + +// Roles +const ( + RoleUser = "user" + RoleAdmin = "admin" +) + +// ID-Types +const ( + IDTypeSHARE = "share" + IDTypeEXPENSE = "expense" + IDTypeUSER = "user" +) diff --git a/models/dbmodels.go b/models/dbmodels.go index a3efc31..ad8b428 100644 --- a/models/dbmodels.go +++ b/models/dbmodels.go @@ -24,8 +24,3 @@ type ExpenseShare struct { UserID string `json:"user_id"` ShareCents int64 `json:"share_cents"` } - -const ( - RoleUser = "user" - RoleAdmin = "admin" -) diff --git a/server/server.go b/server/server.go index 6dc0bb9..d2f91e7 100644 --- a/server/server.go +++ b/server/server.go @@ -62,6 +62,7 @@ func (server *Server) Run() { // Login required mux.Handle("/api/expenses", auth.AuthMiddleware(server.JWTSecret)(http.HandlerFunc(handlers.Expenses))) + mux.Handle("/api/shares", auth.AuthMiddleware(server.JWTSecret)(http.HandlerFunc(handlers.ExpenseShares))) mux.Handle("/api/balance", auth.AuthMiddleware(server.JWTSecret)(http.HandlerFunc(handlers.GetBalance))) mux.Handle("/api/ping", auth.AuthMiddleware(server.JWTSecret)(http.HandlerFunc(handlers.TestHandler))) mux.Handle("/api/userinfo", auth.AuthMiddleware(server.JWTSecret)(http.HandlerFunc(handlers.UserInfo))) diff --git a/storage/storage.go b/storage/storage.go index 20cb232..d9acfee 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -160,6 +160,36 @@ func AddShare(share *models.ExpenseShare) error { share.ShareCents) return err } +func GetShareById(id string) (models.ExpenseShare, error) { + row := DB.QueryRow("SELECT * FROM expense_shares WHERE id = ?", id) + var share models.ExpenseShare + err := row.Scan(&share.ID, &share.ExpenseID, &share.UserID, &share.ShareCents) + return share, err +} +func GetSharesByExpenseId(id string) ([]models.ExpenseShare, error) { + query := "SELECT * FROM expense_shares WHERE expense_id = ?" + rows, err := DB.Query(query, id) + if err != nil { + return nil, err + } + defer rows.Close() + + var shares []models.ExpenseShare + + for rows.Next() { + var share models.ExpenseShare + + err := rows.Scan(&share.ID, &share.ExpenseID, &share.UserID, &share.ShareCents) + if err != nil { + return nil, err + } + shares = append(shares, share) + } + if err = rows.Err(); err != nil { + return nil, err + } + return shares, nil +} // Balances func ComputeBalance(userId string) (float64, error) {