Fixed the device sign
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
// cmd/shard/main.go
|
||||
package main
|
||||
|
||||
import (
|
||||
@@ -26,7 +27,7 @@ func getenvBool(key string, def bool) bool {
|
||||
|
||||
func staticHeaders(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// Security posture for static client
|
||||
// Security headers
|
||||
w.Header().Set("Referrer-Policy", "no-referrer")
|
||||
w.Header().Set("Cross-Origin-Opener-Policy", "same-origin")
|
||||
w.Header().Set("Cross-Origin-Resource-Policy", "same-site")
|
||||
@@ -35,10 +36,7 @@ func staticHeaders(next http.Handler) http.Handler {
|
||||
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||
w.Header().Set("Strict-Transport-Security", "max-age=15552000; includeSubDomains; preload")
|
||||
|
||||
// Strong CSP to block XSS/token theft (enumerate your API host)
|
||||
w.Header().Set("Content-Security-Policy", "default-src 'self'; base-uri 'none'; object-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; connect-src 'self' https://api-gc.fullmooncyberworks.com; frame-ancestors 'none'")
|
||||
|
||||
// CORS for assets
|
||||
// Basic CORS for static (GET only effectively)
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
if r.Method == http.MethodOptions {
|
||||
w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS")
|
||||
@@ -51,6 +49,7 @@ func staticHeaders(next http.Handler) http.Handler {
|
||||
}
|
||||
|
||||
func main() {
|
||||
// ---- Config ----
|
||||
httpAddr := os.Getenv("GC_HTTP_ADDR")
|
||||
if httpAddr == "" {
|
||||
httpAddr = ":9080"
|
||||
@@ -59,52 +58,52 @@ func main() {
|
||||
certFile := os.Getenv("GC_TLS_CERT")
|
||||
keyFile := os.Getenv("GC_TLS_KEY")
|
||||
|
||||
staticAddr := os.Getenv("GC_STATIC_ADDR")
|
||||
if staticAddr == "" {
|
||||
staticAddr = ":9082"
|
||||
}
|
||||
staticDir := os.Getenv("GC_STATIC_DIR")
|
||||
if staticDir == "" {
|
||||
staticDir = "/opt/greencoast/client"
|
||||
}
|
||||
|
||||
dataDir := os.Getenv("GC_DATA_DIR")
|
||||
if dataDir == "" {
|
||||
dataDir = "/var/lib/greencoast"
|
||||
}
|
||||
|
||||
staticDir := os.Getenv("GC_STATIC_DIR")
|
||||
if staticDir == "" {
|
||||
staticDir = "/opt/greencoast/client"
|
||||
}
|
||||
staticAddr := os.Getenv("GC_STATIC_ADDR")
|
||||
if staticAddr == "" {
|
||||
staticAddr = ":9082"
|
||||
}
|
||||
|
||||
coarseTS := getenvBool("GC_COARSE_TS", false)
|
||||
zeroTrust := getenvBool("GC_ZERO_TRUST", true)
|
||||
encRequired := getenvBool("GC_ENCRYPTION_REQUIRED", true) // operator-blind by default
|
||||
requirePOP := getenvBool("GC_REQUIRE_POP", true) // for logging only; API defaults to true internally
|
||||
|
||||
signingSecretHex := os.Getenv("GC_SIGNING_SECRET_HEX")
|
||||
|
||||
discID := os.Getenv("GC_DISCORD_CLIENT_ID")
|
||||
discSecret := os.Getenv("GC_DISCORD_CLIENT_SECRET")
|
||||
discRedirect := os.Getenv("GC_DISCORD_REDIRECT_URI")
|
||||
|
||||
// ---- Storage & Index ----
|
||||
store, err := storage.NewFS(dataDir)
|
||||
if err != nil {
|
||||
log.Fatalf("storage init: %v", err)
|
||||
}
|
||||
|
||||
ix := index.New()
|
||||
|
||||
// Auto-reindex on boot if possible
|
||||
if w, ok := any(store).(interface {
|
||||
Walk(func(hash string, size int64, mod time.Time) error) error
|
||||
}); ok {
|
||||
if err := w.Walk(func(hash string, size int64, mod time.Time) error {
|
||||
return ix.Put(index.Entry{
|
||||
Hash: hash,
|
||||
Bytes: size,
|
||||
StoredAt: mod.UTC().Format(time.RFC3339Nano),
|
||||
Private: false,
|
||||
})
|
||||
}); err != nil {
|
||||
log.Printf("reindex on boot: %v", err)
|
||||
}
|
||||
// Reindex on boot from whatever files exist on disk
|
||||
if err := store.Walk(func(hash string, size int64, mod time.Time) error {
|
||||
return ix.Put(index.Entry{
|
||||
Hash: hash,
|
||||
Bytes: size,
|
||||
StoredAt: mod.UTC().Format(time.RFC3339Nano),
|
||||
Private: false, // unknown here; safe default
|
||||
})
|
||||
}); err != nil {
|
||||
log.Printf("reindex on boot: %v", err)
|
||||
}
|
||||
|
||||
ap := api.AuthProviders{
|
||||
// ---- Auth providers ----
|
||||
providers := api.AuthProviders{
|
||||
SigningSecretHex: signingSecretHex,
|
||||
Discord: api.DiscordProvider{
|
||||
Enabled: discID != "" && discSecret != "" && discRedirect != "",
|
||||
@@ -114,35 +113,28 @@ func main() {
|
||||
},
|
||||
}
|
||||
|
||||
srv := api.New(store, ix, coarseTS, zeroTrust, ap)
|
||||
// ---- API server ----
|
||||
srv := api.New(store, ix, coarseTS, zeroTrust, providers, encRequired)
|
||||
|
||||
// Static client server (9082)
|
||||
// ---- Static file server (separate listener) ----
|
||||
go func() {
|
||||
if st, err := os.Stat(staticDir); err != nil || !st.IsDir() {
|
||||
log.Printf("WARN: GC_STATIC_DIR %q not found or not a dir; client may 404", staticDir)
|
||||
}
|
||||
mux := http.NewServeMux()
|
||||
|
||||
// Optional: forward API paths to API host to avoid 404 if user hits wrong host
|
||||
mux.Handle("/v1/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, "https://api-gc.fullmooncyberworks.com"+r.URL.Path, http.StatusTemporaryRedirect)
|
||||
}))
|
||||
|
||||
mux.Handle("/", http.FileServer(http.Dir(staticDir)))
|
||||
fs := http.FileServer(http.Dir(staticDir))
|
||||
h := staticHeaders(fs)
|
||||
log.Printf("static listening on %s (dir=%s)", staticAddr, staticDir)
|
||||
if err := http.ListenAndServe(staticAddr, staticHeaders(mux)); err != nil {
|
||||
if err := http.ListenAndServe(staticAddr, h); err != nil {
|
||||
log.Fatalf("static server: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
// ---- Start API (HTTP or HTTPS) ----
|
||||
if httpsAddr != "" && certFile != "" && keyFile != "" {
|
||||
log.Printf("starting HTTPS API on %s", httpsAddr)
|
||||
log.Printf("API HTTPS %s POP:%v ENC_REQUIRED:%v", httpsAddr, requirePOP, encRequired)
|
||||
if err := srv.ListenHTTPS(httpsAddr, certFile, keyFile); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
log.Printf("starting HTTP API on %s", httpAddr)
|
||||
log.Printf("API HTTP %s POP:%v ENC_REQUIRED:%v", httpAddr, requirePOP, encRequired)
|
||||
if err := srv.ListenHTTP(httpAddr); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
Reference in New Issue
Block a user