@@ -28,8 +28,8 @@ use crate::constants::NON_ALPHANUMERIC_WITHOUT_DOT;
2828use crate :: context:: Context ;
2929use crate :: imap:: Imap ;
3030use crate :: log:: warn;
31- use crate :: login_param:: EnteredCertificateChecks ;
3231pub use crate :: login_param:: EnteredLoginParam ;
32+ use crate :: login_param:: { EnteredCertificateChecks , Transport } ;
3333use crate :: message:: Message ;
3434use crate :: net:: proxy:: ProxyConfig ;
3535use crate :: oauth2:: get_oauth2_addr;
@@ -110,6 +110,7 @@ impl Context {
110110 /// from a server encoded in a QR code.
111111 /// - [Self::list_transports()] to get a list of all configured transports.
112112 /// - [Self::delete_transport()] to remove a transport.
113+ /// - [Self::set_transport_unpublished()] to set whether contacts see this transport.
113114 pub async fn add_or_update_transport ( & self , param : & mut EnteredLoginParam ) -> Result < ( ) > {
114115 self . stop_io ( ) . await ;
115116 let result = self . add_transport_inner ( param) . await ;
@@ -188,14 +189,22 @@ impl Context {
188189 /// Returns the list of all email accounts that are used as a transport in the current profile.
189190 /// Use [Self::add_or_update_transport()] to add or change a transport
190191 /// and [Self::delete_transport()] to delete a transport.
191- pub async fn list_transports ( & self ) -> Result < Vec < EnteredLoginParam > > {
192+ pub async fn list_transports ( & self ) -> Result < Vec < Transport > > {
192193 let transports = self
193194 . sql
194- . query_map_vec ( "SELECT entered_param FROM transports" , ( ) , |row| {
195- let entered_param: String = row. get ( 0 ) ?;
196- let transport: EnteredLoginParam = serde_json:: from_str ( & entered_param) ?;
197- Ok ( transport)
198- } )
195+ . query_map_vec (
196+ "SELECT entered_param, is_published FROM transports" ,
197+ ( ) ,
198+ |row| {
199+ let param: String = row. get ( 0 ) ?;
200+ let param: EnteredLoginParam = serde_json:: from_str ( & param) ?;
201+ let is_published: bool = row. get ( 1 ) ?;
202+ Ok ( Transport {
203+ param,
204+ is_unpublished : !is_published,
205+ } )
206+ } ,
207+ )
199208 . await ?;
200209
201210 Ok ( transports)
@@ -261,6 +270,40 @@ impl Context {
261270 Ok ( ( ) )
262271 }
263272
273+ /// Change whether the transport is unpublished.
274+ ///
275+ /// Unpublished transports are not advertised to contacts,
276+ /// and self-sent messages are not sent there,
277+ /// so that we don't cause extra messages to the corresponding inbox,
278+ /// but can still receive messages from contacts who don't know the new relay addresses yet.
279+ ///
280+ /// The default is true, but when updating,
281+ /// existing secondary transports are set to unpublished,
282+ /// so that an existing transport address doesn't suddenly get spammed with a lot of messages.
283+ pub async fn set_transport_unpublished ( & self , addr : & str , unpublished : bool ) -> Result < ( ) > {
284+ // We need to update the timestamp so that the key's timestamp changes
285+ // and is recognized as newer by our peers
286+ self . sql
287+ . transaction ( |trans| {
288+ let primary_addr: String = trans. query_row (
289+ "SELECT value FROM config WHERE keyname='configured_addr'" ,
290+ ( ) ,
291+ |row| row. get ( 0 ) ,
292+ ) ?;
293+ if primary_addr == addr && unpublished {
294+ bail ! ( "Can't set primary relay as unpublished" ) ;
295+ }
296+ trans. execute (
297+ "UPDATE transports SET is_published=?, add_timestamp=? WHERE addr=?" ,
298+ ( !unpublished, time ( ) , addr) ,
299+ ) ?;
300+ Ok ( ( ) )
301+ } )
302+ . await ?;
303+ send_sync_transports ( self ) . await ?;
304+ Ok ( ( ) )
305+ }
306+
264307 async fn inner_configure ( & self , param : & EnteredLoginParam ) -> Result < ( ) > {
265308 info ! ( self , "Configure ..." ) ;
266309
0 commit comments