aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2024-07-22 04:36:45 +0900
committernsfisis <nsfisis@gmail.com>2024-07-22 04:36:53 +0900
commita4685927a1f7fe8374a567ee74cc62aad639f4c3 (patch)
tree1eaf5845965c4d5d2db4faf9582c17444a762ffd
parent2512da7ca57dc4c52900417a50daf4f6f2f74054 (diff)
downloadiosdc-japan-2025-albatross-a4685927a1f7fe8374a567ee74cc62aad639f4c3.tar.gz
iosdc-japan-2025-albatross-a4685927a1f7fe8374a567ee74cc62aad639f4c3.tar.zst
iosdc-japan-2025-albatross-a4685927a1f7fe8374a567ee74cc62aad639f4c3.zip
user login
-rw-r--r--backend/Makefile3
-rw-r--r--backend/auth.go19
-rw-r--r--backend/db/db.go32
-rw-r--r--backend/db/models.go32
-rw-r--r--backend/db/query.sql.go49
-rw-r--r--backend/go.mod60
-rw-r--r--backend/go.sum186
-rw-r--r--backend/main.go121
-rw-r--r--backend/query.sql4
-rw-r--r--backend/sqlc.yaml4
-rw-r--r--backend/tools.go7
-rw-r--r--compose.yaml3
-rw-r--r--frontend/src/main.tsx18
-rw-r--r--frontend/src/routes/Login.tsx21
-rw-r--r--frontend/src/routes/teams/Edit.tsx19
-rw-r--r--frontend/src/routes/teams/New.tsx19
-rw-r--r--frontend/src/routes/users/Edit.tsx22
17 files changed, 569 insertions, 50 deletions
diff --git a/backend/Makefile b/backend/Makefile
new file mode 100644
index 0000000..cae3b16
--- /dev/null
+++ b/backend/Makefile
@@ -0,0 +1,3 @@
+.PHONY: sqlc
+sqlc:
+ go run github.com/sqlc-dev/sqlc/cmd/sqlc generate
diff --git a/backend/auth.go b/backend/auth.go
new file mode 100644
index 0000000..f27b8c0
--- /dev/null
+++ b/backend/auth.go
@@ -0,0 +1,19 @@
+package main
+
+import (
+ "context"
+ "fmt"
+
+ "iosdc-code-battle-poc/db"
+)
+
+func authLogin(ctx context.Context, queries *db.Queries, username, password string) (int, error) {
+ userAuth, err := queries.GetUserAuthFromUsername(ctx, username)
+ if err != nil {
+ return 0, err
+ }
+ if userAuth.AuthType == "bypass" {
+ return int(userAuth.UserID), nil
+ }
+ return 0, fmt.Errorf("not implemented")
+}
diff --git a/backend/db/db.go b/backend/db/db.go
new file mode 100644
index 0000000..5b8c8f5
--- /dev/null
+++ b/backend/db/db.go
@@ -0,0 +1,32 @@
+// Code generated by sqlc. DO NOT EDIT.
+// versions:
+// sqlc v1.26.0
+
+package db
+
+import (
+ "context"
+
+ "github.com/jackc/pgx/v5"
+ "github.com/jackc/pgx/v5/pgconn"
+)
+
+type DBTX interface {
+ Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
+ Query(context.Context, string, ...interface{}) (pgx.Rows, error)
+ QueryRow(context.Context, string, ...interface{}) pgx.Row
+}
+
+func New(db DBTX) *Queries {
+ return &Queries{db: db}
+}
+
+type Queries struct {
+ db DBTX
+}
+
+func (q *Queries) WithTx(tx pgx.Tx) *Queries {
+ return &Queries{
+ db: tx,
+ }
+}
diff --git a/backend/db/models.go b/backend/db/models.go
new file mode 100644
index 0000000..bc2010d
--- /dev/null
+++ b/backend/db/models.go
@@ -0,0 +1,32 @@
+// Code generated by sqlc. DO NOT EDIT.
+// versions:
+// sqlc v1.26.0
+
+package db
+
+import (
+ "github.com/jackc/pgx/v5/pgtype"
+)
+
+type Game struct {
+ GameID int32
+ Type string
+ CreatedAt pgtype.Timestamp
+ State string
+}
+
+type User struct {
+ UserID int32
+ Username string
+ DisplayUsername string
+ IconUrl pgtype.Text
+ IsAdmin bool
+ CreatedAt pgtype.Timestamp
+}
+
+type UserAuth struct {
+ UserAuthID int32
+ UserID int32
+ AuthType string
+ PasswordHash pgtype.Text
+}
diff --git a/backend/db/query.sql.go b/backend/db/query.sql.go
new file mode 100644
index 0000000..d5158b5
--- /dev/null
+++ b/backend/db/query.sql.go
@@ -0,0 +1,49 @@
+// Code generated by sqlc. DO NOT EDIT.
+// versions:
+// sqlc v1.26.0
+// source: query.sql
+
+package db
+
+import (
+ "context"
+
+ "github.com/jackc/pgx/v5/pgtype"
+)
+
+const getUserAuthFromUsername = `-- name: GetUserAuthFromUsername :one
+SELECT users.user_id, username, display_username, icon_url, is_admin, created_at, user_auth_id, user_auths.user_id, auth_type, password_hash FROM users
+JOIN user_auths ON users.user_id = user_auths.user_id
+WHERE users.username = $1
+`
+
+type GetUserAuthFromUsernameRow struct {
+ UserID int32
+ Username string
+ DisplayUsername string
+ IconUrl pgtype.Text
+ IsAdmin bool
+ CreatedAt pgtype.Timestamp
+ UserAuthID int32
+ UserID_2 int32
+ AuthType string
+ PasswordHash pgtype.Text
+}
+
+func (q *Queries) GetUserAuthFromUsername(ctx context.Context, username string) (GetUserAuthFromUsernameRow, error) {
+ row := q.db.QueryRow(ctx, getUserAuthFromUsername, username)
+ var i GetUserAuthFromUsernameRow
+ err := row.Scan(
+ &i.UserID,
+ &i.Username,
+ &i.DisplayUsername,
+ &i.IconUrl,
+ &i.IsAdmin,
+ &i.CreatedAt,
+ &i.UserAuthID,
+ &i.UserID_2,
+ &i.AuthType,
+ &i.PasswordHash,
+ )
+ return i, err
+}
diff --git a/backend/go.mod b/backend/go.mod
index 63e750f..b03cf2e 100644
--- a/backend/go.mod
+++ b/backend/go.mod
@@ -4,6 +4,62 @@ go 1.22.3
require (
github.com/gorilla/websocket v1.5.3
- github.com/jmoiron/sqlx v1.4.0
- github.com/lib/pq v1.10.9
+ github.com/jackc/pgx/v5 v5.5.5
+ github.com/sqlc-dev/sqlc v1.26.0
+)
+
+require (
+ filippo.io/edwards25519 v1.1.0 // indirect
+ github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
+ github.com/cubicdaiya/gonp v1.0.4 // indirect
+ github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 // indirect
+ github.com/davecgh/go-spew v1.1.1 // indirect
+ github.com/dustin/go-humanize v1.0.1 // indirect
+ github.com/fatih/structtag v1.2.0 // indirect
+ github.com/go-sql-driver/mysql v1.8.1 // indirect
+ github.com/golang/protobuf v1.5.3 // indirect
+ github.com/google/cel-go v0.20.1 // indirect
+ github.com/google/uuid v1.6.0 // indirect
+ github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
+ github.com/inconshreveable/mousetrap v1.1.0 // indirect
+ github.com/jackc/pgpassfile v1.0.0 // indirect
+ github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
+ github.com/jackc/puddle/v2 v2.2.1 // indirect
+ github.com/jinzhu/inflection v1.0.0 // indirect
+ github.com/mattn/go-isatty v0.0.16 // indirect
+ github.com/ncruces/go-strftime v0.1.9 // indirect
+ github.com/pganalyze/pg_query_go/v5 v5.1.0 // indirect
+ github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63 // indirect
+ github.com/pingcap/failpoint v0.0.0-20220801062533-2eaa32854a6c // indirect
+ github.com/pingcap/log v1.1.0 // indirect
+ github.com/pingcap/tidb/pkg/parser v0.0.0-20231103154709-4f00ece106b1 // indirect
+ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
+ github.com/riza-io/grpc-go v0.2.0 // indirect
+ github.com/spf13/cobra v1.8.0 // indirect
+ github.com/spf13/pflag v1.0.5 // indirect
+ github.com/stoewer/go-strcase v1.2.0 // indirect
+ github.com/tetratelabs/wazero v1.7.0 // indirect
+ github.com/wasilibs/go-pgquery v0.0.0-20240319230125-b9b2e95c69a7 // indirect
+ go.uber.org/atomic v1.11.0 // indirect
+ go.uber.org/multierr v1.11.0 // indirect
+ go.uber.org/zap v1.26.0 // indirect
+ golang.org/x/crypto v0.20.0 // indirect
+ golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 // indirect
+ golang.org/x/net v0.21.0 // indirect
+ golang.org/x/sync v0.6.0 // indirect
+ golang.org/x/sys v0.17.0 // indirect
+ golang.org/x/text v0.14.0 // indirect
+ google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
+ google.golang.org/grpc v1.62.1 // indirect
+ google.golang.org/protobuf v1.33.0 // indirect
+ gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
+ modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
+ modernc.org/libc v1.41.0 // indirect
+ modernc.org/mathutil v1.6.0 // indirect
+ modernc.org/memory v1.7.2 // indirect
+ modernc.org/sqlite v1.29.5 // indirect
+ modernc.org/strutil v1.2.0 // indirect
+ modernc.org/token v1.1.0 // indirect
)
diff --git a/backend/go.sum b/backend/go.sum
index b60655d..09f3607 100644
--- a/backend/go.sum
+++ b/backend/go.sum
@@ -1,12 +1,190 @@
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
+github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
+github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
+github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cubicdaiya/gonp v1.0.4 h1:ky2uIAJh81WiLcGKBVD5R7KsM/36W6IqqTy6Bo6rGws=
+github.com/cubicdaiya/gonp v1.0.4/go.mod h1:iWGuP/7+JVTn02OWhRemVbMmG1DOUnmrGTYYACpOI0I=
+github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 h1:iwZdTE0PVqJCos1vaoKsclOGD3ADKpshg3SRtYBbwso=
+github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
+github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
+github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
+github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
+github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/google/cel-go v0.20.1 h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84=
+github.com/google/cel-go v0.20.1/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
+github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
-github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
-github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
-github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
-github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
+github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
+github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
+github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
+github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
+github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
+github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
+github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
+github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
+github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
+github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
+github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
+github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
+github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
+github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
+github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
+github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
+github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
+github.com/pganalyze/pg_query_go/v5 v5.1.0 h1:MlxQqHZnvA3cbRQYyIrjxEjzo560P6MyTgtlaf3pmXg=
+github.com/pganalyze/pg_query_go/v5 v5.1.0/go.mod h1:FsglvxidZsVN+Ltw3Ai6nTgPVcK2BPukH3jCDEqc1Ug=
+github.com/pingcap/errors v0.11.0/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
+github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
+github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63 h1:+FZIDR/D97YOPik4N4lPDaUcLDF/EQPogxtlHB2ZZRM=
+github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63/go.mod h1:X2r9ueLEUZgtx2cIogM0v4Zj5uvvzhuuiu7Pn8HzMPg=
+github.com/pingcap/failpoint v0.0.0-20220801062533-2eaa32854a6c h1:CgbKAHto5CQgWM9fSBIvaxsJHuGP0uM74HXtv3MyyGQ=
+github.com/pingcap/failpoint v0.0.0-20220801062533-2eaa32854a6c/go.mod h1:4qGtCB0QK0wBzKtFEGDhxXnSnbQApw1gc9siScUl8ew=
+github.com/pingcap/log v1.1.0 h1:ELiPxACz7vdo1qAvvaWJg1NrYFoY6gqAh/+Uo6aXdD8=
+github.com/pingcap/log v1.1.0/go.mod h1:DWQW5jICDR7UJh4HtxXSM20Churx4CQL0fwL/SoOSA4=
+github.com/pingcap/tidb/pkg/parser v0.0.0-20231103154709-4f00ece106b1 h1:SwGY3zMnK4wO85vvRIqrR3Yh6VpIC9pydG0QNOUPHCY=
+github.com/pingcap/tidb/pkg/parser v0.0.0-20231103154709-4f00ece106b1/go.mod h1:yRkiqLFwIqibYg2P7h4bclHjHcJiIFRLKhGRyBcKYus=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
+github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
+github.com/riza-io/grpc-go v0.2.0 h1:2HxQKFVE7VuYstcJ8zqpN84VnAoJ4dCL6YFhJewNcHQ=
+github.com/riza-io/grpc-go v0.2.0/go.mod h1:2bDvR9KkKC3KhtlSHfR3dAXjUMT86kg4UfWFyVGWqi8=
+github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
+github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
+github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
+github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
+github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/sqlc-dev/sqlc v1.26.0 h1:bW6TA1vVdi2lfqsEddN5tSznRMYcWez7hf+AOqSiEp8=
+github.com/sqlc-dev/sqlc v1.26.0/go.mod h1:k2F3RWilLCup3D0XufrzZENCyXjtplALmHDmOt4v5bs=
+github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU=
+github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/tetratelabs/wazero v1.7.0 h1:jg5qPydno59wqjpGrHph81lbtHzTrWzwwtD4cD88+hQ=
+github.com/tetratelabs/wazero v1.7.0/go.mod h1:ytl6Zuh20R/eROuyDaGPkp82O9C/DJfXAwJfQ3X6/7Y=
+github.com/wasilibs/go-pgquery v0.0.0-20240319230125-b9b2e95c69a7 h1:sqqLVb63En4uTKFKBWSJ7c1aIFonhM1yn35/+KchOf4=
+github.com/wasilibs/go-pgquery v0.0.0-20240319230125-b9b2e95c69a7/go.mod h1:ZAUjWnxivykc22k0TKFZylOV0WlVQ9nWMExfGFIBuF4=
+go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
+go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
+go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
+go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
+go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
+go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
+go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
+go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
+go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
+go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
+go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
+go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg=
+golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
+golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 h1:mchzmB1XO2pMaKFRqk/+MV3mgGG96aqaPXaMifQU47w=
+golang.org/x/exp v0.0.0-20231108232855-2478ac86f678/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
+golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
+golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
+golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
+golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
+golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 h1:Lj5rbfG876hIAYFjqiJnPHfhXbv+nzTWfm04Fg/XSVU=
+google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80/go.mod h1:4jWUdICTdgc3Ibxmr8nAJiiLHwQBY0UI0XZcEMaFKaA=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s=
+google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk=
+google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
+google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
+gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
+gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
+modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
+modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI=
+modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
+modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk=
+modernc.org/libc v1.41.0/go.mod h1:w0eszPsiXoOnoMJgrXjglgLuDy/bt5RR4y3QzUUeodY=
+modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
+modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
+modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E=
+modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E=
+modernc.org/sqlite v1.29.5 h1:8l/SQKAjDtZFo9lkJLdk8g9JEOeYRG4/ghStDCCTiTE=
+modernc.org/sqlite v1.29.5/go.mod h1:S02dvcmm7TnTRvGhv8IGYyLnIt7AS2KPaB1F/71p75U=
+modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
+modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
+modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
+modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
diff --git a/backend/main.go b/backend/main.go
index ae39b46..66ab015 100644
--- a/backend/main.go
+++ b/backend/main.go
@@ -1,15 +1,18 @@
package main
import (
+ "context"
+ "encoding/json"
"fmt"
"log"
"net/http"
"os"
"strconv"
- "time"
+ "strings"
- "github.com/jmoiron/sqlx"
- _ "github.com/lib/pq"
+ "github.com/jackc/pgx/v5"
+
+ "iosdc-code-battle-poc/db"
)
type Config struct {
@@ -22,8 +25,6 @@ type Config struct {
var config *Config
-var db *sqlx.DB
-
func loadEnv() (*Config, error) {
dbHost, exists := os.LookupEnv("ALBATROSS_DB_HOST")
if !exists {
@@ -84,37 +85,81 @@ func startGame(game *Game) {
}
func handleGolfPost(w http.ResponseWriter, r *http.Request) {
- var yourTeam string
- waitingGolfGames := []Game{}
- err := db.Select(&waitingGolfGames, "SELECT * FROM games WHERE type = $1 AND state = $2 ORDER BY created_at", gameTypeGolf, gameStateWaiting)
- if err != nil {
- http.Error(w, "Error getting games", http.StatusInternalServerError)
- return
- }
- if len(waitingGolfGames) == 0 {
- _, err = db.Exec("INSERT INTO games (type, state) VALUES ($1, $2)", gameTypeGolf, gameStateWaiting)
- if err != nil {
- http.Error(w, "Error creating game", http.StatusInternalServerError)
- return
- }
- waitingGolfGames = []Game{}
- err = db.Select(&waitingGolfGames, "SELECT * FROM games WHERE type = $1 AND state = $2 ORDER BY created_at", gameTypeGolf, gameStateWaiting)
+ /*
+ var yourTeam string
+ waitingGolfGames := []Game{}
+ err := db.Select(&waitingGolfGames, "SELECT * FROM games WHERE type = $1 AND state = $2 ORDER BY created_at", gameTypeGolf, gameStateWaiting)
if err != nil {
http.Error(w, "Error getting games", http.StatusInternalServerError)
return
}
- yourTeam = "a"
- startGame(&waitingGolfGames[0])
- } else {
- yourTeam = "b"
- db.Exec("UPDATE games SET state = $1 WHERE game_id = $2", gameStateReady, waitingGolfGames[0].GameID)
- }
- waitingGame := waitingGolfGames[0]
+ if len(waitingGolfGames) == 0 {
+ _, err = db.Exec("INSERT INTO games (type, state) VALUES ($1, $2)", gameTypeGolf, gameStateWaiting)
+ if err != nil {
+ http.Error(w, "Error creating game", http.StatusInternalServerError)
+ return
+ }
+ waitingGolfGames = []Game{}
+ err = db.Select(&waitingGolfGames, "SELECT * FROM games WHERE type = $1 AND state = $2 ORDER BY created_at", gameTypeGolf, gameStateWaiting)
+ if err != nil {
+ http.Error(w, "Error getting games", http.StatusInternalServerError)
+ return
+ }
+ yourTeam = "a"
+ startGame(&waitingGolfGames[0])
+ } else {
+ yourTeam = "b"
+ db.Exec("UPDATE games SET state = $1 WHERE game_id = $2", gameStateReady, waitingGolfGames[0].GameID)
+ }
+ waitingGame := waitingGolfGames[0]
- http.Redirect(w, r, fmt.Sprintf("/golf/%d/%s/", waitingGame.GameID, yourTeam), http.StatusSeeOther)
+ http.Redirect(w, r, fmt.Sprintf("/golf/%d/%s/", waitingGame.GameID, yourTeam), http.StatusSeeOther)
+ */
}
-func handleApiLogin(w http.ResponseWriter, r *http.Request) {
+func handleApiLogin(w http.ResponseWriter, r *http.Request, queries *db.Queries) {
+ type LoginRequestData struct {
+ Username string `json:"username"`
+ Password string `json:"password"`
+ }
+
+ type LoginResponseData struct {
+ UserId int `json:"userId"`
+ }
+
+ ctx := r.Context()
+
+ contentType := r.Header.Get("Content-Type")
+ if !strings.HasPrefix(contentType, "application/json") {
+ http.Error(w, "Content-Type is not application/json", http.StatusBadRequest)
+ return
+ }
+
+ var requestData LoginRequestData
+ decoder := json.NewDecoder(r.Body)
+ err := decoder.Decode(&requestData)
+ if err != nil {
+ http.Error(w, "Failed to decode JSON", http.StatusBadRequest)
+ return
+ }
+
+ userId, err := authLogin(ctx, queries, requestData.Username, requestData.Password)
+ if err != nil {
+ http.Error(w, "Login failed", http.StatusUnauthorized)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ responseData := LoginResponseData{
+ UserId: userId,
+ }
+ encoder := json.NewEncoder(w)
+ err = encoder.Encode(responseData)
+ if err != nil {
+ http.Error(w, "Failed to encode JSON", http.StatusInternalServerError)
+ return
+ }
}
func main() {
@@ -125,17 +170,15 @@ func main() {
return
}
- for i := 0; i < 5; i++ {
- db, err = sqlx.Connect("postgres", fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", config.dbHost, config.dbPort, config.dbUser, config.dbPassword, config.dbName))
- if err == nil {
- break
- }
- time.Sleep(5 * time.Second)
- }
+ ctx := context.Background()
+
+ conn, err := pgx.Connect(ctx, fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", config.dbHost, config.dbPort, config.dbUser, config.dbPassword, config.dbName))
if err != nil {
log.Fatalf("Error connecting to db %v", err)
}
- defer db.Close()
+ defer conn.Close(ctx)
+
+ queries := db.New(conn)
server := http.NewServeMux()
@@ -194,8 +237,8 @@ func main() {
serveWs(hub, w, r, team)
})
- server.HandleFunc("POST /api/login/{$}", func(w http.ResponseWriter, r *http.Request) {
- handleApiLogin(w, r)
+ server.HandleFunc("POST /api/login", func(w http.ResponseWriter, r *http.Request) {
+ handleApiLogin(w, r, queries)
})
defer func() {
diff --git a/backend/query.sql b/backend/query.sql
index e69de29..bdcd657 100644
--- a/backend/query.sql
+++ b/backend/query.sql
@@ -0,0 +1,4 @@
+-- name: GetUserAuthFromUsername :one
+SELECT * FROM users
+JOIN user_auths ON users.user_id = user_auths.user_id
+WHERE users.username = $1;
diff --git a/backend/sqlc.yaml b/backend/sqlc.yaml
index 4027d9b..6fc3310 100644
--- a/backend/sqlc.yaml
+++ b/backend/sqlc.yaml
@@ -5,6 +5,6 @@ sql:
schema: "schema.sql"
gen:
go:
- package: "sqlc"
- out: "sqlc"
+ package: "db"
+ out: "db"
sql_package: "pgx/v5"
diff --git a/backend/tools.go b/backend/tools.go
new file mode 100644
index 0000000..7e7d6a6
--- /dev/null
+++ b/backend/tools.go
@@ -0,0 +1,7 @@
+//go:build tools
+
+package tools
+
+import (
+ _ "github.com/sqlc-dev/sqlc/cmd/sqlc"
+)
diff --git a/compose.yaml b/compose.yaml
index 1192903..e5b3994 100644
--- a/compose.yaml
+++ b/compose.yaml
@@ -6,7 +6,8 @@ services:
ports:
- '8002:80'
depends_on:
- - db
+ db:
+ condition: service_healthy
environment:
ALBATROSS_DB_HOST: db
ALBATROSS_DB_PORT: 5432
diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx
index eb5399f..6019704 100644
--- a/frontend/src/main.tsx
+++ b/frontend/src/main.tsx
@@ -5,10 +5,13 @@ import {
RouterProvider,
} from 'react-router-dom';
import Home from './routes/Home.tsx';
-import Login from './routes/Login.tsx';
+import Login, { loginAction } from './routes/Login.tsx';
import GolfEntry from './routes/golf/GolfEntry.tsx';
import GolfPlay from './routes/golf/GolfPlay.tsx';
import GolfWatch from './routes/golf/GolfWatch.tsx';
+import UserEdit from './routes/users/Edit.tsx';
+import TeamNew from './routes/teams/New.tsx';
+import TeamEdit from './routes/teams/Edit.tsx';
const router = createBrowserRouter([
{
@@ -18,6 +21,19 @@ const router = createBrowserRouter([
{
path: "/login/",
element: (<Login />),
+ action: loginAction,
+ },
+ {
+ path: "/users/:userId/",
+ element: (<UserEdit />),
+ },
+ {
+ path: "/teams/new/",
+ element: (<TeamNew />),
+ },
+ {
+ path: "/teams/:teamId/",
+ element: (<TeamEdit />),
},
{
path: "/golf/entry/",
diff --git a/frontend/src/routes/Login.tsx b/frontend/src/routes/Login.tsx
index 1945abe..f3fa00e 100644
--- a/frontend/src/routes/Login.tsx
+++ b/frontend/src/routes/Login.tsx
@@ -1,4 +1,4 @@
-import { Form } from "react-router-dom";
+import { redirect, Form, ActionFunctionArgs } from "react-router-dom";
export default function Login() {
return (
@@ -17,3 +17,22 @@ export default function Login() {
</div>
);
};
+
+export async function loginAction({ request }: ActionFunctionArgs) {
+ const formData = await request.formData();
+ const username = formData.get("username");
+ const password = formData.get("password");
+
+ const res = await fetch("/api/login", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({ username, password }),
+ });
+ if (!res.ok) {
+ throw res;
+ }
+ const { userId } = await res.json();
+ return redirect(`/users/${userId}/`);
+};
diff --git a/frontend/src/routes/teams/Edit.tsx b/frontend/src/routes/teams/Edit.tsx
new file mode 100644
index 0000000..0b3ed74
--- /dev/null
+++ b/frontend/src/routes/teams/Edit.tsx
@@ -0,0 +1,19 @@
+import { Form } from "react-router-dom";
+
+export default function Edit() {
+ return (
+ <div>
+ <h1>Albatross.swift</h1>
+ <h2>
+ Team Edit
+ </h2>
+ <Form method="post">
+ <label>Team name</label>
+ <input type="text" name="name" />
+ <label>Icon</label>
+ <input type="text" name="icon" disabled />
+ <button type="submit">Save</button>
+ </Form>
+ </div>
+ );
+};
diff --git a/frontend/src/routes/teams/New.tsx b/frontend/src/routes/teams/New.tsx
new file mode 100644
index 0000000..2712cd5
--- /dev/null
+++ b/frontend/src/routes/teams/New.tsx
@@ -0,0 +1,19 @@
+import { Form } from "react-router-dom";
+
+export default function New() {
+ return (
+ <div>
+ <h1>Albatross.swift</h1>
+ <h2>
+ Team New
+ </h2>
+ <Form method="post">
+ <label>Team name</label>
+ <input type="text" name="name" />
+ <label>Icon</label>
+ <input type="text" name="icon" disabled />
+ <button type="submit">Create</button>
+ </Form>
+ </div>
+ );
+};
diff --git a/frontend/src/routes/users/Edit.tsx b/frontend/src/routes/users/Edit.tsx
new file mode 100644
index 0000000..fa2a826
--- /dev/null
+++ b/frontend/src/routes/users/Edit.tsx
@@ -0,0 +1,22 @@
+import { Form, Link } from "react-router-dom";
+
+export default function Edit() {
+ return (
+ <div>
+ <h1>Albatross.swift</h1>
+ <h2>
+ User Edit
+ </h2>
+ <Form method="post">
+ <label>Display name</label>
+ <input type="text" name="display_name" />
+ <label>Icon</label>
+ <input type="text" name="icon" disabled />
+ <button type="submit">Save</button>
+ </Form>
+ <p>
+ <Link to="/teams/new/">Create a new team</Link>
+ </p>
+ </div>
+ );
+};