From ed478db50ce898359ad40d9befbb39b6f7c3c0b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Lukas=20=7E=20Znox=20/=20Pl=C3=A4nkler?= <60503970+Plaenkler@users.noreply.github.com> Date: Sat, 17 Aug 2024 21:15:30 +0200 Subject: [PATCH 01/10] [UPD] Revised logging - Log to file and stdout/stderr - Automatic tracing of the origin of the logs --- pkg/logging/logging.go | 82 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 14 deletions(-) diff --git a/pkg/logging/logging.go b/pkg/logging/logging.go index d6c4e5e..cdcd612 100644 --- a/pkg/logging/logging.go +++ b/pkg/logging/logging.go @@ -1,38 +1,92 @@ package logging import ( + "fmt" + "io" "log" "os" + "path/filepath" + "runtime" + "strings" ) const ( - INFO = "[\033[0;32mINF\033[0m] " - ERROR = "[\033[0;31mERR\033[0m] " - FATAL = "[\033[0;31mFAT\033[0m] " + pathToLog = "./data/ddns.log" + dirPerm = 0755 + filePerm = 0644 + INFO = "[INF]" + ERROR = "[ERR]" + FATAL = "[FAT]" + INFOC = "[\033[0;32mINF\033[0m] " + ERRORC = "[\033[0;31mERR\033[0m] " + FATALC = "[\033[0;31mFAT\033[0m] " + UNKOWN = "unknown-origin" ) -var logger *Logger - type Logger struct { infoLogger *log.Logger errorLogger *log.Logger } +var ( + consoleLogger *Logger + fileLogger *Logger + logFile *os.File +) + func init() { - logger = &Logger{ - infoLogger: log.New(os.Stdout, "", log.Ldate|log.Ltime), - errorLogger: log.New(os.Stderr, "", log.Ldate|log.Ltime), + consoleLogger = createLogger(os.Stdout, os.Stderr) + openLogFile() + fileLogger = createLogger(logFile, logFile) +} + +func openLogFile() { + err := os.MkdirAll(filepath.Dir(pathToLog), dirPerm) + if err != nil { + log.Fatalf("could not open log: %v", err) + } + file, err := os.OpenFile(pathToLog, os.O_CREATE|os.O_WRONLY|os.O_APPEND, filePerm) + if err != nil { + log.Fatalf("could not open log: %v", err) + } + logFile = file +} + +func createLogger(infoOutput io.Writer, errorOutput io.Writer) *Logger { + return &Logger{ + infoLogger: log.New(infoOutput, "", log.Ldate|log.Ltime), + errorLogger: log.New(errorOutput, "", log.Ldate|log.Ltime), } } -func Infof(format string, args ...interface{}) { - logger.infoLogger.Printf(INFO+format, args...) +func Infof(msg string, args ...interface{}) { + consoleLogger.infoLogger.Printf(INFOC+trace()+"message: "+msg, args...) + fileLogger.infoLogger.Printf(INFO+trace()+"message: "+msg, args...) +} + +func Errorf(msg string, args ...interface{}) { + consoleLogger.errorLogger.Printf(ERRORC+trace()+"message: "+msg, args...) + fileLogger.errorLogger.Printf(ERROR+trace()+"message: "+msg, args...) } -func Errorf(format string, args ...interface{}) { - logger.errorLogger.Printf(ERROR+format, args...) +func Fatalf(msg string, args ...interface{}) { + consoleLogger.errorLogger.Fatalf(FATALC+trace()+"message: "+msg, args...) + fileLogger.errorLogger.Fatalf(FATAL+trace()+"message: "+msg, args...) } -func Fatalf(format string, args ...interface{}) { - logger.errorLogger.Fatalf(FATAL+format, args...) +func trace() string { + pc, _, line, ok := runtime.Caller(2) + if !ok { + return UNKOWN + } + f := runtime.FuncForPC(pc) + if f == nil { + return UNKOWN + } + origin := f.Name() + parts := strings.Split(origin, "/") + if len(parts) > 0 { + origin = parts[len(parts)-1] + } + return fmt.Sprintf("origin: %v line: %v ", strings.Replace(origin, ".", "-", -1), line) } From 45292209c41006b12cb396b4b45b316db1f3d1bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Lukas=20=7E=20Znox=20/=20Pl=C3=A4nkler?= <60503970+Plaenkler@users.noreply.github.com> Date: Sat, 17 Aug 2024 21:17:14 +0200 Subject: [PATCH 02/10] [UPD] Removed traces of logs --- cmd/def/main.go | 16 +++++++-------- cmd/svc/main.go | 24 +++++++++++----------- pkg/cipher/cipher.go | 18 ++++++++--------- pkg/config/config.go | 4 ++-- pkg/database/service.go | 10 ++++----- pkg/ddns/resolver.go | 10 ++++----- pkg/ddns/service.go | 24 +++++++++++----------- pkg/server/limiter.go | 4 ++-- pkg/server/routes/api/config.go | 14 ++++++------- pkg/server/routes/api/inputs.go | 8 ++++---- pkg/server/routes/api/job.go | 36 ++++++++++++++++----------------- pkg/server/routes/api/login.go | 4 ++-- pkg/server/routes/web/index.go | 14 ++++++------- pkg/server/routes/web/login.go | 4 ++-- pkg/server/service.go | 6 +++--- pkg/server/totps/totps.go | 2 +- 16 files changed, 99 insertions(+), 99 deletions(-) diff --git a/cmd/def/main.go b/cmd/def/main.go index 7f277b9..b587feb 100644 --- a/cmd/def/main.go +++ b/cmd/def/main.go @@ -13,22 +13,22 @@ import ( func main() { database.Start() - log.Infof("[main-main-1] started database connection") + log.Infof("started database connection") go ddns.Start() - log.Infof("[main-main-2] started ddns service") + log.Infof("started ddns service") go session.Start() - log.Infof("[main-main-3] started session service") + log.Infof("started session service") go server.Start() - log.Infof("[main-main-4] started webserver") + log.Infof("started webserver") c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) <-c server.Stop() - log.Infof("[main-main-5] stopped webserver") + log.Infof("stopped webserver") session.Stop() - log.Infof("[main-main-6] stopped session service") + log.Infof("stopped session service") ddns.Stop() - log.Infof("[main-main-7] stopped ddns service") + log.Infof("stopped ddns service") database.Stop() - log.Infof("[main-main-8] stopped database connection") + log.Infof("stopped database connection") } diff --git a/cmd/svc/main.go b/cmd/svc/main.go index f2834f8..e24605c 100644 --- a/cmd/svc/main.go +++ b/cmd/svc/main.go @@ -16,25 +16,25 @@ type program struct{} func (p *program) Start(_ service.Service) error { database.Start() - log.Infof("[main-Start-1] started database connection") + log.Infof("started database connection") go ddns.Start() - log.Infof("[main-Start-2] started ddns service") + log.Infof("started ddns service") go session.Start() - log.Infof("[main-Start-3] started session service") + log.Infof("started session service") go server.Start() - log.Infof("[main-Start-4] started webserver") + log.Infof("started webserver") return nil } func (p *program) Stop(_ service.Service) error { server.Stop() - log.Infof("[main-Stop-1] stopped webserver") + log.Infof("stopped webserver") session.Stop() - log.Infof("[main-Stop-2] stopped session service") + log.Infof("stopped session service") ddns.Stop() - log.Infof("[main-Stop-3] stopped ddns service") + log.Infof("stopped ddns service") database.Stop() - log.Infof("[main-Stop-4] stopped database connection") + log.Infof("stopped database connection") return nil } @@ -43,14 +43,14 @@ func main() { p := &program{} err := p.Start(nil) if err != nil { - log.Fatalf("[main-main-0] failed to start service: %v", err) + log.Fatalf("failed to start service: %v", err) } c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) <-c err = p.Stop(nil) if err != nil { - log.Fatalf("[main-main-0] failed to stop service: %v", err) + log.Fatalf("failed to stop service: %v", err) } return } @@ -62,10 +62,10 @@ func main() { prg := &program{} s, err := service.New(prg, svcConfig) if err != nil { - log.Fatalf("[main-main-1] failed to create service: %v", err) + log.Fatalf("failed to create service: %v", err) } err = s.Run() if err != nil { - log.Errorf("[main-main-2] failed to run service: %v", err) + log.Errorf("failed to run service: %v", err) } } diff --git a/pkg/cipher/cipher.go b/pkg/cipher/cipher.go index b26ab77..6d639ec 100644 --- a/pkg/cipher/cipher.go +++ b/pkg/cipher/cipher.go @@ -27,7 +27,7 @@ func init() { var err error key, err = read() if err != nil { - log.Fatalf("[cipher-init-1] could not load key: %v", err) + log.Fatalf("could not load key: %v", err) } } @@ -80,16 +80,16 @@ func generate() ([]byte, error) { func Encrypt(plaintext string) (string, error) { encrypter, err := aes.NewCipher(key) if err != nil { - return "", fmt.Errorf("[cipher-Encrypt-1] encryption failed: %s", err) + return "", fmt.Errorf("encryption failed: %s", err) } gcm, err := cipher.NewGCM(encrypter) if err != nil { - return "", fmt.Errorf("[cipher-Encrypt-2] encryption failed: %s", err) + return "", fmt.Errorf("encryption failed: %s", err) } nonce := make([]byte, gcm.NonceSize()) _, err = io.ReadFull(rand.Reader, nonce) if err != nil { - return "", fmt.Errorf("[cipher-Encrypt-3] encryption failed: %s", err) + return "", fmt.Errorf("encryption failed: %s", err) } return base64.StdEncoding.EncodeToString(gcm.Seal(nonce, nonce, []byte(plaintext), nil)), nil } @@ -97,24 +97,24 @@ func Encrypt(plaintext string) (string, error) { func Decrypt(ciphertext string) ([]byte, error) { c, err := aes.NewCipher(key) if err != nil { - return nil, fmt.Errorf("[cipher-Decrypt-1] decryption failed: %s", err) + return nil, fmt.Errorf("decryption failed: %s", err) } gcm, err := cipher.NewGCM(c) if err != nil { - return nil, fmt.Errorf("[cipher-Decrypt-2] decryption failed: %s", err) + return nil, fmt.Errorf("decryption failed: %s", err) } cipherBytes, err := base64.StdEncoding.DecodeString(ciphertext) if err != nil { - return nil, fmt.Errorf("[cipher-Decrypt-3] decryption failed: %s", err) + return nil, fmt.Errorf("decryption failed: %s", err) } nonceSize := gcm.NonceSize() if len(cipherBytes) < nonceSize { - return nil, fmt.Errorf("[cipher-Decrypt-4] decryption failed: %s", err) + return nil, fmt.Errorf("decryption failed: %s", err) } nonce, cipherBytes := cipherBytes[:nonceSize], cipherBytes[nonceSize:] plaintext, err := gcm.Open(nil, nonce, cipherBytes, nil) if err != nil { - return nil, fmt.Errorf("[cipher-Decrypt-5] decryption failed: %s", err) + return nil, fmt.Errorf("decryption failed: %s", err) } return plaintext, nil } diff --git a/pkg/config/config.go b/pkg/config/config.go index 6b8e9f2..3c2a764 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -34,7 +34,7 @@ var ( func init() { err := load() if err != nil { - log.Fatalf("[config-init-1] initialization failed: %s", err.Error()) + log.Fatalf("initialization failed: %s", err.Error()) } } @@ -83,7 +83,7 @@ func create() error { if err != nil { return err } - log.Infof("[config-create-1] created default configuration") + log.Infof("created default configuration") return nil } diff --git a/pkg/database/service.go b/pkg/database/service.go index a80782e..5bc9ee5 100644 --- a/pkg/database/service.go +++ b/pkg/database/service.go @@ -24,15 +24,15 @@ func Start() { oc.Do(func() { err := createDBDir() if err != nil { - log.Fatalf("[database-Start-1] failed to create database directory: %s", err.Error()) + log.Fatalf("failed to create database directory: %s", err.Error()) } db, err = openDBConnection() if err != nil { - log.Fatalf("[database-Start-2] failed to open database connection: %s", err.Error()) + log.Fatalf("failed to open database connection: %s", err.Error()) } err = migrateDBSchema(db) if err != nil { - log.Fatalf("[database-Start-3] failed to migrate database schema: %s", err.Error()) + log.Fatalf("failed to migrate database schema: %s", err.Error()) } }) } @@ -70,12 +70,12 @@ func Stop() { } sqlDB, err := db.DB() if err != nil { - log.Errorf("[database-Stop-1] failed to get underlying DB connection: %s", err.Error()) + log.Errorf("failed to get underlying DB connection: %s", err.Error()) return } err = sqlDB.Close() if err != nil { - log.Errorf("[database-Stop-2] failed to close DB connection: %s", err.Error()) + log.Errorf("failed to close DB connection: %s", err.Error()) } } diff --git a/pkg/ddns/resolver.go b/pkg/ddns/resolver.go index b6b3565..c00c3cd 100644 --- a/pkg/ddns/resolver.go +++ b/pkg/ddns/resolver.go @@ -26,21 +26,21 @@ func GetPublicIP() (string, error) { if cRes != "" { addr, err := resolveIPAddress(cRes) if err != nil { - return "", fmt.Errorf("[ddns-GetPublicIP-1] resolver %s failed: %s", cRes, err) + return "", fmt.Errorf("resolver %s failed: %s", cRes, err) } - log.Infof("[ddns-GetPublicIP-2] %s succeeded: %s", cRes, addr) + log.Infof("%s succeeded: %s", cRes, addr) return addr, nil } for r := range resolvers { addr, err := resolveIPAddress(resolvers[r]) if err != nil { - log.Errorf("[ddns-GetPublicIP-3] resolver %s failed: %s", r, err) + log.Errorf("resolver %s failed: %s", r, err) continue } - log.Infof("[ddns-GetPublicIP-4] %s succeeded: %s", r, addr) + log.Infof("%s succeeded: %s", r, addr) return addr, nil } - return "", fmt.Errorf("[ddns-GetPublicIP-5] all resolvers failed") + return "", fmt.Errorf("all resolvers failed") } func resolveIPAddress(url string) (string, error) { diff --git a/pkg/ddns/service.go b/pkg/ddns/service.go index fa2e331..e445318 100644 --- a/pkg/ddns/service.go +++ b/pkg/ddns/service.go @@ -31,7 +31,7 @@ func Start() { updateInterval(interval, ticker) address, err := GetPublicIP() if err != nil { - log.Errorf("[ddns-Start-1] failed to get public IP address: %v", err) + log.Errorf("failed to get public IP address: %v", err) continue } newAddress := model.IPAddress{ @@ -39,17 +39,17 @@ func Start() { } db := database.GetDatabase() if db == nil { - log.Errorf("[ddns-Start-2] failed to get database connection") + log.Errorf("failed to get database connection") continue } err = db.FirstOrCreate(&newAddress, newAddress).Error if err != nil { - log.Errorf("[ddns-Start-3] failed to save new IP address: %v", err) + log.Errorf("failed to save new IP address: %v", err) continue } jobs := getSyncJobs(db, newAddress.ID) if len(jobs) == 0 { - log.Infof("[ddns-Start-4] no dynamic DNS record needs to be updated") + log.Infof("no dynamic DNS record needs to be updated") continue } updateDDNSEntries(db, jobs, newAddress) @@ -63,7 +63,7 @@ func updateInterval(interval time.Duration, ticker *time.Ticker) { newInterval := time.Second * time.Duration(config.Get().Interval) if interval != newInterval && newInterval > 0 { ticker.Reset(newInterval) - log.Infof("[ddns-updateInterval-1] changed interval from %v to %v", interval, newInterval) + log.Infof("changed interval from %v to %v", interval, newInterval) } } @@ -71,7 +71,7 @@ func getSyncJobs(db *gorm.DB, addressID uint) []model.SyncJob { var jobs []model.SyncJob err := db.Where("NOT ip_address_id = ? OR ip_address_id IS NULL", addressID).Find(&jobs).Error if err != nil { - log.Errorf("[ddns-getSyncJobs-1] failed to get DDNS update jobs: %v", err) + log.Errorf("failed to get DDNS update jobs: %v", err) return nil } return jobs @@ -81,30 +81,30 @@ func updateDDNSEntries(db *gorm.DB, jobs []model.SyncJob, a model.IPAddress) { for _, job := range jobs { updater, ok := updaters[job.Provider] if !ok { - log.Errorf("[ddns-updateDDNSEntries-1] no updater found for job %v", job.ID) + log.Errorf("no updater found for job %v", job.ID) continue } params, err := cipher.Decrypt(job.Params) if err != nil { - log.Errorf("[ddns-updateDDNSEntries-2] failed to decrypt job params for job %v: %s", job.ID, err) + log.Errorf("failed to decrypt job params for job %v: %s", job.ID, err) continue } request := reflect.New(reflect.TypeOf(updater.Request)).Interface() err = json.Unmarshal(params, &request) if err != nil { - log.Errorf("[ddns-updateDDNSEntries-3] failed to unmarshal job params for job %v: %s", job.ID, err) + log.Errorf("failed to unmarshal job params for job %v: %s", job.ID, err) continue } err = updater.Updater(request, a.Address) if err != nil { - log.Errorf("[ddns-updateDDNSEntries-4] failed to update DDNS entry for job %v: %s", job.ID, err) + log.Errorf("failed to update DDNS entry for job %v: %s", job.ID, err) continue } err = db.Model(&job).Update("ip_address_id", a.ID).Error if err != nil { - log.Errorf("[ddns-updateDDNSEntries-5] failed to update IP address for job %v: %s", job.ID, err) + log.Errorf("failed to update IP address for job %v: %s", job.ID, err) } - log.Infof("[ddns-updateDDNSEntries-6] updated DDNS entry for ID: %v", job.ID) + log.Infof("updated DDNS entry for ID: %v", job.ID) } } diff --git a/pkg/server/limiter.go b/pkg/server/limiter.go index d93bec5..879a60b 100644 --- a/pkg/server/limiter.go +++ b/pkg/server/limiter.go @@ -17,7 +17,7 @@ var ipLimiters = map[string]ipLimiter{} func isOverLimit(r *http.Request) error { addr, err := getRealClientIP(r) if err != nil { - return fmt.Errorf("[server-IsOverLimit-1] could not get client ip address") + return fmt.Errorf("could not get client ip address") } iplm, ok := ipLimiters[addr] if !ok { @@ -28,7 +28,7 @@ func isOverLimit(r *http.Request) error { ipLimiters[addr] = iplm } if !iplm.limiter.Allow() { - return fmt.Errorf("[server-IsOverLimit-2] ip address %s is over limit", addr) + return fmt.Errorf("ip address %s is over limit", addr) } return nil } diff --git a/pkg/server/routes/api/config.go b/pkg/server/routes/api/config.go index a8660de..a2de71e 100644 --- a/pkg/server/routes/api/config.go +++ b/pkg/server/routes/api/config.go @@ -14,25 +14,25 @@ import ( func UpdateConfig(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err != nil { - log.Errorf("[api-UpdateConfig-1] could not parse form err: %s", err.Error()) + log.Errorf("could not parse form err: %s", err.Error()) w.WriteHeader(http.StatusBadRequest) return } port64, err := strconv.ParseUint(r.FormValue("port"), 10, 16) if err != nil { - log.Errorf("[api-UpdateConfig-2] port is not valid: %s", err) + log.Errorf("port is not valid: %s", err) w.WriteHeader(http.StatusBadRequest) return } port := uint16(port64) interval64, err := strconv.ParseUint(r.FormValue("interval"), 10, 32) if err != nil { - log.Errorf("[api-UpdateConfig-3] interval is not valid: %s", err) + log.Errorf("interval is not valid: %s", err) w.WriteHeader(http.StatusBadRequest) return } if interval64 < 10 { - log.Errorf("[api-UpdateConfig-4] interval is too small: %s", err) + log.Errorf("interval is too small: %s", err) w.WriteHeader(http.StatusBadRequest) return } @@ -41,7 +41,7 @@ func UpdateConfig(w http.ResponseWriter, r *http.Request) { if resolver != "" { _, err = url.ParseRequestURI(resolver) if err != nil { - log.Errorf("[api-UpdateConfig-5] resolver is not valid: %s", err) + log.Errorf("resolver is not valid: %s", err) w.WriteHeader(http.StatusBadRequest) return } @@ -54,11 +54,11 @@ func UpdateConfig(w http.ResponseWriter, r *http.Request) { } if totps.Verify(r.FormValue("otp")) { cfg.UseTOTP = !cfg.UseTOTP - log.Infof("[api-UpdateConfig-6] Token verified TOTP is now %t", cfg.UseTOTP) + log.Infof("Token verified TOTP is now %t", cfg.UseTOTP) } err = config.Update(cfg) if err != nil { - log.Errorf("[api-UpdateConfig-7] could not update config: %s", err) + log.Errorf("could not update config: %s", err) w.WriteHeader(http.StatusInternalServerError) return } diff --git a/pkg/server/routes/api/inputs.go b/pkg/server/routes/api/inputs.go index e88baec..1d13671 100644 --- a/pkg/server/routes/api/inputs.go +++ b/pkg/server/routes/api/inputs.go @@ -10,24 +10,24 @@ import ( func GetInputs(w http.ResponseWriter, r *http.Request) { provider := r.URL.Query().Get("provider") if provider == "" { - http.Error(w, "[api-GetInputs-1] missing provider", http.StatusBadRequest) + http.Error(w, "missing provider", http.StatusBadRequest) return } updater, ok := ddns.GetUpdaters()[provider] if !ok { - http.Error(w, "[api-GetInputs-2] provider is not valid", http.StatusBadRequest) + http.Error(w, "provider is not valid", http.StatusBadRequest) return } fields := updater.Request inputs, err := json.Marshal(fields) if err != nil { - http.Error(w, "[api-GetInputs-3] could not marshal fields", http.StatusInternalServerError) + http.Error(w, "could not marshal fields", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") _, err = w.Write(inputs) if err != nil { - http.Error(w, "[api-GetInputs-4] could not write response", http.StatusInternalServerError) + http.Error(w, "could not write response", http.StatusInternalServerError) return } } diff --git a/pkg/server/routes/api/job.go b/pkg/server/routes/api/job.go index f55883c..a3b5f5b 100644 --- a/pkg/server/routes/api/job.go +++ b/pkg/server/routes/api/job.go @@ -18,7 +18,7 @@ import ( func CreateJob(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err != nil { - log.Errorf("[api-CreateJob-1] could not parse form: %s", err) + log.Errorf("could not parse form: %s", err) http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } @@ -27,12 +27,12 @@ func CreateJob(w http.ResponseWriter, r *http.Request) { err = verifyJobModel(provider, params) if err != nil { http.Error(w, "Invalid values", http.StatusBadRequest) - log.Errorf("[api-UpdateJob-2] invalid values: %s", err) + log.Errorf("invalid values: %s", err) return } encParams, err := cipher.Encrypt(params) if err != nil { - log.Errorf("[api-CreateJob-3] could not encrypt params: %s", err) + log.Errorf("could not encrypt params: %s", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } @@ -42,31 +42,31 @@ func CreateJob(w http.ResponseWriter, r *http.Request) { } db := database.GetDatabase() if db == nil { - log.Errorf("[api-CreateJob-4] could not get database connection") + log.Errorf("could not get database connection") http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } err = db.Create(&job).Error if err != nil { - log.Errorf("[api-CreateJob-5] could not create job: %s", err) + log.Errorf("could not create job: %s", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } http.Redirect(w, r, r.Header.Get("Referer"), http.StatusSeeOther) - log.Infof("[api-CreateJob-6] created job with ID %d", job.ID) + log.Infof("created job with ID %d", job.ID) } func UpdateJob(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err != nil { http.Error(w, "Could not parse form", http.StatusBadRequest) - log.Errorf("[api-UpdateJob-1] could not parse form: %s", err) + log.Errorf("could not parse form: %s", err) return } id, err := strconv.ParseUint(r.FormValue("ID"), 10, 32) if err != nil { http.Error(w, "ID is not valid", http.StatusBadRequest) - log.Errorf("[api-UpdateJob-2] ID is not valid: %s", err) + log.Errorf("ID is not valid: %s", err) return } provider := r.FormValue("provider") @@ -74,13 +74,13 @@ func UpdateJob(w http.ResponseWriter, r *http.Request) { err = verifyJobModel(provider, params) if err != nil { http.Error(w, "Invalid values", http.StatusBadRequest) - log.Errorf("[api-UpdateJob-3] invalid values: %s", err) + log.Errorf("invalid values: %s", err) return } encParams, err := cipher.Encrypt(params) if err != nil { http.Error(w, "Could not encrypt params", http.StatusInternalServerError) - log.Errorf("[api-UpdateJob-4] could not encrypt params: %s", err) + log.Errorf("could not encrypt params: %s", err) return } job := model.SyncJob{ @@ -93,29 +93,29 @@ func UpdateJob(w http.ResponseWriter, r *http.Request) { db := database.GetDatabase() if db == nil { http.Error(w, "Could not get database connection", http.StatusInternalServerError) - log.Errorf("[api-UpdateJob-5] could not get database connection") + log.Errorf("could not get database connection") return } err = db.Save(&job).Error if err != nil { http.Error(w, "Could not update job", http.StatusInternalServerError) - log.Errorf("[api-UpdateJob-6] could not update job: %s", err) + log.Errorf("could not update job: %s", err) return } http.Redirect(w, r, r.Header.Get("Referer"), http.StatusSeeOther) - log.Infof("[api-UpdateJob-7] updated job with ID %d", job.ID) + log.Infof("updated job with ID %d", job.ID) } func DeleteJob(w http.ResponseWriter, r *http.Request) { strID := r.URL.Query().Get("ID") if len(strID) == 0 { - log.Errorf("[api-DeleteJob-1] ID is not set") + log.Errorf("ID is not set") http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } id, err := strconv.ParseUint(strID, 10, 32) if err != nil { - log.Errorf("[api-DeleteJob-2] ID is not valid: %s", err) + log.Errorf("ID is not valid: %s", err) http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } @@ -126,17 +126,17 @@ func DeleteJob(w http.ResponseWriter, r *http.Request) { } db := database.GetDatabase() if db == nil { - log.Errorf("[api-DeleteJob-3] could not get database connection") + log.Errorf("could not get database connection") http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } if err := db.Unscoped().Delete(&job).Error; err != nil { - log.Errorf("[api-DeleteJob-4] could not delete job: %s", err) + log.Errorf("could not delete job: %s", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } http.Redirect(w, r, r.Header.Get("Referer"), http.StatusSeeOther) - log.Infof("[api-DeleteJob-5] deleted job with ID %d", job.ID) + log.Infof("deleted job with ID %d", job.ID) } func verifyJobModel(provider, params string) error { diff --git a/pkg/server/routes/api/login.go b/pkg/server/routes/api/login.go index 5957442..bc55377 100644 --- a/pkg/server/routes/api/login.go +++ b/pkg/server/routes/api/login.go @@ -12,13 +12,13 @@ import ( func Login(w http.ResponseWriter, r *http.Request) { currentTOTP := r.FormValue("totp") if !totps.Verify(currentTOTP) { - log.Errorf("[api-login-1] invalid totp: %s", currentTOTP) + log.Errorf("invalid totp: %s", currentTOTP) http.Redirect(w, r, "/login", http.StatusSeeOther) return } token, err := session.Add() if err != nil { - log.Errorf("[api-login-2] could not add session: %s", err) + log.Errorf("could not add session: %s", err) http.Redirect(w, r, "/login", http.StatusSeeOther) return } diff --git a/pkg/server/routes/web/index.go b/pkg/server/routes/web/index.go index cb45d7c..82c233d 100644 --- a/pkg/server/routes/web/index.go +++ b/pkg/server/routes/web/index.go @@ -37,13 +37,13 @@ func ProvideIndex(w http.ResponseWriter, r *http.Request) { addr, err := ddns.GetPublicIP() if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "[web-ProvideIndex-1] could not get public IP address: %s", err) + fmt.Fprintf(w, "could not get public IP address: %s", err) return } img, err := totps.GetKeyAsQR() if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "[web-ProvideIndex-2] could not generate TOTP QR code: %s", err) + fmt.Fprintf(w, "could not generate TOTP QR code: %s", err) return } data := indexPageData{ @@ -55,19 +55,19 @@ func ProvideIndex(w http.ResponseWriter, r *http.Request) { db := database.GetDatabase() if db == nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "[web-ProvideIndex-3] could not get database connection") + fmt.Fprintf(w, "could not get database connection") return } err = db.Find(&data.Jobs).Error if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "[web-ProvideIndex-4] could not find jobs: %s", err) + fmt.Fprintf(w, "could not find jobs: %s", err) return } err = sanitizeParams(data.Jobs) if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "[web-ProvideIndex-5] formatting params failed: %s", err) + fmt.Fprintf(w, "formatting params failed: %s", err) return } tpl, err := template.New("index").Funcs(template.FuncMap{ @@ -80,14 +80,14 @@ func ProvideIndex(w http.ResponseWriter, r *http.Request) { ) if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "[web-ProvideIndex-6] could not provide template: %s", err) + fmt.Fprintf(w, "could not provide template: %s", err) return } w.Header().Add("Content-Type", "text/html") err = tpl.Execute(w, data) if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "[web-ProvideIndex-7] could not execute parsed template: %v", err) + fmt.Fprintf(w, "could not execute parsed template: %v", err) } } diff --git a/pkg/server/routes/web/login.go b/pkg/server/routes/web/login.go index 4912dc6..63ced41 100644 --- a/pkg/server/routes/web/login.go +++ b/pkg/server/routes/web/login.go @@ -13,13 +13,13 @@ func ProvideLogin(w http.ResponseWriter, r *http.Request) { ) if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "[web-ProvideLogin-1] could not provide template: %s", err) + fmt.Fprintf(w, "could not provide template: %s", err) return } w.Header().Add("Content-Type", "text/html") err = tpl.Execute(w, nil) if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "[web-ProvideLogin-2] could not execute parsed template: %v", err) + fmt.Fprintf(w, "could not execute parsed template: %v", err) } } diff --git a/pkg/server/service.go b/pkg/server/service.go index 0982942..166b73f 100644 --- a/pkg/server/service.go +++ b/pkg/server/service.go @@ -68,7 +68,7 @@ func registerStaticFiles(r *Router) { func createStaticHandler() http.Handler { fs, err := fs.Sub(static, "routes/web/static") if err != nil { - log.Fatalf("[server-createStaticHandler-1] could not create static handler: %v", err) + log.Fatalf("could not create static handler: %v", err) } return controlCache(http.FileServer(http.FS(fs))) } @@ -85,13 +85,13 @@ func initializeServer() { go func() { err := server.ListenAndServe() if err != nil && err != http.ErrServerClosed { - log.Fatalf("[server-initializeServer-1] could not initialize server: %v", err) + log.Fatalf("could not initialize server: %v", err) } }() <-cancel err := server.Shutdown(context.Background()) if err != nil { - log.Fatalf("[server-initializeServer-2] could not shutdown server: %v", err) + log.Fatalf("could not shutdown server: %v", err) } } diff --git a/pkg/server/totps/totps.go b/pkg/server/totps/totps.go index 6c50fff..07ee124 100644 --- a/pkg/server/totps/totps.go +++ b/pkg/server/totps/totps.go @@ -29,7 +29,7 @@ func init() { var err error keySecret, err = read() if err != nil { - log.Fatalf("[totp-init-1] could not load secret: %v", err) + log.Fatalf("could not load secret: %v", err) } } From 3596afd5f46529e0718474dde2f664c929ef68f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Lukas=20=7E=20Znox=20/=20Pl=C3=A4nkler?= <60503970+Plaenkler@users.noreply.github.com> Date: Sun, 18 Aug 2024 17:29:27 +0200 Subject: [PATCH 03/10] [FIX] Spacing after severity --- pkg/logging/logging.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/logging/logging.go b/pkg/logging/logging.go index cdcd612..b035d66 100644 --- a/pkg/logging/logging.go +++ b/pkg/logging/logging.go @@ -14,9 +14,9 @@ const ( pathToLog = "./data/ddns.log" dirPerm = 0755 filePerm = 0644 - INFO = "[INF]" - ERROR = "[ERR]" - FATAL = "[FAT]" + INFO = "[INF] " + ERROR = "[ERR] " + FATAL = "[FAT] " INFOC = "[\033[0;32mINF\033[0m] " ERRORC = "[\033[0;31mERR\033[0m] " FATALC = "[\033[0;31mFAT\033[0m] " From b08afdd0663e989c2d5bb5321234daa28ae2fc3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Lukas=20=7E=20Znox=20/=20Pl=C3=A4nkler?= <60503970+Plaenkler@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:13:28 +0200 Subject: [PATCH 04/10] [UPD] Remove spacing --- pkg/logging/logging.go | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pkg/logging/logging.go b/pkg/logging/logging.go index b035d66..089c56e 100644 --- a/pkg/logging/logging.go +++ b/pkg/logging/logging.go @@ -14,12 +14,12 @@ const ( pathToLog = "./data/ddns.log" dirPerm = 0755 filePerm = 0644 - INFO = "[INF] " - ERROR = "[ERR] " - FATAL = "[FAT] " - INFOC = "[\033[0;32mINF\033[0m] " - ERRORC = "[\033[0;31mERR\033[0m] " - FATALC = "[\033[0;31mFAT\033[0m] " + INFO = "INF " + ERROR = "ERR " + FATAL = "FAT " + INFOC = "\033[0;32mINF\033[0m " + ERRORC = "\033[0;31mERR\033[0m " + FATALC = "\033[0;31mFAT\033[0m " UNKOWN = "unknown-origin" ) @@ -60,18 +60,18 @@ func createLogger(infoOutput io.Writer, errorOutput io.Writer) *Logger { } func Infof(msg string, args ...interface{}) { - consoleLogger.infoLogger.Printf(INFOC+trace()+"message: "+msg, args...) - fileLogger.infoLogger.Printf(INFO+trace()+"message: "+msg, args...) + consoleLogger.infoLogger.Printf(INFOC+trace()+"message:"+msg, args...) + fileLogger.infoLogger.Printf(INFO+trace()+"message:"+msg, args...) } func Errorf(msg string, args ...interface{}) { - consoleLogger.errorLogger.Printf(ERRORC+trace()+"message: "+msg, args...) - fileLogger.errorLogger.Printf(ERROR+trace()+"message: "+msg, args...) + consoleLogger.errorLogger.Printf(ERRORC+trace()+"message:"+msg, args...) + fileLogger.errorLogger.Printf(ERROR+trace()+"message:"+msg, args...) } func Fatalf(msg string, args ...interface{}) { - consoleLogger.errorLogger.Fatalf(FATALC+trace()+"message: "+msg, args...) - fileLogger.errorLogger.Fatalf(FATAL+trace()+"message: "+msg, args...) + consoleLogger.errorLogger.Fatalf(FATALC+trace()+"message:"+msg, args...) + fileLogger.errorLogger.Fatalf(FATAL+trace()+"message:"+msg, args...) } func trace() string { @@ -88,5 +88,5 @@ func trace() string { if len(parts) > 0 { origin = parts[len(parts)-1] } - return fmt.Sprintf("origin: %v line: %v ", strings.Replace(origin, ".", "-", -1), line) + return fmt.Sprintf("origin:%v line:%v ", strings.Replace(origin, ".", "-", -1), line) } From 19e5a07e3f58029d188ceeb7e7a183af2abe8162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Lukas=20=7E=20Znox=20/=20Pl=C3=A4nkler?= <60503970+Plaenkler@users.noreply.github.com> Date: Thu, 29 Aug 2024 17:35:23 +0200 Subject: [PATCH 05/10] [ADD] Logs API --- pkg/logging/logging.go | 13 +++++++++++++ pkg/server/routes/api/logs.go | 21 +++++++++++++++++++++ pkg/server/service.go | 1 + 3 files changed, 35 insertions(+) create mode 100644 pkg/server/routes/api/logs.go diff --git a/pkg/logging/logging.go b/pkg/logging/logging.go index 089c56e..7d9c298 100644 --- a/pkg/logging/logging.go +++ b/pkg/logging/logging.go @@ -1,6 +1,7 @@ package logging import ( + "encoding/json" "fmt" "io" "log" @@ -90,3 +91,15 @@ func trace() string { } return fmt.Sprintf("origin:%v line:%v ", strings.Replace(origin, ".", "-", -1), line) } + +func GetEntries() ([]byte, error) { + file, err := os.ReadFile(pathToLog) + if err != nil { + return nil, fmt.Errorf("could not read log file: %v", err) + } + entries, err := json.Marshal(strings.Split(string(file), "\n")) + if err != nil { + return nil, fmt.Errorf("could not marshal JSON: %v", err) + } + return entries, nil +} diff --git a/pkg/server/routes/api/logs.go b/pkg/server/routes/api/logs.go new file mode 100644 index 0000000..14ce357 --- /dev/null +++ b/pkg/server/routes/api/logs.go @@ -0,0 +1,21 @@ +package api + +import ( + "net/http" + + "github.com/plaenkler/ddns-updater/pkg/logging" +) + +func GetLogs(w http.ResponseWriter, r *http.Request) { + logs, err := logging.GetEntries() + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + _, err = w.Write(logs) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} diff --git a/pkg/server/service.go b/pkg/server/service.go index 166b73f..44e7cc6 100644 --- a/pkg/server/service.go +++ b/pkg/server/service.go @@ -51,6 +51,7 @@ func registerAPIRoutes(r *Router) { r.HandleFunc("/login", web.ProvideLogin) r.HandleFunc("/api/login", api.Login) } + r.HandleFunc("/api/logs", api.GetLogs) r.HandleFunc("/api/inputs", api.GetInputs) r.HandleFunc("/api/job/create", api.CreateJob) r.HandleFunc("/api/job/update", api.UpdateJob) From c516ceda7d9a6f009e45b95d52cda9aeecf72d1b Mon Sep 17 00:00:00 2001 From: Simon Lukas <60503970+Plaenkler@users.noreply.github.com> Date: Mon, 30 Sep 2024 18:53:03 +0200 Subject: [PATCH 06/10] [FIX] Reflected cross-site scripting Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- pkg/server/routes/web/index.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/server/routes/web/index.go b/pkg/server/routes/web/index.go index 82c233d..772d783 100644 --- a/pkg/server/routes/web/index.go +++ b/pkg/server/routes/web/index.go @@ -7,7 +7,7 @@ import ( "html/template" "net/http" "strings" - + "html" "github.com/plaenkler/ddns-updater/pkg/cipher" "github.com/plaenkler/ddns-updater/pkg/config" "github.com/plaenkler/ddns-updater/pkg/database" @@ -37,13 +37,13 @@ func ProvideIndex(w http.ResponseWriter, r *http.Request) { addr, err := ddns.GetPublicIP() if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "could not get public IP address: %s", err) + fmt.Fprintf(w, "could not get public IP address: %s", html.EscapeString(err.Error())) return } img, err := totps.GetKeyAsQR() if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "could not generate TOTP QR code: %s", err) + fmt.Fprintf(w, "could not generate TOTP QR code: %s", html.EscapeString(err.Error())) return } data := indexPageData{ @@ -61,13 +61,13 @@ func ProvideIndex(w http.ResponseWriter, r *http.Request) { err = db.Find(&data.Jobs).Error if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "could not find jobs: %s", err) + fmt.Fprintf(w, "could not find jobs: %s", html.EscapeString(err.Error())) return } err = sanitizeParams(data.Jobs) if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "formatting params failed: %s", err) + fmt.Fprintf(w, "formatting params failed: %s", html.EscapeString(err.Error())) return } tpl, err := template.New("index").Funcs(template.FuncMap{ @@ -80,14 +80,14 @@ func ProvideIndex(w http.ResponseWriter, r *http.Request) { ) if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "could not provide template: %s", err) + fmt.Fprintf(w, "could not provide template: %s", html.EscapeString(err.Error())) return } w.Header().Add("Content-Type", "text/html") err = tpl.Execute(w, data) if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "could not execute parsed template: %v", err) + fmt.Fprintf(w, "could not execute parsed template: %v", html.EscapeString(err.Error())) } } From a1645f5bf401a8d7c1e6b659450614065a04aa98 Mon Sep 17 00:00:00 2001 From: Simon Lukas <60503970+Plaenkler@users.noreply.github.com> Date: Mon, 30 Sep 2024 19:04:52 +0200 Subject: [PATCH 07/10] [FIX] Do not lint JS --- .github/workflows/linters.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index e106ee5..c5e3bac 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -30,6 +30,7 @@ jobs: VALIDATE_ALL_CODEBASE: true VALIDATE_HTML: false VALIDATE_JAVASCRIPT_STANDARD: false + VALIDATE_JAVASCRIPT_PRETTIER: false VALIDATE_GO: false VALIDATE_GO_MODULES: false golangci-lint: From 4e574a68ad2643738149724085cdc18b1bb286d9 Mon Sep 17 00:00:00 2001 From: Simon Lukas <60503970+Plaenkler@users.noreply.github.com> Date: Mon, 30 Sep 2024 19:11:14 +0200 Subject: [PATCH 08/10] [FIX] Do not search duplicates --- .github/workflows/linters.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index c5e3bac..4cf737c 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -31,6 +31,7 @@ jobs: VALIDATE_HTML: false VALIDATE_JAVASCRIPT_STANDARD: false VALIDATE_JAVASCRIPT_PRETTIER: false + VALIDATE_JSCPD: false VALIDATE_GO: false VALIDATE_GO_MODULES: false golangci-lint: From 31b176026a420278e81b56d6a735802b9027b69b Mon Sep 17 00:00:00 2001 From: Simon Lukas <60503970+Plaenkler@users.noreply.github.com> Date: Mon, 30 Sep 2024 19:28:50 +0200 Subject: [PATCH 09/10] [FIX] Escape at the beginning --- pkg/server/routes/api/config.go | 3 ++- pkg/server/routes/web/index.go | 14 +++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/pkg/server/routes/api/config.go b/pkg/server/routes/api/config.go index a2de71e..64e87c2 100644 --- a/pkg/server/routes/api/config.go +++ b/pkg/server/routes/api/config.go @@ -1,6 +1,7 @@ package api import ( + "html" "net/http" "net/url" "strconv" @@ -37,7 +38,7 @@ func UpdateConfig(w http.ResponseWriter, r *http.Request) { return } interval := uint32(interval64) - resolver := strings.TrimSpace(r.FormValue("resolver")) + resolver := html.EscapeString(strings.TrimSpace(r.FormValue("resolver"))) if resolver != "" { _, err = url.ParseRequestURI(resolver) if err != nil { diff --git a/pkg/server/routes/web/index.go b/pkg/server/routes/web/index.go index 772d783..82c233d 100644 --- a/pkg/server/routes/web/index.go +++ b/pkg/server/routes/web/index.go @@ -7,7 +7,7 @@ import ( "html/template" "net/http" "strings" - "html" + "github.com/plaenkler/ddns-updater/pkg/cipher" "github.com/plaenkler/ddns-updater/pkg/config" "github.com/plaenkler/ddns-updater/pkg/database" @@ -37,13 +37,13 @@ func ProvideIndex(w http.ResponseWriter, r *http.Request) { addr, err := ddns.GetPublicIP() if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "could not get public IP address: %s", html.EscapeString(err.Error())) + fmt.Fprintf(w, "could not get public IP address: %s", err) return } img, err := totps.GetKeyAsQR() if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "could not generate TOTP QR code: %s", html.EscapeString(err.Error())) + fmt.Fprintf(w, "could not generate TOTP QR code: %s", err) return } data := indexPageData{ @@ -61,13 +61,13 @@ func ProvideIndex(w http.ResponseWriter, r *http.Request) { err = db.Find(&data.Jobs).Error if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "could not find jobs: %s", html.EscapeString(err.Error())) + fmt.Fprintf(w, "could not find jobs: %s", err) return } err = sanitizeParams(data.Jobs) if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "formatting params failed: %s", html.EscapeString(err.Error())) + fmt.Fprintf(w, "formatting params failed: %s", err) return } tpl, err := template.New("index").Funcs(template.FuncMap{ @@ -80,14 +80,14 @@ func ProvideIndex(w http.ResponseWriter, r *http.Request) { ) if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "could not provide template: %s", html.EscapeString(err.Error())) + fmt.Fprintf(w, "could not provide template: %s", err) return } w.Header().Add("Content-Type", "text/html") err = tpl.Execute(w, data) if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "could not execute parsed template: %v", html.EscapeString(err.Error())) + fmt.Fprintf(w, "could not execute parsed template: %v", err) } } From 5010a39c3cbc4d4be5af09bd9c72b855d320decb Mon Sep 17 00:00:00 2001 From: Simon Lukas <60503970+Plaenkler@users.noreply.github.com> Date: Mon, 30 Sep 2024 19:35:39 +0200 Subject: [PATCH 10/10] [FIX] Use Error() --- pkg/server/routes/web/index.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/server/routes/web/index.go b/pkg/server/routes/web/index.go index 82c233d..97d5f08 100644 --- a/pkg/server/routes/web/index.go +++ b/pkg/server/routes/web/index.go @@ -37,13 +37,13 @@ func ProvideIndex(w http.ResponseWriter, r *http.Request) { addr, err := ddns.GetPublicIP() if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "could not get public IP address: %s", err) + fmt.Fprintf(w, "could not get public IP address: %s", err.Error()) return } img, err := totps.GetKeyAsQR() if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "could not generate TOTP QR code: %s", err) + fmt.Fprintf(w, "could not generate TOTP QR code: %s", err.Error()) return } data := indexPageData{ @@ -61,13 +61,13 @@ func ProvideIndex(w http.ResponseWriter, r *http.Request) { err = db.Find(&data.Jobs).Error if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "could not find jobs: %s", err) + fmt.Fprintf(w, "could not find jobs: %s", err.Error()) return } err = sanitizeParams(data.Jobs) if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "formatting params failed: %s", err) + fmt.Fprintf(w, "formatting params failed: %s", err.Error()) return } tpl, err := template.New("index").Funcs(template.FuncMap{ @@ -80,14 +80,14 @@ func ProvideIndex(w http.ResponseWriter, r *http.Request) { ) if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "could not provide template: %s", err) + fmt.Fprintf(w, "could not provide template: %s", err.Error()) return } w.Header().Add("Content-Type", "text/html") err = tpl.Execute(w, data) if err != nil { w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "could not execute parsed template: %v", err) + fmt.Fprintf(w, "could not execute parsed template: %v", err.Error()) } }