From bacefa8db406aa188d27670649bb57f12a3b4c47 Mon Sep 17 00:00:00 2001 From: Michael Hunteman Date: Sat, 6 Jul 2024 15:24:05 -0700 Subject: Rename to guest --- client/src/apiSlice.ts | 12 ++--- client/src/components/Rsvp.tsx | 2 +- client/src/main.tsx | 2 +- client/src/mocks/handlers.ts | 4 +- client/src/pages.ts | 2 +- server/cmd/main.go | 51 ++++++++++-------- server/guest/models.go | 34 ++++++++++++ server/guest/store.go | 117 +++++++++++++++++++++++++++++++++++++++++ server/guests/models.go | 34 ------------ server/guests/store.go | 117 ----------------------------------------- server/post.json | 11 ++-- server/schema.sql | 2 +- 12 files changed, 196 insertions(+), 192 deletions(-) create mode 100644 server/guest/models.go create mode 100644 server/guest/store.go delete mode 100644 server/guests/models.go delete mode 100644 server/guests/store.go diff --git a/client/src/apiSlice.ts b/client/src/apiSlice.ts index 514f8b1..038615f 100644 --- a/client/src/apiSlice.ts +++ b/client/src/apiSlice.ts @@ -39,23 +39,23 @@ export const apiSlice = createApi({ return headers; }, }), - tagTypes: ['Guests'], + tagTypes: ['Guest'], endpoints: (builder) => ({ getGuests: builder.query({ - query: () => 'guests', - providesTags: ['Guests'], + query: () => 'guest', + providesTags: ['Guest'], }), updateGuest: builder.mutation({ query: (guest) => ({ - url: `guests/${guest?.id}`, + url: `guest/${guest?.id}`, method: 'PUT', body: guest, - providesTags: ['Guests'], + providesTags: ['Guest'], }), }), login: builder.mutation({ query: (credentials) => ({ - url: 'guests/login', + url: 'guest/login', method: 'POST', body: credentials, }), diff --git a/client/src/components/Rsvp.tsx b/client/src/components/Rsvp.tsx index fbcaf4a..d908f75 100644 --- a/client/src/components/Rsvp.tsx +++ b/client/src/components/Rsvp.tsx @@ -22,7 +22,7 @@ function Rsvp() { ) : ( - + ); } diff --git a/client/src/main.tsx b/client/src/main.tsx index 88999f7..45ff68b 100644 --- a/client/src/main.tsx +++ b/client/src/main.tsx @@ -31,7 +31,7 @@ const router = createBrowserRouter([ element: , }, { - path: 'guests/login', + path: 'guest/login', element: , }, { diff --git a/client/src/mocks/handlers.ts b/client/src/mocks/handlers.ts index 0e882ee..8dc92b7 100644 --- a/client/src/mocks/handlers.ts +++ b/client/src/mocks/handlers.ts @@ -4,7 +4,7 @@ import { nanoid } from '@reduxjs/toolkit'; const token = nanoid(); export const handlers = [ - http.post('/guests/login', () => { + http.post('/guest/login', () => { return HttpResponse.json({ guest: { id: 1, @@ -17,7 +17,7 @@ export const handlers = [ token, }); }), - http.patch('/guests/1', () => { + http.patch('/guest/1', () => { return HttpResponse.json({ id: 1, firstName: 'Michael', diff --git a/client/src/pages.ts b/client/src/pages.ts index a1dbdfd..8bf5d23 100644 --- a/client/src/pages.ts +++ b/client/src/pages.ts @@ -1,7 +1,7 @@ const pages = [ { name: 'Home', to: '/' }, { name: 'Schedule', to: '/schedule' }, - { name: 'RSVP', to: '/guests/login' }, + { name: 'RSVP', to: '/guest/login' }, { name: 'Registry', to: '/registry' }, ]; diff --git a/server/cmd/main.go b/server/cmd/main.go index b4b1c6d..83a64af 100644 --- a/server/cmd/main.go +++ b/server/cmd/main.go @@ -8,12 +8,13 @@ import ( "net/http" "os" "regexp" + "slices" "time" "github.com/golang-jwt/jwt/v5" "github.com/jackc/pgx/v5/pgxpool" - "git.huntm.net/wedding/server/guests" + "git.huntm.net/wedding/server/guest" ) type guestHandler struct { @@ -21,10 +22,10 @@ type guestHandler struct { } type guestStore interface { - FindGuest(creds guests.Credentials) (guests.Guest, error) - Get() ([]guests.Guest, error) - Add(guest guests.Guest) error - Update(guest guests.Guest) error + FindGuest(creds guest.Credentials) (guest.Guest, error) + Get() ([]guest.Guest, error) + Add(guest guest.Guest) error + Update(guest guest.Guest) error } var ( @@ -34,8 +35,8 @@ var ( port = "5432" database = "postgres" - guestRe = regexp.MustCompile(`^/guests/*$`) - guestIdRe = regexp.MustCompile(`^/guests/([0-9]+)$`) + guestRe = regexp.MustCompile(`^/guest/*$`) + guestIdRe = regexp.MustCompile(`^/guest/([0-9]+)$`) ) func newGuestHandler(s guestStore) *guestHandler { @@ -45,7 +46,7 @@ func newGuestHandler(s guestStore) *guestHandler { } func (h *guestHandler) login(w http.ResponseWriter, r *http.Request) { - var creds guests.Credentials + var creds guest.Credentials err := json.NewDecoder(r.Body).Decode(&creds) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) @@ -53,14 +54,14 @@ func (h *guestHandler) login(w http.ResponseWriter, r *http.Request) { } defer r.Body.Close() - guest, err := h.store.FindGuest(creds) + weddingGuest, err := h.store.FindGuest(creds) if err != nil { http.Error(w, err.Error(), http.StatusUnauthorized) return } expirationTime := time.Now().Add(15 * time.Minute) - claims := &guests.Claims{ + claims := &guest.Claims{ Credentials: creds, RegisteredClaims: jwt.RegisteredClaims{ ExpiresAt: jwt.NewNumericDate(expirationTime), @@ -80,8 +81,8 @@ func (h *guestHandler) login(w http.ResponseWriter, r *http.Request) { return } - loginResponse := &guests.LoginResponse{ - Guest: guest, + loginResponse := &guest.LoginResponse{ + Guest: weddingGuest, Token: tokenString, } @@ -113,7 +114,7 @@ func (h *guestHandler) getGuests(w http.ResponseWriter, _ *http.Request) { } func (h *guestHandler) createGuest(w http.ResponseWriter, r *http.Request) { - var guest guests.Guest + var guest guest.Guest err := json.NewDecoder(r.Body).Decode(&guest) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) @@ -145,7 +146,7 @@ func (h *guestHandler) createGuest(w http.ResponseWriter, r *http.Request) { func (h *guestHandler) updateGuest(w http.ResponseWriter, r *http.Request) { tokenString := r.Header.Get("Authorization") - claims := &guests.Claims{} + claims := &guest.Claims{} key, err := os.ReadFile("C:\\Users\\mhunt\\skey.pem") if err != nil { @@ -175,7 +176,7 @@ func (h *guestHandler) updateGuest(w http.ResponseWriter, r *http.Request) { return } - var guest guests.Guest + var guest guest.Guest err = json.NewDecoder(r.Body).Decode(&guest) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) @@ -194,7 +195,7 @@ func (h *guestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { switch { case r.Method == http.MethodOptions: w.WriteHeader(http.StatusOK) - case r.Method == http.MethodPost && r.URL.Path == "/guests/login": + case r.Method == http.MethodPost && r.URL.Path == "/guest/login": h.login(w, r) case r.Method == http.MethodGet && guestRe.MatchString(r.URL.Path): h.getGuests(w, r) @@ -208,11 +209,19 @@ func (h *guestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } func enableCors(next http.Handler) http.Handler { + allowedOrigins := []string{"http://localhost:5173", "http://192.168.1.41:5173"} + allowedMethods := []string{"OPTIONS", "POST", "PUT"} return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if isPreflight(r) { - w.Header().Add("Access-Control-Allow-Methods", "*") + method := r.Header.Get("Method") + if isPreflight(r) && slices.Contains(allowedMethods, method) { + w.Header().Add("Access-Control-Allow-Methods", method) } - w.Header().Add("Access-Control-Allow-Origin", "*") + + origin := r.Header.Get("Origin") + if slices.Contains(allowedOrigins, origin) { + w.Header().Add("Access-Control-Allow-Origin", origin) + } + w.Header().Add("Access-Control-Allow-Headers", "*") next.ServeHTTP(w, r) }) @@ -231,10 +240,10 @@ func main() { } defer db.Close() - store := guests.NewMemStore(db) + store := guest.NewMemStore(db) guestHandler := newGuestHandler(store) mux := http.NewServeMux() - mux.Handle("/guests/", guestHandler) + mux.Handle("/guest/", guestHandler) log.Fatal(http.ListenAndServe(":8080", enableCors(mux))) } diff --git a/server/guest/models.go b/server/guest/models.go new file mode 100644 index 0000000..aa2c56f --- /dev/null +++ b/server/guest/models.go @@ -0,0 +1,34 @@ +package guest + +import "github.com/golang-jwt/jwt/v5" + +type Guest struct { + Id int `json:"id"` + FirstName string `json:"firstName"` + LastName string `json:"lastName"` + Attendance string `json:"attendance"` + Email string `json:"email"` + Message string `json:"message"` + PartySize int `json:"partySize"` + PartyList []PartyGuest `json:"partyList"` +} + +type PartyGuest struct { + FirstName string `json:"firstName"` + LastName string `json:"lastName"` +} + +type Credentials struct { + FirstName string `json:"firstName"` + LastName string `json:"lastName"` +} + +type Claims struct { + Credentials Credentials `json:"credentials"` + jwt.RegisteredClaims +} + +type LoginResponse struct { + Guest Guest `json:"guest"` + Token string `json:"token"` +} diff --git a/server/guest/store.go b/server/guest/store.go new file mode 100644 index 0000000..525bb71 --- /dev/null +++ b/server/guest/store.go @@ -0,0 +1,117 @@ +package guest + +import ( + "context" + "errors" + + "github.com/jackc/pgx/v5/pgxpool" +) + +type MemStore struct { + db *pgxpool.Pool +} + +func NewMemStore(db *pgxpool.Pool) *MemStore { + return &MemStore{ + db, + } +} + +func (m MemStore) FindGuest(creds Credentials) (Guest, error) { + rows, err := m.db.Query(context.Background(), "select * from guest") + var guest Guest + if err != nil { + return guest, err + } + defer rows.Close() + + for rows.Next() { + err := rows.Scan(&guest.Id, &guest.FirstName, &guest.LastName, &guest.Attendance, &guest.Email, &guest.Message, &guest.PartySize) + if err != nil { + return guest, err + } + if guest.FirstName == creds.FirstName && guest.LastName == creds.LastName { + return guest, nil + } + } + return guest, errors.New("Guest does not exist") +} + +func (m MemStore) Get() ([]Guest, error) { + rows, err := m.db.Query(context.Background(), "select * from guest") + if err != nil { + return nil, err + } + defer rows.Close() + + guestSlice := []Guest{} + for rows.Next() { + var guest Guest + err := rows.Scan(&guest.Id, &guest.FirstName, &guest.LastName, &guest.Attendance, &guest.Email, &guest.Message, &guest.PartySize) + if err != nil { + return guestSlice, err + } + guestSlice = append(guestSlice, guest) + } + + rows, err = m.db.Query(context.Background(), "select * from party") + if err != nil { + return guestSlice, err + } + defer rows.Close() + + for rows.Next() { + var guestId int + var partyGuest PartyGuest + err := rows.Scan(&guestId, &partyGuest.FirstName, &partyGuest.LastName) + if err != nil { + return guestSlice, err + } + for i, g := range guestSlice { + if guestId == g.Id { + guestSlice[i].PartyList = append(g.PartyList, partyGuest) + } + } + } + return guestSlice, nil +} + +func (m MemStore) Add(guest Guest) error { + statement := "insert into guest (id, first_name, last_name, attendance, email, message, party_size) values ($1, $2, $3, $4, $5, $6, $7)" + _, err := m.db.Exec(context.Background(), statement, guest.Id, guest.FirstName, guest.LastName, guest.Attendance, guest.Email, guest.Message, guest.PartySize) + if err != nil { + return err + } + + statement = "insert into party (guest_id, first_name, last_name) values ($1, $2, $3)" + for _, pg := range guest.PartyList { + _, err = m.db.Exec(context.Background(), statement, guest.Id, pg.FirstName, pg.LastName) + if err != nil { + return err + } + } + return nil +} + +func (m MemStore) Update(guest Guest) error { + statement := "update guest set attendance = $1, email = $2, message = $3, party_size = $4 where id = $5" + _, err := m.db.Exec(context.Background(), statement, guest.Attendance, guest.Email, guest.Message, guest.PartySize, guest.Id) + if err != nil { + return err + } + + statement = "delete from party where guest_id = $1" + _, err = m.db.Exec(context.Background(), statement, guest.Id) + if err != nil { + return err + } + + statement = "insert into party (guest_id, first_name, last_name) values ($1, $2, $3)" + for _, pg := range guest.PartyList { + _, err = m.db.Exec(context.Background(), statement, guest.Id, pg.FirstName, pg.LastName) + if err != nil { + return err + } + } + return nil +} diff --git a/server/guests/models.go b/server/guests/models.go deleted file mode 100644 index bcc6a52..0000000 --- a/server/guests/models.go +++ /dev/null @@ -1,34 +0,0 @@ -package guests - -import "github.com/golang-jwt/jwt/v5" - -type Guest struct { - Id int `json:"id"` - FirstName string `json:"firstName"` - LastName string `json:"lastName"` - Attendance string `json:"attendance"` - Email string `json:"email"` - Message string `json:"message"` - PartySize int `json:"partySize"` - PartyList []PartyGuest `json:"partyList"` -} - -type PartyGuest struct { - FirstName string `json:"firstName"` - LastName string `json:"lastName"` -} - -type Credentials struct { - FirstName string `json:"firstName"` - LastName string `json:"lastName"` -} - -type Claims struct { - Credentials Credentials `json:"credentials"` - jwt.RegisteredClaims -} - -type LoginResponse struct { - Guest Guest `json:"guest"` - Token string `json:"token"` -} diff --git a/server/guests/store.go b/server/guests/store.go deleted file mode 100644 index bedc646..0000000 --- a/server/guests/store.go +++ /dev/null @@ -1,117 +0,0 @@ -package guests - -import ( - "context" - "errors" - - "github.com/jackc/pgx/v5/pgxpool" -) - -type MemStore struct { - db *pgxpool.Pool -} - -func NewMemStore(db *pgxpool.Pool) *MemStore { - return &MemStore{ - db, - } -} - -func (m MemStore) FindGuest(creds Credentials) (Guest, error) { - rows, err := m.db.Query(context.Background(), "select * from guest") - var guest Guest - if err != nil { - return guest, err - } - defer rows.Close() - - for rows.Next() { - err := rows.Scan(&guest.Id, &guest.FirstName, &guest.LastName, &guest.Attendance, &guest.Email, &guest.Message, &guest.PartySize) - if err != nil { - return guest, err - } - if guest.FirstName == creds.FirstName && guest.LastName == creds.LastName { - return guest, nil - } - } - return guest, errors.New("Guest does not exist") -} - -func (m MemStore) Get() ([]Guest, error) { - rows, err := m.db.Query(context.Background(), "select * from guest") - if err != nil { - return nil, err - } - defer rows.Close() - - guestSlice := []Guest{} - for rows.Next() { - var guest Guest - err := rows.Scan(&guest.Id, &guest.FirstName, &guest.LastName, &guest.Attendance, &guest.Email, &guest.Message, &guest.PartySize) - if err != nil { - return guestSlice, err - } - guestSlice = append(guestSlice, guest) - } - - rows, err = m.db.Query(context.Background(), "select * from party") - if err != nil { - return guestSlice, err - } - defer rows.Close() - - for rows.Next() { - var guestId int - var partyGuest PartyGuest - err := rows.Scan(&guestId, &partyGuest.FirstName, &partyGuest.LastName) - if err != nil { - return guestSlice, err - } - for i, g := range guestSlice { - if guestId == g.Id { - guestSlice[i].PartyList = append(g.PartyList, partyGuest) - } - } - } - return guestSlice, nil -} - -func (m MemStore) Add(guest Guest) error { - statement := "insert into guest (id, first_name, last_name, attendance, email, message, party_size) values ($1, $2, $3, $4, $5, $6, $7)" - _, err := m.db.Exec(context.Background(), statement, guest.Id, guest.FirstName, guest.LastName, guest.Attendance, guest.Email, guest.Message, guest.PartySize) - if err != nil { - return err - } - - statement = "insert into party (guest_id, first_name, last_name) values ($1, $2, $3)" - for _, pg := range guest.PartyList { - _, err = m.db.Exec(context.Background(), statement, guest.Id, pg.FirstName, pg.LastName) - if err != nil { - return err - } - } - return nil -} - -func (m MemStore) Update(guest Guest) error { - statement := "update guest set attendance = $1, email = $2, message = $3, party_size = $4 where id = $5" - _, err := m.db.Exec(context.Background(), statement, guest.Attendance, guest.Email, guest.Message, guest.PartySize, guest.Id) - if err != nil { - return err - } - - statement = "delete from party where guest_id = $1" - _, err = m.db.Exec(context.Background(), statement, guest.Id) - if err != nil { - return err - } - - statement = "insert into party (guest_id, first_name, last_name) values ($1, $2, $3)" - for _, pg := range guest.PartyList { - _, err = m.db.Exec(context.Background(), statement, guest.Id, pg.FirstName, pg.LastName) - if err != nil { - return err - } - } - return nil -} diff --git a/server/post.json b/server/post.json index 39e1d55..f12bd5a 100644 --- a/server/post.json +++ b/server/post.json @@ -4,12 +4,7 @@ "lastName": "Hunteman", "attendance": "yes", "email": "mhunteman@cox.net", - "message": "Hi", - "partySize": 2, - "partyList": [ - { - "firstName": "Madison", - "lastName": "Rossitto" - } - ] + "message": "", + "partySize": 1, + "partyList": [] } diff --git a/server/schema.sql b/server/schema.sql index b2dd533..fdc589a 100644 --- a/server/schema.sql +++ b/server/schema.sql @@ -9,7 +9,7 @@ create table guest ( ); create table party ( - guest_id integer NOT NULL references guests(id) ON DELETE CASCADE, + guest_id integer NOT NULL references guest(id) ON DELETE CASCADE, first_name varchar(64), last_name varchar(64) ); \ No newline at end of file -- cgit v1.2.3