Add error emails

This commit is contained in:
Melon 2024-02-21 00:21:22 +00:00
parent 02bfb4f62f
commit 6fc319dd0d
Signed by: melon
GPG Key ID: 6C9D970C50D26A25
10 changed files with 107 additions and 6 deletions

View File

@ -1,6 +1,9 @@
package main package main
import "github.com/1f349/orchid/renewal" import (
"github.com/1f349/orchid/renewal"
"github.com/1f349/simplemail"
)
type startUpConfig struct { type startUpConfig struct {
Listen string `yaml:"listen"` Listen string `yaml:"listen"`
@ -8,6 +11,7 @@ type startUpConfig struct {
LE renewal.LetsEncryptConfig `yaml:"letsEncrypt"` LE renewal.LetsEncryptConfig `yaml:"letsEncrypt"`
Domains []string `yaml:"domains"` Domains []string `yaml:"domains"`
AgentKey string `yaml:"agentKey"` AgentKey string `yaml:"agentKey"`
Mail mailConfig `yaml:"mail"`
} }
type acmeConfig struct { type acmeConfig struct {
@ -15,3 +19,8 @@ type acmeConfig struct {
CleanUpUrl string `yaml:"cleanUpUrl"` CleanUpUrl string `yaml:"cleanUpUrl"`
RefreshUrl string `yaml:"refreshUrl"` RefreshUrl string `yaml:"refreshUrl"`
} }
type mailConfig struct {
simplemail.Mail `yaml:",inline"`
To simplemail.FromAddress `yaml:"to"`
}

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Failed to find</title>
</head>
<body>
<h1>Hello</h1>
<p>World</p>
</body>
</html>

View File

@ -0,0 +1 @@
Failed to find

View File

@ -1,6 +1,8 @@
package main package main
import ( import (
"embed"
"errors"
"flag" "flag"
"github.com/1f349/mjwt" "github.com/1f349/mjwt"
"github.com/1f349/orchid" "github.com/1f349/orchid"
@ -9,10 +11,13 @@ import (
"github.com/1f349/orchid/logger" "github.com/1f349/orchid/logger"
"github.com/1f349/orchid/renewal" "github.com/1f349/orchid/renewal"
"github.com/1f349/orchid/servers" "github.com/1f349/orchid/servers"
"github.com/1f349/overlapfs"
"github.com/1f349/simplemail"
"github.com/1f349/violet/utils" "github.com/1f349/violet/utils"
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
exitReload "github.com/mrmelon54/exit-reload" exitReload "github.com/mrmelon54/exit-reload"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"io/fs"
"os" "os"
"path/filepath" "path/filepath"
"sync" "sync"
@ -20,6 +25,9 @@ import (
var configPath string var configPath string
//go:embed mail-templates/*
var mailTemplates embed.FS
func main() { func main() {
flag.StringVar(&configPath, "conf", "", "/path/to/config.json : path to the config file") flag.StringVar(&configPath, "conf", "", "/path/to/config.json : path to the config file")
flag.Parse() flag.Parse()
@ -70,6 +78,24 @@ func runDaemon(wd string, conf startUpConfig) {
logger.Logger.Fatal("Failed to load MJWT verifier public key from file", "path", filepath.Join(wd, "keys"), "err", err) logger.Logger.Fatal("Failed to load MJWT verifier public key from file", "path", filepath.Join(wd, "keys"), "err", err)
} }
// get mail templates
mailDir := filepath.Join(wd, "mail-templates")
err = os.Mkdir(mailDir, os.ModePerm)
if err != nil && !errors.Is(err, os.ErrExist) {
return
}
wdFs := os.DirFS(mailDir)
mailTemplatesSub, err := fs.Sub(mailTemplates, "mail-templates")
if err != nil {
logger.Logger.Fatal("Failed to load embedded mail templates", "err", err)
}
templatesFS := overlapfs.OverlapFS{A: mailTemplatesSub, B: wdFs}
mail, err := simplemail.New(&conf.Mail.Mail, templatesFS)
if err != nil {
logger.Logger.Fatal("Failed to load email sender", "err", err)
}
// open sqlite database // open sqlite database
db, err := orchid.InitDB(filepath.Join(wd, "orchid.db.sqlite")) db, err := orchid.InitDB(filepath.Join(wd, "orchid.db.sqlite"))
if err != nil { if err != nil {
@ -84,7 +110,7 @@ func runDaemon(wd string, conf startUpConfig) {
if err != nil { if err != nil {
logger.Logger.Fatal("HTTP Acme Error", "err", err) logger.Logger.Fatal("HTTP Acme Error", "err", err)
} }
renewalService, err := renewal.NewService(wg, db, acmeProv, conf.LE, certDir, keyDir) renewalService, err := renewal.NewService(wg, db, acmeProv, conf.LE, certDir, keyDir, mail, conf.Mail.To)
if err != nil { if err != nil {
logger.Logger.Fatal("Service Error", "err", err) logger.Logger.Fatal("Service Error", "err", err)
} }

5
go.mod
View File

@ -4,6 +4,8 @@ go 1.23.5
require ( require (
github.com/1f349/mjwt v0.4.1 github.com/1f349/mjwt v0.4.1
github.com/1f349/overlapfs v0.0.1
github.com/1f349/simplemail v0.0.8
github.com/1f349/violet v0.0.14 github.com/1f349/violet v0.0.14
github.com/AlecAivazis/survey/v2 v2.3.7 github.com/AlecAivazis/survey/v2 v2.3.7
github.com/bramvdbogaerde/go-scp v1.5.0 github.com/bramvdbogaerde/go-scp v1.5.0
@ -30,6 +32,9 @@ require (
github.com/charmbracelet/lipgloss v1.0.0 // indirect github.com/charmbracelet/lipgloss v1.0.0 // indirect
github.com/charmbracelet/x/ansi v0.8.0 // indirect github.com/charmbracelet/x/ansi v0.8.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emersion/go-message v0.18.2 // indirect
github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6 // indirect
github.com/emersion/go-smtp v0.21.3 // indirect
github.com/go-jose/go-jose/v4 v4.0.4 // indirect github.com/go-jose/go-jose/v4 v4.0.4 // indirect
github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-querystring v1.1.0 // indirect

19
go.sum
View File

@ -1,7 +1,11 @@
github.com/1f349/mjwt v0.4.1 h1:ooCroMMw2kcL5c9L3sLbdtxI0H4/QC8RfTxiloKr+4Y= github.com/1f349/mjwt v0.4.1 h1:ooCroMMw2kcL5c9L3sLbdtxI0H4/QC8RfTxiloKr+4Y=
github.com/1f349/mjwt v0.4.1/go.mod h1:qwnzokkqc7Z9YmKA1m9beI3OZL1GvGYHOQU2rOwoV1M= github.com/1f349/mjwt v0.4.1/go.mod h1:qwnzokkqc7Z9YmKA1m9beI3OZL1GvGYHOQU2rOwoV1M=
github.com/1f349/overlapfs v0.0.1 h1:LAxBolrXFAgU0yqZtXg/C/aaPq3eoQSPpBc49BHuTp0=
github.com/1f349/overlapfs v0.0.1/go.mod h1:I6aItQycr7nrzplmfNXp/QF9tTmKRSgY3fXmu/7Ky2o=
github.com/1f349/rsa-helper v0.0.2 h1:N/fLQqg5wrjIzG6G4zdwa5Xcv9/jIPutCls9YekZr9U= github.com/1f349/rsa-helper v0.0.2 h1:N/fLQqg5wrjIzG6G4zdwa5Xcv9/jIPutCls9YekZr9U=
github.com/1f349/rsa-helper v0.0.2/go.mod h1:VUQ++1tYYhYrXeOmVFkQ82BegR24HQEJHl5lHbjg7yg= github.com/1f349/rsa-helper v0.0.2/go.mod h1:VUQ++1tYYhYrXeOmVFkQ82BegR24HQEJHl5lHbjg7yg=
github.com/1f349/simplemail v0.0.8 h1:stcNaTwt/21K9fMtpDS4Y5wMKkTGHKk1CaU7M3fcSA4=
github.com/1f349/simplemail v0.0.8/go.mod h1:ppAIqkvVkI6L99EefbR5NgOjpePNK/RKgeoehj5A+kU=
github.com/1f349/violet v0.0.14 h1:MpBZ4n1dJjdiIwYMTfh0PBIFll3kjqowxR6DLasafqE= github.com/1f349/violet v0.0.14 h1:MpBZ4n1dJjdiIwYMTfh0PBIFll3kjqowxR6DLasafqE=
github.com/1f349/violet v0.0.14/go.mod h1:iAREhm+wxnGXkmuvmBhOuhUx2T7/5w7stLYNgQGbqC8= github.com/1f349/violet v0.0.14/go.mod h1:iAREhm+wxnGXkmuvmBhOuhUx2T7/5w7stLYNgQGbqC8=
github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ=
@ -28,6 +32,13 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/emersion/go-message v0.18.2 h1:rl55SQdjd9oJcIoQNhubD2Acs1E6IzlZISRTK7x/Lpg=
github.com/emersion/go-message v0.18.2/go.mod h1:XpJyL70LwRvq2a8rVbHXikPgKj8+aI0kGdHlg16ibYA=
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6 h1:oP4q0fw+fOSWn3DfFi4EXdT+B+gTtzx8GC9xsc26Znk=
github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
github.com/emersion/go-smtp v0.21.3 h1:7uVwagE8iPYE48WhNsng3RRpCUpFvNl39JGNSIyGVMY=
github.com/emersion/go-smtp v0.21.3/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ=
github.com/go-acme/lego/v4 v4.22.2 h1:ck+HllWrV/rZGeYohsKQ5iKNnU/WAZxwOdiu6cxky+0= github.com/go-acme/lego/v4 v4.22.2 h1:ck+HllWrV/rZGeYohsKQ5iKNnU/WAZxwOdiu6cxky+0=
github.com/go-acme/lego/v4 v4.22.2/go.mod h1:E2FndyI3Ekv0usNJt46mFb9LVpV/XBYT+4E3tz02Tzo= github.com/go-acme/lego/v4 v4.22.2/go.mod h1:E2FndyI3Ekv0usNJt46mFb9LVpV/XBYT+4E3tz02Tzo=
github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E= github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E=
@ -115,15 +126,18 @@ golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrCPyJZ+eyRsABUPs1mz4= golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrCPyJZ+eyRsABUPs1mz4=
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -132,22 +146,27 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@ -14,6 +14,7 @@ import (
"github.com/1f349/orchid/database" "github.com/1f349/orchid/database"
"github.com/1f349/orchid/pebble" "github.com/1f349/orchid/pebble"
"github.com/1f349/orchid/utils" "github.com/1f349/orchid/utils"
"github.com/1f349/simplemail"
"github.com/go-acme/lego/v4/certificate" "github.com/go-acme/lego/v4/certificate"
"github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/challenge/dns01" "github.com/go-acme/lego/v4/challenge/dns01"
@ -65,10 +66,12 @@ type Service struct {
keyDir string keyDir string
insecure bool insecure bool
client *lego.Client client *lego.Client
mail *simplemail.SimpleMail
mailTo simplemail.FromAddress
} }
// NewService creates a new certificate renewal service. // NewService creates a new certificate renewal service.
func NewService(wg *sync.WaitGroup, db *database.Queries, httpAcme challenge.Provider, leConfig LetsEncryptConfig, certDir, keyDir string) (*Service, error) { func NewService(wg *sync.WaitGroup, db *database.Queries, httpAcme challenge.Provider, leConfig LetsEncryptConfig, certDir, keyDir string, mail *simplemail.SimpleMail, mailTo simplemail.FromAddress) (*Service, error) {
s := &Service{ s := &Service{
db: db, db: db,
httpAcme: httpAcme, httpAcme: httpAcme,
@ -81,6 +84,8 @@ func NewService(wg *sync.WaitGroup, db *database.Queries, httpAcme challenge.Pro
certDir: certDir, certDir: certDir,
keyDir: keyDir, keyDir: keyDir,
insecure: leConfig.insecure, insecure: leConfig.insecure,
mail: mail,
mailTo: mailTo,
} }
// make certDir and keyDir // make certDir and keyDir
@ -125,6 +130,26 @@ func (s *Service) Shutdown() {
close(s.certDone) close(s.certDone)
} }
func (s *Service) sendErrorEmail(templateName, subject string, data map[string]any, err error) error {
// sending mail is disabled
if s.mail == nil {
return nil
}
// create empty data map
if data == nil {
data = make(map[string]any)
}
data["error"] = err
// send email and listen for errors
mailErr := s.mail.Send(templateName, subject, s.mailTo.ToMailAddress(), data)
if mailErr != nil {
return fmt.Errorf("failed to send error email for: %w because: %w", err, mailErr)
}
return err
}
// resolveLEPrivKey resolves the private key for the LetsEncrypt account. // resolveLEPrivKey resolves the private key for the LetsEncrypt account.
// If the string is a path to a file then the contents of the file is read. // If the string is a path to a file then the contents of the file is read.
func (s *Service) resolveLEPrivKey(a string) error { func (s *Service) resolveLEPrivKey(a string) error {
@ -255,7 +280,7 @@ func (s *Service) renewalCheck() error {
// check for running out certificates in the database // check for running out certificates in the database
localData, err := s.findNextCertificateToRenew() localData, err := s.findNextCertificateToRenew()
if err != nil { if err != nil {
return fmt.Errorf("failed to find a certificate to renew: %w", err) return s.sendErrorEmail("failed-to-find", "Failed to find a certificate to renew", nil, fmt.Errorf("failed to find a certificate to renew: %w", err))
} }
// no certificates to update // no certificates to update
@ -268,7 +293,12 @@ func (s *Service) renewalCheck() error {
err = s.renewCert(localData) err = s.renewCert(localData)
if err != nil { if err != nil {
Logger.Debug("Failed to renew certificate", "err", err) Logger.Debug("Failed to renew certificate", "err", err)
return err return s.sendErrorEmail("failed-to-renew", "Failed to renew a certificate", map[string]any{
"id": localData.id,
"dns-name": localData.dns.name,
"domains": localData.domains,
"not-after": localData.notAfter,
}, fmt.Errorf("failed to renew a certificate: %w", err))
} }
// renew succeeded // renew succeeded

View File

@ -13,6 +13,7 @@ import (
"github.com/1f349/orchid/logger" "github.com/1f349/orchid/logger"
"github.com/1f349/orchid/pebble" "github.com/1f349/orchid/pebble"
"github.com/1f349/orchid/test" "github.com/1f349/orchid/test"
"github.com/1f349/simplemail"
"github.com/charmbracelet/log" "github.com/charmbracelet/log"
"github.com/go-acme/lego/v4/lego" "github.com/go-acme/lego/v4/lego"
"github.com/google/uuid" "github.com/google/uuid"
@ -125,7 +126,7 @@ func setupPebbleTest(t *testing.T, serverTls *certgen.CertGen) (*Service, *sql.D
Directory: "https://localhost:14000/dir", Directory: "https://localhost:14000/dir",
Certificate: "insecure", Certificate: "insecure",
insecure: true, insecure: true,
}, certDir, keyDir) }, certDir, keyDir, nil, simplemail.FromAddress{})
fmt.Println(err) fmt.Println(err)
assert.NoError(t, err) assert.NoError(t, err)