Other: Switch from liteapi to go-proton-api

This commit is contained in:
James Houlahan
2022-11-23 15:17:56 +01:00
parent e852c5a22f
commit ad1fb47b0d
52 changed files with 599 additions and 593 deletions

View File

@ -25,6 +25,7 @@ Proton Mail Bridge includes the following 3rd party software:
* [semver](https://github.com/Masterminds/semver/v3) available under [license](https://github.com/Masterminds/semver/v3/blob/master/LICENSE) * [semver](https://github.com/Masterminds/semver/v3) available under [license](https://github.com/Masterminds/semver/v3/blob/master/LICENSE)
* [gluon](https://github.com/ProtonMail/gluon) available under [license](https://github.com/ProtonMail/gluon/blob/master/LICENSE) * [gluon](https://github.com/ProtonMail/gluon) available under [license](https://github.com/ProtonMail/gluon/blob/master/LICENSE)
* [go-autostart](https://github.com/ProtonMail/go-autostart) available under [license](https://github.com/ProtonMail/go-autostart/blob/master/LICENSE) * [go-autostart](https://github.com/ProtonMail/go-autostart) available under [license](https://github.com/ProtonMail/go-autostart/blob/master/LICENSE)
* [go-proton-api](https://github.com/ProtonMail/go-proton-api) available under [license](https://github.com/ProtonMail/go-proton-api/blob/master/LICENSE)
* [go-rfc5322](https://github.com/ProtonMail/go-rfc5322) available under [license](https://github.com/ProtonMail/go-rfc5322/blob/master/LICENSE) * [go-rfc5322](https://github.com/ProtonMail/go-rfc5322) available under [license](https://github.com/ProtonMail/go-rfc5322/blob/master/LICENSE)
* [gopenpgp](https://github.com/ProtonMail/gopenpgp/v2) available under [license](https://github.com/ProtonMail/gopenpgp/v2/blob/master/LICENSE) * [gopenpgp](https://github.com/ProtonMail/gopenpgp/v2) available under [license](https://github.com/ProtonMail/gopenpgp/v2/blob/master/LICENSE)
* [goquery](https://github.com/PuerkitoBio/goquery) available under [license](https://github.com/PuerkitoBio/goquery/blob/master/LICENSE) * [goquery](https://github.com/PuerkitoBio/goquery) available under [license](https://github.com/PuerkitoBio/goquery/blob/master/LICENSE)
@ -58,7 +59,6 @@ Proton Mail Bridge includes the following 3rd party software:
* [testify](https://github.com/stretchr/testify) available under [license](https://github.com/stretchr/testify/blob/master/LICENSE) * [testify](https://github.com/stretchr/testify) available under [license](https://github.com/stretchr/testify/blob/master/LICENSE)
* [cli](https://github.com/urfave/cli/v2) available under [license](https://github.com/urfave/cli/v2/blob/master/LICENSE) * [cli](https://github.com/urfave/cli/v2) available under [license](https://github.com/urfave/cli/v2/blob/master/LICENSE)
* [msgpack](https://github.com/vmihailenco/msgpack/v5) available under [license](https://github.com/vmihailenco/msgpack/v5/blob/master/LICENSE) * [msgpack](https://github.com/vmihailenco/msgpack/v5) available under [license](https://github.com/vmihailenco/msgpack/v5/blob/master/LICENSE)
* [liteapi](https://gitlab.protontech.ch/go/liteapi)
* [goleak](https://go.uber.org/goleak) * [goleak](https://go.uber.org/goleak)
* [exp](https://golang.org/x/exp) available under [license](https://cs.opensource.google/go/x/exp/+/master:LICENSE) * [exp](https://golang.org/x/exp) available under [license](https://cs.opensource.google/go/x/exp/+/master:LICENSE)
* [net](https://golang.org/x/net) available under [license](https://cs.opensource.google/go/x/net/+/master:LICENSE) * [net](https://golang.org/x/net) available under [license](https://cs.opensource.google/go/x/net/+/master:LICENSE)

2
go.mod
View File

@ -7,6 +7,7 @@ require (
github.com/Masterminds/semver/v3 v3.1.1 github.com/Masterminds/semver/v3 v3.1.1
github.com/ProtonMail/gluon v0.13.1-0.20221122080348-aa074432d7ee github.com/ProtonMail/gluon v0.13.1-0.20221122080348-aa074432d7ee
github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a
github.com/ProtonMail/go-proton-api v0.0.0-20221123110304-2323ea736020
github.com/ProtonMail/go-rfc5322 v0.11.0 github.com/ProtonMail/go-rfc5322 v0.11.0
github.com/ProtonMail/gopenpgp/v2 v2.4.10 github.com/ProtonMail/gopenpgp/v2 v2.4.10
github.com/PuerkitoBio/goquery v1.8.0 github.com/PuerkitoBio/goquery v1.8.0
@ -40,7 +41,6 @@ require (
github.com/stretchr/testify v1.8.0 github.com/stretchr/testify v1.8.0
github.com/urfave/cli/v2 v2.20.3 github.com/urfave/cli/v2 v2.20.3
github.com/vmihailenco/msgpack/v5 v5.3.5 github.com/vmihailenco/msgpack/v5 v5.3.5
gitlab.protontech.ch/go/liteapi v0.43.2
go.uber.org/goleak v1.2.0 go.uber.org/goleak v1.2.0
golang.org/x/exp v0.0.0-20221023144134-a1e5550cf13e golang.org/x/exp v0.0.0-20221023144134-a1e5550cf13e
golang.org/x/net v0.1.0 golang.org/x/net v0.1.0

4
go.sum
View File

@ -43,6 +43,8 @@ github.com/ProtonMail/go-message v0.0.0-20210611055058-fabeff2ec753/go.mod h1:NB
github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f/go.mod h1:NYt+V3/4rEeDuaev/zw1zCq8uqVEuPHzDPo3OZrlGJ4= github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f/go.mod h1:NYt+V3/4rEeDuaev/zw1zCq8uqVEuPHzDPo3OZrlGJ4=
github.com/ProtonMail/go-mime v0.0.0-20220429130430-2192574d760f h1:4IWzKjHzZxdrW9k4zl/qCwenOVHDbVDADPPHFLjs0Oc= github.com/ProtonMail/go-mime v0.0.0-20220429130430-2192574d760f h1:4IWzKjHzZxdrW9k4zl/qCwenOVHDbVDADPPHFLjs0Oc=
github.com/ProtonMail/go-mime v0.0.0-20220429130430-2192574d760f/go.mod h1:qRZgbeASl2a9OwmsV85aWwRqic0NHPh+9ewGAzb4cgM= github.com/ProtonMail/go-mime v0.0.0-20220429130430-2192574d760f/go.mod h1:qRZgbeASl2a9OwmsV85aWwRqic0NHPh+9ewGAzb4cgM=
github.com/ProtonMail/go-proton-api v0.0.0-20221123110304-2323ea736020 h1:DyvKJ2+CjOmm7P/5rNclegawPqOCaFFX4Bp1nK86/LE=
github.com/ProtonMail/go-proton-api v0.0.0-20221123110304-2323ea736020/go.mod h1:j5lGWAEkSdNmboopnyKHVYvQaLlRTC6zB8yzIEgBQ7s=
github.com/ProtonMail/go-rfc5322 v0.11.0 h1:o5Obrm4DpmQEffvgsVqG6S4BKwC1Wat+hYwjIp2YcCY= github.com/ProtonMail/go-rfc5322 v0.11.0 h1:o5Obrm4DpmQEffvgsVqG6S4BKwC1Wat+hYwjIp2YcCY=
github.com/ProtonMail/go-rfc5322 v0.11.0/go.mod h1:6oOKr0jXvpoE6pwTx/HukigQpX2J9WUf6h0auplrFTw= github.com/ProtonMail/go-rfc5322 v0.11.0/go.mod h1:6oOKr0jXvpoE6pwTx/HukigQpX2J9WUf6h0auplrFTw=
github.com/ProtonMail/go-srp v0.0.5 h1:xhUioxZgDbCnpo9JehyFhwwsn9JLWkUGfB0oiKXgiGg= github.com/ProtonMail/go-srp v0.0.5 h1:xhUioxZgDbCnpo9JehyFhwwsn9JLWkUGfB0oiKXgiGg=
@ -403,8 +405,6 @@ github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsr
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/zclconf/go-cty v1.11.0 h1:726SxLdi2SDnjY+BStqB9J1hNp4+2WlzyXLuimibIe0= github.com/zclconf/go-cty v1.11.0 h1:726SxLdi2SDnjY+BStqB9J1hNp4+2WlzyXLuimibIe0=
github.com/zclconf/go-cty v1.11.0/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeWIMfhLvA= github.com/zclconf/go-cty v1.11.0/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeWIMfhLvA=
gitlab.protontech.ch/go/liteapi v0.43.2 h1:4/tF6pQuOg3sz2/JF1XGRff3KB0jFWM2uDstJiYmDYk=
gitlab.protontech.ch/go/liteapi v0.43.2/go.mod h1:IM7ADWjgIL2hXopzx0WNamizEuMgM2QZl7QH12FNflk=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=

View File

@ -21,9 +21,9 @@ import (
"net/http" "net/http"
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/proton-bridge/v2/internal/constants" "github.com/ProtonMail/proton-bridge/v2/internal/constants"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gitlab.protontech.ch/go/liteapi"
) )
// defaultAPIOptions returns a set of default API options for the given parameters. // defaultAPIOptions returns a set of default API options for the given parameters.
@ -33,13 +33,13 @@ func defaultAPIOptions(
cookieJar http.CookieJar, cookieJar http.CookieJar,
transport http.RoundTripper, transport http.RoundTripper,
poolSize int, poolSize int,
) []liteapi.Option { ) []proton.Option {
return []liteapi.Option{ return []proton.Option{
liteapi.WithHostURL(apiURL), proton.WithHostURL(apiURL),
liteapi.WithAppVersion(constants.AppVersion(version.Original())), proton.WithAppVersion(constants.AppVersion(version.Original())),
liteapi.WithCookieJar(cookieJar), proton.WithCookieJar(cookieJar),
liteapi.WithTransport(transport), proton.WithTransport(transport),
liteapi.WithAttPoolSize(poolSize), proton.WithAttPoolSize(poolSize),
liteapi.WithLogger(logrus.StandardLogger()), proton.WithLogger(logrus.StandardLogger()),
} }
} }

View File

@ -23,7 +23,7 @@ import (
"net/http" "net/http"
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"gitlab.protontech.ch/go/liteapi" "github.com/ProtonMail/go-proton-api"
) )
// newAPIOptions returns a set of API options for the given parameters. // newAPIOptions returns a set of API options for the given parameters.
@ -33,6 +33,6 @@ func newAPIOptions(
cookieJar http.CookieJar, cookieJar http.CookieJar,
transport http.RoundTripper, transport http.RoundTripper,
poolSize int, poolSize int,
) []liteapi.Option { ) []proton.Option {
return defaultAPIOptions(apiURL, version, cookieJar, transport, poolSize) return defaultAPIOptions(apiURL, version, cookieJar, transport, poolSize)
} }

View File

@ -24,7 +24,7 @@ import (
"os" "os"
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"gitlab.protontech.ch/go/liteapi" "github.com/ProtonMail/go-proton-api"
) )
// newAPIOptions returns a set of API options for the given parameters. // newAPIOptions returns a set of API options for the given parameters.
@ -34,19 +34,19 @@ func newAPIOptions(
cookieJar http.CookieJar, cookieJar http.CookieJar,
transport http.RoundTripper, transport http.RoundTripper,
poolSize int, poolSize int,
) []liteapi.Option { ) []proton.Option {
opt := defaultAPIOptions(apiURL, version, cookieJar, transport, poolSize) opt := defaultAPIOptions(apiURL, version, cookieJar, transport, poolSize)
if host := os.Getenv("BRIDGE_API_HOST"); host != "" { if host := os.Getenv("BRIDGE_API_HOST"); host != "" {
opt = append(opt, liteapi.WithHostURL(host)) opt = append(opt, proton.WithHostURL(host))
} }
if debug := os.Getenv("BRIDGE_API_DEBUG"); debug != "" { if debug := os.Getenv("BRIDGE_API_DEBUG"); debug != "" {
opt = append(opt, liteapi.WithDebug(true)) opt = append(opt, proton.WithDebug(true))
} }
if skipVerify := os.Getenv("BRIDGE_API_SKIP_VERIFY"); skipVerify != "" { if skipVerify := os.Getenv("BRIDGE_API_SKIP_VERIFY"); skipVerify != "" {
opt = append(opt, liteapi.WithSkipVerifyProofs()) opt = append(opt, proton.WithSkipVerifyProofs())
} }
return opt return opt

View File

@ -32,6 +32,7 @@ import (
imapEvents "github.com/ProtonMail/gluon/events" imapEvents "github.com/ProtonMail/gluon/events"
"github.com/ProtonMail/gluon/reporter" "github.com/ProtonMail/gluon/reporter"
"github.com/ProtonMail/gluon/watcher" "github.com/ProtonMail/gluon/watcher"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/proton-bridge/v2/internal/async" "github.com/ProtonMail/proton-bridge/v2/internal/async"
"github.com/ProtonMail/proton-bridge/v2/internal/constants" "github.com/ProtonMail/proton-bridge/v2/internal/constants"
"github.com/ProtonMail/proton-bridge/v2/internal/events" "github.com/ProtonMail/proton-bridge/v2/internal/events"
@ -43,7 +44,6 @@ import (
"github.com/emersion/go-smtp" "github.com/emersion/go-smtp"
"github.com/go-resty/resty/v2" "github.com/go-resty/resty/v2"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gitlab.protontech.ch/go/liteapi"
) )
type Bridge struct { type Bridge struct {
@ -55,7 +55,7 @@ type Bridge struct {
usersLock safe.RWMutex usersLock safe.RWMutex
// api manages user API clients. // api manages user API clients.
api *liteapi.Manager api *proton.Manager
proxyCtl ProxyController proxyCtl ProxyController
identifier Identifier identifier Identifier
@ -139,7 +139,7 @@ func New( //nolint:funlen
logSMTP bool, // whether to log SMTP activity logSMTP bool, // whether to log SMTP activity
) (*Bridge, <-chan events.Event, error) { ) (*Bridge, <-chan events.Event, error) {
// api is the user's API manager. // api is the user's API manager.
api := liteapi.New(newAPIOptions(apiURL, curVersion, cookieJar, roundTripper, vault.SyncAttPool())...) api := proton.New(newAPIOptions(apiURL, curVersion, cookieJar, roundTripper, vault.SyncAttPool())...)
// tasks holds all the bridge's background tasks. // tasks holds all the bridge's background tasks.
tasks := async.NewGroup(context.Background(), crashHandler) tasks := async.NewGroup(context.Background(), crashHandler)
@ -203,7 +203,7 @@ func newBridge(
crashHandler async.PanicHandler, crashHandler async.PanicHandler,
reporter reporter.Reporter, reporter reporter.Reporter,
api *liteapi.Manager, api *proton.Manager,
identifier Identifier, identifier Identifier,
proxyCtl ProxyController, proxyCtl ProxyController,
@ -288,22 +288,22 @@ func (bridge *Bridge) init(tlsReporter TLSReporter) error {
} }
// Handle connection up/down events. // Handle connection up/down events.
bridge.api.AddStatusObserver(func(status liteapi.Status) { bridge.api.AddStatusObserver(func(status proton.Status) {
logrus.Info("API status changed: ", status) logrus.Info("API status changed: ", status)
switch { switch {
case status == liteapi.StatusUp: case status == proton.StatusUp:
bridge.publish(events.ConnStatusUp{}) bridge.publish(events.ConnStatusUp{})
bridge.tasks.Once(bridge.onStatusUp) bridge.tasks.Once(bridge.onStatusUp)
case status == liteapi.StatusDown: case status == proton.StatusDown:
bridge.publish(events.ConnStatusDown{}) bridge.publish(events.ConnStatusDown{})
bridge.tasks.Once(bridge.onStatusDown) bridge.tasks.Once(bridge.onStatusDown)
} }
}) })
// If any call returns a bad version code, we need to update. // If any call returns a bad version code, we need to update.
bridge.api.AddErrorHandler(liteapi.AppVersionBadCode, func() { bridge.api.AddErrorHandler(proton.AppVersionBadCode, func() {
logrus.Warn("App version is bad") logrus.Warn("App version is bad")
bridge.publish(events.UpdateForced{}) bridge.publish(events.UpdateForced{})
}) })
@ -316,7 +316,7 @@ func (bridge *Bridge) init(tlsReporter TLSReporter) error {
// Log all manager API requests (client requests are logged separately). // Log all manager API requests (client requests are logged separately).
bridge.api.AddPostRequestHook(func(_ *resty.Client, r *resty.Response) error { bridge.api.AddPostRequestHook(func(_ *resty.Client, r *resty.Response) error {
if _, ok := liteapi.ClientIDFromContext(r.Request.Context()); !ok { if _, ok := proton.ClientIDFromContext(r.Request.Context()); !ok {
logrus.Infof("[MANAGER] %v: %v %v", r.Status(), r.Request.Method, r.Request.URL) logrus.Infof("[MANAGER] %v: %v %v", r.Status(), r.Request.Method, r.Request.URL)
} }

View File

@ -28,6 +28,9 @@ import (
"time" "time"
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/go-proton-api/server"
"github.com/ProtonMail/go-proton-api/server/backend"
"github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/ProtonMail/proton-bridge/v2/internal/bridge" "github.com/ProtonMail/proton-bridge/v2/internal/bridge"
"github.com/ProtonMail/proton-bridge/v2/internal/certs" "github.com/ProtonMail/proton-bridge/v2/internal/certs"
@ -42,9 +45,6 @@ import (
"github.com/ProtonMail/proton-bridge/v2/tests" "github.com/ProtonMail/proton-bridge/v2/tests"
"github.com/bradenaw/juniper/xslices" "github.com/bradenaw/juniper/xslices"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.protontech.ch/go/liteapi"
"gitlab.protontech.ch/go/liteapi/server"
"gitlab.protontech.ch/go/liteapi/server/backend"
"go.uber.org/goleak" "go.uber.org/goleak"
) )
@ -68,7 +68,7 @@ func init() {
} }
func TestBridge_ConnStatus(t *testing.T) { func TestBridge_ConnStatus(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, vaultKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
// Get a stream of connection status events. // Get a stream of connection status events.
eventCh, done := bridge.GetEvents(events.ConnStatusUp{}, events.ConnStatusDown{}) eventCh, done := bridge.GetEvents(events.ConnStatusUp{}, events.ConnStatusDown{})
@ -99,7 +99,7 @@ func TestBridge_ConnStatus(t *testing.T) {
} }
func TestBridge_TLSIssue(t *testing.T) { func TestBridge_TLSIssue(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, vaultKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
// Get a stream of TLS issue events. // Get a stream of TLS issue events.
tlsEventCh, done := bridge.GetEvents(events.TLSIssue{}) tlsEventCh, done := bridge.GetEvents(events.TLSIssue{})
@ -117,7 +117,7 @@ func TestBridge_TLSIssue(t *testing.T) {
} }
func TestBridge_Focus(t *testing.T) { func TestBridge_Focus(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, vaultKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
// Get a stream of TLS issue events. // Get a stream of TLS issue events.
raiseCh, done := bridge.GetEvents(events.Raise{}) raiseCh, done := bridge.GetEvents(events.Raise{})
@ -133,7 +133,7 @@ func TestBridge_Focus(t *testing.T) {
} }
func TestBridge_UserAgent(t *testing.T) { func TestBridge_UserAgent(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, vaultKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) {
var ( var (
calls []server.Call calls []server.Call
lock sync.Mutex lock sync.Mutex
@ -167,7 +167,7 @@ func TestBridge_UserAgent(t *testing.T) {
} }
func TestBridge_Cookies(t *testing.T) { func TestBridge_Cookies(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, vaultKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) {
var ( var (
sessionIDs []string sessionIDs []string
sessionIDsLock sync.RWMutex sessionIDsLock sync.RWMutex
@ -206,7 +206,7 @@ func TestBridge_Cookies(t *testing.T) {
} }
func TestBridge_CheckUpdate(t *testing.T) { func TestBridge_CheckUpdate(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, vaultKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
// Disable autoupdate for this test. // Disable autoupdate for this test.
require.NoError(t, bridge.SetAutoUpdate(false)) require.NoError(t, bridge.SetAutoUpdate(false))
@ -246,7 +246,7 @@ func TestBridge_CheckUpdate(t *testing.T) {
} }
func TestBridge_AutoUpdate(t *testing.T) { func TestBridge_AutoUpdate(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, vaultKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
// Enable autoupdate for this test. // Enable autoupdate for this test.
require.NoError(t, bridge.SetAutoUpdate(true)) require.NoError(t, bridge.SetAutoUpdate(true))
@ -275,7 +275,7 @@ func TestBridge_AutoUpdate(t *testing.T) {
} }
func TestBridge_ManualUpdate(t *testing.T) { func TestBridge_ManualUpdate(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, vaultKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
// Disable autoupdate for this test. // Disable autoupdate for this test.
require.NoError(t, bridge.SetAutoUpdate(false)) require.NoError(t, bridge.SetAutoUpdate(false))
@ -305,7 +305,7 @@ func TestBridge_ManualUpdate(t *testing.T) {
} }
func TestBridge_ForceUpdate(t *testing.T) { func TestBridge_ForceUpdate(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, vaultKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
// Get a stream of update events. // Get a stream of update events.
updateCh, done := bridge.GetEvents(events.UpdateForced{}) updateCh, done := bridge.GetEvents(events.UpdateForced{})
@ -325,7 +325,7 @@ func TestBridge_ForceUpdate(t *testing.T) {
} }
func TestBridge_BadVaultKey(t *testing.T) { func TestBridge_BadVaultKey(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, vaultKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) {
var userID string var userID string
// Login a user. // Login a user.
@ -354,7 +354,7 @@ func TestBridge_BadVaultKey(t *testing.T) {
} }
func TestBridge_MissingGluonDir(t *testing.T) { func TestBridge_MissingGluonDir(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, vaultKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) {
var gluonDir string var gluonDir string
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
@ -379,10 +379,10 @@ func TestBridge_MissingGluonDir(t *testing.T) {
} }
func TestBridge_AddressWithoutKeys(t *testing.T) { func TestBridge_AddressWithoutKeys(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, vaultKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) {
m := liteapi.New( m := proton.New(
liteapi.WithHostURL(s.GetHostURL()), proton.WithHostURL(s.GetHostURL()),
liteapi.WithTransport(liteapi.InsecureTransport()), proton.WithTransport(proton.InsecureTransport()),
) )
defer m.Close() defer m.Close()
@ -422,7 +422,7 @@ func TestBridge_AddressWithoutKeys(t *testing.T) {
} }
// withEnv creates the full test environment and runs the tests. // withEnv creates the full test environment and runs the tests.
func withEnv(t *testing.T, tests func(context.Context, *server.Server, *liteapi.NetCtl, bridge.Locator, []byte), opts ...server.Option) { func withEnv(t *testing.T, tests func(context.Context, *server.Server, *proton.NetCtl, bridge.Locator, []byte), opts ...server.Option) {
server := server.New(opts...) server := server.New(opts...)
defer server.Close() defer server.Close()
@ -439,7 +439,7 @@ func withEnv(t *testing.T, tests func(context.Context, *server.Server, *liteapi.
defer cancel() defer cancel()
// Create a net controller so we can simulate network connectivity issues. // Create a net controller so we can simulate network connectivity issues.
netCtl := liteapi.NewNetCtl() netCtl := proton.NewNetCtl()
// Create a locations object to provide temporary locations for bridge data during the test. // Create a locations object to provide temporary locations for bridge data during the test.
locations := locations.New(bridge.NewTestLocationsProvider(t.TempDir()), "config-name") locations := locations.New(bridge.NewTestLocationsProvider(t.TempDir()), "config-name")
@ -453,7 +453,7 @@ func withBridge(
ctx context.Context, ctx context.Context,
t *testing.T, t *testing.T,
apiURL string, apiURL string,
netCtl *liteapi.NetCtl, netCtl *proton.NetCtl,
locator bridge.Locator, locator bridge.Locator,
vaultKey []byte, vaultKey []byte,
tests func(*bridge.Bridge, *bridge.Mocks), tests func(*bridge.Bridge, *bridge.Mocks),
@ -492,7 +492,7 @@ func withBridge(
cookieJar, cookieJar,
useragent.New(), useragent.New(),
mocks.TLSReporter, mocks.TLSReporter,
liteapi.NewDialer(netCtl, &tls.Config{InsecureSkipVerify: true}).GetRoundTripper(), proton.NewDialer(netCtl, &tls.Config{InsecureSkipVerify: true}).GetRoundTripper(),
mocks.ProxyCtl, mocks.ProxyCtl,
mocks.CrashHandler, mocks.CrashHandler,
mocks.Reporter, mocks.Reporter,

View File

@ -26,10 +26,10 @@ import (
"path/filepath" "path/filepath"
"sort" "sort"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/proton-bridge/v2/internal/constants" "github.com/ProtonMail/proton-bridge/v2/internal/constants"
"github.com/ProtonMail/proton-bridge/v2/internal/logging" "github.com/ProtonMail/proton-bridge/v2/internal/logging"
"github.com/ProtonMail/proton-bridge/v2/internal/vault" "github.com/ProtonMail/proton-bridge/v2/internal/vault"
"gitlab.protontech.ch/go/liteapi"
) )
const ( const (
@ -50,7 +50,7 @@ func (bridge *Bridge) ReportBug(ctx context.Context, osType, osVersion, descript
} }
} }
var atts []liteapi.ReportBugAttachment var atts []proton.ReportBugAttachment
if attachLogs { if attachLogs {
logs, err := getMatchingLogs(bridge.locator, func(filename string) bool { logs, err := getMatchingLogs(bridge.locator, func(filename string) bool {
@ -97,7 +97,7 @@ func (bridge *Bridge) ReportBug(ctx context.Context, osType, osVersion, descript
return err return err
} }
atts = append(atts, liteapi.ReportBugAttachment{ atts = append(atts, proton.ReportBugAttachment{
Name: "logs.zip", Name: "logs.zip",
Filename: "logs.zip", Filename: "logs.zip",
MIMEType: "application/zip", MIMEType: "application/zip",
@ -105,7 +105,7 @@ func (bridge *Bridge) ReportBug(ctx context.Context, osType, osVersion, descript
}) })
} }
return bridge.api.ReportBug(ctx, liteapi.ReportBugReq{ return bridge.api.ReportBug(ctx, proton.ReportBugReq{
OS: osType, OS: osType,
OSVersion: osVersion, OSVersion: osVersion,
@ -113,7 +113,7 @@ func (bridge *Bridge) ReportBug(ctx context.Context, osType, osVersion, descript
Description: description, Description: description,
Client: client, Client: client,
ClientType: liteapi.ClientTypeEmail, ClientType: proton.ClientTypeEmail,
ClientVersion: constants.AppVersion(bridge.curVersion.Original()), ClientVersion: constants.AppVersion(bridge.curVersion.Original()),
Username: account, Username: account,

View File

@ -20,14 +20,14 @@ package mocks
import ( import (
"strings" "strings"
"gitlab.protontech.ch/go/liteapi" "github.com/ProtonMail/go-proton-api"
) )
type refreshContextMatcher struct { type refreshContextMatcher struct {
wantRefresh liteapi.RefreshFlag wantRefresh proton.RefreshFlag
} }
func NewRefreshContextMatcher(refreshFlag liteapi.RefreshFlag) *refreshContextMatcher { //nolint:revive func NewRefreshContextMatcher(refreshFlag proton.RefreshFlag) *refreshContextMatcher { //nolint:revive
return &refreshContextMatcher{wantRefresh: refreshFlag} return &refreshContextMatcher{wantRefresh: refreshFlag}
} }
@ -66,7 +66,7 @@ func (m *refreshContextMatcher) Matches(x interface{}) bool {
return false return false
} }
refresh, ok := vRefresh.(liteapi.RefreshFlag) refresh, ok := vRefresh.(proton.RefreshFlag)
if !ok { if !ok {
return false return false
} }
@ -75,11 +75,10 @@ func (m *refreshContextMatcher) Matches(x interface{}) bool {
} }
func (m *refreshContextMatcher) String() string { func (m *refreshContextMatcher) String() string {
return `map[string]interface which contains "Refresh" field with value liteapi.RefreshAll` return `map[string]interface which contains "Refresh" field with value proton.RefreshAll`
} }
type closedConnectionMatcher struct { type closedConnectionMatcher struct{}
}
func NewClosedConnectionMatcher() *closedConnectionMatcher { //nolint:revive func NewClosedConnectionMatcher() *closedConnectionMatcher { //nolint:revive
return &closedConnectionMatcher{} return &closedConnectionMatcher{}

View File

@ -22,6 +22,8 @@ import (
"fmt" "fmt"
"testing" "testing"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/go-proton-api/server"
"github.com/ProtonMail/proton-bridge/v2/internal/bridge" "github.com/ProtonMail/proton-bridge/v2/internal/bridge"
"github.com/ProtonMail/proton-bridge/v2/internal/constants" "github.com/ProtonMail/proton-bridge/v2/internal/constants"
"github.com/ProtonMail/proton-bridge/v2/internal/events" "github.com/ProtonMail/proton-bridge/v2/internal/events"
@ -29,12 +31,10 @@ import (
"github.com/emersion/go-imap/client" "github.com/emersion/go-imap/client"
"github.com/golang/mock/gomock" "github.com/golang/mock/gomock"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.protontech.ch/go/liteapi"
"gitlab.protontech.ch/go/liteapi/server"
) )
func TestBridge_Refresh(t *testing.T) { func TestBridge_Refresh(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
userID, _, err := s.CreateUser("imap", "imap@pm.me", password) userID, _, err := s.CreateUser("imap", "imap@pm.me", password)
require.NoError(t, err) require.NoError(t, err)
@ -43,7 +43,7 @@ func TestBridge_Refresh(t *testing.T) {
})) }))
for _, name := range names { for _, name := range names {
must(s.CreateLabel(userID, name, "", liteapi.LabelTypeFolder)) must(s.CreateLabel(userID, name, "", proton.LabelTypeFolder))
} }
// The initial user should be fully synced. // The initial user should be fully synced.
@ -78,7 +78,7 @@ func TestBridge_Refresh(t *testing.T) {
}) })
// Refresh the user; this will force a resync. // Refresh the user; this will force a resync.
require.NoError(t, s.RefreshUser(userID, liteapi.RefreshAll)) require.NoError(t, s.RefreshUser(userID, proton.RefreshAll))
// If we then connect an IMAP client, it should see all the labels with UID validity of 1. // If we then connect an IMAP client, it should see all the labels with UID validity of 1.
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(b *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(b *bridge.Bridge, mocks *bridge.Mocks) {

View File

@ -26,6 +26,8 @@ import (
"testing" "testing"
"time" "time"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/go-proton-api/server"
"github.com/ProtonMail/proton-bridge/v2/internal/bridge" "github.com/ProtonMail/proton-bridge/v2/internal/bridge"
"github.com/ProtonMail/proton-bridge/v2/internal/constants" "github.com/ProtonMail/proton-bridge/v2/internal/constants"
"github.com/emersion/go-imap" "github.com/emersion/go-imap"
@ -33,12 +35,10 @@ import (
"github.com/emersion/go-sasl" "github.com/emersion/go-sasl"
"github.com/emersion/go-smtp" "github.com/emersion/go-smtp"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.protontech.ch/go/liteapi"
"gitlab.protontech.ch/go/liteapi/server"
) )
func TestBridge_Send(t *testing.T) { func TestBridge_Send(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
_, _, err := s.CreateUser("recipient", "recipient@pm.me", password) _, _, err := s.CreateUser("recipient", "recipient@pm.me", password)
require.NoError(t, err) require.NoError(t, err)

View File

@ -22,14 +22,14 @@ import (
"os" "os"
"testing" "testing"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/go-proton-api/server"
"github.com/ProtonMail/proton-bridge/v2/internal/bridge" "github.com/ProtonMail/proton-bridge/v2/internal/bridge"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.protontech.ch/go/liteapi"
"gitlab.protontech.ch/go/liteapi/server"
) )
func TestBridge_Settings_GluonDir(t *testing.T) { func TestBridge_Settings_GluonDir(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
// Create a user. // Create a user.
_, err := bridge.LoginFull(context.Background(), username, password, nil, nil) _, err := bridge.LoginFull(context.Background(), username, password, nil, nil)
@ -52,7 +52,7 @@ func TestBridge_Settings_GluonDir(t *testing.T) {
} }
func TestBridge_Settings_IMAPPort(t *testing.T) { func TestBridge_Settings_IMAPPort(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
curPort := bridge.GetIMAPPort() curPort := bridge.GetIMAPPort()
@ -69,7 +69,7 @@ func TestBridge_Settings_IMAPPort(t *testing.T) {
} }
func TestBridge_Settings_IMAPSSL(t *testing.T) { func TestBridge_Settings_IMAPSSL(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
// By default, IMAP SSL is disabled. // By default, IMAP SSL is disabled.
require.False(t, bridge.GetIMAPSSL()) require.False(t, bridge.GetIMAPSSL())
@ -84,7 +84,7 @@ func TestBridge_Settings_IMAPSSL(t *testing.T) {
} }
func TestBridge_Settings_SMTPPort(t *testing.T) { func TestBridge_Settings_SMTPPort(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
curPort := bridge.GetSMTPPort() curPort := bridge.GetSMTPPort()
@ -101,7 +101,7 @@ func TestBridge_Settings_SMTPPort(t *testing.T) {
} }
func TestBridge_Settings_SMTPSSL(t *testing.T) { func TestBridge_Settings_SMTPSSL(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
// By default, SMTP SSL is disabled. // By default, SMTP SSL is disabled.
require.False(t, bridge.GetSMTPSSL()) require.False(t, bridge.GetSMTPSSL())
@ -116,7 +116,7 @@ func TestBridge_Settings_SMTPSSL(t *testing.T) {
} }
func TestBridge_Settings_Proxy(t *testing.T) { func TestBridge_Settings_Proxy(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
// By default, proxy is allowed. // By default, proxy is allowed.
require.True(t, bridge.GetProxyAllowed()) require.True(t, bridge.GetProxyAllowed())
@ -132,7 +132,7 @@ func TestBridge_Settings_Proxy(t *testing.T) {
} }
func TestBridge_Settings_Autostart(t *testing.T) { func TestBridge_Settings_Autostart(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
// By default, autostart is disabled. // By default, autostart is disabled.
require.False(t, bridge.GetAutostart()) require.False(t, bridge.GetAutostart())
@ -148,7 +148,7 @@ func TestBridge_Settings_Autostart(t *testing.T) {
} }
func TestBridge_Settings_FirstStart(t *testing.T) { func TestBridge_Settings_FirstStart(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
// By default, first start is true. // By default, first start is true.
require.True(t, bridge.GetFirstStart()) require.True(t, bridge.GetFirstStart())
@ -163,7 +163,7 @@ func TestBridge_Settings_FirstStart(t *testing.T) {
} }
func TestBridge_Settings_FirstStartGUI(t *testing.T) { func TestBridge_Settings_FirstStartGUI(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
// By default, first start is true. // By default, first start is true.
require.True(t, bridge.GetFirstStartGUI()) require.True(t, bridge.GetFirstStartGUI())

View File

@ -26,6 +26,8 @@ import (
"sync/atomic" "sync/atomic"
"testing" "testing"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/go-proton-api/server"
"github.com/ProtonMail/proton-bridge/v2/internal/bridge" "github.com/ProtonMail/proton-bridge/v2/internal/bridge"
"github.com/ProtonMail/proton-bridge/v2/internal/constants" "github.com/ProtonMail/proton-bridge/v2/internal/constants"
"github.com/ProtonMail/proton-bridge/v2/internal/events" "github.com/ProtonMail/proton-bridge/v2/internal/events"
@ -33,21 +35,19 @@ import (
"github.com/bradenaw/juniper/stream" "github.com/bradenaw/juniper/stream"
"github.com/emersion/go-imap/client" "github.com/emersion/go-imap/client"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.protontech.ch/go/liteapi"
"gitlab.protontech.ch/go/liteapi/server"
) )
func TestBridge_Sync(t *testing.T) { func TestBridge_Sync(t *testing.T) {
numMsg := 1 << 8 numMsg := 1 << 8
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
userID, addrID, err := s.CreateUser("imap", "imap@pm.me", password) userID, addrID, err := s.CreateUser("imap", "imap@pm.me", password)
require.NoError(t, err) require.NoError(t, err)
labelID, err := s.CreateLabel(userID, "folder", "", liteapi.LabelTypeFolder) labelID, err := s.CreateLabel(userID, "folder", "", proton.LabelTypeFolder)
require.NoError(t, err) require.NoError(t, err)
withClient(ctx, t, s, "imap", password, func(ctx context.Context, c *liteapi.Client) { withClient(ctx, t, s, "imap", password, func(ctx context.Context, c *proton.Client) {
createMessages(ctx, t, c, addrID, labelID, numMsg) createMessages(ctx, t, c, addrID, labelID, numMsg)
}) })
@ -142,10 +142,10 @@ func TestBridge_Sync(t *testing.T) {
}, server.WithTLS(false)) }, server.WithTLS(false))
} }
func withClient(ctx context.Context, t *testing.T, s *server.Server, username string, password []byte, fn func(context.Context, *liteapi.Client)) { func withClient(ctx context.Context, t *testing.T, s *server.Server, username string, password []byte, fn func(context.Context, *proton.Client)) {
m := liteapi.New( m := proton.New(
liteapi.WithHostURL(s.GetHostURL()), proton.WithHostURL(s.GetHostURL()),
liteapi.WithTransport(liteapi.InsecureTransport()), proton.WithTransport(proton.InsecureTransport()),
) )
c, _, err := m.NewClientWithLogin(ctx, username, password) c, _, err := m.NewClientWithLogin(ctx, username, password)
@ -155,7 +155,7 @@ func withClient(ctx context.Context, t *testing.T, s *server.Server, username st
fn(ctx, c) fn(ctx, c)
} }
func createMessages(ctx context.Context, t *testing.T, c *liteapi.Client, addrID, labelID string, count int) { func createMessages(ctx context.Context, t *testing.T, c *proton.Client, addrID, labelID string, count int) {
literal, err := os.ReadFile(filepath.Join("testdata", "text-plain.eml")) literal, err := os.ReadFile(filepath.Join("testdata", "text-plain.eml"))
require.NoError(t, err) require.NoError(t, err)
@ -171,7 +171,7 @@ func createMessages(ctx context.Context, t *testing.T, c *liteapi.Client, addrID
keyPass, err := salt.SaltForKey(password, user.Keys.Primary().ID) keyPass, err := salt.SaltForKey(password, user.Keys.Primary().ID)
require.NoError(t, err) require.NoError(t, err)
_, addrKRs, err := liteapi.Unlock(user, addr, keyPass) _, addrKRs, err := proton.Unlock(user, addr, keyPass)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, getErr(stream.Collect(ctx, c.ImportMessages( require.NoError(t, getErr(stream.Collect(ctx, c.ImportMessages(
@ -179,12 +179,12 @@ func createMessages(ctx context.Context, t *testing.T, c *liteapi.Client, addrID
addrKRs[addrID], addrKRs[addrID],
runtime.NumCPU(), runtime.NumCPU(),
runtime.NumCPU(), runtime.NumCPU(),
iterator.Collect(iterator.Map(iterator.Counter(count), func(i int) liteapi.ImportReq { iterator.Collect(iterator.Map(iterator.Counter(count), func(i int) proton.ImportReq {
return liteapi.ImportReq{ return proton.ImportReq{
Metadata: liteapi.ImportMetadata{ Metadata: proton.ImportMetadata{
AddressID: addrID, AddressID: addrID,
LabelIDs: []string{labelID}, LabelIDs: []string{labelID},
Flags: liteapi.MessageFlagReceived, Flags: proton.MessageFlagReceived,
}, },
Message: literal, Message: literal,
} }
@ -192,7 +192,7 @@ func createMessages(ctx context.Context, t *testing.T, c *liteapi.Client, addrID
)))) ))))
} }
func countBytesRead(ctl *liteapi.NetCtl, fn func()) uint64 { func countBytesRead(ctl *proton.NetCtl, fn func()) uint64 {
var read uint64 var read uint64
ctl.OnRead(func(b []byte) { ctl.OnRead(func(b []byte) {

View File

@ -24,6 +24,7 @@ import (
"runtime" "runtime"
"github.com/ProtonMail/gluon/imap" "github.com/ProtonMail/gluon/imap"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/proton-bridge/v2/internal/async" "github.com/ProtonMail/proton-bridge/v2/internal/async"
"github.com/ProtonMail/proton-bridge/v2/internal/events" "github.com/ProtonMail/proton-bridge/v2/internal/events"
"github.com/ProtonMail/proton-bridge/v2/internal/logging" "github.com/ProtonMail/proton-bridge/v2/internal/logging"
@ -33,7 +34,6 @@ import (
"github.com/ProtonMail/proton-bridge/v2/internal/vault" "github.com/ProtonMail/proton-bridge/v2/internal/vault"
"github.com/go-resty/resty/v2" "github.com/go-resty/resty/v2"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gitlab.protontech.ch/go/liteapi"
) )
type UserState int type UserState int
@ -112,7 +112,7 @@ func (bridge *Bridge) QueryUserInfo(query string) (UserInfo, error) {
} }
// LoginAuth begins the login process. It returns an authorized client that might need 2FA. // LoginAuth begins the login process. It returns an authorized client that might need 2FA.
func (bridge *Bridge) LoginAuth(ctx context.Context, username string, password []byte) (*liteapi.Client, liteapi.Auth, error) { func (bridge *Bridge) LoginAuth(ctx context.Context, username string, password []byte) (*proton.Client, proton.Auth, error) {
logrus.WithField("username", logging.Sensitive(username)).Info("Authorizing user for login") logrus.WithField("username", logging.Sensitive(username)).Info("Authorizing user for login")
if username == "crash@bandicoot" { if username == "crash@bandicoot" {
@ -121,7 +121,7 @@ func (bridge *Bridge) LoginAuth(ctx context.Context, username string, password [
client, auth, err := bridge.api.NewClientWithLogin(ctx, username, password) client, auth, err := bridge.api.NewClientWithLogin(ctx, username, password)
if err != nil { if err != nil {
return nil, liteapi.Auth{}, fmt.Errorf("failed to create new API client: %w", err) return nil, proton.Auth{}, fmt.Errorf("failed to create new API client: %w", err)
} }
if ok := safe.RLockRet(func() bool { return mapHas(bridge.users, auth.UID) }, bridge.usersLock); ok { if ok := safe.RLockRet(func() bool { return mapHas(bridge.users, auth.UID) }, bridge.usersLock); ok {
@ -131,7 +131,7 @@ func (bridge *Bridge) LoginAuth(ctx context.Context, username string, password [
logrus.WithError(err).Warn("Failed to delete auth") logrus.WithError(err).Warn("Failed to delete auth")
} }
return nil, liteapi.Auth{}, ErrUserAlreadyLoggedIn return nil, proton.Auth{}, ErrUserAlreadyLoggedIn
} }
return client, auth, nil return client, auth, nil
@ -140,8 +140,8 @@ func (bridge *Bridge) LoginAuth(ctx context.Context, username string, password [
// LoginUser finishes the user login process using the client and auth received from LoginAuth. // LoginUser finishes the user login process using the client and auth received from LoginAuth.
func (bridge *Bridge) LoginUser( func (bridge *Bridge) LoginUser(
ctx context.Context, ctx context.Context,
client *liteapi.Client, client *proton.Client,
auth liteapi.Auth, auth proton.Auth,
keyPass []byte, keyPass []byte,
) (string, error) { ) (string, error) {
logrus.WithField("userID", auth.UserID).Info("Logging in authorized user") logrus.WithField("userID", auth.UserID).Info("Logging in authorized user")
@ -182,7 +182,7 @@ func (bridge *Bridge) LoginFull(
return "", fmt.Errorf("failed to begin login process: %w", err) return "", fmt.Errorf("failed to begin login process: %w", err)
} }
if auth.TwoFA.Enabled == liteapi.TOTPEnabled { if auth.TwoFA.Enabled == proton.TOTPEnabled {
logrus.WithField("userID", auth.UserID).Info("Requesting TOTP") logrus.WithField("userID", auth.UserID).Info("Requesting TOTP")
totp, err := getTOTP() totp, err := getTOTP()
@ -190,14 +190,14 @@ func (bridge *Bridge) LoginFull(
return "", fmt.Errorf("failed to get TOTP: %w", err) return "", fmt.Errorf("failed to get TOTP: %w", err)
} }
if err := client.Auth2FA(ctx, liteapi.Auth2FAReq{TwoFactorCode: totp}); err != nil { if err := client.Auth2FA(ctx, proton.Auth2FAReq{TwoFactorCode: totp}); err != nil {
return "", fmt.Errorf("failed to authorize 2FA: %w", err) return "", fmt.Errorf("failed to authorize 2FA: %w", err)
} }
} }
var keyPass []byte var keyPass []byte
if auth.PasswordMode == liteapi.TwoPasswordMode { if auth.PasswordMode == proton.TwoPasswordMode {
logrus.WithField("userID", auth.UserID).Info("Requesting mailbox password") logrus.WithField("userID", auth.UserID).Info("Requesting mailbox password")
userKeyPass, err := getKeyPass() userKeyPass, err := getKeyPass()
@ -296,7 +296,7 @@ func (bridge *Bridge) SetAddressMode(ctx context.Context, userID string, mode va
}, bridge.usersLock) }, bridge.usersLock)
} }
func (bridge *Bridge) loginUser(ctx context.Context, client *liteapi.Client, authUID, authRef string, keyPass []byte) (string, error) { func (bridge *Bridge) loginUser(ctx context.Context, client *proton.Client, authUID, authRef string, keyPass []byte) (string, error) {
apiUser, err := client.GetUser(ctx) apiUser, err := client.GetUser(ctx)
if err != nil { if err != nil {
return "", fmt.Errorf("failed to get API user: %w", err) return "", fmt.Errorf("failed to get API user: %w", err)
@ -365,7 +365,7 @@ func (bridge *Bridge) loadUsers(ctx context.Context) error {
func (bridge *Bridge) loadUser(ctx context.Context, user *vault.User) error { func (bridge *Bridge) loadUser(ctx context.Context, user *vault.User) error {
client, auth, err := bridge.api.NewClientWithRefresh(ctx, user.AuthUID(), user.AuthRef()) client, auth, err := bridge.api.NewClientWithRefresh(ctx, user.AuthUID(), user.AuthRef())
if err != nil { if err != nil {
if apiErr := new(liteapi.Error); errors.As(err, &apiErr) && (apiErr.Code == liteapi.AuthRefreshTokenInvalid) { if apiErr := new(proton.Error); errors.As(err, &apiErr) && (apiErr.Code == proton.AuthRefreshTokenInvalid) {
// The session cannot be refreshed, we sign out the user by clearing his auth secrets. // The session cannot be refreshed, we sign out the user by clearing his auth secrets.
if err := user.Clear(); err != nil { if err := user.Clear(); err != nil {
logrus.WithError(err).Warn("Failed to clear user secrets") logrus.WithError(err).Warn("Failed to clear user secrets")
@ -393,8 +393,8 @@ func (bridge *Bridge) loadUser(ctx context.Context, user *vault.User) error {
// addUser adds a new user with an already salted mailbox password. // addUser adds a new user with an already salted mailbox password.
func (bridge *Bridge) addUser( func (bridge *Bridge) addUser(
ctx context.Context, ctx context.Context,
client *liteapi.Client, client *proton.Client,
apiUser liteapi.User, apiUser proton.User,
authUID, authRef string, authUID, authRef string,
saltedKeyPass []byte, saltedKeyPass []byte,
isLogin bool, isLogin bool,
@ -436,8 +436,8 @@ func (bridge *Bridge) addUser(
// addUserWithVault adds a new user to bridge with the given vault. // addUserWithVault adds a new user to bridge with the given vault.
func (bridge *Bridge) addUserWithVault( func (bridge *Bridge) addUserWithVault(
ctx context.Context, ctx context.Context,
client *liteapi.Client, client *proton.Client,
apiUser liteapi.User, apiUser proton.User,
vault *vault.User, vault *vault.User,
) error { ) error {
user, err := user.New( user, err := user.New(
@ -497,7 +497,7 @@ func (bridge *Bridge) addUserWithVault(
// newVaultUser creates a new vault user from the given auth information. // newVaultUser creates a new vault user from the given auth information.
// If one already exists in the vault, its data will be updated. // If one already exists in the vault, its data will be updated.
func (bridge *Bridge) newVaultUser( func (bridge *Bridge) newVaultUser(
apiUser liteapi.User, apiUser proton.User,
authUID, authRef string, authUID, authRef string,
saltedKeyPass []byte, saltedKeyPass []byte,
) (*vault.User, bool, error) { ) (*vault.User, bool, error) {

View File

@ -23,18 +23,18 @@ import (
"testing" "testing"
"time" "time"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/go-proton-api/server"
"github.com/ProtonMail/proton-bridge/v2/internal/bridge" "github.com/ProtonMail/proton-bridge/v2/internal/bridge"
mocksPkg "github.com/ProtonMail/proton-bridge/v2/internal/bridge/mocks" mocksPkg "github.com/ProtonMail/proton-bridge/v2/internal/bridge/mocks"
"github.com/ProtonMail/proton-bridge/v2/internal/events" "github.com/ProtonMail/proton-bridge/v2/internal/events"
"github.com/ProtonMail/proton-bridge/v2/internal/vault" "github.com/ProtonMail/proton-bridge/v2/internal/vault"
"github.com/golang/mock/gomock" "github.com/golang/mock/gomock"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.protontech.ch/go/liteapi"
"gitlab.protontech.ch/go/liteapi/server"
) )
func TestBridge_WithoutUsers(t *testing.T) { func TestBridge_WithoutUsers(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
require.Empty(t, bridge.GetUserIDs()) require.Empty(t, bridge.GetUserIDs())
require.Empty(t, getConnectedUserIDs(t, bridge)) require.Empty(t, getConnectedUserIDs(t, bridge))
@ -48,7 +48,7 @@ func TestBridge_WithoutUsers(t *testing.T) {
} }
func TestBridge_Login(t *testing.T) { func TestBridge_Login(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
// Login the user. // Login the user.
userID, err := bridge.LoginFull(ctx, username, password, nil, nil) userID, err := bridge.LoginFull(ctx, username, password, nil, nil)
@ -62,7 +62,7 @@ func TestBridge_Login(t *testing.T) {
} }
func TestBridge_LoginLogoutLogin(t *testing.T) { func TestBridge_LoginLogoutLogin(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
// Login the user. // Login the user.
userID := must(bridge.LoginFull(ctx, username, password, nil, nil)) userID := must(bridge.LoginFull(ctx, username, password, nil, nil))
@ -90,7 +90,7 @@ func TestBridge_LoginLogoutLogin(t *testing.T) {
} }
func TestBridge_LoginDeleteLogin(t *testing.T) { func TestBridge_LoginDeleteLogin(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
// Login the user. // Login the user.
userID := must(bridge.LoginFull(ctx, username, password, nil, nil)) userID := must(bridge.LoginFull(ctx, username, password, nil, nil))
@ -118,7 +118,7 @@ func TestBridge_LoginDeleteLogin(t *testing.T) {
} }
func TestBridge_LoginDeauthLogin(t *testing.T) { func TestBridge_LoginDeauthLogin(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
// Login the user. // Login the user.
userID := must(bridge.LoginFull(ctx, username, password, nil, nil)) userID := must(bridge.LoginFull(ctx, username, password, nil, nil))
@ -150,7 +150,7 @@ func TestBridge_LoginDeauthLogin(t *testing.T) {
} }
func TestBridge_LoginDeauthRestartLogin(t *testing.T) { func TestBridge_LoginDeauthRestartLogin(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
var userID string var userID string
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
@ -192,7 +192,7 @@ func TestBridge_LoginDeauthRestartLogin(t *testing.T) {
func TestBridge_LoginExpireLogin(t *testing.T) { func TestBridge_LoginExpireLogin(t *testing.T) {
const authLife = 2 * time.Second const authLife = 2 * time.Second
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
s.SetAuthLife(authLife) s.SetAuthLife(authLife)
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
@ -209,7 +209,7 @@ func TestBridge_LoginExpireLogin(t *testing.T) {
} }
func TestBridge_FailToLoad(t *testing.T) { func TestBridge_FailToLoad(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
var userID string var userID string
// Login the user. // Login the user.
@ -229,7 +229,7 @@ func TestBridge_FailToLoad(t *testing.T) {
} }
func TestBridge_LoadWithoutInternet(t *testing.T) { func TestBridge_LoadWithoutInternet(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
var userID string var userID string
// Login the user. // Login the user.
@ -260,7 +260,7 @@ func TestBridge_LoadWithoutInternet(t *testing.T) {
} }
func TestBridge_LoginRestart(t *testing.T) { func TestBridge_LoginRestart(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
var userID string var userID string
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
@ -275,7 +275,7 @@ func TestBridge_LoginRestart(t *testing.T) {
} }
func TestBridge_LoginLogoutRestart(t *testing.T) { func TestBridge_LoginLogoutRestart(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
var userID string var userID string
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
@ -295,7 +295,7 @@ func TestBridge_LoginLogoutRestart(t *testing.T) {
} }
func TestBridge_LoginDeleteRestart(t *testing.T) { func TestBridge_LoginDeleteRestart(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
var userID string var userID string
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
@ -317,7 +317,7 @@ func TestBridge_LoginDeleteRestart(t *testing.T) {
func TestBridge_FailLoginRecover(t *testing.T) { func TestBridge_FailLoginRecover(t *testing.T) {
for i := uint64(1); i < 10; i++ { for i := uint64(1); i < 10; i++ {
t.Run(fmt.Sprintf("read %v%% of the data", 100*i/10), func(t *testing.T) { t.Run(fmt.Sprintf("read %v%% of the data", 100*i/10), func(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
var userID string var userID string
// Log the user in, wait for it to sync, then log it out. // Log the user in, wait for it to sync, then log it out.
@ -374,7 +374,7 @@ func TestBridge_FailLoginRecover(t *testing.T) {
func TestBridge_FailLoadRecover(t *testing.T) { func TestBridge_FailLoadRecover(t *testing.T) {
for i := uint64(1); i < 10; i++ { for i := uint64(1); i < 10; i++ {
t.Run(fmt.Sprintf("read %v%% of the data", 100*i/10), func(t *testing.T) { t.Run(fmt.Sprintf("read %v%% of the data", 100*i/10), func(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
var userID string var userID string
// Log the user in and wait for it to sync. // Log the user in and wait for it to sync.
@ -417,7 +417,7 @@ func TestBridge_FailLoadRecover(t *testing.T) {
} }
func TestBridge_BridgePass(t *testing.T) { func TestBridge_BridgePass(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
var userID string var userID string
var pass []byte var pass []byte
@ -451,7 +451,7 @@ func TestBridge_BridgePass(t *testing.T) {
} }
func TestBridge_AddressMode(t *testing.T) { func TestBridge_AddressMode(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
// Login the user. // Login the user.
userID, err := bridge.LoginFull(ctx, username, password, nil, nil) userID, err := bridge.LoginFull(ctx, username, password, nil, nil)
@ -489,7 +489,7 @@ func TestBridge_AddressMode(t *testing.T) {
} }
func TestBridge_LoginLogoutRepeated(t *testing.T) { func TestBridge_LoginLogoutRepeated(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
// Log the user in. // Log the user in.
@ -503,7 +503,7 @@ func TestBridge_LoginLogoutRepeated(t *testing.T) {
} }
func TestBridge_LogoutOffline(t *testing.T) { func TestBridge_LogoutOffline(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
var userID string var userID string
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
@ -537,7 +537,7 @@ func TestBridge_LogoutOffline(t *testing.T) {
} }
func TestBridge_DeleteDisconnected(t *testing.T) { func TestBridge_DeleteDisconnected(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
// Login the user. // Login the user.
userID, err := bridge.LoginFull(ctx, username, password, nil, nil) userID, err := bridge.LoginFull(ctx, username, password, nil, nil)
@ -565,7 +565,7 @@ func TestBridge_DeleteDisconnected(t *testing.T) {
} }
func TestBridge_DeleteOffline(t *testing.T) { func TestBridge_DeleteOffline(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, storeKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
// Login the user. // Login the user.
userID, err := bridge.LoginFull(ctx, username, password, nil, nil) userID, err := bridge.LoginFull(ctx, username, password, nil, nil)
@ -589,7 +589,7 @@ func TestBridge_DeleteOffline(t *testing.T) {
} }
func TestBridge_UserInfo_Alias(t *testing.T) { func TestBridge_UserInfo_Alias(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, vaultKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
// Create a new user. // Create a new user.
userID, _, err := s.CreateUser("primary", "primary@pm.me", []byte("password")) userID, _, err := s.CreateUser("primary", "primary@pm.me", []byte("password"))
@ -612,11 +612,11 @@ func TestBridge_UserInfo_Alias(t *testing.T) {
} }
func TestBridge_User_Refresh(t *testing.T) { func TestBridge_User_Refresh(t *testing.T) {
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *liteapi.NetCtl, locator bridge.Locator, vaultKey []byte) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
mocks.Reporter.EXPECT().ReportMessageWithContext( mocks.Reporter.EXPECT().ReportMessageWithContext(
gomock.Eq("Warning: refresh occurred"), gomock.Eq("Warning: refresh occurred"),
mocksPkg.NewRefreshContextMatcher(liteapi.RefreshAll), mocksPkg.NewRefreshContextMatcher(proton.RefreshAll),
).Return(nil) ).Return(nil)
// Get a channel of sync started events. // Get a channel of sync started events.
@ -635,7 +635,7 @@ func TestBridge_User_Refresh(t *testing.T) {
require.Equal(t, userID, (<-syncFinishCh).UserID) require.Equal(t, userID, (<-syncFinishCh).UserID)
// Trigger a refresh. // Trigger a refresh.
require.NoError(t, s.RefreshUser(userID, liteapi.RefreshAll)) require.NoError(t, s.RefreshUser(userID, proton.RefreshAll))
// The sync should start and finish again. // The sync should start and finish again.
require.Equal(t, userID, (<-syncStartCh).UserID) require.Equal(t, userID, (<-syncStartCh).UserID)

View File

@ -22,6 +22,7 @@ package constants
import ( import (
"fmt" "fmt"
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
) )

View File

@ -23,11 +23,11 @@ import (
"testing" "testing"
"time" "time"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/go-proton-api/server"
"github.com/ProtonMail/proton-bridge/v2/internal/useragent" "github.com/ProtonMail/proton-bridge/v2/internal/useragent"
a "github.com/stretchr/testify/assert" a "github.com/stretchr/testify/assert"
r "github.com/stretchr/testify/require" r "github.com/stretchr/testify/require"
"gitlab.protontech.ch/go/liteapi"
"gitlab.protontech.ch/go/liteapi/server"
) )
func getRootURL() string { func getRootURL() string {
@ -110,7 +110,7 @@ func TestTLSSelfSignedCertTrustedPublicKey(t *testing.T) {
r.NoError(t, err, "expected dial to succeed because public key is known despite cert being self-signed") r.NoError(t, err, "expected dial to succeed because public key is known despite cert being self-signed")
} }
func createClientWithPinningDialer(hostURL string) (*atomicUint64, *PinningTLSDialer, *TLSReporter, *TLSPinChecker, *liteapi.Manager) { func createClientWithPinningDialer(hostURL string) (*atomicUint64, *PinningTLSDialer, *TLSReporter, *TLSPinChecker, *proton.Manager) {
called := &atomicUint64{} called := &atomicUint64{}
reporter := NewTLSReporter(hostURL, "appVersion", useragent.New(), TrustedAPIPins) reporter := NewTLSReporter(hostURL, "appVersion", useragent.New(), TrustedAPIPins)
@ -123,9 +123,9 @@ func createClientWithPinningDialer(hostURL string) (*atomicUint64, *PinningTLSDi
} }
}() }()
return called, dialer, reporter, checker, liteapi.New( return called, dialer, reporter, checker, proton.New(
liteapi.WithHostURL(hostURL), proton.WithHostURL(hostURL),
liteapi.WithTransport(CreateTransportWithDialer(dialer)), proton.WithTransport(CreateTransportWithDialer(dialer)),
) )
} }

View File

@ -24,11 +24,12 @@
package proto package proto
import ( import (
reflect "reflect"
sync "sync"
protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl" protoimpl "google.golang.org/protobuf/runtime/protoimpl"
emptypb "google.golang.org/protobuf/types/known/emptypb" emptypb "google.golang.org/protobuf/types/known/emptypb"
reflect "reflect"
sync "sync"
) )
const ( const (

View File

@ -8,6 +8,7 @@ package proto
import ( import (
context "context" context "context"
grpc "google.golang.org/grpc" grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes" codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status" status "google.golang.org/grpc/status"

View File

@ -21,11 +21,11 @@ import (
"context" "context"
"strings" "strings"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/proton-bridge/v2/internal/bridge" "github.com/ProtonMail/proton-bridge/v2/internal/bridge"
"github.com/ProtonMail/proton-bridge/v2/internal/constants" "github.com/ProtonMail/proton-bridge/v2/internal/constants"
"github.com/ProtonMail/proton-bridge/v2/internal/vault" "github.com/ProtonMail/proton-bridge/v2/internal/vault"
"github.com/abiosoft/ishell" "github.com/abiosoft/ishell"
"gitlab.protontech.ch/go/liteapi"
) )
func (f *frontendCLI) listAccounts(_ *ishell.Context) { func (f *frontendCLI) listAccounts(_ *ishell.Context) {
@ -149,14 +149,14 @@ func (f *frontendCLI) loginAccount(c *ishell.Context) { //nolint:funlen
return return
} }
if auth.TwoFA.Enabled == liteapi.TOTPEnabled { if auth.TwoFA.Enabled == proton.TOTPEnabled {
code := f.readStringInAttempts("Two factor code", c.ReadLine, isNotEmpty) code := f.readStringInAttempts("Two factor code", c.ReadLine, isNotEmpty)
if code == "" { if code == "" {
f.printAndLogError("Cannot login: need two factor code") f.printAndLogError("Cannot login: need two factor code")
return return
} }
if err := client.Auth2FA(context.Background(), liteapi.Auth2FAReq{TwoFactorCode: code}); err != nil { if err := client.Auth2FA(context.Background(), proton.Auth2FAReq{TwoFactorCode: code}); err != nil {
f.printAndLogError("Cannot login: ", err) f.printAndLogError("Cannot login: ", err)
return return
} }
@ -164,7 +164,7 @@ func (f *frontendCLI) loginAccount(c *ishell.Context) { //nolint:funlen
var keyPass []byte var keyPass []byte
if auth.PasswordMode == liteapi.TwoPasswordMode { if auth.PasswordMode == proton.TwoPasswordMode {
keyPass = []byte(f.readStringInAttempts("Mailbox password", c.ReadPassword, isNotEmpty)) keyPass = []byte(f.readStringInAttempts("Mailbox password", c.ReadPassword, isNotEmpty))
if len(keyPass) == 0 { if len(keyPass) == 0 {
f.printAndLogError("Cannot login: need mailbox password") f.printAndLogError("Cannot login: need mailbox password")

View File

@ -24,12 +24,13 @@
package grpc package grpc
import ( import (
reflect "reflect"
sync "sync"
protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl" protoimpl "google.golang.org/protobuf/runtime/protoimpl"
emptypb "google.golang.org/protobuf/types/known/emptypb" emptypb "google.golang.org/protobuf/types/known/emptypb"
wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" wrapperspb "google.golang.org/protobuf/types/known/wrapperspb"
reflect "reflect"
sync "sync"
) )
const ( const (
@ -39,9 +40,9 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
) )
//********************************************************** // **********************************************************
// Log related message // Log related message
//********************************************************** // **********************************************************
// Note: the enum values are prefixed with 'LOG_' to avoid a clash in C++ on Windows with the ERROR macro defined in wingdi.h // Note: the enum values are prefixed with 'LOG_' to avoid a clash in C++ on Windows with the ERROR macro defined in wingdi.h
type LogLevel int32 type LogLevel int32
@ -104,9 +105,9 @@ func (LogLevel) EnumDescriptor() ([]byte, []int) {
return file_bridge_proto_rawDescGZIP(), []int{0} return file_bridge_proto_rawDescGZIP(), []int{0}
} }
//********************************************************** // **********************************************************
// user related messages // user related messages
//********************************************************** // **********************************************************
type UserState int32 type UserState int32
const ( const (
@ -436,9 +437,11 @@ func (x *AddLogEntryRequest) GetMessage() string {
return "" return ""
} }
//********************************************************** // **********************************************************
//
// Bug reporting related messages. // Bug reporting related messages.
//********************************************************** //
// **********************************************************
type ReportBugRequest struct { type ReportBugRequest struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -628,9 +631,9 @@ func (x *LoginAbortRequest) GetUsername() string {
return "" return ""
} }
//********************************************************** // **********************************************************
// IMAP/SMTP Mail Server settings // IMAP/SMTP Mail Server settings
//********************************************************** // **********************************************************
type ImapSmtpSettings struct { type ImapSmtpSettings struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -702,9 +705,9 @@ func (x *ImapSmtpSettings) GetUseSSLForSmtp() bool {
return false return false
} }
//********************************************************** // **********************************************************
// Keychain related message // Keychain related message
//********************************************************** // **********************************************************
type AvailableKeychainsResponse struct { type AvailableKeychainsResponse struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -1239,9 +1242,9 @@ func (*StreamEvent_Mail) isStreamEvent_Event() {}
func (*StreamEvent_User) isStreamEvent_Event() {} func (*StreamEvent_User) isStreamEvent_Event() {}
//********************************************************** // **********************************************************
// App related events // App related events
//********************************************************** // **********************************************************
type AppEvent struct { type AppEvent struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -1667,9 +1670,9 @@ func (*ShowMainWindowEvent) Descriptor() ([]byte, []int) {
return file_bridge_proto_rawDescGZIP(), []int{19} return file_bridge_proto_rawDescGZIP(), []int{19}
} }
//********************************************************** // **********************************************************
// Login related events // Login related events
//********************************************************** // **********************************************************
type LoginEvent struct { type LoginEvent struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -1979,9 +1982,9 @@ func (x *LoginFinishedEvent) GetUserID() string {
return "" return ""
} }
//********************************************************** // **********************************************************
// Update related events // Update related events
//********************************************************** // **********************************************************
type UpdateEvent struct { type UpdateEvent struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -2477,9 +2480,9 @@ func (*UpdateVersionChanged) Descriptor() ([]byte, []int) {
return file_bridge_proto_rawDescGZIP(), []int{33} return file_bridge_proto_rawDescGZIP(), []int{33}
} }
//********************************************************** // **********************************************************
// Cache on disk related events // Cache on disk related events
//********************************************************** // **********************************************************
type DiskCacheEvent struct { type DiskCacheEvent struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -2706,9 +2709,9 @@ func (*DiskCachePathChangeFinishedEvent) Descriptor() ([]byte, []int) {
return file_bridge_proto_rawDescGZIP(), []int{37} return file_bridge_proto_rawDescGZIP(), []int{37}
} }
//********************************************************** // **********************************************************
// Mail server settings related events // Mail server settings related events
//********************************************************** // **********************************************************
type MailServerSettingsEvent struct { type MailServerSettingsEvent struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -2935,9 +2938,9 @@ func (*ChangeMailServerSettingsFinishedEvent) Descriptor() ([]byte, []int) {
return file_bridge_proto_rawDescGZIP(), []int{41} return file_bridge_proto_rawDescGZIP(), []int{41}
} }
//********************************************************** // **********************************************************
// keychain related events // keychain related events
//********************************************************** // **********************************************************
type KeychainEvent struct { type KeychainEvent struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -3146,9 +3149,9 @@ func (*RebuildKeychainEvent) Descriptor() ([]byte, []int) {
return file_bridge_proto_rawDescGZIP(), []int{45} return file_bridge_proto_rawDescGZIP(), []int{45}
} }
//********************************************************** // **********************************************************
// Mail related events // Mail related events
//********************************************************** // **********************************************************
type MailEvent struct { type MailEvent struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache

View File

@ -8,6 +8,7 @@ package grpc
import ( import (
context "context" context "context"
grpc "google.golang.org/grpc" grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes" codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status" status "google.golang.org/grpc/status"

View File

@ -29,6 +29,7 @@ import (
"sync" "sync"
"time" "time"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/proton-bridge/v2/internal/bridge" "github.com/ProtonMail/proton-bridge/v2/internal/bridge"
"github.com/ProtonMail/proton-bridge/v2/internal/certs" "github.com/ProtonMail/proton-bridge/v2/internal/certs"
"github.com/ProtonMail/proton-bridge/v2/internal/events" "github.com/ProtonMail/proton-bridge/v2/internal/events"
@ -39,7 +40,6 @@ import (
sysinfotypes "github.com/elastic/go-sysinfo/types" sysinfotypes "github.com/elastic/go-sysinfo/types"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gitlab.protontech.ch/go/liteapi"
"google.golang.org/grpc" "google.golang.org/grpc"
codes "google.golang.org/grpc/codes" codes "google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
@ -76,8 +76,8 @@ type Service struct { // nolint:structcheck
target updater.VersionInfo target updater.VersionInfo
targetLock safe.RWMutex targetLock safe.RWMutex
authClient *liteapi.Client authClient *proton.Client
auth liteapi.Auth auth proton.Auth
password []byte password []byte
log *logrus.Entry log *logrus.Entry
@ -352,7 +352,7 @@ func (s *Service) loginAbort() {
} }
func (s *Service) loginClean() { func (s *Service) loginClean() {
s.auth = liteapi.Auth{} s.auth = proton.Auth{}
s.authClient = nil s.authClient = nil
for i := range s.password { for i := range s.password {
s.password[i] = '\x00' s.password[i] = '\x00'

View File

@ -24,6 +24,7 @@ import (
"runtime" "runtime"
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/proton-bridge/v2/internal/bridge" "github.com/ProtonMail/proton-bridge/v2/internal/bridge"
"github.com/ProtonMail/proton-bridge/v2/internal/constants" "github.com/ProtonMail/proton-bridge/v2/internal/constants"
"github.com/ProtonMail/proton-bridge/v2/internal/events" "github.com/ProtonMail/proton-bridge/v2/internal/events"
@ -33,7 +34,6 @@ import (
"github.com/ProtonMail/proton-bridge/v2/pkg/keychain" "github.com/ProtonMail/proton-bridge/v2/pkg/keychain"
"github.com/ProtonMail/proton-bridge/v2/pkg/ports" "github.com/ProtonMail/proton-bridge/v2/pkg/ports"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gitlab.protontech.ch/go/liteapi"
"golang.org/x/exp/maps" "golang.org/x/exp/maps"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
@ -383,12 +383,12 @@ func (s *Service) Login(ctx context.Context, login *LoginRequest) (*emptypb.Empt
if errors.Is(err, bridge.ErrUserAlreadyLoggedIn) { if errors.Is(err, bridge.ErrUserAlreadyLoggedIn) {
_ = s.SendEvent(NewLoginAlreadyLoggedInEvent(auth.UserID)) _ = s.SendEvent(NewLoginAlreadyLoggedInEvent(auth.UserID))
} else if apiErr := new(liteapi.Error); errors.As(err, &apiErr) { } else if apiErr := new(proton.Error); errors.As(err, &apiErr) {
switch apiErr.Code { // nolint:exhaustive switch apiErr.Code { // nolint:exhaustive
case liteapi.PasswordWrong: case proton.PasswordWrong:
_ = s.SendEvent(NewLoginError(LoginErrorType_USERNAME_PASSWORD_ERROR, "")) _ = s.SendEvent(NewLoginError(LoginErrorType_USERNAME_PASSWORD_ERROR, ""))
case liteapi.PaidPlanRequired: case proton.PaidPlanRequired:
_ = s.SendEvent(NewLoginError(LoginErrorType_FREE_USER, "")) _ = s.SendEvent(NewLoginError(LoginErrorType_FREE_USER, ""))
default: default:
@ -406,10 +406,10 @@ func (s *Service) Login(ctx context.Context, login *LoginRequest) (*emptypb.Empt
s.auth = auth s.auth = auth
switch { switch {
case auth.TwoFA.Enabled == liteapi.TOTPEnabled: case auth.TwoFA.Enabled == proton.TOTPEnabled:
_ = s.SendEvent(NewLoginTfaRequestedEvent(login.Username)) _ = s.SendEvent(NewLoginTfaRequestedEvent(login.Username))
case auth.PasswordMode == liteapi.TwoPasswordMode: case auth.PasswordMode == proton.TwoPasswordMode:
_ = s.SendEvent(NewLoginTwoPasswordsRequestedEvent()) _ = s.SendEvent(NewLoginTwoPasswordsRequestedEvent())
default: default:
@ -441,8 +441,8 @@ func (s *Service) Login2FA(ctx context.Context, login *LoginRequest) (*emptypb.E
return return
} }
if err := s.authClient.Auth2FA(context.Background(), liteapi.Auth2FAReq{TwoFactorCode: string(twoFA)}); err != nil { if err := s.authClient.Auth2FA(context.Background(), proton.Auth2FAReq{TwoFactorCode: string(twoFA)}); err != nil {
if apiErr := new(liteapi.Error); errors.As(err, &apiErr) && apiErr.Code == liteapi.PasswordWrong { if apiErr := new(proton.Error); errors.As(err, &apiErr) && apiErr.Code == proton.PasswordWrong {
s.log.Warn("Login 2FA: retry 2fa") s.log.Warn("Login 2FA: retry 2fa")
_ = s.SendEvent(NewLoginError(LoginErrorType_TFA_ERROR, "")) _ = s.SendEvent(NewLoginError(LoginErrorType_TFA_ERROR, ""))
} else { } else {
@ -454,7 +454,7 @@ func (s *Service) Login2FA(ctx context.Context, login *LoginRequest) (*emptypb.E
return return
} }
if s.auth.PasswordMode == liteapi.TwoPasswordMode { if s.auth.PasswordMode == proton.TwoPasswordMode {
_ = s.SendEvent(NewLoginTwoPasswordsRequestedEvent()) _ = s.SendEvent(NewLoginTwoPasswordsRequestedEvent())
return return
} }

View File

@ -20,8 +20,7 @@ package logging
import "github.com/sirupsen/logrus" import "github.com/sirupsen/logrus"
// IMAPLogger implements the writer interface for Gluon IMAP logs. // IMAPLogger implements the writer interface for Gluon IMAP logs.
type IMAPLogger struct { type IMAPLogger struct{}
}
func NewIMAPLogger() *IMAPLogger { func NewIMAPLogger() *IMAPLogger {
return &IMAPLogger{} return &IMAPLogger{}

View File

@ -23,18 +23,18 @@ import (
"github.com/ProtonMail/gluon/imap" "github.com/ProtonMail/gluon/imap"
"github.com/ProtonMail/gluon/queue" "github.com/ProtonMail/gluon/queue"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/ProtonMail/proton-bridge/v2/internal/events" "github.com/ProtonMail/proton-bridge/v2/internal/events"
"github.com/ProtonMail/proton-bridge/v2/internal/logging" "github.com/ProtonMail/proton-bridge/v2/internal/logging"
"github.com/ProtonMail/proton-bridge/v2/internal/safe" "github.com/ProtonMail/proton-bridge/v2/internal/safe"
"github.com/ProtonMail/proton-bridge/v2/internal/vault" "github.com/ProtonMail/proton-bridge/v2/internal/vault"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gitlab.protontech.ch/go/liteapi"
) )
// handleAPIEvent handles the given liteapi.Event. // handleAPIEvent handles the given proton.Event.
func (user *User) handleAPIEvent(ctx context.Context, event liteapi.Event) error { func (user *User) handleAPIEvent(ctx context.Context, event proton.Event) error {
if event.Refresh&liteapi.RefreshMail != 0 { if event.Refresh&proton.RefreshMail != 0 {
return user.handleRefreshEvent(ctx, event.Refresh, event.EventID) return user.handleRefreshEvent(ctx, event.Refresh, event.EventID)
} }
@ -65,7 +65,7 @@ func (user *User) handleAPIEvent(ctx context.Context, event liteapi.Event) error
return nil return nil
} }
func (user *User) handleRefreshEvent(ctx context.Context, refresh liteapi.RefreshFlag, eventID string) error { func (user *User) handleRefreshEvent(ctx context.Context, refresh proton.RefreshFlag, eventID string) error {
l := user.log.WithFields(logrus.Fields{ l := user.log.WithFields(logrus.Fields{
"eventID": eventID, "eventID": eventID,
"refresh": refresh, "refresh": refresh,
@ -100,15 +100,15 @@ func (user *User) handleRefreshEvent(ctx context.Context, refresh liteapi.Refres
} }
// Fetch latest label info. // Fetch latest label info.
apiLabels, err := user.client.GetLabels(ctx, liteapi.LabelTypeSystem, liteapi.LabelTypeFolder, liteapi.LabelTypeLabel) apiLabels, err := user.client.GetLabels(ctx, proton.LabelTypeSystem, proton.LabelTypeFolder, proton.LabelTypeLabel)
if err != nil { if err != nil {
return fmt.Errorf("failed to get labels: %w", err) return fmt.Errorf("failed to get labels: %w", err)
} }
// Update the API info in the user. // Update the API info in the user.
user.apiUser = apiUser user.apiUser = apiUser
user.apiAddrs = groupBy(apiAddrs, func(addr liteapi.Address) string { return addr.ID }) user.apiAddrs = groupBy(apiAddrs, func(addr proton.Address) string { return addr.ID })
user.apiLabels = groupBy(apiLabels, func(label liteapi.Label) string { return label.ID }) user.apiLabels = groupBy(apiLabels, func(label proton.Label) string { return label.ID })
// Reinitialize the update channels. // Reinitialize the update channels.
user.initUpdateCh(user.vault.AddressMode()) user.initUpdateCh(user.vault.AddressMode())
@ -128,7 +128,7 @@ func (user *User) handleRefreshEvent(ctx context.Context, refresh liteapi.Refres
} }
// handleUserEvent handles the given user event. // handleUserEvent handles the given user event.
func (user *User) handleUserEvent(_ context.Context, userEvent liteapi.User) error { func (user *User) handleUserEvent(_ context.Context, userEvent proton.User) error {
return safe.LockRet(func() error { return safe.LockRet(func() error {
user.log.WithFields(logrus.Fields{ user.log.WithFields(logrus.Fields{
"userID": userEvent.ID, "userID": userEvent.ID,
@ -147,20 +147,20 @@ func (user *User) handleUserEvent(_ context.Context, userEvent liteapi.User) err
// handleAddressEvents handles the given address events. // handleAddressEvents handles the given address events.
// GODT-1945: If split address mode, need to signal back to bridge to update the addresses. // GODT-1945: If split address mode, need to signal back to bridge to update the addresses.
func (user *User) handleAddressEvents(ctx context.Context, addressEvents []liteapi.AddressEvent) error { func (user *User) handleAddressEvents(ctx context.Context, addressEvents []proton.AddressEvent) error {
for _, event := range addressEvents { for _, event := range addressEvents {
switch event.Action { switch event.Action {
case liteapi.EventCreate: case proton.EventCreate:
if err := user.handleCreateAddressEvent(ctx, event); err != nil { if err := user.handleCreateAddressEvent(ctx, event); err != nil {
return fmt.Errorf("failed to handle create address event: %w", err) return fmt.Errorf("failed to handle create address event: %w", err)
} }
case liteapi.EventUpdate, liteapi.EventUpdateFlags: case proton.EventUpdate, proton.EventUpdateFlags:
if err := user.handleUpdateAddressEvent(ctx, event); err != nil { if err := user.handleUpdateAddressEvent(ctx, event); err != nil {
return fmt.Errorf("failed to handle update address event: %w", err) return fmt.Errorf("failed to handle update address event: %w", err)
} }
case liteapi.EventDelete: case proton.EventDelete:
if err := user.handleDeleteAddressEvent(ctx, event); err != nil { if err := user.handleDeleteAddressEvent(ctx, event); err != nil {
return fmt.Errorf("failed to delete address: %w", err) return fmt.Errorf("failed to delete address: %w", err)
} }
@ -170,7 +170,7 @@ func (user *User) handleAddressEvents(ctx context.Context, addressEvents []litea
return nil return nil
} }
func (user *User) handleCreateAddressEvent(ctx context.Context, event liteapi.AddressEvent) error { func (user *User) handleCreateAddressEvent(ctx context.Context, event proton.AddressEvent) error {
if err := safe.LockRet(func() error { if err := safe.LockRet(func() error {
user.log.WithFields(logrus.Fields{ user.log.WithFields(logrus.Fields{
"addressID": event.ID, "addressID": event.ID,
@ -219,7 +219,7 @@ func (user *User) handleCreateAddressEvent(ctx context.Context, event liteapi.Ad
}, user.apiAddrsLock, user.apiLabelsLock, user.updateChLock) }, user.apiAddrsLock, user.apiLabelsLock, user.updateChLock)
} }
func (user *User) handleUpdateAddressEvent(_ context.Context, event liteapi.AddressEvent) error { //nolint:unparam func (user *User) handleUpdateAddressEvent(_ context.Context, event proton.AddressEvent) error { //nolint:unparam
return safe.LockRet(func() error { return safe.LockRet(func() error {
user.log.WithFields(logrus.Fields{ user.log.WithFields(logrus.Fields{
"addressID": event.ID, "addressID": event.ID,
@ -242,7 +242,7 @@ func (user *User) handleUpdateAddressEvent(_ context.Context, event liteapi.Addr
}, user.apiAddrsLock) }, user.apiAddrsLock)
} }
func (user *User) handleDeleteAddressEvent(_ context.Context, event liteapi.AddressEvent) error { func (user *User) handleDeleteAddressEvent(_ context.Context, event proton.AddressEvent) error {
return safe.LockRet(func() error { return safe.LockRet(func() error {
user.log.WithField("addressID", event.ID).Info("Handling address deleted event") user.log.WithField("addressID", event.ID).Info("Handling address deleted event")
@ -269,20 +269,20 @@ func (user *User) handleDeleteAddressEvent(_ context.Context, event liteapi.Addr
} }
// handleLabelEvents handles the given label events. // handleLabelEvents handles the given label events.
func (user *User) handleLabelEvents(ctx context.Context, labelEvents []liteapi.LabelEvent) error { func (user *User) handleLabelEvents(ctx context.Context, labelEvents []proton.LabelEvent) error {
for _, event := range labelEvents { for _, event := range labelEvents {
switch event.Action { switch event.Action {
case liteapi.EventCreate: case proton.EventCreate:
if err := user.handleCreateLabelEvent(ctx, event); err != nil { if err := user.handleCreateLabelEvent(ctx, event); err != nil {
return fmt.Errorf("failed to handle create label event: %w", err) return fmt.Errorf("failed to handle create label event: %w", err)
} }
case liteapi.EventUpdate, liteapi.EventUpdateFlags: case proton.EventUpdate, proton.EventUpdateFlags:
if err := user.handleUpdateLabelEvent(ctx, event); err != nil { if err := user.handleUpdateLabelEvent(ctx, event); err != nil {
return fmt.Errorf("failed to handle update label event: %w", err) return fmt.Errorf("failed to handle update label event: %w", err)
} }
case liteapi.EventDelete: case proton.EventDelete:
if err := user.handleDeleteLabelEvent(ctx, event); err != nil { if err := user.handleDeleteLabelEvent(ctx, event); err != nil {
return fmt.Errorf("failed to handle delete label event: %w", err) return fmt.Errorf("failed to handle delete label event: %w", err)
} }
@ -292,7 +292,7 @@ func (user *User) handleLabelEvents(ctx context.Context, labelEvents []liteapi.L
return nil return nil
} }
func (user *User) handleCreateLabelEvent(_ context.Context, event liteapi.LabelEvent) error { //nolint:unparam func (user *User) handleCreateLabelEvent(_ context.Context, event proton.LabelEvent) error { //nolint:unparam
return safe.LockRet(func() error { return safe.LockRet(func() error {
user.log.WithFields(logrus.Fields{ user.log.WithFields(logrus.Fields{
"labelID": event.ID, "labelID": event.ID,
@ -319,7 +319,7 @@ func (user *User) handleCreateLabelEvent(_ context.Context, event liteapi.LabelE
}, user.apiLabelsLock, user.updateChLock) }, user.apiLabelsLock, user.updateChLock)
} }
func (user *User) handleUpdateLabelEvent(_ context.Context, event liteapi.LabelEvent) error { //nolint:unparam func (user *User) handleUpdateLabelEvent(_ context.Context, event proton.LabelEvent) error { //nolint:unparam
return safe.LockRet(func() error { return safe.LockRet(func() error {
user.log.WithFields(logrus.Fields{ user.log.WithFields(logrus.Fields{
"labelID": event.ID, "labelID": event.ID,
@ -349,7 +349,7 @@ func (user *User) handleUpdateLabelEvent(_ context.Context, event liteapi.LabelE
}, user.apiLabelsLock, user.updateChLock) }, user.apiLabelsLock, user.updateChLock)
} }
func (user *User) handleDeleteLabelEvent(_ context.Context, event liteapi.LabelEvent) error { //nolint:unparam func (user *User) handleDeleteLabelEvent(_ context.Context, event proton.LabelEvent) error { //nolint:unparam
return safe.LockRet(func() error { return safe.LockRet(func() error {
user.log.WithField("labelID", event.ID).Info("Handling label deleted event") user.log.WithField("labelID", event.ID).Info("Handling label deleted event")
@ -375,12 +375,12 @@ func (user *User) handleDeleteLabelEvent(_ context.Context, event liteapi.LabelE
} }
// handleMessageEvents handles the given message events. // handleMessageEvents handles the given message events.
func (user *User) handleMessageEvents(ctx context.Context, messageEvents []liteapi.MessageEvent) error { func (user *User) handleMessageEvents(ctx context.Context, messageEvents []proton.MessageEvent) error {
for _, event := range messageEvents { for _, event := range messageEvents {
ctx = logging.WithLogrusField(ctx, "messageID", event.ID) ctx = logging.WithLogrusField(ctx, "messageID", event.ID)
switch event.Action { switch event.Action {
case liteapi.EventCreate: case proton.EventCreate:
if err := user.handleCreateMessageEvent( if err := user.handleCreateMessageEvent(
logging.WithLogrusField(ctx, "action", "create message"), logging.WithLogrusField(ctx, "action", "create message"),
event, event,
@ -388,9 +388,9 @@ func (user *User) handleMessageEvents(ctx context.Context, messageEvents []litea
return fmt.Errorf("failed to handle create message event: %w", err) return fmt.Errorf("failed to handle create message event: %w", err)
} }
case liteapi.EventUpdate, liteapi.EventUpdateFlags: case proton.EventUpdate, proton.EventUpdateFlags:
// GODT-2028 - Use better events here. It should be possible to have 3 separate events that refrain to // GODT-2028 - Use better events here. It should be possible to have 3 separate events that refrain to
// whether the flags, labels or read only data (header+body) has been changed. This requires fixing liteapi // whether the flags, labels or read only data (header+body) has been changed. This requires fixing proton
// first so that it correctly reports those cases. // first so that it correctly reports those cases.
// Issue regular update to handle mailboxes and flag changes. // Issue regular update to handle mailboxes and flag changes.
if err := user.handleUpdateMessageEvent( if err := user.handleUpdateMessageEvent(
@ -410,7 +410,7 @@ func (user *User) handleMessageEvents(ctx context.Context, messageEvents []litea
} }
} }
case liteapi.EventDelete: case proton.EventDelete:
if err := user.handleDeleteMessageEvent( if err := user.handleDeleteMessageEvent(
logging.WithLogrusField(ctx, "action", "delete message"), logging.WithLogrusField(ctx, "action", "delete message"),
event, event,
@ -423,7 +423,7 @@ func (user *User) handleMessageEvents(ctx context.Context, messageEvents []litea
return nil return nil
} }
func (user *User) handleCreateMessageEvent(ctx context.Context, event liteapi.MessageEvent) error { func (user *User) handleCreateMessageEvent(ctx context.Context, event proton.MessageEvent) error {
full, err := user.client.GetFullMessage(ctx, event.Message.ID) full, err := user.client.GetFullMessage(ctx, event.Message.ID)
if err != nil { if err != nil {
return fmt.Errorf("failed to get full message: %w", err) return fmt.Errorf("failed to get full message: %w", err)
@ -448,7 +448,7 @@ func (user *User) handleCreateMessageEvent(ctx context.Context, event liteapi.Me
}, user.apiUserLock, user.apiAddrsLock, user.apiLabelsLock, user.updateChLock) }, user.apiUserLock, user.apiAddrsLock, user.apiLabelsLock, user.updateChLock)
} }
func (user *User) handleUpdateMessageEvent(ctx context.Context, event liteapi.MessageEvent) error { //nolint:unparam func (user *User) handleUpdateMessageEvent(ctx context.Context, event proton.MessageEvent) error { //nolint:unparam
return safe.RLockRet(func() error { return safe.RLockRet(func() error {
user.log.WithFields(logrus.Fields{ user.log.WithFields(logrus.Fields{
"messageID": event.ID, "messageID": event.ID,
@ -466,7 +466,7 @@ func (user *User) handleUpdateMessageEvent(ctx context.Context, event liteapi.Me
}, user.apiLabelsLock, user.updateChLock) }, user.apiLabelsLock, user.updateChLock)
} }
func (user *User) handleDeleteMessageEvent(ctx context.Context, event liteapi.MessageEvent) error { //nolint:unparam func (user *User) handleDeleteMessageEvent(ctx context.Context, event proton.MessageEvent) error { //nolint:unparam
return safe.RLockRet(func() error { return safe.RLockRet(func() error {
user.log.WithField("messageID", event.ID).Info("Handling message deleted event") user.log.WithField("messageID", event.ID).Info("Handling message deleted event")
@ -478,7 +478,7 @@ func (user *User) handleDeleteMessageEvent(ctx context.Context, event liteapi.Me
}, user.updateChLock) }, user.updateChLock)
} }
func (user *User) handleUpdateDraftEvent(ctx context.Context, event liteapi.MessageEvent) error { //nolint:unparam func (user *User) handleUpdateDraftEvent(ctx context.Context, event proton.MessageEvent) error { //nolint:unparam
return safe.RLockRet(func() error { return safe.RLockRet(func() error {
user.log.WithFields(logrus.Fields{ user.log.WithFields(logrus.Fields{
"messageID": event.ID, "messageID": event.ID,
@ -508,19 +508,19 @@ func (user *User) handleUpdateDraftEvent(ctx context.Context, event liteapi.Mess
}, user.apiUserLock, user.apiAddrsLock, user.apiLabelsLock, user.updateChLock) }, user.apiUserLock, user.apiAddrsLock, user.apiLabelsLock, user.updateChLock)
} }
func getMailboxName(label liteapi.Label) []string { func getMailboxName(label proton.Label) []string {
var name []string var name []string
switch label.Type { switch label.Type {
case liteapi.LabelTypeFolder: case proton.LabelTypeFolder:
name = append([]string{folderPrefix}, label.Path...) name = append([]string{folderPrefix}, label.Path...)
case liteapi.LabelTypeLabel: case proton.LabelTypeLabel:
name = append([]string{labelPrefix}, label.Path...) name = append([]string{labelPrefix}, label.Path...)
case liteapi.LabelTypeContactGroup: case proton.LabelTypeContactGroup:
fallthrough fallthrough
case liteapi.LabelTypeSystem: case proton.LabelTypeSystem:
fallthrough fallthrough
default: default:
name = label.Path name = label.Path

View File

@ -26,13 +26,13 @@ import (
"github.com/ProtonMail/gluon/connector" "github.com/ProtonMail/gluon/connector"
"github.com/ProtonMail/gluon/imap" "github.com/ProtonMail/gluon/imap"
"github.com/ProtonMail/gluon/rfc822" "github.com/ProtonMail/gluon/rfc822"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/ProtonMail/proton-bridge/v2/internal/safe" "github.com/ProtonMail/proton-bridge/v2/internal/safe"
"github.com/ProtonMail/proton-bridge/v2/internal/vault" "github.com/ProtonMail/proton-bridge/v2/internal/vault"
"github.com/ProtonMail/proton-bridge/v2/pkg/message" "github.com/ProtonMail/proton-bridge/v2/pkg/message"
"github.com/bradenaw/juniper/stream" "github.com/bradenaw/juniper/stream"
"github.com/bradenaw/juniper/xslices" "github.com/bradenaw/juniper/xslices"
"gitlab.protontech.ch/go/liteapi"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
) )
@ -109,10 +109,10 @@ func (conn *imapConnector) createLabel(ctx context.Context, name []string) (imap
return imap.Mailbox{}, fmt.Errorf("a label cannot have children") return imap.Mailbox{}, fmt.Errorf("a label cannot have children")
} }
label, err := conn.client.CreateLabel(ctx, liteapi.CreateLabelReq{ label, err := conn.client.CreateLabel(ctx, proton.CreateLabelReq{
Name: name[0], Name: name[0],
Color: "#f66", Color: "#f66",
Type: liteapi.LabelTypeLabel, Type: proton.LabelTypeLabel,
}) })
if err != nil { if err != nil {
return imap.Mailbox{}, err return imap.Mailbox{}, err
@ -141,10 +141,10 @@ func (conn *imapConnector) createFolder(ctx context.Context, name []string) (ima
} }
} }
label, err := conn.client.CreateLabel(ctx, liteapi.CreateLabelReq{ label, err := conn.client.CreateLabel(ctx, proton.CreateLabelReq{
Name: name[len(name)-1], Name: name[len(name)-1],
Color: "#f66", Color: "#f66",
Type: liteapi.LabelTypeFolder, Type: proton.LabelTypeFolder,
ParentID: parentID, ParentID: parentID,
}) })
if err != nil { if err != nil {
@ -180,12 +180,12 @@ func (conn *imapConnector) updateLabel(ctx context.Context, labelID imap.Mailbox
return fmt.Errorf("a label cannot have children") return fmt.Errorf("a label cannot have children")
} }
label, err := conn.client.GetLabel(ctx, string(labelID), liteapi.LabelTypeLabel) label, err := conn.client.GetLabel(ctx, string(labelID), proton.LabelTypeLabel)
if err != nil { if err != nil {
return err return err
} }
if _, err := conn.client.UpdateLabel(ctx, label.ID, liteapi.UpdateLabelReq{ if _, err := conn.client.UpdateLabel(ctx, label.ID, proton.UpdateLabelReq{
Name: name[0], Name: name[0],
Color: label.Color, Color: label.Color,
}); err != nil { }); err != nil {
@ -215,12 +215,12 @@ func (conn *imapConnector) updateFolder(ctx context.Context, labelID imap.Mailbo
} }
} }
label, err := conn.client.GetLabel(ctx, string(labelID), liteapi.LabelTypeFolder) label, err := conn.client.GetLabel(ctx, string(labelID), proton.LabelTypeFolder)
if err != nil { if err != nil {
return err return err
} }
if _, err := conn.client.UpdateLabel(ctx, string(labelID), liteapi.UpdateLabelReq{ if _, err := conn.client.UpdateLabel(ctx, string(labelID), proton.UpdateLabelReq{
Name: name[len(name)-1], Name: name[len(name)-1],
Color: label.Color, Color: label.Color,
ParentID: parentID, ParentID: parentID,
@ -274,38 +274,38 @@ func (conn *imapConnector) CreateMessage(
wantLabelIDs := []string{string(mailboxID)} wantLabelIDs := []string{string(mailboxID)}
if flags.Contains(imap.FlagFlagged) { if flags.Contains(imap.FlagFlagged) {
wantLabelIDs = append(wantLabelIDs, liteapi.StarredLabel) wantLabelIDs = append(wantLabelIDs, proton.StarredLabel)
} }
var wantFlags liteapi.MessageFlag var wantFlags proton.MessageFlag
unread := !flags.Contains(imap.FlagSeen) unread := !flags.Contains(imap.FlagSeen)
if mailboxID != liteapi.DraftsLabel { if mailboxID != proton.DraftsLabel {
header, err := rfc822.Parse(literal).ParseHeader() header, err := rfc822.Parse(literal).ParseHeader()
if err != nil { if err != nil {
return imap.Message{}, nil, err return imap.Message{}, nil, err
} }
switch { switch {
case mailboxID == liteapi.InboxLabel: case mailboxID == proton.InboxLabel:
wantFlags = wantFlags.Add(liteapi.MessageFlagReceived) wantFlags = wantFlags.Add(proton.MessageFlagReceived)
case mailboxID == liteapi.SentLabel: case mailboxID == proton.SentLabel:
wantFlags = wantFlags.Add(liteapi.MessageFlagSent) wantFlags = wantFlags.Add(proton.MessageFlagSent)
case header.Has("Received"): case header.Has("Received"):
wantFlags = wantFlags.Add(liteapi.MessageFlagReceived) wantFlags = wantFlags.Add(proton.MessageFlagReceived)
default: default:
wantFlags = wantFlags.Add(liteapi.MessageFlagSent) wantFlags = wantFlags.Add(proton.MessageFlagSent)
} }
} else { } else {
unread = false unread = false
} }
if flags.Contains(imap.FlagAnswered) { if flags.Contains(imap.FlagAnswered) {
wantFlags = wantFlags.Add(liteapi.MessageFlagReplied) wantFlags = wantFlags.Add(proton.MessageFlagReplied)
} }
return conn.importMessage(ctx, literal, wantLabelIDs, wantFlags, unread) return conn.importMessage(ctx, literal, wantLabelIDs, wantFlags, unread)
@ -326,13 +326,13 @@ func (conn *imapConnector) RemoveMessagesFromMailbox(ctx context.Context, messag
return err return err
} }
if mailboxID == liteapi.SpamLabel || mailboxID == liteapi.TrashLabel || mailboxID == liteapi.DraftsLabel { if mailboxID == proton.SpamLabel || mailboxID == proton.TrashLabel || mailboxID == proton.DraftsLabel {
var metadata []liteapi.MessageMetadata var metadata []proton.MessageMetadata
// There's currently no limit on how many IDs we can filter on, // There's currently no limit on how many IDs we can filter on,
// but to be nice to API, let's chunk it by 150. // but to be nice to API, let's chunk it by 150.
for _, messageIDs := range xslices.Chunk(messageIDs, 150) { for _, messageIDs := range xslices.Chunk(messageIDs, 150) {
m, err := conn.client.GetMessageMetadata(ctx, liteapi.MessageFilter{ m, err := conn.client.GetMessageMetadata(ctx, proton.MessageFilter{
ID: mapTo[imap.MessageID, string](messageIDs), ID: mapTo[imap.MessageID, string](messageIDs),
}) })
if err != nil { if err != nil {
@ -341,9 +341,9 @@ func (conn *imapConnector) RemoveMessagesFromMailbox(ctx context.Context, messag
// If a message is not preset in any other label other than AllMail, AllDrafts and AllSent, it can be // If a message is not preset in any other label other than AllMail, AllDrafts and AllSent, it can be
// permanently deleted. // permanently deleted.
m = xslices.Filter(m, func(m liteapi.MessageMetadata) bool { m = xslices.Filter(m, func(m proton.MessageMetadata) bool {
labelsThatMatter := xslices.Filter(m.LabelIDs, func(id string) bool { labelsThatMatter := xslices.Filter(m.LabelIDs, func(id string) bool {
return id != liteapi.AllDraftsLabel && id != liteapi.AllMailLabel && id != liteapi.AllSentLabel return id != proton.AllDraftsLabel && id != proton.AllMailLabel && id != proton.AllSentLabel
}) })
return len(labelsThatMatter) == 0 return len(labelsThatMatter) == 0
}) })
@ -351,7 +351,7 @@ func (conn *imapConnector) RemoveMessagesFromMailbox(ctx context.Context, messag
metadata = append(metadata, m...) metadata = append(metadata, m...)
} }
if err := conn.client.DeleteMessage(ctx, xslices.Map(metadata, func(m liteapi.MessageMetadata) string { if err := conn.client.DeleteMessage(ctx, xslices.Map(metadata, func(m proton.MessageMetadata) string {
return m.ID return m.ID
})...); err != nil { })...); err != nil {
return err return err
@ -392,10 +392,10 @@ func (conn *imapConnector) MarkMessagesFlagged(ctx context.Context, messageIDs [
defer conn.goPollAPIEvents(false) defer conn.goPollAPIEvents(false)
if flagged { if flagged {
return conn.client.LabelMessages(ctx, mapTo[imap.MessageID, string](messageIDs), liteapi.StarredLabel) return conn.client.LabelMessages(ctx, mapTo[imap.MessageID, string](messageIDs), proton.StarredLabel)
} }
return conn.client.UnlabelMessages(ctx, mapTo[imap.MessageID, string](messageIDs), liteapi.StarredLabel) return conn.client.UnlabelMessages(ctx, mapTo[imap.MessageID, string](messageIDs), proton.StarredLabel)
} }
// GetUpdates returns a stream of updates that the gluon server should apply. // GetUpdates returns a stream of updates that the gluon server should apply.
@ -418,7 +418,7 @@ func (conn *imapConnector) SetUIDValidity(validity imap.UID) error {
// IsMailboxVisible returns whether this mailbox should be visible over IMAP. // IsMailboxVisible returns whether this mailbox should be visible over IMAP.
func (conn *imapConnector) IsMailboxVisible(_ context.Context, mailboxID imap.MailboxID) bool { func (conn *imapConnector) IsMailboxVisible(_ context.Context, mailboxID imap.MailboxID) bool {
return atomic.LoadUint32(&conn.showAllMail) != 0 || mailboxID != liteapi.AllMailLabel return atomic.LoadUint32(&conn.showAllMail) != 0 || mailboxID != proton.AllMailLabel
} }
// Close the connector will no longer be used and all resources should be closed/released. // Close the connector will no longer be used and all resources should be closed/released.
@ -430,18 +430,18 @@ func (conn *imapConnector) importMessage(
ctx context.Context, ctx context.Context,
literal []byte, literal []byte,
labelIDs []string, labelIDs []string,
flags liteapi.MessageFlag, flags proton.MessageFlag,
unread bool, unread bool,
) (imap.Message, []byte, error) { ) (imap.Message, []byte, error) {
var full liteapi.FullMessage var full proton.FullMessage
if err := safe.RLockRet(func() error { if err := safe.RLockRet(func() error {
return withAddrKR(conn.apiUser, conn.apiAddrs[conn.addrID], conn.vault.KeyPass(), func(_, addrKR *crypto.KeyRing) error { return withAddrKR(conn.apiUser, conn.apiAddrs[conn.addrID], conn.vault.KeyPass(), func(_, addrKR *crypto.KeyRing) error {
res, err := stream.Collect(ctx, conn.client.ImportMessages(ctx, addrKR, 1, 1, []liteapi.ImportReq{{ res, err := stream.Collect(ctx, conn.client.ImportMessages(ctx, addrKR, 1, 1, []proton.ImportReq{{
Metadata: liteapi.ImportMetadata{ Metadata: proton.ImportMetadata{
AddressID: conn.addrID, AddressID: conn.addrID,
LabelIDs: labelIDs, LabelIDs: labelIDs,
Unread: liteapi.Bool(unread), Unread: proton.Bool(unread),
Flags: flags, Flags: flags,
}, },
Message: literal, Message: literal,
@ -467,18 +467,18 @@ func (conn *imapConnector) importMessage(
return toIMAPMessage(full.MessageMetadata), literal, nil return toIMAPMessage(full.MessageMetadata), literal, nil
} }
func toIMAPMessage(message liteapi.MessageMetadata) imap.Message { func toIMAPMessage(message proton.MessageMetadata) imap.Message {
flags := imap.NewFlagSet() flags := imap.NewFlagSet()
if !message.Unread { if !message.Unread {
flags = flags.Add(imap.FlagSeen) flags = flags.Add(imap.FlagSeen)
} }
if slices.Contains(message.LabelIDs, liteapi.StarredLabel) { if slices.Contains(message.LabelIDs, proton.StarredLabel) {
flags = flags.Add(imap.FlagFlagged) flags = flags.Add(imap.FlagFlagged)
} }
if slices.Contains(message.LabelIDs, liteapi.DraftsLabel) { if slices.Contains(message.LabelIDs, proton.DraftsLabel) {
flags = flags.Add(imap.FlagDraft) flags = flags.Add(imap.FlagDraft)
} }
@ -497,10 +497,10 @@ func toIMAPMessage(message liteapi.MessageMetadata) imap.Message {
} }
} }
func toIMAPMailbox(label liteapi.Label, flags, permFlags, attrs imap.FlagSet) imap.Mailbox { func toIMAPMailbox(label proton.Label, flags, permFlags, attrs imap.FlagSet) imap.Mailbox {
if label.Type == liteapi.LabelTypeLabel { if label.Type == proton.LabelTypeLabel {
label.Path = append([]string{labelPrefix}, label.Path...) label.Path = append([]string{labelPrefix}, label.Path...)
} else if label.Type == liteapi.LabelTypeFolder { } else if label.Type == proton.LabelTypeFolder {
label.Path = append([]string{folderPrefix}, label.Path...) label.Path = append([]string{folderPrefix}, label.Path...)
} }

View File

@ -20,12 +20,12 @@ package user
import ( import (
"fmt" "fmt"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gitlab.protontech.ch/go/liteapi"
) )
func withAddrKR(apiUser liteapi.User, apiAddr liteapi.Address, keyPass []byte, fn func(userKR, addrKR *crypto.KeyRing) error) error { func withAddrKR(apiUser proton.User, apiAddr proton.Address, keyPass []byte, fn func(userKR, addrKR *crypto.KeyRing) error) error {
userKR, err := apiUser.Keys.Unlock(keyPass, nil) userKR, err := apiUser.Keys.Unlock(keyPass, nil)
if err != nil { if err != nil {
return fmt.Errorf("failed to unlock user keys: %w", err) return fmt.Errorf("failed to unlock user keys: %w", err)
@ -41,7 +41,7 @@ func withAddrKR(apiUser liteapi.User, apiAddr liteapi.Address, keyPass []byte, f
return fn(userKR, addrKR) return fn(userKR, addrKR)
} }
func withAddrKRs(apiUser liteapi.User, apiAddr map[string]liteapi.Address, keyPass []byte, fn func(*crypto.KeyRing, map[string]*crypto.KeyRing) error) error { func withAddrKRs(apiUser proton.User, apiAddr map[string]proton.Address, keyPass []byte, fn func(*crypto.KeyRing, map[string]*crypto.KeyRing) error) error {
userKR, err := apiUser.Keys.Unlock(keyPass, nil) userKR, err := apiUser.Keys.Unlock(keyPass, nil)
if err != nil { if err != nil {
return fmt.Errorf("failed to unlock user keys: %w", err) return fmt.Errorf("failed to unlock user keys: %w", err)

View File

@ -21,16 +21,16 @@ import (
"context" "context"
"testing" "testing"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/go-proton-api/server"
"github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.protontech.ch/go/liteapi"
"gitlab.protontech.ch/go/liteapi/server"
) )
func BenchmarkAddrKeyRing(b *testing.B) { func BenchmarkAddrKeyRing(b *testing.B) {
b.StopTimer() b.StopTimer()
withAPI(b, context.Background(), func(ctx context.Context, s *server.Server, m *liteapi.Manager) { withAPI(b, context.Background(), func(ctx context.Context, s *server.Server, m *proton.Manager) {
withAccount(b, s, "username", "password", []string{"email@pm.me"}, func(userID string, addrIDs []string) { withAccount(b, s, "username", "password", []string{"email@pm.me"}, func(userID string, addrIDs []string) {
withUser(b, ctx, s, m, "username", "password", func(user *User) { withUser(b, ctx, s, m, "username", "password", func(user *User) {
b.StartTimer() b.StartTimer()

View File

@ -29,6 +29,7 @@ import (
"time" "time"
"github.com/ProtonMail/gluon/rfc822" "github.com/ProtonMail/gluon/rfc822"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/go-rfc5322" "github.com/ProtonMail/go-rfc5322"
"github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/ProtonMail/proton-bridge/v2/internal/logging" "github.com/ProtonMail/proton-bridge/v2/internal/logging"
@ -39,7 +40,6 @@ import (
"github.com/bradenaw/juniper/parallel" "github.com/bradenaw/juniper/parallel"
"github.com/bradenaw/juniper/xslices" "github.com/bradenaw/juniper/xslices"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gitlab.protontech.ch/go/liteapi"
"golang.org/x/exp/maps" "golang.org/x/exp/maps"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
) )
@ -56,7 +56,7 @@ func (user *User) sendMail(authID string, from string, to []string, r io.Reader)
return ErrInvalidReturnPath return ErrInvalidReturnPath
} }
emails := xslices.Map(maps.Values(user.apiAddrs), func(addr liteapi.Address) string { emails := xslices.Map(maps.Values(user.apiAddrs), func(addr proton.Address) string {
return addr.Email return addr.Email
}) })
@ -113,7 +113,7 @@ func (user *User) sendMail(authID string, from string, to []string, r io.Reader)
} }
// If we have to attach the public key, do it now. // If we have to attach the public key, do it now.
if settings.AttachPublicKey == liteapi.AttachPublicKeyEnabled { if settings.AttachPublicKey == proton.AttachPublicKeyEnabled {
key, err := addrKR.GetKey(0) key, err := addrKR.GetKey(0)
if err != nil { if err != nil {
return fmt.Errorf("failed to get sending key: %w", err) return fmt.Errorf("failed to get sending key: %w", err)
@ -159,19 +159,19 @@ func (user *User) sendMail(authID string, from string, to []string, r io.Reader)
// sendWithKey sends the message with the given address key. // sendWithKey sends the message with the given address key.
func sendWithKey( //nolint:funlen func sendWithKey( //nolint:funlen
ctx context.Context, ctx context.Context,
client *liteapi.Client, client *proton.Client,
authAddrID string, authAddrID string,
addrMode vault.AddressMode, addrMode vault.AddressMode,
settings liteapi.MailSettings, settings proton.MailSettings,
userKR, addrKR *crypto.KeyRing, userKR, addrKR *crypto.KeyRing,
emails []string, emails []string,
from string, from string,
to []string, to []string,
message message.Message, message message.Message,
) (liteapi.Message, error) { ) (proton.Message, error) {
parentID, err := getParentID(ctx, client, authAddrID, addrMode, message.References) parentID, err := getParentID(ctx, client, authAddrID, addrMode, message.References)
if err != nil { if err != nil {
return liteapi.Message{}, fmt.Errorf("failed to get parent ID: %w", err) return proton.Message{}, fmt.Errorf("failed to get parent ID: %w", err)
} }
var decBody string var decBody string
@ -185,20 +185,20 @@ func sendWithKey( //nolint:funlen
decBody = string(message.PlainBody) decBody = string(message.PlainBody)
default: default:
return liteapi.Message{}, fmt.Errorf("unsupported MIME type: %v", message.MIMEType) return proton.Message{}, fmt.Errorf("unsupported MIME type: %v", message.MIMEType)
} }
encBody, err := addrKR.Encrypt(crypto.NewPlainMessageFromString(decBody), nil) encBody, err := addrKR.Encrypt(crypto.NewPlainMessageFromString(decBody), nil)
if err != nil { if err != nil {
return liteapi.Message{}, fmt.Errorf("failed to encrypt message body: %w", err) return proton.Message{}, fmt.Errorf("failed to encrypt message body: %w", err)
} }
armBody, err := encBody.GetArmored() armBody, err := encBody.GetArmored()
if err != nil { if err != nil {
return liteapi.Message{}, fmt.Errorf("failed to get armored message body: %w", err) return proton.Message{}, fmt.Errorf("failed to get armored message body: %w", err)
} }
draft, err := createDraft(ctx, client, emails, from, to, parentID, message.InReplyTo, liteapi.DraftTemplate{ draft, err := createDraft(ctx, client, emails, from, to, parentID, message.InReplyTo, proton.DraftTemplate{
Subject: message.Subject, Subject: message.Subject,
Body: armBody, Body: armBody,
MIMEType: message.MIMEType, MIMEType: message.MIMEType,
@ -211,27 +211,27 @@ func sendWithKey( //nolint:funlen
ExternalID: message.ExternalID, ExternalID: message.ExternalID,
}) })
if err != nil { if err != nil {
return liteapi.Message{}, fmt.Errorf("failed to create attachments: %w", err) return proton.Message{}, fmt.Errorf("failed to create attachments: %w", err)
} }
attKeys, err := createAttachments(ctx, client, addrKR, draft.ID, message.Attachments) attKeys, err := createAttachments(ctx, client, addrKR, draft.ID, message.Attachments)
if err != nil { if err != nil {
return liteapi.Message{}, fmt.Errorf("failed to create attachments: %w", err) return proton.Message{}, fmt.Errorf("failed to create attachments: %w", err)
} }
recipients, err := getRecipients(ctx, client, userKR, settings, draft) recipients, err := getRecipients(ctx, client, userKR, settings, draft)
if err != nil { if err != nil {
return liteapi.Message{}, fmt.Errorf("failed to get recipients: %w", err) return proton.Message{}, fmt.Errorf("failed to get recipients: %w", err)
} }
req, err := createSendReq(addrKR, message.MIMEBody, message.RichBody, message.PlainBody, recipients, attKeys) req, err := createSendReq(addrKR, message.MIMEBody, message.RichBody, message.PlainBody, recipients, attKeys)
if err != nil { if err != nil {
return liteapi.Message{}, fmt.Errorf("failed to create packages: %w", err) return proton.Message{}, fmt.Errorf("failed to create packages: %w", err)
} }
res, err := client.SendDraft(ctx, draft.ID, req) res, err := client.SendDraft(ctx, draft.ID, req)
if err != nil { if err != nil {
return liteapi.Message{}, fmt.Errorf("failed to send draft: %w", err) return proton.Message{}, fmt.Errorf("failed to send draft: %w", err)
} }
return res, nil return res, nil
@ -239,7 +239,7 @@ func sendWithKey( //nolint:funlen
func getParentID( //nolint:funlen func getParentID( //nolint:funlen
ctx context.Context, ctx context.Context,
client *liteapi.Client, client *proton.Client,
authAddrID string, authAddrID string,
addrMode vault.AddressMode, addrMode vault.AddressMode,
references []string, references []string,
@ -267,7 +267,7 @@ func getParentID( //nolint:funlen
addrID = authAddrID addrID = authAddrID
} }
metadata, err := client.GetMessageMetadata(ctx, liteapi.MessageFilter{ metadata, err := client.GetMessageMetadata(ctx, proton.MessageFilter{
ID: []string{internal}, ID: []string{internal},
AddressID: addrID, AddressID: addrID,
}) })
@ -293,7 +293,7 @@ func getParentID( //nolint:funlen
addrID = authAddrID addrID = authAddrID
} }
metadata, err := client.GetMessageMetadata(ctx, liteapi.MessageFilter{ metadata, err := client.GetMessageMetadata(ctx, proton.MessageFilter{
ExternalID: external[len(external)-1], ExternalID: external[len(external)-1],
AddressID: addrID, AddressID: addrID,
}) })
@ -311,14 +311,14 @@ func getParentID( //nolint:funlen
func createDraft( func createDraft(
ctx context.Context, ctx context.Context,
client *liteapi.Client, client *proton.Client,
emails []string, emails []string,
from string, from string,
to []string, to []string,
parentID string, parentID string,
replyToID string, replyToID string,
template liteapi.DraftTemplate, template proton.DraftTemplate,
) (liteapi.Message, error) { ) (proton.Message, error) {
// Check sender: set the sender if it's missing. // Check sender: set the sender if it's missing.
if template.Sender == nil { if template.Sender == nil {
template.Sender = &mail.Address{Address: from} template.Sender = &mail.Address{Address: from}
@ -330,7 +330,7 @@ func createDraft(
if idx := xslices.IndexFunc(emails, func(email string) bool { if idx := xslices.IndexFunc(emails, func(email string) bool {
return strings.EqualFold(email, sanitizeEmail(template.Sender.Address)) return strings.EqualFold(email, sanitizeEmail(template.Sender.Address))
}); idx < 0 { }); idx < 0 {
return liteapi.Message{}, fmt.Errorf("address %q is not owned by user", template.Sender.Address) return proton.Message{}, fmt.Errorf("address %q is not owned by user", template.Sender.Address)
} else { //nolint:revive } else { //nolint:revive
template.Sender.Address = constructEmail(template.Sender.Address, emails[idx]) template.Sender.Address = constructEmail(template.Sender.Address, emails[idx])
} }
@ -349,15 +349,15 @@ func createDraft(
} }
} }
var action liteapi.CreateDraftAction var action proton.CreateDraftAction
if len(replyToID) > 0 { if len(replyToID) > 0 {
action = liteapi.ReplyAction action = proton.ReplyAction
} else { } else {
action = liteapi.ForwardAction action = proton.ForwardAction
} }
return client.CreateDraft(ctx, liteapi.CreateDraftReq{ return client.CreateDraft(ctx, proton.CreateDraftReq{
Message: template, Message: template,
ParentID: parentID, ParentID: parentID,
Action: action, Action: action,
@ -367,7 +367,7 @@ func createDraft(
// nolint:funlen // nolint:funlen
func createAttachments( func createAttachments(
ctx context.Context, ctx context.Context,
client *liteapi.Client, client *proton.Client,
addrKR *crypto.KeyRing, addrKR *crypto.KeyRing,
draftID string, draftID string,
attachments []message.Attachment, attachments []message.Attachment,
@ -387,15 +387,15 @@ func createAttachments(
// Some clients use inline disposition but don't set a content ID. Our API doesn't support this. // Some clients use inline disposition but don't set a content ID. Our API doesn't support this.
// We could generate our own content ID, but for simplicity, we just set the disposition to attachment. // We could generate our own content ID, but for simplicity, we just set the disposition to attachment.
if att.Disposition == string(liteapi.InlineDisposition) && att.ContentID == "" { if att.Disposition == string(proton.InlineDisposition) && att.ContentID == "" {
att.Disposition = string(liteapi.AttachmentDisposition) att.Disposition = string(proton.AttachmentDisposition)
} }
attachment, err := client.UploadAttachment(ctx, addrKR, liteapi.CreateAttachmentReq{ attachment, err := client.UploadAttachment(ctx, addrKR, proton.CreateAttachmentReq{
Filename: att.Name, Filename: att.Name,
MessageID: draftID, MessageID: draftID,
MIMEType: rfc822.MIMEType(att.MIMEType), MIMEType: rfc822.MIMEType(att.MIMEType),
Disposition: liteapi.Disposition(att.Disposition), Disposition: proton.Disposition(att.Disposition),
ContentID: att.ContentID, ContentID: att.ContentID,
Body: att.Data, Body: att.Data,
}) })
@ -430,27 +430,27 @@ func createAttachments(
func getRecipients( func getRecipients(
ctx context.Context, ctx context.Context,
client *liteapi.Client, client *proton.Client,
userKR *crypto.KeyRing, userKR *crypto.KeyRing,
settings liteapi.MailSettings, settings proton.MailSettings,
draft liteapi.Message, draft proton.Message,
) (recipients, error) { ) (recipients, error) {
addresses := xslices.Map(xslices.Join(draft.ToList, draft.CCList, draft.BCCList), func(addr *mail.Address) string { addresses := xslices.Map(xslices.Join(draft.ToList, draft.CCList, draft.BCCList), func(addr *mail.Address) string {
return addr.Address return addr.Address
}) })
prefs, err := parallel.MapContext(ctx, runtime.NumCPU(), addresses, func(ctx context.Context, recipient string) (liteapi.SendPreferences, error) { prefs, err := parallel.MapContext(ctx, runtime.NumCPU(), addresses, func(ctx context.Context, recipient string) (proton.SendPreferences, error) {
pubKeys, recType, err := client.GetPublicKeys(ctx, recipient) pubKeys, recType, err := client.GetPublicKeys(ctx, recipient)
if err != nil { if err != nil {
return liteapi.SendPreferences{}, fmt.Errorf("failed to get public keys: %w", err) return proton.SendPreferences{}, fmt.Errorf("failed to get public keys: %w", err)
} }
contactSettings, err := getContactSettings(ctx, client, userKR, recipient) contactSettings, err := getContactSettings(ctx, client, userKR, recipient)
if err != nil { if err != nil {
return liteapi.SendPreferences{}, fmt.Errorf("failed to get contact settings: %w", err) return proton.SendPreferences{}, fmt.Errorf("failed to get contact settings: %w", err)
} }
return buildSendPrefs(contactSettings, settings, pubKeys, draft.MIMEType, recType == liteapi.RecipientTypeInternal) return buildSendPrefs(contactSettings, settings, pubKeys, draft.MIMEType, recType == proton.RecipientTypeInternal)
}) })
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to get send preferences: %w", err) return nil, fmt.Errorf("failed to get send preferences: %w", err)
@ -467,26 +467,26 @@ func getRecipients(
func getContactSettings( func getContactSettings(
ctx context.Context, ctx context.Context,
client *liteapi.Client, client *proton.Client,
userKR *crypto.KeyRing, userKR *crypto.KeyRing,
recipient string, recipient string,
) (liteapi.ContactSettings, error) { ) (proton.ContactSettings, error) {
contacts, err := client.GetAllContactEmails(ctx, recipient) contacts, err := client.GetAllContactEmails(ctx, recipient)
if err != nil { if err != nil {
return liteapi.ContactSettings{}, fmt.Errorf("failed to get contact data: %w", err) return proton.ContactSettings{}, fmt.Errorf("failed to get contact data: %w", err)
} }
idx := xslices.IndexFunc(contacts, func(contact liteapi.ContactEmail) bool { idx := xslices.IndexFunc(contacts, func(contact proton.ContactEmail) bool {
return contact.Email == recipient return contact.Email == recipient
}) })
if idx < 0 { if idx < 0 {
return liteapi.ContactSettings{}, nil return proton.ContactSettings{}, nil
} }
contact, err := client.GetContact(ctx, contacts[idx].ContactID) contact, err := client.GetContact(ctx, contacts[idx].ContactID)
if err != nil { if err != nil {
return liteapi.ContactSettings{}, fmt.Errorf("failed to get contact: %w", err) return proton.ContactSettings{}, fmt.Errorf("failed to get contact: %w", err)
} }
return contact.GetSettings(userKR, recipient) return contact.GetSettings(userKR, recipient)

View File

@ -19,10 +19,10 @@ package user
import ( import (
"github.com/ProtonMail/gluon/rfc822" "github.com/ProtonMail/gluon/rfc822"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/ProtonMail/proton-bridge/v2/pkg/message" "github.com/ProtonMail/proton-bridge/v2/pkg/message"
"github.com/bradenaw/juniper/xslices" "github.com/bradenaw/juniper/xslices"
"gitlab.protontech.ch/go/liteapi"
"golang.org/x/exp/maps" "golang.org/x/exp/maps"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
) )
@ -33,25 +33,25 @@ func createSendReq(
richBody, plainBody message.Body, richBody, plainBody message.Body,
recipients recipients, recipients recipients,
attKeys map[string]*crypto.SessionKey, attKeys map[string]*crypto.SessionKey,
) (liteapi.SendDraftReq, error) { ) (proton.SendDraftReq, error) {
var req liteapi.SendDraftReq var req proton.SendDraftReq
if recs := recipients.scheme(liteapi.PGPMIMEScheme, liteapi.ClearMIMEScheme); len(recs) > 0 { if recs := recipients.scheme(proton.PGPMIMEScheme, proton.ClearMIMEScheme); len(recs) > 0 {
if err := req.AddMIMEPackage(kr, string(mimeBody), recs); err != nil { if err := req.AddMIMEPackage(kr, string(mimeBody), recs); err != nil {
return liteapi.SendDraftReq{}, err return proton.SendDraftReq{}, err
} }
} }
if recs := recipients.scheme(liteapi.InternalScheme, liteapi.ClearScheme, liteapi.PGPInlineScheme); len(recs) > 0 { if recs := recipients.scheme(proton.InternalScheme, proton.ClearScheme, proton.PGPInlineScheme); len(recs) > 0 {
if recs := recs.content(rfc822.TextHTML); len(recs) > 0 { if recs := recs.content(rfc822.TextHTML); len(recs) > 0 {
if err := req.AddTextPackage(kr, string(richBody), rfc822.TextHTML, recs, attKeys); err != nil { if err := req.AddTextPackage(kr, string(richBody), rfc822.TextHTML, recs, attKeys); err != nil {
return liteapi.SendDraftReq{}, err return proton.SendDraftReq{}, err
} }
} }
if recs := recs.content(rfc822.TextPlain); len(recs) > 0 { if recs := recs.content(rfc822.TextPlain); len(recs) > 0 {
if err := req.AddTextPackage(kr, string(plainBody), rfc822.TextPlain, recs, attKeys); err != nil { if err := req.AddTextPackage(kr, string(plainBody), rfc822.TextPlain, recs, attKeys); err != nil {
return liteapi.SendDraftReq{}, err return proton.SendDraftReq{}, err
} }
} }
} }
@ -59,9 +59,9 @@ func createSendReq(
return req, nil return req, nil
} }
type recipients map[string]liteapi.SendPreferences type recipients map[string]proton.SendPreferences
func (r recipients) scheme(scheme ...liteapi.EncryptionScheme) recipients { func (r recipients) scheme(scheme ...proton.EncryptionScheme) recipients {
res := make(recipients) res := make(recipients)
for _, addr := range xslices.Filter(maps.Keys(r), func(addr string) bool { for _, addr := range xslices.Filter(maps.Keys(r), func(addr string) bool {

View File

@ -21,9 +21,9 @@ import (
"fmt" "fmt"
"github.com/ProtonMail/gluon/rfc822" "github.com/ProtonMail/gluon/rfc822"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/pkg/errors" "github.com/pkg/errors"
"gitlab.protontech.ch/go/liteapi"
) )
const ( const (
@ -44,7 +44,7 @@ type contactSettings struct {
// newContactSettings converts the API settings into our local settings. // newContactSettings converts the API settings into our local settings.
// This is due to the legacy send preferences code. // This is due to the legacy send preferences code.
func newContactSettings(settings liteapi.ContactSettings) *contactSettings { func newContactSettings(settings proton.ContactSettings) *contactSettings {
metadata := &contactSettings{} metadata := &contactSettings{}
if settings.MIMEType != nil { if settings.MIMEType != nil {
@ -62,10 +62,10 @@ func newContactSettings(settings liteapi.ContactSettings) *contactSettings {
if settings.Scheme != nil { if settings.Scheme != nil {
switch *settings.Scheme { // nolint:exhaustive switch *settings.Scheme { // nolint:exhaustive
case liteapi.PGPMIMEScheme: case proton.PGPMIMEScheme:
metadata.Scheme = pgpMIME metadata.Scheme = pgpMIME
case liteapi.PGPInlineScheme: case proton.PGPInlineScheme:
metadata.Scheme = pgpInline metadata.Scheme = pgpInline
default: default:
@ -88,16 +88,16 @@ func newContactSettings(settings liteapi.ContactSettings) *contactSettings {
} }
func buildSendPrefs( func buildSendPrefs(
contactSettings liteapi.ContactSettings, contactSettings proton.ContactSettings,
mailSettings liteapi.MailSettings, mailSettings proton.MailSettings,
pubKeys []liteapi.PublicKey, pubKeys []proton.PublicKey,
mimeType rfc822.MIMEType, mimeType rfc822.MIMEType,
isInternal bool, isInternal bool,
) (liteapi.SendPreferences, error) { ) (proton.SendPreferences, error) {
builder := &sendPrefsBuilder{} builder := &sendPrefsBuilder{}
if err := builder.setPGPSettings(newContactSettings(contactSettings), pubKeys, isInternal); err != nil { if err := builder.setPGPSettings(newContactSettings(contactSettings), pubKeys, isInternal); err != nil {
return liteapi.SendPreferences{}, fmt.Errorf("failed to set PGP settings: %w", err) return proton.SendPreferences{}, fmt.Errorf("failed to set PGP settings: %w", err)
} }
builder.setEncryptionPreferences(mailSettings) builder.setEncryptionPreferences(mailSettings)
@ -222,37 +222,37 @@ func (b *sendPrefsBuilder) withPublicKey(v *crypto.KeyRing) {
// mimeType: 'text/html' | 'text/plain' | 'multipart/mixed', // mimeType: 'text/html' | 'text/plain' | 'multipart/mixed',
// publicKey: OpenPGPKey | undefined/null // publicKey: OpenPGPKey | undefined/null
// }. // }.
func (b *sendPrefsBuilder) build() (p liteapi.SendPreferences) { func (b *sendPrefsBuilder) build() (p proton.SendPreferences) {
p.Encrypt = b.shouldEncrypt() p.Encrypt = b.shouldEncrypt()
p.MIMEType = b.getMIMEType() p.MIMEType = b.getMIMEType()
p.PubKey = b.publicKey p.PubKey = b.publicKey
if b.shouldSign() { if b.shouldSign() {
p.SignatureType = liteapi.DetachedSignature p.SignatureType = proton.DetachedSignature
} else { } else {
p.SignatureType = liteapi.NoSignature p.SignatureType = proton.NoSignature
} }
switch { switch {
case b.isInternal(): case b.isInternal():
p.EncryptionScheme = liteapi.InternalScheme p.EncryptionScheme = proton.InternalScheme
case b.shouldSign() && b.shouldEncrypt(): case b.shouldSign() && b.shouldEncrypt():
if b.getScheme() == pgpInline { if b.getScheme() == pgpInline {
p.EncryptionScheme = liteapi.PGPInlineScheme p.EncryptionScheme = proton.PGPInlineScheme
} else { } else {
p.EncryptionScheme = liteapi.PGPMIMEScheme p.EncryptionScheme = proton.PGPMIMEScheme
} }
case b.shouldSign() && !b.shouldEncrypt(): case b.shouldSign() && !b.shouldEncrypt():
if b.getScheme() == pgpInline { if b.getScheme() == pgpInline {
p.EncryptionScheme = liteapi.ClearScheme p.EncryptionScheme = proton.ClearScheme
} else { } else {
p.EncryptionScheme = liteapi.ClearMIMEScheme p.EncryptionScheme = proton.ClearMIMEScheme
} }
default: default:
p.EncryptionScheme = liteapi.ClearScheme p.EncryptionScheme = proton.ClearScheme
} }
return p return p
@ -272,7 +272,7 @@ func (b *sendPrefsBuilder) build() (p liteapi.SendPreferences) {
// key info retrieved from the API via the GET KEYS route. // key info retrieved from the API via the GET KEYS route.
func (b *sendPrefsBuilder) setPGPSettings( func (b *sendPrefsBuilder) setPGPSettings(
vCardData *contactSettings, vCardData *contactSettings,
apiKeys []liteapi.PublicKey, apiKeys []proton.PublicKey,
isInternal bool, isInternal bool,
) (err error) { ) (err error) {
// If there is no contact metadata, we can just use a default constructed one. // If there is no contact metadata, we can just use a default constructed one.
@ -304,7 +304,7 @@ func (b *sendPrefsBuilder) setPGPSettings(
// registered with proton. // registered with proton.
func (b *sendPrefsBuilder) setInternalPGPSettings( func (b *sendPrefsBuilder) setInternalPGPSettings(
vCardData *contactSettings, vCardData *contactSettings,
apiKeys []liteapi.PublicKey, apiKeys []proton.PublicKey,
) (err error) { ) (err error) {
// We're guaranteed to get at least one valid (i.e. not expired, revoked or // We're guaranteed to get at least one valid (i.e. not expired, revoked or
// marked as verification-only) public key from the server. // marked as verification-only) public key from the server.
@ -349,7 +349,7 @@ func (b *sendPrefsBuilder) setInternalPGPSettings(
// 3. If there are no pinned keys, then the client should encrypt with the // 3. If there are no pinned keys, then the client should encrypt with the
// first valid key served by the API (in principle the server already // first valid key served by the API (in principle the server already
// validates the keys and the first one provided should be valid). // validates the keys and the first one provided should be valid).
func pickSendingKey(vCardData *contactSettings, rawAPIKeys []liteapi.PublicKey) (kr *crypto.KeyRing, err error) { func pickSendingKey(vCardData *contactSettings, rawAPIKeys []proton.PublicKey) (kr *crypto.KeyRing, err error) {
contactKeys := make([]*crypto.Key, len(vCardData.Keys)) contactKeys := make([]*crypto.Key, len(vCardData.Keys))
apiKeys := make([]*crypto.Key, len(rawAPIKeys)) apiKeys := make([]*crypto.Key, len(rawAPIKeys))
@ -415,7 +415,7 @@ func matchFingerprints(a, b []*crypto.Key) (res []*crypto.Key) {
func (b *sendPrefsBuilder) setExternalPGPSettingsWithWKDKeys( func (b *sendPrefsBuilder) setExternalPGPSettingsWithWKDKeys(
vCardData *contactSettings, vCardData *contactSettings,
apiKeys []liteapi.PublicKey, apiKeys []proton.PublicKey,
) (err error) { ) (err error) {
// We're guaranteed to get at least one valid (i.e. not expired, revoked or // We're guaranteed to get at least one valid (i.e. not expired, revoked or
// marked as verification-only) public key from the server. // marked as verification-only) public key from the server.
@ -520,7 +520,7 @@ func (b *sendPrefsBuilder) setExternalPGPSettingsWithoutWKDKeys(
// //
// The public key can still be undefined as we do not need it if the outgoing // The public key can still be undefined as we do not need it if the outgoing
// email is not encrypted. // email is not encrypted.
func (b *sendPrefsBuilder) setEncryptionPreferences(mailSettings liteapi.MailSettings) { func (b *sendPrefsBuilder) setEncryptionPreferences(mailSettings proton.MailSettings) {
// For internal addresses or external ones with WKD keys, this flag should // For internal addresses or external ones with WKD keys, this flag should
// always be true. For external ones, an undefined flag defaults to false. // always be true. For external ones, an undefined flag defaults to false.
b.withEncryptDefault(false) b.withEncryptDefault(false)
@ -541,11 +541,11 @@ func (b *sendPrefsBuilder) setEncryptionPreferences(mailSettings liteapi.MailSet
// If undefined, default to the user mail setting "Default PGP scheme". // If undefined, default to the user mail setting "Default PGP scheme".
// Otherwise keep the defined value. // Otherwise keep the defined value.
switch mailSettings.PGPScheme { switch mailSettings.PGPScheme {
case liteapi.PGPInlineScheme: case proton.PGPInlineScheme:
b.withSchemeDefault(pgpInline) b.withSchemeDefault(pgpInline)
case liteapi.PGPMIMEScheme: case proton.PGPMIMEScheme:
b.withSchemeDefault(pgpMIME) b.withSchemeDefault(pgpMIME)
case liteapi.ClearMIMEScheme, liteapi.ClearScheme, liteapi.EncryptedOutsideScheme, liteapi.InternalScheme: case proton.ClearMIMEScheme, proton.ClearScheme, proton.EncryptedOutsideScheme, proton.InternalScheme:
// nothing to set // nothing to set
} }

View File

@ -21,10 +21,10 @@ import (
"testing" "testing"
"github.com/ProtonMail/gluon/rfc822" "github.com/ProtonMail/gluon/rfc822"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.protontech.ch/go/liteapi"
) )
func TestPreferencesBuilder(t *testing.T) { func TestPreferencesBuilder(t *testing.T) {
@ -35,14 +35,14 @@ func TestPreferencesBuilder(t *testing.T) {
name string name string
contactMeta *contactSettings contactMeta *contactSettings
receivedKeys []liteapi.PublicKey receivedKeys []proton.PublicKey
isInternal bool isInternal bool
mailSettings liteapi.MailSettings mailSettings proton.MailSettings
composerMIMEType string composerMIMEType string
wantEncrypt bool wantEncrypt bool
wantSign liteapi.SignatureType wantSign proton.SignatureType
wantScheme liteapi.EncryptionScheme wantScheme proton.EncryptionScheme
wantMIMEType rfc822.MIMEType wantMIMEType rfc822.MIMEType
wantPublicKey string wantPublicKey string
}{ }{
@ -50,13 +50,13 @@ func TestPreferencesBuilder(t *testing.T) {
name: "internal", name: "internal",
contactMeta: &contactSettings{}, contactMeta: &contactSettings{},
receivedKeys: []liteapi.PublicKey{{PublicKey: testPublicKey}}, receivedKeys: []proton.PublicKey{{PublicKey: testPublicKey}},
isInternal: true, isInternal: true,
mailSettings: liteapi.MailSettings{PGPScheme: liteapi.PGPMIMEScheme, DraftMIMEType: "text/html"}, mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"},
wantEncrypt: true, wantEncrypt: true,
wantSign: liteapi.DetachedSignature, wantSign: proton.DetachedSignature,
wantScheme: liteapi.InternalScheme, wantScheme: proton.InternalScheme,
wantMIMEType: "text/html", wantMIMEType: "text/html",
wantPublicKey: testPublicKey, wantPublicKey: testPublicKey,
}, },
@ -65,13 +65,13 @@ func TestPreferencesBuilder(t *testing.T) {
name: "internal with contact-specific email format", name: "internal with contact-specific email format",
contactMeta: &contactSettings{MIMEType: "text/plain"}, contactMeta: &contactSettings{MIMEType: "text/plain"},
receivedKeys: []liteapi.PublicKey{{PublicKey: testPublicKey}}, receivedKeys: []proton.PublicKey{{PublicKey: testPublicKey}},
isInternal: true, isInternal: true,
mailSettings: liteapi.MailSettings{PGPScheme: liteapi.PGPMIMEScheme, DraftMIMEType: "text/html"}, mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"},
wantEncrypt: true, wantEncrypt: true,
wantSign: liteapi.DetachedSignature, wantSign: proton.DetachedSignature,
wantScheme: liteapi.InternalScheme, wantScheme: proton.InternalScheme,
wantMIMEType: "text/plain", wantMIMEType: "text/plain",
wantPublicKey: testPublicKey, wantPublicKey: testPublicKey,
}, },
@ -80,13 +80,13 @@ func TestPreferencesBuilder(t *testing.T) {
name: "internal with pinned contact public key", name: "internal with pinned contact public key",
contactMeta: &contactSettings{Keys: []string{testContactKey}}, contactMeta: &contactSettings{Keys: []string{testContactKey}},
receivedKeys: []liteapi.PublicKey{{PublicKey: testPublicKey}}, receivedKeys: []proton.PublicKey{{PublicKey: testPublicKey}},
isInternal: true, isInternal: true,
mailSettings: liteapi.MailSettings{PGPScheme: liteapi.PGPMIMEScheme, DraftMIMEType: "text/html"}, mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"},
wantEncrypt: true, wantEncrypt: true,
wantSign: liteapi.DetachedSignature, wantSign: proton.DetachedSignature,
wantScheme: liteapi.InternalScheme, wantScheme: proton.InternalScheme,
wantMIMEType: "text/html", wantMIMEType: "text/html",
wantPublicKey: testPublicKey, wantPublicKey: testPublicKey,
}, },
@ -96,13 +96,13 @@ func TestPreferencesBuilder(t *testing.T) {
name: "internal with conflicting contact public key", name: "internal with conflicting contact public key",
contactMeta: &contactSettings{Keys: []string{testOtherContactKey}}, contactMeta: &contactSettings{Keys: []string{testOtherContactKey}},
receivedKeys: []liteapi.PublicKey{{PublicKey: testPublicKey}}, receivedKeys: []proton.PublicKey{{PublicKey: testPublicKey}},
isInternal: true, isInternal: true,
mailSettings: liteapi.MailSettings{PGPScheme: liteapi.PGPMIMEScheme, DraftMIMEType: "text/html"}, mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"},
wantEncrypt: true, wantEncrypt: true,
wantSign: liteapi.DetachedSignature, wantSign: proton.DetachedSignature,
wantScheme: liteapi.InternalScheme, wantScheme: proton.InternalScheme,
wantMIMEType: "text/html", wantMIMEType: "text/html",
wantPublicKey: testPublicKey, wantPublicKey: testPublicKey,
}, },
@ -111,13 +111,13 @@ func TestPreferencesBuilder(t *testing.T) {
name: "wkd-external", name: "wkd-external",
contactMeta: &contactSettings{}, contactMeta: &contactSettings{},
receivedKeys: []liteapi.PublicKey{{PublicKey: testPublicKey}}, receivedKeys: []proton.PublicKey{{PublicKey: testPublicKey}},
isInternal: false, isInternal: false,
mailSettings: liteapi.MailSettings{PGPScheme: liteapi.PGPMIMEScheme, DraftMIMEType: "text/html"}, mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"},
wantEncrypt: true, wantEncrypt: true,
wantSign: liteapi.DetachedSignature, wantSign: proton.DetachedSignature,
wantScheme: liteapi.PGPMIMEScheme, wantScheme: proton.PGPMIMEScheme,
wantMIMEType: "multipart/mixed", wantMIMEType: "multipart/mixed",
wantPublicKey: testPublicKey, wantPublicKey: testPublicKey,
}, },
@ -126,13 +126,13 @@ func TestPreferencesBuilder(t *testing.T) {
name: "wkd-external with contact-specific email format", name: "wkd-external with contact-specific email format",
contactMeta: &contactSettings{MIMEType: "text/plain"}, contactMeta: &contactSettings{MIMEType: "text/plain"},
receivedKeys: []liteapi.PublicKey{{PublicKey: testPublicKey}}, receivedKeys: []proton.PublicKey{{PublicKey: testPublicKey}},
isInternal: false, isInternal: false,
mailSettings: liteapi.MailSettings{PGPScheme: liteapi.PGPMIMEScheme, DraftMIMEType: "text/html"}, mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"},
wantEncrypt: true, wantEncrypt: true,
wantSign: liteapi.DetachedSignature, wantSign: proton.DetachedSignature,
wantScheme: liteapi.PGPMIMEScheme, wantScheme: proton.PGPMIMEScheme,
wantMIMEType: "multipart/mixed", wantMIMEType: "multipart/mixed",
wantPublicKey: testPublicKey, wantPublicKey: testPublicKey,
}, },
@ -141,13 +141,13 @@ func TestPreferencesBuilder(t *testing.T) {
name: "wkd-external with global pgp-inline scheme", name: "wkd-external with global pgp-inline scheme",
contactMeta: &contactSettings{}, contactMeta: &contactSettings{},
receivedKeys: []liteapi.PublicKey{{PublicKey: testPublicKey}}, receivedKeys: []proton.PublicKey{{PublicKey: testPublicKey}},
isInternal: false, isInternal: false,
mailSettings: liteapi.MailSettings{PGPScheme: liteapi.PGPInlineScheme, DraftMIMEType: "text/html"}, mailSettings: proton.MailSettings{PGPScheme: proton.PGPInlineScheme, DraftMIMEType: "text/html"},
wantEncrypt: true, wantEncrypt: true,
wantSign: liteapi.DetachedSignature, wantSign: proton.DetachedSignature,
wantScheme: liteapi.PGPInlineScheme, wantScheme: proton.PGPInlineScheme,
wantMIMEType: "text/plain", wantMIMEType: "text/plain",
wantPublicKey: testPublicKey, wantPublicKey: testPublicKey,
}, },
@ -156,13 +156,13 @@ func TestPreferencesBuilder(t *testing.T) {
name: "wkd-external with contact-specific pgp-inline scheme overriding global pgp-mime setting", name: "wkd-external with contact-specific pgp-inline scheme overriding global pgp-mime setting",
contactMeta: &contactSettings{Scheme: pgpInline}, contactMeta: &contactSettings{Scheme: pgpInline},
receivedKeys: []liteapi.PublicKey{{PublicKey: testPublicKey}}, receivedKeys: []proton.PublicKey{{PublicKey: testPublicKey}},
isInternal: false, isInternal: false,
mailSettings: liteapi.MailSettings{PGPScheme: liteapi.PGPMIMEScheme, DraftMIMEType: "text/html"}, mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"},
wantEncrypt: true, wantEncrypt: true,
wantSign: liteapi.DetachedSignature, wantSign: proton.DetachedSignature,
wantScheme: liteapi.PGPInlineScheme, wantScheme: proton.PGPInlineScheme,
wantMIMEType: "text/plain", wantMIMEType: "text/plain",
wantPublicKey: testPublicKey, wantPublicKey: testPublicKey,
}, },
@ -171,13 +171,13 @@ func TestPreferencesBuilder(t *testing.T) {
name: "wkd-external with contact-specific pgp-mime scheme overriding global pgp-inline setting", name: "wkd-external with contact-specific pgp-mime scheme overriding global pgp-inline setting",
contactMeta: &contactSettings{Scheme: pgpMIME}, contactMeta: &contactSettings{Scheme: pgpMIME},
receivedKeys: []liteapi.PublicKey{{PublicKey: testPublicKey}}, receivedKeys: []proton.PublicKey{{PublicKey: testPublicKey}},
isInternal: false, isInternal: false,
mailSettings: liteapi.MailSettings{PGPScheme: liteapi.PGPInlineScheme, DraftMIMEType: "text/html"}, mailSettings: proton.MailSettings{PGPScheme: proton.PGPInlineScheme, DraftMIMEType: "text/html"},
wantEncrypt: true, wantEncrypt: true,
wantSign: liteapi.DetachedSignature, wantSign: proton.DetachedSignature,
wantScheme: liteapi.PGPMIMEScheme, wantScheme: proton.PGPMIMEScheme,
wantMIMEType: "multipart/mixed", wantMIMEType: "multipart/mixed",
wantPublicKey: testPublicKey, wantPublicKey: testPublicKey,
}, },
@ -186,13 +186,13 @@ func TestPreferencesBuilder(t *testing.T) {
name: "wkd-external with additional pinned contact public key", name: "wkd-external with additional pinned contact public key",
contactMeta: &contactSettings{Keys: []string{testContactKey}}, contactMeta: &contactSettings{Keys: []string{testContactKey}},
receivedKeys: []liteapi.PublicKey{{PublicKey: testPublicKey}}, receivedKeys: []proton.PublicKey{{PublicKey: testPublicKey}},
isInternal: false, isInternal: false,
mailSettings: liteapi.MailSettings{PGPScheme: liteapi.PGPMIMEScheme, DraftMIMEType: "text/html"}, mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"},
wantEncrypt: true, wantEncrypt: true,
wantSign: liteapi.DetachedSignature, wantSign: proton.DetachedSignature,
wantScheme: liteapi.PGPMIMEScheme, wantScheme: proton.PGPMIMEScheme,
wantMIMEType: "multipart/mixed", wantMIMEType: "multipart/mixed",
wantPublicKey: testPublicKey, wantPublicKey: testPublicKey,
}, },
@ -202,13 +202,13 @@ func TestPreferencesBuilder(t *testing.T) {
name: "wkd-external with additional conflicting contact public key", name: "wkd-external with additional conflicting contact public key",
contactMeta: &contactSettings{Keys: []string{testOtherContactKey}}, contactMeta: &contactSettings{Keys: []string{testOtherContactKey}},
receivedKeys: []liteapi.PublicKey{{PublicKey: testPublicKey}}, receivedKeys: []proton.PublicKey{{PublicKey: testPublicKey}},
isInternal: false, isInternal: false,
mailSettings: liteapi.MailSettings{PGPScheme: liteapi.PGPMIMEScheme, DraftMIMEType: "text/html"}, mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"},
wantEncrypt: true, wantEncrypt: true,
wantSign: liteapi.DetachedSignature, wantSign: proton.DetachedSignature,
wantScheme: liteapi.PGPMIMEScheme, wantScheme: proton.PGPMIMEScheme,
wantMIMEType: "multipart/mixed", wantMIMEType: "multipart/mixed",
wantPublicKey: testPublicKey, wantPublicKey: testPublicKey,
}, },
@ -217,13 +217,13 @@ func TestPreferencesBuilder(t *testing.T) {
name: "external", name: "external",
contactMeta: &contactSettings{}, contactMeta: &contactSettings{},
receivedKeys: []liteapi.PublicKey{}, receivedKeys: []proton.PublicKey{},
isInternal: false, isInternal: false,
mailSettings: liteapi.MailSettings{PGPScheme: liteapi.PGPMIMEScheme, DraftMIMEType: "text/html"}, mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"},
wantEncrypt: false, wantEncrypt: false,
wantSign: liteapi.NoSignature, wantSign: proton.NoSignature,
wantScheme: liteapi.ClearScheme, wantScheme: proton.ClearScheme,
wantMIMEType: "text/html", wantMIMEType: "text/html",
}, },
@ -231,13 +231,13 @@ func TestPreferencesBuilder(t *testing.T) {
name: "external with contact-specific email format", name: "external with contact-specific email format",
contactMeta: &contactSettings{MIMEType: "text/plain"}, contactMeta: &contactSettings{MIMEType: "text/plain"},
receivedKeys: []liteapi.PublicKey{}, receivedKeys: []proton.PublicKey{},
isInternal: false, isInternal: false,
mailSettings: liteapi.MailSettings{PGPScheme: liteapi.PGPMIMEScheme, DraftMIMEType: "text/html"}, mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"},
wantEncrypt: false, wantEncrypt: false,
wantSign: liteapi.NoSignature, wantSign: proton.NoSignature,
wantScheme: liteapi.ClearScheme, wantScheme: proton.ClearScheme,
wantMIMEType: "text/plain", wantMIMEType: "text/plain",
}, },
@ -245,13 +245,13 @@ func TestPreferencesBuilder(t *testing.T) {
name: "external with sign enabled", name: "external with sign enabled",
contactMeta: &contactSettings{Sign: true, SignIsSet: true}, contactMeta: &contactSettings{Sign: true, SignIsSet: true},
receivedKeys: []liteapi.PublicKey{}, receivedKeys: []proton.PublicKey{},
isInternal: false, isInternal: false,
mailSettings: liteapi.MailSettings{PGPScheme: liteapi.PGPMIMEScheme, DraftMIMEType: "text/html"}, mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"},
wantEncrypt: false, wantEncrypt: false,
wantSign: liteapi.DetachedSignature, wantSign: proton.DetachedSignature,
wantScheme: liteapi.ClearMIMEScheme, wantScheme: proton.ClearMIMEScheme,
wantMIMEType: "multipart/mixed", wantMIMEType: "multipart/mixed",
}, },
@ -259,13 +259,13 @@ func TestPreferencesBuilder(t *testing.T) {
name: "external with contact sign enabled and plain text", name: "external with contact sign enabled and plain text",
contactMeta: &contactSettings{MIMEType: "text/plain", Scheme: pgpInline, Sign: true, SignIsSet: true}, contactMeta: &contactSettings{MIMEType: "text/plain", Scheme: pgpInline, Sign: true, SignIsSet: true},
receivedKeys: []liteapi.PublicKey{}, receivedKeys: []proton.PublicKey{},
isInternal: false, isInternal: false,
mailSettings: liteapi.MailSettings{PGPScheme: liteapi.PGPMIMEScheme, DraftMIMEType: "text/html"}, mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"},
wantEncrypt: false, wantEncrypt: false,
wantSign: liteapi.DetachedSignature, wantSign: proton.DetachedSignature,
wantScheme: liteapi.ClearScheme, wantScheme: proton.ClearScheme,
wantMIMEType: "text/plain", wantMIMEType: "text/plain",
}, },
@ -273,13 +273,13 @@ func TestPreferencesBuilder(t *testing.T) {
name: "external with sign enabled, sending plaintext, should still send as ClearMIME", name: "external with sign enabled, sending plaintext, should still send as ClearMIME",
contactMeta: &contactSettings{Sign: true, SignIsSet: true}, contactMeta: &contactSettings{Sign: true, SignIsSet: true},
receivedKeys: []liteapi.PublicKey{}, receivedKeys: []proton.PublicKey{},
isInternal: false, isInternal: false,
mailSettings: liteapi.MailSettings{PGPScheme: liteapi.PGPMIMEScheme, DraftMIMEType: "text/plain"}, mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/plain"},
wantEncrypt: false, wantEncrypt: false,
wantSign: liteapi.DetachedSignature, wantSign: proton.DetachedSignature,
wantScheme: liteapi.ClearMIMEScheme, wantScheme: proton.ClearMIMEScheme,
wantMIMEType: "multipart/mixed", wantMIMEType: "multipart/mixed",
}, },
@ -287,13 +287,13 @@ func TestPreferencesBuilder(t *testing.T) {
name: "external with pinned contact public key but no intention to encrypt/sign", name: "external with pinned contact public key but no intention to encrypt/sign",
contactMeta: &contactSettings{Keys: []string{testContactKey}}, contactMeta: &contactSettings{Keys: []string{testContactKey}},
receivedKeys: []liteapi.PublicKey{}, receivedKeys: []proton.PublicKey{},
isInternal: false, isInternal: false,
mailSettings: liteapi.MailSettings{PGPScheme: liteapi.PGPMIMEScheme, DraftMIMEType: "text/html"}, mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"},
wantEncrypt: false, wantEncrypt: false,
wantSign: liteapi.NoSignature, wantSign: proton.NoSignature,
wantScheme: liteapi.ClearScheme, wantScheme: proton.ClearScheme,
wantMIMEType: "text/html", wantMIMEType: "text/html",
wantPublicKey: testPublicKey, wantPublicKey: testPublicKey,
}, },
@ -302,13 +302,13 @@ func TestPreferencesBuilder(t *testing.T) {
name: "external with pinned contact public key, encrypted and signed", name: "external with pinned contact public key, encrypted and signed",
contactMeta: &contactSettings{Keys: []string{testContactKey}, Encrypt: true, Sign: true, SignIsSet: true}, contactMeta: &contactSettings{Keys: []string{testContactKey}, Encrypt: true, Sign: true, SignIsSet: true},
receivedKeys: []liteapi.PublicKey{}, receivedKeys: []proton.PublicKey{},
isInternal: false, isInternal: false,
mailSettings: liteapi.MailSettings{PGPScheme: liteapi.PGPMIMEScheme, DraftMIMEType: "text/html"}, mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"},
wantEncrypt: true, wantEncrypt: true,
wantSign: liteapi.DetachedSignature, wantSign: proton.DetachedSignature,
wantScheme: liteapi.PGPMIMEScheme, wantScheme: proton.PGPMIMEScheme,
wantMIMEType: "multipart/mixed", wantMIMEType: "multipart/mixed",
wantPublicKey: testPublicKey, wantPublicKey: testPublicKey,
}, },
@ -317,13 +317,13 @@ func TestPreferencesBuilder(t *testing.T) {
name: "external with pinned contact public key, encrypted and signed using contact-specific pgp-inline", name: "external with pinned contact public key, encrypted and signed using contact-specific pgp-inline",
contactMeta: &contactSettings{Keys: []string{testContactKey}, Encrypt: true, Sign: true, Scheme: pgpInline, SignIsSet: true}, contactMeta: &contactSettings{Keys: []string{testContactKey}, Encrypt: true, Sign: true, Scheme: pgpInline, SignIsSet: true},
receivedKeys: []liteapi.PublicKey{}, receivedKeys: []proton.PublicKey{},
isInternal: false, isInternal: false,
mailSettings: liteapi.MailSettings{PGPScheme: liteapi.PGPMIMEScheme, DraftMIMEType: "text/html"}, mailSettings: proton.MailSettings{PGPScheme: proton.PGPMIMEScheme, DraftMIMEType: "text/html"},
wantEncrypt: true, wantEncrypt: true,
wantSign: liteapi.DetachedSignature, wantSign: proton.DetachedSignature,
wantScheme: liteapi.PGPInlineScheme, wantScheme: proton.PGPInlineScheme,
wantMIMEType: "text/plain", wantMIMEType: "text/plain",
wantPublicKey: testPublicKey, wantPublicKey: testPublicKey,
}, },
@ -332,13 +332,13 @@ func TestPreferencesBuilder(t *testing.T) {
name: "external with pinned contact public key, encrypted and signed using global pgp-inline", name: "external with pinned contact public key, encrypted and signed using global pgp-inline",
contactMeta: &contactSettings{Keys: []string{testContactKey}, Encrypt: true, Sign: true, SignIsSet: true}, contactMeta: &contactSettings{Keys: []string{testContactKey}, Encrypt: true, Sign: true, SignIsSet: true},
receivedKeys: []liteapi.PublicKey{}, receivedKeys: []proton.PublicKey{},
isInternal: false, isInternal: false,
mailSettings: liteapi.MailSettings{PGPScheme: liteapi.PGPInlineScheme, DraftMIMEType: "text/html"}, mailSettings: proton.MailSettings{PGPScheme: proton.PGPInlineScheme, DraftMIMEType: "text/html"},
wantEncrypt: true, wantEncrypt: true,
wantSign: liteapi.DetachedSignature, wantSign: proton.DetachedSignature,
wantScheme: liteapi.PGPInlineScheme, wantScheme: proton.PGPInlineScheme,
wantMIMEType: "text/plain", wantMIMEType: "text/plain",
wantPublicKey: testPublicKey, wantPublicKey: testPublicKey,
}, },

View File

@ -26,6 +26,7 @@ import (
"github.com/ProtonMail/gluon/imap" "github.com/ProtonMail/gluon/imap"
"github.com/ProtonMail/gluon/queue" "github.com/ProtonMail/gluon/queue"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/ProtonMail/proton-bridge/v2/internal/events" "github.com/ProtonMail/proton-bridge/v2/internal/events"
"github.com/ProtonMail/proton-bridge/v2/internal/safe" "github.com/ProtonMail/proton-bridge/v2/internal/safe"
@ -34,7 +35,6 @@ import (
"github.com/bradenaw/juniper/xslices" "github.com/bradenaw/juniper/xslices"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gitlab.protontech.ch/go/liteapi"
"golang.org/x/exp/maps" "golang.org/x/exp/maps"
) )
@ -138,7 +138,7 @@ func (user *User) sync(ctx context.Context) error {
} }
// nolint:exhaustive // nolint:exhaustive
func syncLabels(ctx context.Context, apiLabels map[string]liteapi.Label, updateCh ...*queue.QueuedChannel[imap.Update]) error { func syncLabels(ctx context.Context, apiLabels map[string]proton.Label, updateCh ...*queue.QueuedChannel[imap.Update]) error {
// Create placeholder Folders/Labels mailboxes with a random ID and with the \Noselect attribute. // Create placeholder Folders/Labels mailboxes with a random ID and with the \Noselect attribute.
for _, prefix := range []string{folderPrefix, labelPrefix} { for _, prefix := range []string{folderPrefix, labelPrefix} {
for _, updateCh := range updateCh { for _, updateCh := range updateCh {
@ -153,12 +153,12 @@ func syncLabels(ctx context.Context, apiLabels map[string]liteapi.Label, updateC
} }
switch label.Type { switch label.Type {
case liteapi.LabelTypeSystem: case proton.LabelTypeSystem:
for _, updateCh := range updateCh { for _, updateCh := range updateCh {
updateCh.Enqueue(newSystemMailboxCreatedUpdate(imap.MailboxID(label.ID), label.Name)) updateCh.Enqueue(newSystemMailboxCreatedUpdate(imap.MailboxID(label.ID), label.Name))
} }
case liteapi.LabelTypeFolder, liteapi.LabelTypeLabel: case proton.LabelTypeFolder, proton.LabelTypeLabel:
for _, updateCh := range updateCh { for _, updateCh := range updateCh {
updateCh.Enqueue(newMailboxCreatedUpdate(imap.MailboxID(labelID), getMailboxName(label))) updateCh.Enqueue(newMailboxCreatedUpdate(imap.MailboxID(labelID), getMailboxName(label)))
} }
@ -183,9 +183,9 @@ func syncLabels(ctx context.Context, apiLabels map[string]liteapi.Label, updateC
func syncMessages( func syncMessages(
ctx context.Context, ctx context.Context,
userID string, userID string,
client *liteapi.Client, client *proton.Client,
vault *vault.User, vault *vault.User,
apiLabels map[string]liteapi.Label, apiLabels map[string]proton.Label,
addrKRs map[string]*crypto.KeyRing, addrKRs map[string]*crypto.KeyRing,
updateCh map[string]*queue.QueuedChannel[imap.Update], updateCh map[string]*queue.QueuedChannel[imap.Update],
eventCh *queue.QueuedChannel[events.Event], eventCh *queue.QueuedChannel[events.Event],
@ -261,7 +261,6 @@ func syncMessages(
return buildRFC822(apiLabels, msg, addrKRs[msg.AddressID]) return buildRFC822(apiLabels, msg, addrKRs[msg.AddressID])
}) })
if err != nil { if err != nil {
errorCh <- err errorCh <- err
return return
@ -328,25 +327,25 @@ func newSystemMailboxCreatedUpdate(labelID imap.MailboxID, labelName string) *im
attrs := imap.NewFlagSet(imap.AttrNoInferiors) attrs := imap.NewFlagSet(imap.AttrNoInferiors)
switch labelID { switch labelID {
case liteapi.TrashLabel: case proton.TrashLabel:
attrs = attrs.Add(imap.AttrTrash) attrs = attrs.Add(imap.AttrTrash)
case liteapi.SpamLabel: case proton.SpamLabel:
attrs = attrs.Add(imap.AttrJunk) attrs = attrs.Add(imap.AttrJunk)
case liteapi.AllMailLabel: case proton.AllMailLabel:
attrs = attrs.Add(imap.AttrAll) attrs = attrs.Add(imap.AttrAll)
case liteapi.ArchiveLabel: case proton.ArchiveLabel:
attrs = attrs.Add(imap.AttrArchive) attrs = attrs.Add(imap.AttrArchive)
case liteapi.SentLabel: case proton.SentLabel:
attrs = attrs.Add(imap.AttrSent) attrs = attrs.Add(imap.AttrSent)
case liteapi.DraftsLabel: case proton.DraftsLabel:
attrs = attrs.Add(imap.AttrDrafts) attrs = attrs.Add(imap.AttrDrafts)
case liteapi.StarredLabel: case proton.StarredLabel:
attrs = attrs.Add(imap.AttrFlagged) attrs = attrs.Add(imap.AttrFlagged)
} }
@ -379,35 +378,35 @@ func newMailboxCreatedUpdate(labelID imap.MailboxID, labelName []string) *imap.M
}) })
} }
func wantLabel(label liteapi.Label) bool { func wantLabel(label proton.Label) bool {
if label.Type != liteapi.LabelTypeSystem { if label.Type != proton.LabelTypeSystem {
return true return true
} }
// nolint:exhaustive // nolint:exhaustive
switch label.ID { switch label.ID {
case liteapi.InboxLabel: case proton.InboxLabel:
return true return true
case liteapi.TrashLabel: case proton.TrashLabel:
return true return true
case liteapi.SpamLabel: case proton.SpamLabel:
return true return true
case liteapi.AllMailLabel: case proton.AllMailLabel:
return true return true
case liteapi.ArchiveLabel: case proton.ArchiveLabel:
return true return true
case liteapi.SentLabel: case proton.SentLabel:
return true return true
case liteapi.DraftsLabel: case proton.DraftsLabel:
return true return true
case liteapi.StarredLabel: case proton.StarredLabel:
return true return true
default: default:
@ -415,7 +414,7 @@ func wantLabel(label liteapi.Label) bool {
} }
} }
func wantLabels(apiLabels map[string]liteapi.Label, labelIDs []string) []string { func wantLabels(apiLabels map[string]proton.Label, labelIDs []string) []string {
return xslices.Filter(labelIDs, func(labelID string) bool { return xslices.Filter(labelIDs, func(labelID string) bool {
return wantLabel(apiLabels[labelID]) return wantLabel(apiLabels[labelID])
}) })

View File

@ -21,9 +21,9 @@ import (
"fmt" "fmt"
"github.com/ProtonMail/gluon/imap" "github.com/ProtonMail/gluon/imap"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/ProtonMail/proton-bridge/v2/pkg/message" "github.com/ProtonMail/proton-bridge/v2/pkg/message"
"gitlab.protontech.ch/go/liteapi"
) )
type buildRes struct { type buildRes struct {
@ -43,7 +43,7 @@ func defaultJobOpts() message.JobOptions {
} }
} }
func buildRFC822(apiLabels map[string]liteapi.Label, full liteapi.FullMessage, addrKR *crypto.KeyRing) (*buildRes, error) { func buildRFC822(apiLabels map[string]proton.Label, full proton.FullMessage, addrKR *crypto.KeyRing) (*buildRes, error) {
literal, err := message.BuildRFC822(addrKR, full.Message, full.AttData, defaultJobOpts()) literal, err := message.BuildRFC822(addrKR, full.Message, full.AttData, defaultJobOpts())
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to build message %s: %w", full.ID, err) return nil, fmt.Errorf("failed to build message %s: %w", full.ID, err)
@ -62,8 +62,8 @@ func buildRFC822(apiLabels map[string]liteapi.Label, full liteapi.FullMessage, a
} }
func newMessageCreatedUpdate( func newMessageCreatedUpdate(
apiLabels map[string]liteapi.Label, apiLabels map[string]proton.Label,
message liteapi.MessageMetadata, message proton.MessageMetadata,
literal []byte, literal []byte,
) (*imap.MessageCreated, error) { ) (*imap.MessageCreated, error) {
parsedMessage, err := imap.NewParsedMessage(literal) parsedMessage, err := imap.NewParsedMessage(literal)

View File

@ -23,7 +23,7 @@ import (
"reflect" "reflect"
"strings" "strings"
"gitlab.protontech.ch/go/liteapi" "github.com/ProtonMail/go-proton-api"
"golang.org/x/exp/maps" "golang.org/x/exp/maps"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
) )
@ -80,7 +80,7 @@ func b64Decode(b []byte) ([]byte, error) {
} }
// getAddrID returns the address ID for the given email address. // getAddrID returns the address ID for the given email address.
func getAddrID(apiAddrs map[string]liteapi.Address, email string) (string, error) { func getAddrID(apiAddrs map[string]proton.Address, email string) (string, error) {
for _, addr := range apiAddrs { for _, addr := range apiAddrs {
if strings.EqualFold(addr.Email, sanitizeEmail(email)) { if strings.EqualFold(addr.Email, sanitizeEmail(email)) {
return addr.ID, nil return addr.ID, nil
@ -91,13 +91,13 @@ func getAddrID(apiAddrs map[string]liteapi.Address, email string) (string, error
} }
// getAddrIdx returns the address with the given index. // getAddrIdx returns the address with the given index.
func getAddrIdx(apiAddrs map[string]liteapi.Address, idx int) (liteapi.Address, error) { func getAddrIdx(apiAddrs map[string]proton.Address, idx int) (proton.Address, error) {
sorted := sortSlice(maps.Values(apiAddrs), func(a, b liteapi.Address) bool { sorted := sortSlice(maps.Values(apiAddrs), func(a, b proton.Address) bool {
return a.Order < b.Order return a.Order < b.Order
}) })
if idx < 0 || idx >= len(sorted) { if idx < 0 || idx >= len(sorted) {
return liteapi.Address{}, fmt.Errorf("address index %d out of range", idx) return proton.Address{}, fmt.Errorf("address index %d out of range", idx)
} }
return sorted[idx], nil return sorted[idx], nil

View File

@ -30,6 +30,7 @@ import (
"github.com/ProtonMail/gluon/imap" "github.com/ProtonMail/gluon/imap"
"github.com/ProtonMail/gluon/queue" "github.com/ProtonMail/gluon/queue"
gluonReporter "github.com/ProtonMail/gluon/reporter" gluonReporter "github.com/ProtonMail/gluon/reporter"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/proton-bridge/v2/internal/async" "github.com/ProtonMail/proton-bridge/v2/internal/async"
"github.com/ProtonMail/proton-bridge/v2/internal/events" "github.com/ProtonMail/proton-bridge/v2/internal/events"
"github.com/ProtonMail/proton-bridge/v2/internal/logging" "github.com/ProtonMail/proton-bridge/v2/internal/logging"
@ -38,7 +39,6 @@ import (
"github.com/bradenaw/juniper/xslices" "github.com/bradenaw/juniper/xslices"
"github.com/go-resty/resty/v2" "github.com/go-resty/resty/v2"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gitlab.protontech.ch/go/liteapi"
"golang.org/x/exp/maps" "golang.org/x/exp/maps"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
) )
@ -56,17 +56,17 @@ type User struct {
log *logrus.Entry log *logrus.Entry
vault *vault.User vault *vault.User
client *liteapi.Client client *proton.Client
eventCh *queue.QueuedChannel[events.Event] eventCh *queue.QueuedChannel[events.Event]
sendHash *sendRecorder sendHash *sendRecorder
apiUser liteapi.User apiUser proton.User
apiUserLock safe.RWMutex apiUserLock safe.RWMutex
apiAddrs map[string]liteapi.Address apiAddrs map[string]proton.Address
apiAddrsLock safe.RWMutex apiAddrsLock safe.RWMutex
apiLabels map[string]liteapi.Label apiLabels map[string]proton.Label
apiLabelsLock safe.RWMutex apiLabelsLock safe.RWMutex
updateCh map[string]*queue.QueuedChannel[imap.Update] updateCh map[string]*queue.QueuedChannel[imap.Update]
@ -91,8 +91,8 @@ type User struct {
func New( func New(
ctx context.Context, ctx context.Context,
encVault *vault.User, encVault *vault.User,
client *liteapi.Client, client *proton.Client,
apiUser liteapi.User, apiUser proton.User,
crashHandler async.PanicHandler, crashHandler async.PanicHandler,
reporter gluonReporter.Reporter, reporter gluonReporter.Reporter,
syncWorkers int, syncWorkers int,
@ -107,7 +107,7 @@ func New(
} }
// Get the user's API labels. // Get the user's API labels.
apiLabels, err := client.GetLabels(ctx, liteapi.LabelTypeSystem, liteapi.LabelTypeFolder, liteapi.LabelTypeLabel) apiLabels, err := client.GetLabels(ctx, proton.LabelTypeSystem, proton.LabelTypeFolder, proton.LabelTypeLabel)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to get labels: %w", err) return nil, fmt.Errorf("failed to get labels: %w", err)
} }
@ -124,10 +124,10 @@ func New(
apiUser: apiUser, apiUser: apiUser,
apiUserLock: safe.NewRWMutex(), apiUserLock: safe.NewRWMutex(),
apiAddrs: groupBy(apiAddrs, func(addr liteapi.Address) string { return addr.ID }), apiAddrs: groupBy(apiAddrs, func(addr proton.Address) string { return addr.ID }),
apiAddrsLock: safe.NewRWMutex(), apiAddrsLock: safe.NewRWMutex(),
apiLabels: groupBy(apiLabels, func(label liteapi.Label) string { return label.ID }), apiLabels: groupBy(apiLabels, func(label proton.Label) string { return label.ID }),
apiLabelsLock: safe.NewRWMutex(), apiLabelsLock: safe.NewRWMutex(),
updateCh: make(map[string]*queue.QueuedChannel[imap.Update]), updateCh: make(map[string]*queue.QueuedChannel[imap.Update]),
@ -147,7 +147,7 @@ func New(
// When we receive an auth object, we update it in the vault. // When we receive an auth object, we update it in the vault.
// This will be used to authorize the user on the next run. // This will be used to authorize the user on the next run.
user.client.AddAuthHandler(func(auth liteapi.Auth) { user.client.AddAuthHandler(func(auth proton.Auth) {
if err := user.vault.SetAuth(auth.UID, auth.RefreshToken); err != nil { if err := user.vault.SetAuth(auth.UID, auth.RefreshToken); err != nil {
user.log.WithError(err).Error("Failed to update auth in vault") user.log.WithError(err).Error("Failed to update auth in vault")
} }
@ -172,7 +172,7 @@ func New(
// When we receive an API event, we attempt to handle it. // When we receive an API event, we attempt to handle it.
// If successful, we update the event ID in the vault. // If successful, we update the event ID in the vault.
user.tasks.Once(func(ctx context.Context) { user.tasks.Once(func(ctx context.Context) {
ticker := liteapi.NewTicker(EventPeriod, EventJitter) ticker := proton.NewTicker(EventPeriod, EventJitter)
defer ticker.Stop() defer ticker.Stop()
for { for {
@ -271,11 +271,11 @@ func (user *User) Emails() []string {
return safe.RLockRet(func() []string { return safe.RLockRet(func() []string {
addresses := maps.Values(user.apiAddrs) addresses := maps.Values(user.apiAddrs)
slices.SortFunc(addresses, func(a, b liteapi.Address) bool { slices.SortFunc(addresses, func(a, b proton.Address) bool {
return a.Order < b.Order return a.Order < b.Order
}) })
return xslices.Map(addresses, func(addr liteapi.Address) string { return xslices.Map(addresses, func(addr proton.Address) string {
return addr.Email return addr.Email
}) })
}, user.apiAddrsLock) }, user.apiAddrsLock)

View File

@ -23,6 +23,9 @@ import (
"time" "time"
"github.com/ProtonMail/gluon/connector" "github.com/ProtonMail/gluon/connector"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/go-proton-api/server"
"github.com/ProtonMail/go-proton-api/server/backend"
"github.com/ProtonMail/proton-bridge/v2/internal/bridge/mocks" "github.com/ProtonMail/proton-bridge/v2/internal/bridge/mocks"
"github.com/ProtonMail/proton-bridge/v2/internal/certs" "github.com/ProtonMail/proton-bridge/v2/internal/certs"
"github.com/ProtonMail/proton-bridge/v2/internal/events" "github.com/ProtonMail/proton-bridge/v2/internal/events"
@ -30,9 +33,6 @@ import (
"github.com/ProtonMail/proton-bridge/v2/tests" "github.com/ProtonMail/proton-bridge/v2/tests"
"github.com/golang/mock/gomock" "github.com/golang/mock/gomock"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.protontech.ch/go/liteapi"
"gitlab.protontech.ch/go/liteapi/server"
"gitlab.protontech.ch/go/liteapi/server/backend"
"go.uber.org/goleak" "go.uber.org/goleak"
) )
@ -48,7 +48,7 @@ func TestMain(m *testing.M) {
} }
func TestUser_Info(t *testing.T) { func TestUser_Info(t *testing.T) {
withAPI(t, context.Background(), func(ctx context.Context, s *server.Server, m *liteapi.Manager) { withAPI(t, context.Background(), func(ctx context.Context, s *server.Server, m *proton.Manager) {
withAccount(t, s, "username", "password", []string{"email@pm.me", "alias@pm.me"}, func(userID string, _ []string) { withAccount(t, s, "username", "password", []string{"email@pm.me", "alias@pm.me"}, func(userID string, _ []string) {
withUser(t, ctx, s, m, "username", "password", func(user *User) { withUser(t, ctx, s, m, "username", "password", func(user *User) {
// User's ID should be correct. // User's ID should be correct.
@ -71,7 +71,7 @@ func TestUser_Info(t *testing.T) {
} }
func TestUser_Sync(t *testing.T) { func TestUser_Sync(t *testing.T) {
withAPI(t, context.Background(), func(ctx context.Context, s *server.Server, m *liteapi.Manager) { withAPI(t, context.Background(), func(ctx context.Context, s *server.Server, m *proton.Manager) {
withAccount(t, s, "username", "password", []string{"email@pm.me"}, func(string, []string) { withAccount(t, s, "username", "password", []string{"email@pm.me"}, func(string, []string) {
withUser(t, ctx, s, m, "username", "password", func(user *User) { withUser(t, ctx, s, m, "username", "password", func(user *User) {
// User starts a sync at startup. // User starts a sync at startup.
@ -88,7 +88,7 @@ func TestUser_Sync(t *testing.T) {
} }
func TestUser_AddressMode(t *testing.T) { func TestUser_AddressMode(t *testing.T) {
withAPI(t, context.Background(), func(ctx context.Context, s *server.Server, m *liteapi.Manager) { withAPI(t, context.Background(), func(ctx context.Context, s *server.Server, m *proton.Manager) {
withAccount(t, s, "username", "password", []string{"email@pm.me", "alias@pm.me"}, func(string, []string) { withAccount(t, s, "username", "password", []string{"email@pm.me", "alias@pm.me"}, func(string, []string) {
withUser(t, ctx, s, m, "username", "password", func(user *User) { withUser(t, ctx, s, m, "username", "password", func(user *User) {
// User finishes syncing at startup. // User finishes syncing at startup.
@ -125,7 +125,7 @@ func TestUser_AddressMode(t *testing.T) {
} }
func TestUser_Deauth(t *testing.T) { func TestUser_Deauth(t *testing.T) {
withAPI(t, context.Background(), func(ctx context.Context, s *server.Server, m *liteapi.Manager) { withAPI(t, context.Background(), func(ctx context.Context, s *server.Server, m *proton.Manager) {
withAccount(t, s, "username", "password", []string{"email@pm.me"}, func(string, []string) { withAccount(t, s, "username", "password", []string{"email@pm.me"}, func(string, []string) {
withUser(t, ctx, s, m, "username", "password", func(user *User) { withUser(t, ctx, s, m, "username", "password", func(user *User) {
require.IsType(t, events.SyncStarted{}, <-user.GetEventCh()) require.IsType(t, events.SyncStarted{}, <-user.GetEventCh())
@ -146,7 +146,7 @@ func TestUser_Refresh(t *testing.T) {
ctl := gomock.NewController(t) ctl := gomock.NewController(t)
mockReporter := mocks.NewMockReporter(ctl) mockReporter := mocks.NewMockReporter(ctl)
withAPI(t, context.Background(), func(ctx context.Context, s *server.Server, m *liteapi.Manager) { withAPI(t, context.Background(), func(ctx context.Context, s *server.Server, m *proton.Manager) {
withAccount(t, s, "username", "password", []string{"email@pm.me"}, func(string, []string) { withAccount(t, s, "username", "password", []string{"email@pm.me"}, func(string, []string) {
withUser(t, ctx, s, m, "username", "password", func(user *User) { withUser(t, ctx, s, m, "username", "password", func(user *User) {
require.IsType(t, events.SyncStarted{}, <-user.GetEventCh()) require.IsType(t, events.SyncStarted{}, <-user.GetEventCh())
@ -157,11 +157,11 @@ func TestUser_Refresh(t *testing.T) {
mockReporter.EXPECT().ReportMessageWithContext( mockReporter.EXPECT().ReportMessageWithContext(
gomock.Eq("Warning: refresh occurred"), gomock.Eq("Warning: refresh occurred"),
mocks.NewRefreshContextMatcher(liteapi.RefreshAll), mocks.NewRefreshContextMatcher(proton.RefreshAll),
).Return(nil) ).Return(nil)
// Send refresh event // Send refresh event
require.NoError(t, s.RefreshUser(user.ID(), liteapi.RefreshAll)) require.NoError(t, s.RefreshUser(user.ID(), proton.RefreshAll))
// The user should eventually be re-synced. // The user should eventually be re-synced.
require.Eventually(t, func() bool { _, ok := (<-user.GetEventCh()).(events.UserRefreshed); return ok }, 5*time.Second, 100*time.Millisecond) require.Eventually(t, func() bool { _, ok := (<-user.GetEventCh()).(events.UserRefreshed); return ok }, 5*time.Second, 100*time.Millisecond)
@ -170,13 +170,13 @@ func TestUser_Refresh(t *testing.T) {
}) })
} }
func withAPI(_ testing.TB, ctx context.Context, fn func(context.Context, *server.Server, *liteapi.Manager)) { //nolint:revive func withAPI(_ testing.TB, ctx context.Context, fn func(context.Context, *server.Server, *proton.Manager)) { //nolint:revive
server := server.New() server := server.New()
defer server.Close() defer server.Close()
fn(ctx, server, liteapi.New( fn(ctx, server, proton.New(
liteapi.WithHostURL(server.GetHostURL()), proton.WithHostURL(server.GetHostURL()),
liteapi.WithTransport(liteapi.InsecureTransport()), proton.WithTransport(proton.InsecureTransport()),
)) ))
} }
@ -198,7 +198,7 @@ func withAccount(tb testing.TB, s *server.Server, username, password string, ema
fn(userID, addrIDs) fn(userID, addrIDs)
} }
func withUser(tb testing.TB, ctx context.Context, _ *server.Server, m *liteapi.Manager, username, password string, fn func(*User)) { //nolint:unparam,revive func withUser(tb testing.TB, ctx context.Context, _ *server.Server, m *proton.Manager, username, password string, fn func(*User)) { //nolint:unparam,revive
client, apiAuth, err := m.NewClientWithLogin(ctx, username, []byte(password)) client, apiAuth, err := m.NewClientWithLogin(ctx, username, []byte(password))
require.NoError(tb, err) require.NoError(tb, err)

View File

@ -49,7 +49,7 @@ func TestMigrate(t *testing.T) {
}) })
// Write the vault to disk. // Write the vault to disk.
require.NoError(t, os.WriteFile(filepath.Join(dir, "vault.enc"), b, 0600)) require.NoError(t, os.WriteFile(filepath.Join(dir, "vault.enc"), b, 0o600))
// Migrate the vault. // Migrate the vault.
s, corrupt, err := New(dir, "default-gluon-dir", []byte("my secret key")) s, corrupt, err := New(dir, "default-gluon-dir", []byte("my secret key"))

View File

@ -27,6 +27,7 @@ import (
"unicode/utf8" "unicode/utf8"
"github.com/ProtonMail/gluon/rfc822" "github.com/ProtonMail/gluon/rfc822"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/go-rfc5322" "github.com/ProtonMail/go-rfc5322"
"github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/ProtonMail/proton-bridge/v2/pkg/algo" "github.com/ProtonMail/proton-bridge/v2/pkg/algo"
@ -34,7 +35,6 @@ import (
"github.com/emersion/go-message" "github.com/emersion/go-message"
"github.com/emersion/go-message/textproto" "github.com/emersion/go-message/textproto"
"github.com/pkg/errors" "github.com/pkg/errors"
"gitlab.protontech.ch/go/liteapi"
) )
var ( var (
@ -45,7 +45,7 @@ var (
// InternalIDDomain is used as a placeholder for reference/message ID headers to improve compatibility with various clients. // InternalIDDomain is used as a placeholder for reference/message ID headers to improve compatibility with various clients.
const InternalIDDomain = `protonmail.internalid` const InternalIDDomain = `protonmail.internalid`
func BuildRFC822(kr *crypto.KeyRing, msg liteapi.Message, attData [][]byte, opts JobOptions) ([]byte, error) { func BuildRFC822(kr *crypto.KeyRing, msg proton.Message, attData [][]byte, opts JobOptions) ([]byte, error) {
switch { switch {
case len(msg.Attachments) > 0: case len(msg.Attachments) > 0:
return buildMultipartRFC822(kr, msg, attData, opts) return buildMultipartRFC822(kr, msg, attData, opts)
@ -58,7 +58,7 @@ func BuildRFC822(kr *crypto.KeyRing, msg liteapi.Message, attData [][]byte, opts
} }
} }
func buildSimpleRFC822(kr *crypto.KeyRing, msg liteapi.Message, opts JobOptions) ([]byte, error) { func buildSimpleRFC822(kr *crypto.KeyRing, msg proton.Message, opts JobOptions) ([]byte, error) {
dec, err := msg.Decrypt(kr) dec, err := msg.Decrypt(kr)
if err != nil { if err != nil {
if !opts.IgnoreDecryptionErrors { if !opts.IgnoreDecryptionErrors {
@ -90,7 +90,7 @@ func buildSimpleRFC822(kr *crypto.KeyRing, msg liteapi.Message, opts JobOptions)
func buildMultipartRFC822( func buildMultipartRFC822(
kr *crypto.KeyRing, kr *crypto.KeyRing,
msg liteapi.Message, msg proton.Message,
attData [][]byte, attData [][]byte,
opts JobOptions, opts JobOptions,
) ([]byte, error) { ) ([]byte, error) {
@ -108,14 +108,14 @@ func buildMultipartRFC822(
} }
var ( var (
inlineAtts []liteapi.Attachment inlineAtts []proton.Attachment
inlineData [][]byte inlineData [][]byte
attachAtts []liteapi.Attachment attachAtts []proton.Attachment
attachData [][]byte attachData [][]byte
) )
for index, att := range msg.Attachments { for index, att := range msg.Attachments {
if att.Disposition == liteapi.InlineDisposition { if att.Disposition == proton.InlineDisposition {
inlineAtts = append(inlineAtts, att) inlineAtts = append(inlineAtts, att)
inlineData = append(inlineData, attData[index]) inlineData = append(inlineData, attData[index])
} else { } else {
@ -148,7 +148,7 @@ func buildMultipartRFC822(
func writeTextPart( func writeTextPart(
w *message.Writer, w *message.Writer,
kr *crypto.KeyRing, kr *crypto.KeyRing,
msg liteapi.Message, msg proton.Message,
opts JobOptions, opts JobOptions,
) error { ) error {
dec, err := msg.Decrypt(kr) dec, err := msg.Decrypt(kr)
@ -166,7 +166,7 @@ func writeTextPart(
func writeAttachmentPart( func writeAttachmentPart(
w *message.Writer, w *message.Writer,
kr *crypto.KeyRing, kr *crypto.KeyRing,
att liteapi.Attachment, att proton.Attachment,
attData []byte, attData []byte,
opts JobOptions, opts JobOptions,
) error { ) error {
@ -198,8 +198,8 @@ func writeRelatedParts(
w *message.Writer, w *message.Writer,
kr *crypto.KeyRing, kr *crypto.KeyRing,
boundary *boundary, boundary *boundary,
msg liteapi.Message, msg proton.Message,
atts []liteapi.Attachment, atts []proton.Attachment,
attData [][]byte, attData [][]byte,
opts JobOptions, opts JobOptions,
) error { ) error {
@ -222,7 +222,7 @@ func writeRelatedParts(
}) })
} }
func buildPGPRFC822(kr *crypto.KeyRing, msg liteapi.Message, opts JobOptions) ([]byte, error) { func buildPGPRFC822(kr *crypto.KeyRing, msg proton.Message, opts JobOptions) ([]byte, error) {
dec, err := msg.Decrypt(kr) dec, err := msg.Decrypt(kr)
if err != nil { if err != nil {
if !opts.IgnoreDecryptionErrors { if !opts.IgnoreDecryptionErrors {
@ -234,7 +234,7 @@ func buildPGPRFC822(kr *crypto.KeyRing, msg liteapi.Message, opts JobOptions) ([
hdr := getMessageHeader(msg, opts) hdr := getMessageHeader(msg, opts)
sigs, err := liteapi.ExtractSignatures(kr, msg.Body) sigs, err := proton.ExtractSignatures(kr, msg.Body)
if err != nil { if err != nil {
log.WithError(err).WithField("id", msg.ID).Warn("Extract signature failed") log.WithError(err).WithField("id", msg.ID).Warn("Extract signature failed")
} }
@ -246,7 +246,7 @@ func buildPGPRFC822(kr *crypto.KeyRing, msg liteapi.Message, opts JobOptions) ([
return writeMultipartEncryptedRFC822(hdr, dec) return writeMultipartEncryptedRFC822(hdr, dec)
} }
func buildPGPMIMEFallbackRFC822(msg liteapi.Message, opts JobOptions) ([]byte, error) { func buildPGPMIMEFallbackRFC822(msg proton.Message, opts JobOptions) ([]byte, error) {
hdr := getMessageHeader(msg, opts) hdr := getMessageHeader(msg, opts)
hdr.SetContentType("multipart/encrypted", map[string]string{ hdr.SetContentType("multipart/encrypted", map[string]string{
@ -287,7 +287,7 @@ func buildPGPMIMEFallbackRFC822(msg liteapi.Message, opts JobOptions) ([]byte, e
return buf.Bytes(), nil return buf.Bytes(), nil
} }
func writeMultipartSignedRFC822(header message.Header, body []byte, sig liteapi.Signature) ([]byte, error) { //nolint:funlen func writeMultipartSignedRFC822(header message.Header, body []byte, sig proton.Signature) ([]byte, error) { //nolint:funlen
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
boundary := newBoundary("").gen() boundary := newBoundary("").gen()
@ -378,7 +378,7 @@ func writeMultipartEncryptedRFC822(header message.Header, body []byte) ([]byte,
return buf.Bytes(), nil return buf.Bytes(), nil
} }
func getMessageHeader(msg liteapi.Message, opts JobOptions) message.Header { //nolint:funlen func getMessageHeader(msg proton.Message, opts JobOptions) message.Header { //nolint:funlen
hdr := toMessageHeader(msg.ParsedHeaders) hdr := toMessageHeader(msg.ParsedHeaders)
// SetText will RFC2047-encode. // SetText will RFC2047-encode.
@ -461,7 +461,7 @@ func SanitizeMessageDate(msgTime int64) time.Time {
// setMessageIDIfNeeded sets Message-Id from ExternalID or ID if it's not // setMessageIDIfNeeded sets Message-Id from ExternalID or ID if it's not
// already set. // already set.
func setMessageIDIfNeeded(msg liteapi.Message, hdr *message.Header) { func setMessageIDIfNeeded(msg proton.Message, hdr *message.Header) {
if hdr.Get("Message-Id") == "" { if hdr.Get("Message-Id") == "" {
if msg.ExternalID != "" { if msg.ExternalID != "" {
hdr.Set("Message-Id", "<"+msg.ExternalID+">") hdr.Set("Message-Id", "<"+msg.ExternalID+">")
@ -486,7 +486,7 @@ func getTextPartHeader(hdr message.Header, body []byte, mimeType rfc822.MIMEType
return hdr return hdr
} }
func getAttachmentPartHeader(att liteapi.Attachment) message.Header { func getAttachmentPartHeader(att proton.Attachment) message.Header {
hdr := toMessageHeader(att.Headers) hdr := toMessageHeader(att.Headers)
// All attachments have a content type. // All attachments have a content type.
@ -505,7 +505,7 @@ func getAttachmentPartHeader(att liteapi.Attachment) message.Header {
return hdr return hdr
} }
func toMessageHeader(hdr liteapi.Headers) message.Header { func toMessageHeader(hdr proton.Headers) message.Header {
var res message.Header var res message.Header
for key, val := range hdr { for key, val := range hdr {

View File

@ -21,16 +21,16 @@ import (
"fmt" "fmt"
"mime" "mime"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/gopenpgp/v2/constants" "github.com/ProtonMail/gopenpgp/v2/constants"
"github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/emersion/go-message" "github.com/emersion/go-message"
"gitlab.protontech.ch/go/liteapi"
) )
// writeCustomTextPart writes an armored-PGP text part for a message body that couldn't be decrypted. // writeCustomTextPart writes an armored-PGP text part for a message body that couldn't be decrypted.
func writeCustomTextPart( func writeCustomTextPart(
w *message.Writer, w *message.Writer,
msg liteapi.Message, msg proton.Message,
decError error, decError error,
) error { ) error {
enc, err := crypto.NewPGPMessageFromArmored(msg.Body) enc, err := crypto.NewPGPMessageFromArmored(msg.Body)
@ -65,7 +65,7 @@ func writeCustomTextPart(
// writeCustomAttachmentPart writes an armored-PGP data part for an attachment that couldn't be decrypted. // writeCustomAttachmentPart writes an armored-PGP data part for an attachment that couldn't be decrypted.
func writeCustomAttachmentPart( func writeCustomAttachmentPart(
w *message.Writer, w *message.Writer,
att liteapi.Attachment, att proton.Attachment,
msg *crypto.PGPMessage, msg *crypto.PGPMessage,
decError error, decError error,
) error { ) error {

View File

@ -26,10 +26,10 @@ import (
"time" "time"
"github.com/ProtonMail/gluon/rfc822" "github.com/ProtonMail/gluon/rfc822"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/ProtonMail/proton-bridge/v2/pkg/message/parser" "github.com/ProtonMail/proton-bridge/v2/pkg/message/parser"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gitlab.protontech.ch/go/liteapi"
"golang.org/x/text/encoding/htmlindex" "golang.org/x/text/encoding/htmlindex"
) )
@ -38,7 +38,7 @@ func newTestMessage(
kr *crypto.KeyRing, kr *crypto.KeyRing,
messageID, addressID, mimeType, body string, //nolint:unparam messageID, addressID, mimeType, body string, //nolint:unparam
date time.Time, date time.Time,
) liteapi.Message { ) proton.Message {
enc, err := kr.Encrypt(crypto.NewPlainMessageFromString(body), kr) enc, err := kr.Encrypt(crypto.NewPlainMessageFromString(body), kr)
require.NoError(t, err) require.NoError(t, err)
@ -48,14 +48,14 @@ func newTestMessage(
return newRawTestMessage(messageID, addressID, mimeType, arm, date) return newRawTestMessage(messageID, addressID, mimeType, arm, date)
} }
func newRawTestMessage(messageID, addressID, mimeType, body string, date time.Time) liteapi.Message { func newRawTestMessage(messageID, addressID, mimeType, body string, date time.Time) proton.Message {
return liteapi.Message{ return proton.Message{
MessageMetadata: liteapi.MessageMetadata{ MessageMetadata: proton.MessageMetadata{
ID: messageID, ID: messageID,
AddressID: addressID, AddressID: addressID,
Time: date.Unix(), Time: date.Unix(),
}, },
ParsedHeaders: liteapi.Headers{ ParsedHeaders: proton.Headers{
"Content-Type": {mimeType}, "Content-Type": {mimeType},
"Date": {date.In(time.UTC).Format(time.RFC1123Z)}, "Date": {date.In(time.UTC).Format(time.RFC1123Z)},
}, },
@ -67,22 +67,22 @@ func newRawTestMessage(messageID, addressID, mimeType, body string, date time.Ti
func addTestAttachment( func addTestAttachment(
t *testing.T, t *testing.T,
kr *crypto.KeyRing, kr *crypto.KeyRing,
msg *liteapi.Message, msg *proton.Message,
attachmentID, name, mimeType, disposition, data string, attachmentID, name, mimeType, disposition, data string,
) []byte { ) []byte {
enc, err := kr.EncryptAttachment(crypto.NewPlainMessageFromString(data), attachmentID+".bin") enc, err := kr.EncryptAttachment(crypto.NewPlainMessageFromString(data), attachmentID+".bin")
require.NoError(t, err) require.NoError(t, err)
msg.Attachments = append(msg.Attachments, liteapi.Attachment{ msg.Attachments = append(msg.Attachments, proton.Attachment{
ID: attachmentID, ID: attachmentID,
Name: name, Name: name,
MIMEType: rfc822.MIMEType(mimeType), MIMEType: rfc822.MIMEType(mimeType),
Headers: liteapi.Headers{ Headers: proton.Headers{
"Content-Type": {mimeType}, "Content-Type": {mimeType},
"Content-Disposition": {disposition}, "Content-Disposition": {disposition},
"Content-Transfer-Encoding": {"base64"}, "Content-Transfer-Encoding": {"base64"},
}, },
Disposition: liteapi.Disposition(disposition), Disposition: proton.Disposition(disposition),
KeyPackets: base64.StdEncoding.EncodeToString(enc.GetBinaryKeyPacket()), KeyPackets: base64.StdEncoding.EncodeToString(enc.GetBinaryKeyPacket()),
}) })

View File

@ -27,6 +27,7 @@ import (
"strings" "strings"
"github.com/ProtonMail/gluon/rfc822" "github.com/ProtonMail/gluon/rfc822"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/go-rfc5322" "github.com/ProtonMail/go-rfc5322"
"github.com/ProtonMail/proton-bridge/v2/pkg/message/parser" "github.com/ProtonMail/proton-bridge/v2/pkg/message/parser"
pmmime "github.com/ProtonMail/proton-bridge/v2/pkg/mime" pmmime "github.com/ProtonMail/proton-bridge/v2/pkg/mime"
@ -34,7 +35,6 @@ import (
"github.com/jaytaylor/html2text" "github.com/jaytaylor/html2text"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gitlab.protontech.ch/go/liteapi"
) )
type MIMEBody string type MIMEBody string
@ -559,7 +559,7 @@ func parseAttachment(h message.Header, body []byte) (Attachment, error) {
return Attachment{}, err return Attachment{}, err
} }
if disp == string(liteapi.InlineDisposition) { if disp == string(proton.InlineDisposition) {
att.ContentID = strings.Trim(h.Get("Content-Id"), " <>") att.ContentID = strings.Trim(h.Get("Content-Id"), " <>")
} }
} else if h.Has("Content-Id") { } else if h.Has("Content-Id") {

View File

@ -26,9 +26,9 @@ import (
"unicode/utf8" "unicode/utf8"
"github.com/ProtonMail/gluon/rfc822" "github.com/ProtonMail/gluon/rfc822"
"github.com/ProtonMail/go-proton-api"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gitlab.protontech.ch/go/liteapi"
"golang.org/x/net/html/charset" "golang.org/x/net/html/charset"
"golang.org/x/text/encoding" "golang.org/x/text/encoding"
"golang.org/x/text/encoding/htmlindex" "golang.org/x/text/encoding/htmlindex"
@ -36,7 +36,7 @@ import (
func init() { func init() {
rfc822.ParseMediaType = ParseMediaType rfc822.ParseMediaType = ParseMediaType
liteapi.CharsetReader = CharsetReader proton.CharsetReader = CharsetReader
} }
func CharsetReader(charset string, input io.Reader) (io.Reader, error) { func CharsetReader(charset string, input io.Reader) (io.Reader, error) {

View File

@ -27,8 +27,10 @@ import (
"golang.org/x/sys/execabs" "golang.org/x/sys/execabs"
) )
const BridgeCrashCount = "BRIDGE_CRASH_COUNT" const (
const MaxCrashRestarts = 10 BridgeCrashCount = "BRIDGE_CRASH_COUNT"
MaxCrashRestarts = 10
)
type Restarter struct { type Restarter struct {
restart bool restart bool

View File

@ -19,8 +19,8 @@ package tests
import ( import (
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"gitlab.protontech.ch/go/liteapi" "github.com/ProtonMail/go-proton-api"
"gitlab.protontech.ch/go/liteapi/server" "github.com/ProtonMail/go-proton-api/server"
) )
type API interface { type API interface {
@ -36,7 +36,7 @@ type API interface {
RemoveAddress(userID, addrID string) error RemoveAddress(userID, addrID string) error
RemoveAddressKey(userID, addrID, keyID string) error RemoveAddressKey(userID, addrID, keyID string) error
UpdateDraft(userID, draftID string, changes liteapi.DraftTemplate) error UpdateDraft(userID, draftID string, changes proton.DraftTemplate) error
Close() Close()
} }

View File

@ -30,6 +30,7 @@ import (
"time" "time"
"github.com/ProtonMail/gluon/queue" "github.com/ProtonMail/gluon/queue"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/proton-bridge/v2/internal/bridge" "github.com/ProtonMail/proton-bridge/v2/internal/bridge"
"github.com/ProtonMail/proton-bridge/v2/internal/constants" "github.com/ProtonMail/proton-bridge/v2/internal/constants"
"github.com/ProtonMail/proton-bridge/v2/internal/cookies" "github.com/ProtonMail/proton-bridge/v2/internal/cookies"
@ -38,7 +39,6 @@ import (
"github.com/ProtonMail/proton-bridge/v2/internal/useragent" "github.com/ProtonMail/proton-bridge/v2/internal/useragent"
"github.com/ProtonMail/proton-bridge/v2/internal/vault" "github.com/ProtonMail/proton-bridge/v2/internal/vault"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gitlab.protontech.ch/go/liteapi"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
"google.golang.org/grpc/metadata" "google.golang.org/grpc/metadata"
@ -157,7 +157,7 @@ func (t *testCtx) initBridge() (<-chan events.Event, error) {
persister, persister,
useragent.New(), useragent.New(),
t.mocks.TLSReporter, t.mocks.TLSReporter,
liteapi.NewDialer(t.netCtl, &tls.Config{InsecureSkipVerify: true}).GetRoundTripper(), proton.NewDialer(t.netCtl, &tls.Config{InsecureSkipVerify: true}).GetRoundTripper(),
t.mocks.ProxyCtl, t.mocks.ProxyCtl,
t.mocks.CrashHandler, t.mocks.CrashHandler,
t.reporter, t.reporter,

View File

@ -25,19 +25,19 @@ import (
"testing" "testing"
"github.com/ProtonMail/gluon/reporter" "github.com/ProtonMail/gluon/reporter"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/bradenaw/juniper/stream" "github.com/bradenaw/juniper/stream"
"github.com/bradenaw/juniper/xslices" "github.com/bradenaw/juniper/xslices"
"github.com/golang/mock/gomock" "github.com/golang/mock/gomock"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"gitlab.protontech.ch/go/liteapi"
) )
func (t *testCtx) withClient(ctx context.Context, username string, fn func(context.Context, *liteapi.Client) error) error { func (t *testCtx) withClient(ctx context.Context, username string, fn func(context.Context, *proton.Client) error) error {
c, _, err := liteapi.New( c, _, err := proton.New(
liteapi.WithHostURL(t.api.GetHostURL()), proton.WithHostURL(t.api.GetHostURL()),
liteapi.WithTransport(liteapi.InsecureTransport()), proton.WithTransport(proton.InsecureTransport()),
).NewClientWithLogin(ctx, username, []byte(t.getUserPass(t.getUserID(username)))) ).NewClientWithLogin(ctx, username, []byte(t.getUserPass(t.getUserID(username))))
if err != nil { if err != nil {
return err return err
@ -58,7 +58,7 @@ func (t *testCtx) withClient(ctx context.Context, username string, fn func(conte
func (t *testCtx) withAddrKR( func (t *testCtx) withAddrKR(
ctx context.Context, ctx context.Context,
c *liteapi.Client, c *proton.Client,
username, addrID string, username, addrID string,
fn func(context.Context, *crypto.KeyRing) error, fn func(context.Context, *crypto.KeyRing) error,
) error { ) error {
@ -82,7 +82,7 @@ func (t *testCtx) withAddrKR(
return err return err
} }
_, addrKRs, err := liteapi.Unlock(user, addr, keyPass) _, addrKRs, err := proton.Unlock(user, addr, keyPass)
if err != nil { if err != nil {
return err return err
} }
@ -90,8 +90,8 @@ func (t *testCtx) withAddrKR(
return fn(ctx, addrKRs[addrID]) return fn(ctx, addrKRs[addrID])
} }
func (t *testCtx) createMessages(ctx context.Context, username, addrID string, req []liteapi.ImportReq) error { func (t *testCtx) createMessages(ctx context.Context, username, addrID string, req []proton.ImportReq) error {
return t.withClient(ctx, username, func(ctx context.Context, c *liteapi.Client) error { return t.withClient(ctx, username, func(ctx context.Context, c *proton.Client) error {
return t.withAddrKR(ctx, c, username, addrID, func(ctx context.Context, addrKR *crypto.KeyRing) error { return t.withAddrKR(ctx, c, username, addrID, func(ctx context.Context, addrKR *crypto.KeyRing) error {
if _, err := stream.Collect(ctx, c.ImportMessages( if _, err := stream.Collect(ctx, c.ImportMessages(
ctx, ctx,

View File

@ -27,6 +27,8 @@ import (
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/ProtonMail/gluon/queue" "github.com/ProtonMail/gluon/queue"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/go-proton-api/server"
"github.com/ProtonMail/proton-bridge/v2/internal/bridge" "github.com/ProtonMail/proton-bridge/v2/internal/bridge"
frontend "github.com/ProtonMail/proton-bridge/v2/internal/frontend/grpc" frontend "github.com/ProtonMail/proton-bridge/v2/internal/frontend/grpc"
"github.com/ProtonMail/proton-bridge/v2/internal/locations" "github.com/ProtonMail/proton-bridge/v2/internal/locations"
@ -34,8 +36,6 @@ import (
"github.com/emersion/go-imap/client" "github.com/emersion/go-imap/client"
"github.com/golang/mock/gomock" "github.com/golang/mock/gomock"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gitlab.protontech.ch/go/liteapi"
"gitlab.protontech.ch/go/liteapi/server"
"golang.org/x/exp/maps" "golang.org/x/exp/maps"
"google.golang.org/grpc" "google.golang.org/grpc"
) )
@ -46,7 +46,7 @@ type testCtx struct {
// These are the objects supporting the test. // These are the objects supporting the test.
dir string dir string
api API api API
netCtl *liteapi.NetCtl netCtl *proton.NetCtl
locator *locations.Locations locator *locations.Locations
storeKey []byte storeKey []byte
version *semver.Version version *semver.Version
@ -101,7 +101,7 @@ func newTestCtx(tb testing.TB) *testCtx {
t := &testCtx{ t := &testCtx{
dir: dir, dir: dir,
api: newFakeAPI(), api: newFakeAPI(),
netCtl: liteapi.NewNetCtl(), netCtl: proton.NewNetCtl(),
locator: locations.New(bridge.NewTestLocationsProvider(dir), "config-name"), locator: locations.New(bridge.NewTestLocationsProvider(dir), "config-name"),
storeKey: []byte("super-secret-store-key"), storeKey: []byte("super-secret-store-key"),
version: defaultVersion, version: defaultVersion,
@ -203,13 +203,13 @@ func (t *testCtx) getMBoxID(userID string, name string) string {
var labelID string var labelID string
if err := t.withClient(ctx, t.getName(userID), func(ctx context.Context, client *liteapi.Client) error { if err := t.withClient(ctx, t.getName(userID), func(ctx context.Context, client *proton.Client) error {
labels, err := client.GetLabels(ctx, liteapi.LabelTypeLabel, liteapi.LabelTypeFolder, liteapi.LabelTypeSystem) labels, err := client.GetLabels(ctx, proton.LabelTypeLabel, proton.LabelTypeFolder, proton.LabelTypeSystem)
if err != nil { if err != nil {
panic(err) panic(err)
} }
idx := xslices.IndexFunc(labels, func(label liteapi.Label) bool { idx := xslices.IndexFunc(labels, func(label proton.Label) bool {
return label.Name == name return label.Name == name
}) })
@ -240,9 +240,9 @@ func (t *testCtx) getDraftID(username string, draftIndex int) string {
var draftID string var draftID string
if err := t.withClient(ctx, username, func(ctx context.Context, client *liteapi.Client) error { if err := t.withClient(ctx, username, func(ctx context.Context, client *proton.Client) error {
messages, err := client.GetMessageMetadata( messages, err := client.GetMessageMetadata(
ctx, liteapi.MessageFilter{LabelID: liteapi.DraftsLabel}, ctx, proton.MessageFilter{LabelID: proton.DraftsLabel},
) )
if err != nil { if err != nil {
panic(err) panic(err)

View File

@ -20,9 +20,9 @@ package tests
import ( import (
"time" "time"
"github.com/ProtonMail/go-proton-api/server/backend"
"github.com/ProtonMail/proton-bridge/v2/internal/certs" "github.com/ProtonMail/proton-bridge/v2/internal/certs"
"github.com/ProtonMail/proton-bridge/v2/internal/user" "github.com/ProtonMail/proton-bridge/v2/internal/user"
"gitlab.protontech.ch/go/liteapi/server/backend"
) )
func init() { func init() {

View File

@ -23,13 +23,13 @@ import (
"fmt" "fmt"
"net/mail" "net/mail"
"github.com/ProtonMail/go-proton-api"
"github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/ProtonMail/proton-bridge/v2/internal/bridge" "github.com/ProtonMail/proton-bridge/v2/internal/bridge"
"github.com/bradenaw/juniper/iterator" "github.com/bradenaw/juniper/iterator"
"github.com/bradenaw/juniper/xslices" "github.com/bradenaw/juniper/xslices"
"github.com/cucumber/godog" "github.com/cucumber/godog"
"github.com/google/uuid" "github.com/google/uuid"
"gitlab.protontech.ch/go/liteapi"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
) )
@ -82,11 +82,11 @@ func (s *scenario) theAccountHasCustomFolders(username string, count int) error
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
return s.t.withClient(ctx, username, func(ctx context.Context, client *liteapi.Client) error { return s.t.withClient(ctx, username, func(ctx context.Context, client *proton.Client) error {
for idx := 0; idx < count; idx++ { for idx := 0; idx < count; idx++ {
if _, err := client.CreateLabel(ctx, liteapi.CreateLabelReq{ if _, err := client.CreateLabel(ctx, proton.CreateLabelReq{
Name: uuid.NewString(), Name: uuid.NewString(),
Type: liteapi.LabelTypeFolder, Type: proton.LabelTypeFolder,
}); err != nil { }); err != nil {
return err return err
} }
@ -100,11 +100,11 @@ func (s *scenario) theAccountHasCustomLabels(username string, count int) error {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
return s.t.withClient(ctx, username, func(ctx context.Context, client *liteapi.Client) error { return s.t.withClient(ctx, username, func(ctx context.Context, client *proton.Client) error {
for idx := 0; idx < count; idx++ { for idx := 0; idx < count; idx++ {
if _, err := client.CreateLabel(ctx, liteapi.CreateLabelReq{ if _, err := client.CreateLabel(ctx, proton.CreateLabelReq{
Name: uuid.NewString(), Name: uuid.NewString(),
Type: liteapi.LabelTypeLabel, Type: proton.LabelTypeLabel,
}); err != nil { }); err != nil {
return err return err
} }
@ -128,19 +128,19 @@ func (s *scenario) theAccountHasTheFollowingCustomMailboxes(username string, tab
return err return err
} }
return s.t.withClient(ctx, username, func(ctx context.Context, client *liteapi.Client) error { return s.t.withClient(ctx, username, func(ctx context.Context, client *proton.Client) error {
for _, wantMailbox := range wantMailboxes { for _, wantMailbox := range wantMailboxes {
var labelType liteapi.LabelType var labelType proton.LabelType
switch wantMailbox.Type { switch wantMailbox.Type {
case "folder": case "folder":
labelType = liteapi.LabelTypeFolder labelType = proton.LabelTypeFolder
case "label": case "label":
labelType = liteapi.LabelTypeLabel labelType = proton.LabelTypeLabel
} }
if _, err := client.CreateLabel(ctx, liteapi.CreateLabelReq{ if _, err := client.CreateLabel(ctx, proton.CreateLabelReq{
Name: wantMailbox.Name, Name: wantMailbox.Name,
Type: labelType, Type: labelType,
}); err != nil { }); err != nil {
@ -165,13 +165,13 @@ func (s *scenario) theAddressOfAccountHasTheFollowingMessagesInMailbox(address,
return err return err
} }
return s.t.createMessages(ctx, username, addrID, xslices.Map(wantMessages, func(message Message) liteapi.ImportReq { return s.t.createMessages(ctx, username, addrID, xslices.Map(wantMessages, func(message Message) proton.ImportReq {
return liteapi.ImportReq{ return proton.ImportReq{
Metadata: liteapi.ImportMetadata{ Metadata: proton.ImportMetadata{
AddressID: addrID, AddressID: addrID,
LabelIDs: []string{mboxID}, LabelIDs: []string{mboxID},
Unread: liteapi.Bool(message.Unread), Unread: proton.Bool(message.Unread),
Flags: liteapi.MessageFlagReceived, Flags: proton.MessageFlagReceived,
}, },
Message: message.Build(), Message: message.Build(),
} }
@ -186,12 +186,12 @@ func (s *scenario) theAddressOfAccountHasMessagesInMailbox(address, username str
addrID := s.t.getUserAddrID(userID, address) addrID := s.t.getUserAddrID(userID, address)
mboxID := s.t.getMBoxID(userID, mailbox) mboxID := s.t.getMBoxID(userID, mailbox)
return s.t.createMessages(ctx, username, addrID, iterator.Collect(iterator.Map(iterator.Counter(count), func(idx int) liteapi.ImportReq { return s.t.createMessages(ctx, username, addrID, iterator.Collect(iterator.Map(iterator.Counter(count), func(idx int) proton.ImportReq {
return liteapi.ImportReq{ return proton.ImportReq{
Metadata: liteapi.ImportMetadata{ Metadata: proton.ImportMetadata{
AddressID: addrID, AddressID: addrID,
LabelIDs: []string{mboxID}, LabelIDs: []string{mboxID},
Flags: liteapi.MessageFlagReceived, Flags: proton.MessageFlagReceived,
}, },
Message: Message{ Message: Message{
Subject: fmt.Sprintf("%d", idx), Subject: fmt.Sprintf("%d", idx),
@ -207,7 +207,7 @@ func (s *scenario) theAddressOfAccountHasNoKeys(address, username string) error
userID := s.t.getUserID(username) userID := s.t.getUserID(username)
addrID := s.t.getUserAddrID(userID, address) addrID := s.t.getUserAddrID(userID, address)
return s.t.withClient(context.Background(), username, func(ctx context.Context, client *liteapi.Client) error { return s.t.withClient(context.Background(), username, func(ctx context.Context, client *proton.Client) error {
address, err := client.GetAddress(ctx, addrID) address, err := client.GetAddress(ctx, addrID)
if err != nil { if err != nil {
return err return err
@ -244,11 +244,11 @@ func (s *scenario) addressDraftChanged(draftIndex int, address, username string,
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
if err := s.t.withClient(ctx, username, func(ctx context.Context, c *liteapi.Client) error { if err := s.t.withClient(ctx, username, func(ctx context.Context, c *proton.Client) error {
return s.t.withAddrKR(ctx, c, username, s.t.getUserAddrID(s.t.getUserID(username), address), return s.t.withAddrKR(ctx, c, username, s.t.getUserAddrID(s.t.getUserID(username), address),
func(ctx context.Context, addrKR *crypto.KeyRing) error { func(ctx context.Context, addrKR *crypto.KeyRing) error {
var err error var err error
encBody, err = liteapi.EncryptRFC822(addrKR, wantMessages[0].Build()) encBody, err = proton.EncryptRFC822(addrKR, wantMessages[0].Build())
return err return err
}) })
}); err != nil { }); err != nil {
@ -256,7 +256,7 @@ func (s *scenario) addressDraftChanged(draftIndex int, address, username string,
} }
} }
changes := liteapi.DraftTemplate{ changes := proton.DraftTemplate{
Subject: wantMessages[0].Subject, Subject: wantMessages[0].Subject,
Body: string(encBody), Body: string(encBody),
} }