diff --git a/auth/auth.go b/auth/auth.go index 5d8fa4e..8a346bc 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -13,8 +13,8 @@ import ( "golang.org/x/crypto/bcrypt" "golang.org/x/crypto/nacl/secretbox" - "github.com/emersion/hydroxide/config" - "github.com/emersion/hydroxide/protonmail" + "github.com/0ranki/hydroxide-push/config" + "github.com/0ranki/hydroxide-push/protonmail" ) func authFilePath() (string, error) { diff --git a/carddav/carddav.go b/carddav/carddav.go index e2b613c..29ed296 100644 --- a/carddav/carddav.go +++ b/carddav/carddav.go @@ -13,10 +13,10 @@ import ( "strings" "sync" + "github.com/0ranki/hydroxide-push/protonmail" "github.com/ProtonMail/go-crypto/openpgp" "github.com/emersion/go-vcard" "github.com/emersion/go-webdav/carddav" - "github.com/emersion/hydroxide/protonmail" ) // TODO: use a HTTP error diff --git a/cmd/hydroxide-push/main.go b/cmd/hydroxide-push/main.go index 4db87e9..f147604 100644 --- a/cmd/hydroxide-push/main.go +++ b/cmd/hydroxide-push/main.go @@ -5,16 +5,15 @@ import ( "crypto/tls" "flag" "fmt" - "github.com/emersion/go-imap" + "github.com/0ranki/hydroxide-push/auth" + "github.com/0ranki/hydroxide-push/config" + "github.com/0ranki/hydroxide-push/events" + imapbackend "github.com/0ranki/hydroxide-push/imap" + "github.com/0ranki/hydroxide-push/ntfy" + "github.com/0ranki/hydroxide-push/protonmail" imapserver "github.com/emersion/go-imap/server" - "github.com/emersion/hydroxide/auth" - "github.com/emersion/hydroxide/config" - "github.com/emersion/hydroxide/events" - imapbackend "github.com/emersion/hydroxide/imap" - "github.com/emersion/hydroxide/protonmail" "golang.org/x/term" "log" - "net" "os" "time" ) @@ -28,9 +27,7 @@ var ( debug bool apiEndpoint string appVersion string - - //imapUser *backend.User - ntfyTopic string + cfg ntfy.NtfyConfig ) func newClient() *protonmail.Client { @@ -60,7 +57,7 @@ func askPass(prompt string) ([]byte, error) { return b, err } -func listenAndServeIMAP(addr string, debug bool, authManager *auth.Manager, eventsManager *events.Manager, tlsConfig *tls.Config) error { +func listenEventsAndNotify(addr string, debug bool, authManager *auth.Manager, eventsManager *events.Manager, tlsConfig *tls.Config) error { be := imapbackend.New(authManager, eventsManager) s := imapserver.New(be) s.Addr = addr @@ -69,53 +66,19 @@ func listenAndServeIMAP(addr string, debug bool, authManager *auth.Manager, even if debug { s.Debug = os.Stdout } - - if s.TLSConfig != nil { - log.Println("IMAP server listening with TLS on", s.Addr) - return s.ListenAndServeTLS() + ntfy.Login(&cfg, be) + log.Println("Listening for events", s.Addr) + for { + time.Sleep(10 * time.Second) } - go func() { - time.Sleep(1 * time.Second) - c, _ := net.ResolveIPAddr("ip", "127.0.0.1") - conn := imap.ConnInfo{ - RemoteAddr: c, - LocalAddr: c, - TLS: nil, - } - usernames, err := auth.ListUsernames() - if err != nil { - log.Fatal(err) - } - if len(usernames) > 1 { - log.Fatal("only one login supported for now") - } - if len(usernames) == 0 { - executable, _ := os.Executable() - log.Fatal("login first using " + executable + " auth ") - } - // TODO: bridge password - _, err = be.Login(&conn, usernames[0], os.Getenv("HYDROXIDE_BRIDGE_PASS")) - if err != nil { - log.Fatal(err) - } - }() - - log.Println("IMAP server listening on", s.Addr) - return s.ListenAndServe() + return nil } -const usage = `usage: hydroxide [options...] +const usage = `usage: hydroxide-push [options...] Commands: auth Login to ProtonMail via hydroxide - carddav Run hydroxide as a CardDAV server - export-secret-keys Export secret keys - imap Run hydroxide as an IMAP server - import-messages [file] Import messages - export-messages [options...] Export messages - sendmail -- sendmail(1) interface - serve Run all servers - smtp Run hydroxide as an SMTP server - status View hydroxide status + status View hydroxide status + notify Start the notification daemon Global options: -debug @@ -124,30 +87,6 @@ Global options: ProtonMail API endpoint -app-version ProtonMail application version - -smtp-host example.com - Allowed SMTP email hostname on which hydroxide listens, defaults to 127.0.0.1 - -imap-host example.com - Allowed IMAP email hostname on which hydroxide listens, defaults to 127.0.0.1 - -carddav-host example.com - Allowed SMTP email hostname on which hydroxide listens, defaults to 127.0.0.1 - -smtp-port example.com - SMTP port on which hydroxide listens, defaults to 1025 - -imap-port example.com - IMAP port on which hydroxide listens, defaults to 1143 - -carddav-port example.com - CardDAV port on which hydroxide listens, defaults to 8080 - -disable-imap - Disable IMAP for hydroxide serve - -disable-smtp - Disable SMTP for hydroxide serve - -disable-carddav - Disable CardDAV for hydroxide serve - -tls-cert /path/to/cert.pem - Path to the certificate to use for incoming connections (Optional) - -tls-key /path/to/key.pem - Path to the certificate key to use for incoming connections (Optional) - -tls-client-ca /path/to/ca.pem - If set, clients must provide a certificate signed by the given CA (Optional) Environment variables: HYDROXIDE_BRIDGE_PASS Don't prompt for the bridge password, use this variable instead @@ -157,10 +96,6 @@ func main() { flag.BoolVar(&debug, "debug", false, "Enable debug logs") flag.StringVar(&apiEndpoint, "api-endpoint", defaultAPIEndpoint, "ProtonMail API endpoint") flag.StringVar(&appVersion, "app-version", defaultAppVersion, "ProtonMail app version") - flag.StringVar(&ntfyTopic, "topic", "", "ntfy.sh/NextPush topic to push notifications to") - - imapHost := "127.0.0.1" // flag.String("imap-host", "127.0.0.1", "Allowed IMAP email hostname on which hydroxide listens, defaults to 127.0.0.1") - imapPort := "1143" // flag.String("imap-port", "1143", "IMAP port on which hydroxide listens, defaults to 1143") tlsCert := flag.String("tls-cert", "", "Path to the certificate to use for incoming connections") tlsCertKey := flag.String("tls-key", "", "Path to the certificate key to use for incoming connections") @@ -294,16 +229,24 @@ func main() { } case "setup-ntfy": - - case "notify": - if ntfyTopic == "" { - log.Fatal("please set ntfy.sh topic using --topic") + scanner := bufio.NewScanner(os.Stdin) + fmt.Printf("Input push server URL (e.g. 'http://ntfy.sh') : ") + scanner.Scan() + cfg.URL = scanner.Text() + scanner = bufio.NewScanner(os.Stdin) + fmt.Printf("Input push topic (e.g. my-proton-notifications)\nLeave blank to generate a random one: ") + scanner.Scan() + cfg.Topic = scanner.Text() + fmt.Printf("Using URL %s\n", cfg.String()) + err = cfg.Save() + if err != nil { + log.Fatal(err) } - addr := imapHost + ":" + imapPort + log.Println("Notification configuration saved") + case "notify": authManager := auth.NewManager(newClient) eventsManager := events.NewManager() - - log.Fatal(listenAndServeIMAP(addr, debug, authManager, eventsManager, tlsConfig)) + log.Fatal(listenEventsAndNotify("0", debug, authManager, eventsManager, tlsConfig)) default: fmt.Print(usage) diff --git a/cmd/hydroxide/main.go b/cmd/hydroxide/main.go index b32780f..c1456c4 100644 --- a/cmd/hydroxide/main.go +++ b/cmd/hydroxide/main.go @@ -18,15 +18,15 @@ import ( "github.com/emersion/go-smtp" "golang.org/x/term" - "github.com/emersion/hydroxide/auth" - "github.com/emersion/hydroxide/carddav" - "github.com/emersion/hydroxide/config" - "github.com/emersion/hydroxide/events" - "github.com/emersion/hydroxide/exports" - imapbackend "github.com/emersion/hydroxide/imap" - "github.com/emersion/hydroxide/imports" - "github.com/emersion/hydroxide/protonmail" - smtpbackend "github.com/emersion/hydroxide/smtp" + "github.com/0ranki/hydroxide-push/auth" + "github.com/0ranki/hydroxide-push/carddav" + "github.com/0ranki/hydroxide-push/config" + "github.com/0ranki/hydroxide-push/events" + "github.com/0ranki/hydroxide-push/exports" + imapbackend "github.com/0ranki/hydroxide-push/imap" + "github.com/0ranki/hydroxide-push/imports" + "github.com/0ranki/hydroxide-push/protonmail" + smtpbackend "github.com/0ranki/hydroxide-push/smtp" ) const ( diff --git a/events/events.go b/events/events.go index f24a97d..48482f8 100644 --- a/events/events.go +++ b/events/events.go @@ -5,7 +5,7 @@ import ( "sync" "time" - "github.com/emersion/hydroxide/protonmail" + "github.com/0ranki/hydroxide-push/protonmail" ) const pollInterval = 10 * time.Second diff --git a/exports/messages.go b/exports/messages.go index 3eddb7c..c915530 100644 --- a/exports/messages.go +++ b/exports/messages.go @@ -12,7 +12,7 @@ import ( "github.com/emersion/go-message/mail" "github.com/emersion/go-message/textproto" - "github.com/emersion/hydroxide/protonmail" + "github.com/0ranki/hydroxide-push/protonmail" ) func writeMessage(c *protonmail.Client, privateKeys openpgp.KeyRing, w io.Writer, msg *protonmail.Message) error { diff --git a/go.mod b/go.mod index 6e7ec07..a743401 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/emersion/hydroxide +module github.com/0ranki/hydroxide-push go 1.13 @@ -14,6 +14,7 @@ require ( github.com/emersion/go-smtp v0.19.0 github.com/emersion/go-vcard v0.0.0-20230815062825-8fda7d206ec9 github.com/emersion/go-webdav v0.3.2-0.20220524091811-5d845721d8f7 + github.com/emersion/hydroxide v0.2.28 golang.org/x/crypto v0.15.0 golang.org/x/term v0.14.0 ) diff --git a/go.sum b/go.sum index a763765..4218b97 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,4 @@ +github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c h1:kMFnB0vCcX7IL/m9Y5LO+KQYv+t1CQOiFe6+SV2J7bE= github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= @@ -14,11 +15,14 @@ github.com/emersion/go-imap v1.2.1/go.mod h1:Qlx1FSx2FTxjnjWpIlVNEuX+ylerZQNFE5N github.com/emersion/go-mbox v1.0.3 h1:Kac75r/EGi6KZAz48HXal9q7EiaXNl+U5HZfyDz0LKM= github.com/emersion/go-mbox v1.0.3/go.mod h1:Yp9IVuuOYLEuMv4yjgDHvhb5mHOcYH6x92Oas3QqEZI= github.com/emersion/go-message v0.15.0/go.mod h1:wQUEfE+38+7EW8p8aZ96ptg6bAb1iwdgej19uXASlE4= +github.com/emersion/go-message v0.16.0/go.mod h1:pDJDgf/xeUIF+eicT6B/hPX/ZbEorKkUMPOxrPVG2eQ= github.com/emersion/go-message v0.17.0 h1:NIdSKHiVUx4qKqdd0HyJFD41cW8iFguM2XJnRZWQH04= github.com/emersion/go-message v0.17.0/go.mod h1:/9Bazlb1jwUNB0npYYBsdJ2EMOiiyN3m5UVHbY7GoNw= github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= +github.com/emersion/go-sasl v0.0.0-20220912192320-0145f2c60ead/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43 h1:hH4PQfOndHDlpzYfLAAfl63E8Le6F2+EL/cdhlkyRJY= github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= +github.com/emersion/go-smtp v0.18.0/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ= github.com/emersion/go-smtp v0.19.0 h1:iVCDtR2/JY3RpKoaZ7u6I/sb52S3EzfNHO1fAWVHgng= github.com/emersion/go-smtp v0.19.0/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ= github.com/emersion/go-textwrapper v0.0.0-20200911093747-65d896831594 h1:IbFBtwoTQyw0fIM5xv1HF+Y+3ZijDR839WMulgxCcUY= @@ -28,11 +32,14 @@ github.com/emersion/go-vcard v0.0.0-20230815062825-8fda7d206ec9 h1:ATgqloALX6cHC github.com/emersion/go-vcard v0.0.0-20230815062825-8fda7d206ec9/go.mod h1:HMJKR5wlh/ziNp+sHEDV2ltblO4JD2+IdDOWtGcQBTM= github.com/emersion/go-webdav v0.3.2-0.20220524091811-5d845721d8f7 h1:HqrKOBl8HdSnlo8kz72tCU36aK3WwSmpnnz04+dD0oc= github.com/emersion/go-webdav v0.3.2-0.20220524091811-5d845721d8f7/go.mod h1:uSM1VveeKtogBVWaYccTksToczooJ0rrVGNsgnDsr4Q= +github.com/emersion/hydroxide v0.2.28 h1:4gUyOJkVv4owVa3XHNlS/jEb+++q49O8EQR+kpO/s6w= +github.com/emersion/hydroxide v0.2.28/go.mod h1:wYHmI++eFDFxzWgWRfFFYiFpCfdZcHeLA3X1oGU2JjI= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA= golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -57,6 +64,7 @@ golang.org/x/sys v0.3.0/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.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -65,6 +73,7 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8= golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/imap/backend.go b/imap/backend.go index e44769b..803a019 100644 --- a/imap/backend.go +++ b/imap/backend.go @@ -7,8 +7,8 @@ import ( "github.com/emersion/go-imap" imapbackend "github.com/emersion/go-imap/backend" - "github.com/emersion/hydroxide/auth" - "github.com/emersion/hydroxide/events" + "github.com/0ranki/hydroxide-push/auth" + "github.com/0ranki/hydroxide-push/events" ) var errNotYetImplemented = errors.New("not yet implemented") diff --git a/imap/database/mailbox.go b/imap/database/mailbox.go index fd9b053..ab06270 100644 --- a/imap/database/mailbox.go +++ b/imap/database/mailbox.go @@ -7,7 +7,7 @@ import ( "github.com/boltdb/bolt" - "github.com/emersion/hydroxide/protonmail" + "github.com/0ranki/hydroxide-push/protonmail" ) func serializeUID(uid uint32) []byte { diff --git a/imap/database/user.go b/imap/database/user.go index bc3e8b2..d7bc547 100644 --- a/imap/database/user.go +++ b/imap/database/user.go @@ -6,8 +6,8 @@ import ( "github.com/boltdb/bolt" - "github.com/emersion/hydroxide/config" - "github.com/emersion/hydroxide/protonmail" + "github.com/0ranki/hydroxide-push/config" + "github.com/0ranki/hydroxide-push/protonmail" ) var ErrNotFound = errors.New("message not found in local database") diff --git a/imap/mailbox.go b/imap/mailbox.go index 1068c28..09fe15a 100644 --- a/imap/mailbox.go +++ b/imap/mailbox.go @@ -10,8 +10,8 @@ import ( "github.com/emersion/go-imap" imapbackend "github.com/emersion/go-imap/backend" - "github.com/emersion/hydroxide/imap/database" - "github.com/emersion/hydroxide/protonmail" + "github.com/0ranki/hydroxide-push/imap/database" + "github.com/0ranki/hydroxide-push/protonmail" ) const delimiter = "/" diff --git a/imap/message.go b/imap/message.go index 5051259..4472c38 100644 --- a/imap/message.go +++ b/imap/message.go @@ -15,7 +15,7 @@ import ( "github.com/emersion/go-message" "github.com/emersion/go-message/mail" - "github.com/emersion/hydroxide/protonmail" + "github.com/0ranki/hydroxide-push/protonmail" ) func messageID(msg *protonmail.Message) string { diff --git a/imap/user.go b/imap/user.go index dfd879d..82c0127 100644 --- a/imap/user.go +++ b/imap/user.go @@ -1,17 +1,17 @@ package imap import ( - "github.com/emersion/hydroxide/ntfy" + "github.com/0ranki/hydroxide-push/ntfy" "log" "strings" "sync" + "github.com/0ranki/hydroxide-push/events" + "github.com/0ranki/hydroxide-push/imap/database" + "github.com/0ranki/hydroxide-push/protonmail" "github.com/ProtonMail/go-crypto/openpgp" "github.com/emersion/go-imap" imapbackend "github.com/emersion/go-imap/backend" - "github.com/emersion/hydroxide/events" - "github.com/emersion/hydroxide/imap/database" - "github.com/emersion/hydroxide/protonmail" ) var systemMailboxes = []struct { @@ -118,7 +118,7 @@ func newUser(be *backend, username string, c *protonmail.Client, privateKeys ope go uu.receiveEvents(be.updates, ch) uu.eventsReceiver = be.eventsManager.Register(c, u.Name, ch, done) - log.Printf("User %q logged in via IMAP", u.Name) + log.Printf("Logged in as user %q", u.Name) return uu, nil } diff --git a/imports/messages.go b/imports/messages.go index 60fe9fd..0c8ae40 100644 --- a/imports/messages.go +++ b/imports/messages.go @@ -8,7 +8,7 @@ import ( "github.com/ProtonMail/go-crypto/openpgp/armor" "github.com/emersion/go-message/mail" - "github.com/emersion/hydroxide/protonmail" + "github.com/0ranki/hydroxide-push/protonmail" ) func ImportMessage(c *protonmail.Client, r io.Reader) error { diff --git a/ntfy/ntfy.go b/ntfy/ntfy.go index 6fc7d2e..8388e1c 100644 --- a/ntfy/ntfy.go +++ b/ntfy/ntfy.go @@ -1,10 +1,46 @@ package ntfy import ( + "bufio" + "encoding/json" + "fmt" + "github.com/0ranki/hydroxide-push/auth" + "github.com/0ranki/hydroxide-push/config" + "github.com/emersion/go-imap" + "github.com/emersion/go-imap/backend" + "log" + "net" "net/http" + "os" "strings" ) +type NtfyConfig struct { + URL string `json:"url"` + Topic string `json:"topic"` + BridgePw string `json:"bridgePw"` +} + +func (cfg *NtfyConfig) String() string { + return fmt.Sprintf("%s/%s", cfg.URL, cfg.Topic) +} + +func (cfg *NtfyConfig) Save() error { + b, err := json.Marshal(cfg) + if err != nil { + return err + } + path, err := ntfyConfigFile() + if err != nil { + return err + } + return os.WriteFile(path, b, 0600) +} + +func ntfyConfigFile() (string, error) { + return config.Path("notify.json") +} + func Notify() { req, _ := http.NewRequest("POST", "https://push.oranki.net/testing20240325", strings.NewReader("New message received")) req.Header.Set("Title", "ProtoMail") @@ -12,3 +48,62 @@ func Notify() { req.Header.Set("Tags", "envelope") http.DefaultClient.Do(req) } + +func (cfg *NtfyConfig) Read() error { + f, err := ntfyConfigFile() + if err == nil { + b, err := os.ReadFile(f) + if err == nil { + err = json.Unmarshal(b, &cfg) + } + if err != nil { + return err + } + } + return nil +} + +func Login(cfg *NtfyConfig, be backend.Backend) { + //time.Sleep(1 * time.Second) + c, _ := net.ResolveIPAddr("ip", "127.0.0.1") + conn := imap.ConnInfo{ + RemoteAddr: c, + LocalAddr: c, + TLS: nil, + } + usernames, err := auth.ListUsernames() + if err != nil { + log.Fatal(err) + } + if len(usernames) > 1 { + log.Fatal("only one login supported for now") + } + err = cfg.Read() + if err != nil { + log.Println(err) + } + if len(usernames) == 0 || cfg.URL == "" || cfg.Topic == "" { + executable, _ := os.Executable() + log.Println("login first using " + executable + " auth ") + log.Fatalln("then setup ntfy using " + executable + "setup-ntfy") + } + cfg.BridgePw = os.Getenv("HYDROXIDE_BRIDGE_PASSWORD") + if cfg.BridgePw == "" { + scanner := bufio.NewScanner(os.Stdin) + fmt.Printf("Bridge password: ") + scanner.Scan() + cfg.BridgePw = scanner.Text() + scanner = bufio.NewScanner(os.Stdin) + fmt.Printf("Save password to config? The password is stored in plain text! (yes/n): ") + scanner.Scan() + if scanner.Text() == "yes" { + if err = cfg.Save(); err != nil { + log.Fatal("failed to save notification config") + } + } + } + _, err = be.Login(&conn, usernames[0], cfg.BridgePw) + if err != nil { + log.Fatal(err) + } +} diff --git a/smtp/smtp.go b/smtp/smtp.go index 6df1006..abff6d5 100644 --- a/smtp/smtp.go +++ b/smtp/smtp.go @@ -13,8 +13,8 @@ import ( "github.com/emersion/go-message/mail" "github.com/emersion/go-smtp" - "github.com/emersion/hydroxide/auth" - "github.com/emersion/hydroxide/protonmail" + "github.com/0ranki/hydroxide-push/auth" + "github.com/0ranki/hydroxide-push/protonmail" ) func toPMAddressList(addresses []*mail.Address) []*protonmail.MessageAddress {