aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Culverhouse <tim@timculverhouse.com>2024-08-16 09:14:45 -0500
committerRobin Jarry <robin@jarry.cc>2024-08-20 12:26:46 +0200
commitb896120f00d0b811a4b7e41709d8331a29c82cb0 (patch)
tree4bb143188430ade9f0777783e9295fc584f84892
parent93207b733046f7fde645b68f4bafd1cab51b3dff (diff)
downloadaerc-b896120f00d0b811a4b7e41709d8331a29c82cb0.tar.gz
jmap: lazily fetch identities
Fetch Identities only when required: when we are sending an email. Refactor connect.go to check the state string of the Session on every request, and update the session as needed. Move the Session validity check to happen on any request, eg when our client returns an error we first update the Session object (via re-authenticating) and then retry the request. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry <robin@jarry.cc>
-rw-r--r--worker/jmap/connect.go47
-rw-r--r--worker/jmap/send.go5
2 files changed, 33 insertions, 19 deletions
diff --git a/worker/jmap/connect.go b/worker/jmap/connect.go
index c5eabe63..6ae22283 100644
--- a/worker/jmap/connect.go
+++ b/worker/jmap/connect.go
@@ -26,24 +26,9 @@ func (w *JMAPWorker) handleConnect(msg *types.Connect) error {
if session, err := w.cache.GetSession(); err == nil {
w.client.Session = session
- if w.GetIdentities() != nil {
- w.client.Session = nil
- w.identities = make(map[string]*identity.Identity)
- if err := w.cache.DeleteSession(); err != nil {
- w.w.Warnf("DeleteSession: %s", err)
- }
- }
}
if w.client.Session == nil {
- if err := w.client.Authenticate(); err != nil {
- return err
- }
- if err := w.cache.PutSession(w.client.Session); err != nil {
- w.w.Warnf("PutSession: %s", err)
- }
- }
- if len(w.identities) == 0 {
- if err := w.GetIdentities(); err != nil {
+ if err := w.UpdateSession(); err != nil {
return err
}
}
@@ -64,6 +49,16 @@ func (w *JMAPWorker) AccountId() jmap.ID {
}
}
+func (w *JMAPWorker) UpdateSession() error {
+ if err := w.client.Authenticate(); err != nil {
+ return err
+ }
+ if err := w.cache.PutSession(w.client.Session); err != nil {
+ w.w.Warnf("PutSession: %s", err)
+ }
+ return nil
+}
+
func (w *JMAPWorker) GetIdentities() error {
var req jmap.Request
@@ -93,11 +88,25 @@ func (w *JMAPWorker) Do(req *jmap.Request) (*jmap.Response, error) {
body, _ := json.Marshal(req.Calls)
w.w.Debugf(">%d> POST %s", seq, body)
resp, err := w.client.Do(req)
- if err == nil {
- w.w.Debugf("<%d< done", seq)
- } else {
+ if err != nil {
w.w.Debugf("<%d< %s", seq, err)
+ // Try to update session in case an endpoint changed
+ err := w.UpdateSession()
+ if err != nil {
+ return nil, err
+ }
+ // And try again if we succeeded
+ resp, err = w.client.Do(req)
+ if err != nil {
+ return nil, err
+ }
+ }
+ if resp.SessionState != w.client.Session.State {
+ if err := w.UpdateSession(); err != nil {
+ return nil, err
+ }
}
+ w.w.Debugf("<%d< done", seq)
return resp, err
}
diff --git a/worker/jmap/send.go b/worker/jmap/send.go
index 757e5420..2fbb8aed 100644
--- a/worker/jmap/send.go
+++ b/worker/jmap/send.go
@@ -136,6 +136,11 @@ func (w *jmapSendWriter) Close() error {
}
func (w *JMAPWorker) getSenderIdentity(from *mail.Address) (jmap.ID, error) {
+ if len(w.identities) == 0 {
+ if err := w.GetIdentities(); err != nil {
+ return "", err
+ }
+ }
name, domain, _ := strings.Cut(from.Address, "@")
for _, ident := range w.identities {
n, d, _ := strings.Cut(ident.Email, "@")