feat(imap): postkasser kan læses, og det er bevist mod en rigtig server
Handlere til at forbinde, koble fra og hente nu, plus baggrundssynk hvert tiende minut ved siden af Gmails. Forbindelsen prøves FØR den gemmes: en postkasse, der blev taget imod og så fejler stille hvert tiende minut, er værre end en, der blev afvist ved døren, mens man stadig sidder med kodeordet i hånden. Ingen "set"-liste til deduplikering som Gmail har. Uid'er er monotone, så last_uid er hele svaret — og den skrives også, når budgettet løb ud, for en kørsel, der lavede opgaver og glemte hvor langt den nåede, laver dem alle igen næste gang. Rundturen køres nu mod go-imap's egen server i processen: flaget post kommer med, uflaget gør ikke, og fortsættelsen fra et uid henter kun det nyere. De hidtidige prøver dækkede de rene dele og ville alle have bestået med selve hentningen i stykker. Testen kræver et selvsigneret certifikat, og klienten nægter dem. Account.RootCAs lader en test TILFØJE tillid; der er stadig ingen måde at fjerne den på. Forskellen er en søm og ikke et hul — en prøve viser, at samme server afvises uden. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
1e59886d86
commit
6b4ef5b2f2
+13
-1
@@ -17,6 +17,7 @@ package imap
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
@@ -41,6 +42,13 @@ type Account struct {
|
||||
Username string
|
||||
Password string // an app-specific password on every host worth naming
|
||||
Folder string // "INBOX" when empty
|
||||
|
||||
// RootCAs adds a certificate authority to trust, on top of the system's. It
|
||||
// exists so a test can put a real IMAP server behind a self-signed certificate
|
||||
// and still be refused by everything else — the field can only widen trust,
|
||||
// never switch verification off, which is the difference between a seam and a
|
||||
// hole. Nil in production, where the system's roots are the answer.
|
||||
RootCAs *x509.CertPool
|
||||
}
|
||||
|
||||
// Dial opens a TLS connection and logs in. The caller closes it.
|
||||
@@ -55,7 +63,11 @@ func Dial(a Account) (*Client, error) {
|
||||
}
|
||||
|
||||
c, err := imapclient.DialTLS(a.Host, &imapclient.Options{
|
||||
TLSConfig: &tls.Config{ServerName: host, MinVersion: tls.VersionTLS12},
|
||||
TLSConfig: &tls.Config{
|
||||
ServerName: host,
|
||||
MinVersion: tls.VersionTLS12,
|
||||
RootCAs: a.RootCAs,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("connect to %s: %w", a.Host, err)
|
||||
|
||||
Reference in New Issue
Block a user