-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmain.go
More file actions
103 lines (90 loc) · 2.9 KB
/
main.go
File metadata and controls
103 lines (90 loc) · 2.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package main
import (
"context"
"os"
"os/signal"
clts "polybot/clients"
"polybot/config"
"polybot/internal/app"
"strings"
"syscall"
"time"
"go.uber.org/zap"
)
const (
// loadTimeout is the maximum time to wait for loading from gist
loadTimeout = 30 * time.Second
)
func main() {
logger, err := zap.NewProduction()
if err != nil {
panic(err)
}
defer logger.Sync()
// Load config from environment variables
envConfig := config.Load()
logger.Info("starting bot", zap.Bool("isProd", envConfig.IsProd))
// Create LiveConfig with env config as initial value
liveConfig := config.NewLiveConfig(envConfig)
// Initialize clients (needed for Gist access)
logger.Info("instantiating clients")
clients := clts.NewClients(logger, envConfig)
// Get settings Gist ID from env
settingsGistID := os.Getenv("SETTINGS_GIST_ID")
// Create SettingsManager
settingsManager := config.NewSettingsManager(logger, clients.Gist, settingsGistID, liveConfig)
// Load settings from Gist if enabled
if settingsManager.IsEnabled() {
logger.Info("loading settings from gist", zap.String("gist_id", settingsGistID))
loadCtx, loadCancel := context.WithTimeout(context.Background(), loadTimeout)
cfg, err := settingsManager.LoadSettings(loadCtx, envConfig)
loadCancel()
if err != nil {
logger.Warn("failed to load settings from gist, using env/defaults", zap.Error(err))
} else if cfg != nil {
if err := liveConfig.Update(cfg); err != nil {
logger.Warn("failed to apply gist settings", zap.Error(err))
} else {
logger.Info("settings loaded from gist")
}
}
} else {
logger.Info("settings gist not configured, using env/defaults")
}
// Create AuthHandler for passkey authentication
var authHandler *app.AuthHandler
rpID := os.Getenv("WEBAUTHN_RP_ID")
rpOriginsStr := os.Getenv("WEBAUTHN_RP_ORIGINS")
logger.Info("webauthn config from env",
zap.String("WEBAUTHN_RP_ID", rpID),
zap.String("WEBAUTHN_RP_ORIGINS", rpOriginsStr),
)
if settingsGistID != "" && rpID != "" && rpOriginsStr != "" {
rpOrigins := strings.Split(rpOriginsStr, ",")
var err error
authHandler, err = app.NewAuthHandler(logger, clients.Gist, settingsGistID, rpID, rpOrigins)
if err != nil {
logger.Warn("failed to create auth handler", zap.Error(err))
} else {
loadCtx, loadCancel := context.WithTimeout(context.Background(), loadTimeout)
err := authHandler.LoadCredentials(loadCtx)
loadCancel()
if err != nil {
logger.Warn("failed to load passkeys from gist", zap.Error(err))
}
}
} else if settingsGistID != "" {
logger.Info("passkey auth not configured (WEBAUTHN_RP_ID and WEBAUTHN_RP_ORIGINS required)")
}
ctx, stop := signal.NotifyContext(
context.Background(),
os.Interrupt,
syscall.SIGINT,
syscall.SIGTERM,
)
defer stop()
runner := app.NewRunner(clients, liveConfig, settingsManager, authHandler)
if err := runner.Run(ctx); err != nil {
logger.Fatal("runner failed", zap.Error(err))
}
}