2025-11-03 12:22:06 +00:00
|
|
|
package main
|
2025-11-03 12:38:47 +00:00
|
|
|
|
2025-11-03 12:22:06 +00:00
|
|
|
import (
|
2025-11-04 23:11:32 +00:00
|
|
|
"context"
|
2025-11-03 12:38:47 +00:00
|
|
|
"log"
|
|
|
|
|
"net/http"
|
|
|
|
|
"os"
|
|
|
|
|
"time"
|
|
|
|
|
|
2025-11-05 17:15:33 +00:00
|
|
|
"github.com/alexedwards/scs/pgxstore"
|
2025-11-03 12:38:47 +00:00
|
|
|
"github.com/alexedwards/scs/v2"
|
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
|
|
|
"github.com/go-chi/chi/v5/middleware"
|
2025-11-03 12:22:06 +00:00
|
|
|
)
|
2025-11-03 12:38:47 +00:00
|
|
|
|
|
|
|
|
var sessionManager *scs.SessionManager
|
|
|
|
|
|
|
|
|
|
var BaseURL, ClientID, ClientSecret string
|
|
|
|
|
|
2025-11-03 12:22:06 +00:00
|
|
|
func main() {
|
2025-11-03 12:38:47 +00:00
|
|
|
ClientID = os.Getenv("ARCGIS_CLIENT_ID")
|
|
|
|
|
if ClientID == "" {
|
2025-11-04 23:11:32 +00:00
|
|
|
log.Println("You must specify a non-empty ARCGIS_CLIENT_ID")
|
2025-11-03 12:38:47 +00:00
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
ClientSecret = os.Getenv("ARCGIS_CLIENT_SECRET")
|
|
|
|
|
if ClientSecret == "" {
|
2025-11-04 23:11:32 +00:00
|
|
|
log.Println("You must specify a non-empty ARCGIS_CLIENT_SECRET")
|
2025-11-03 12:38:47 +00:00
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
BaseURL = os.Getenv("BASE_URL")
|
|
|
|
|
if BaseURL == "" {
|
|
|
|
|
log.Println("You must specify a non-empty BASE_URL")
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
bind := os.Getenv("BIND")
|
|
|
|
|
if bind == "" {
|
|
|
|
|
bind = ":9001"
|
|
|
|
|
}
|
2025-11-04 23:11:32 +00:00
|
|
|
pg_dsn := os.Getenv("POSTGRES_DSN")
|
|
|
|
|
if pg_dsn == "" {
|
|
|
|
|
log.Println("You must specify a non-empty POSTGRES_DSN")
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
2025-11-03 12:38:47 +00:00
|
|
|
|
|
|
|
|
log.Println("Starting...")
|
2025-11-04 23:11:32 +00:00
|
|
|
err := initializeDatabase(context.TODO(), pg_dsn)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Printf("Failed to connect to database: %v", err)
|
|
|
|
|
os.Exit(2)
|
|
|
|
|
}
|
2025-11-03 12:38:47 +00:00
|
|
|
sessionManager = scs.New()
|
2025-11-05 17:15:33 +00:00
|
|
|
sessionManager.Store = pgxstore.New(PGInstance.PGXPool)
|
2025-11-03 12:38:47 +00:00
|
|
|
sessionManager.Lifetime = 24 * time.Hour
|
|
|
|
|
|
|
|
|
|
r := chi.NewRouter()
|
|
|
|
|
r.Use(middleware.Logger)
|
|
|
|
|
r.Use(sessionManager.LoadAndSave)
|
|
|
|
|
|
|
|
|
|
r.Get("/", getRoot)
|
2025-11-06 00:23:58 +00:00
|
|
|
r.Get("/arcgis/oauth/begin", getArcgisOauthBegin)
|
|
|
|
|
r.Get("/arcgis/oauth/callback", getArcgisOauthCallback)
|
2025-11-05 21:21:58 +00:00
|
|
|
r.Get("/qr-code/report/{code}", getQRCodeReport)
|
2025-11-05 21:05:10 +00:00
|
|
|
r.Get("/report", getReport)
|
2025-11-05 21:37:11 +00:00
|
|
|
r.Get("/report/{code}", getReportDetail)
|
2025-11-05 22:03:33 +00:00
|
|
|
r.Get("/report/{code}/confirm", getReportConfirmation)
|
2025-11-05 21:51:23 +00:00
|
|
|
r.Get("/report/{code}/contribute", getReportContribute)
|
|
|
|
|
r.Get("/report/{code}/evidence", getReportEvidence)
|
2025-11-05 21:57:59 +00:00
|
|
|
r.Get("/report/{code}/schedule", getReportSchedule)
|
2025-11-05 23:41:21 +00:00
|
|
|
r.Get("/report/{code}/update", getReportUpdate)
|
2025-11-05 17:15:33 +00:00
|
|
|
r.Post("/signin", postSignin)
|
2025-11-04 00:02:51 +00:00
|
|
|
r.Get("/signup", getSignup)
|
2025-11-04 23:21:13 +00:00
|
|
|
r.Post("/signup", postSignup)
|
2025-11-03 12:38:47 +00:00
|
|
|
r.Get("/favicon.ico", getFavicon)
|
2025-11-03 22:13:11 +00:00
|
|
|
|
|
|
|
|
localFS := http.Dir("./static")
|
|
|
|
|
FileServer(r, "/static", localFS, embeddedStaticFS, "static")
|
|
|
|
|
|
2025-11-07 02:07:33 +00:00
|
|
|
newTokenChannel := make(chan int)
|
|
|
|
|
endChannel := make(chan struct{})
|
|
|
|
|
go refreshFieldseekerData(newTokenChannel, endChannel)
|
2025-11-03 12:38:47 +00:00
|
|
|
log.Printf("Serving on %s", bind)
|
|
|
|
|
log.Fatal(http.ListenAndServe(bind, r))
|
2025-11-03 12:22:06 +00:00
|
|
|
}
|