Files
foundry-core/cmd/foundry/main.go
codex-bot 5c0ad30a7a
Foundry Go checks / check (push) Failing after 2m2s
Foundry Go checks / check (pull_request) Failing after 2m4s
Add Slack OpenID login with verified identities and callback replay protection
2026-11-05 18:49:41 +08:00

80 lines
2.6 KiB
Go

package main
import (
"context"
"encoding/json"
"log"
"net"
"net/http"
"net/url"
"os"
"time"
"gitea.entroia.com/Zayden-Jung/foundry-core/internal/auth"
"gitea.entroia.com/Zayden-Jung/foundry-core/internal/codex"
"gitea.entroia.com/Zayden-Jung/foundry-core/internal/platform"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/stdlib"
)
func env(key, fallback string) string {
if value := os.Getenv(key); value != "" {
return value
}
return fallback
}
func main() {
if len(os.Args) == 2 && os.Args[1] == "codex-worker" {
log.Fatal(codex.ServeWorker("/run/foundry-codex/worker.sock"))
}
origin, err := url.Parse(os.Getenv("PUBLIC_ORIGIN"))
if err != nil || origin.Scheme != "https" || origin.Hostname() == "" || origin.User != nil ||
(origin.Path != "" && origin.Path != "/") || origin.RawQuery != "" || origin.Fragment != "" {
log.Fatal("PUBLIC_ORIGIN must be an HTTPS origin")
}
var callbacks map[string]string
if err := json.Unmarshal([]byte(os.Getenv("FOUNDRY_PROJECTS")), &callbacks); err != nil || len(callbacks) == 0 {
log.Fatal("FOUNDRY_PROJECTS must configure at least one project")
}
id, secret, dsn := os.Getenv("GOOGLE_CLIENT_ID"), os.Getenv("GOOGLE_CLIENT_SECRET"), os.Getenv("DATABASE_URL")
if id == "" || secret == "" || dsn == "" {
log.Fatal("Google credentials and DATABASE_URL are required")
}
config, err := pgx.ParseConfig(dsn)
if err != nil {
log.Fatal("Invalid DATABASE_URL")
}
db := stdlib.OpenDB(*config)
defer db.Close()
email, err := auth.EmailConfigFromEnv()
if err != nil {
log.Fatal(err)
}
go email.Run(context.Background(), db)
slack, err := auth.SlackConfigFromEnv(origin.ResolveReference(&url.URL{Path: "/auth/slack/callback"}).String())
if err != nil {
log.Fatal(err)
}
handler, err := auth.New(db, callbacks, origin.ResolveReference(&url.URL{Path: "/auth/google/callback"}).String(), id, secret, email, slack)
if err != nil {
log.Fatal(err)
}
mux := http.NewServeMux()
if err := codex.Register(mux, callbacks, os.Getenv("FOUNDRY_CODEX_SOCKET"), os.Getenv("FOUNDRY_CODEX_GRANTS")); err != nil {
log.Fatal(err)
}
onboarding, err := platform.ParseOnboarding(os.Getenv("FOUNDRY_ONBOARDING"), callbacks)
if err != nil {
log.Fatal(err)
}
platform.Register(mux, db, callbacks, origin.Scheme+"://"+origin.Host, onboarding)
mux.Handle("/", handler)
server := &http.Server{
Addr: net.JoinHostPort(env("HOST", "127.0.0.1"), env("PORT", "8080")),
Handler: mux, ReadHeaderTimeout: 5 * time.Second, ReadTimeout: 10 * time.Second,
WriteTimeout: 110 * time.Second, IdleTimeout: 60 * time.Second,
}
log.Fatal(server.ListenAndServe())
}