@ -549,99 +549,31 @@ public final class SnodeAPI {
. eraseToAnyPublisher ( )
}
public static func getExpiries (
from snode : Snode ,
public static func preparedGetExpiries (
of serverHashes : [ String ] ,
authInfo : AuthenticationInfo ,
using dependencies : Dependencies = Dependencies ( )
) -> AnyPublisher < ( ResponseInfoType , GetExpiriesResponse ) , Error > {
let sendTimestamp : UInt64 = UInt64 ( SnodeAPI . currentOffsetTimestampMs ( using : dependencies ) )
) throws -> HTTP . PreparedRequest < GetExpiriesResponse > {
// FIXME: T h e r e i s a b u g o n S S n o w t h a t a s i n g l e - h a s h l o o k u p i s n o t w o r k i n g . R e m o v e i t w h e n t h e b u g i s f i x e d
let serverHashes : [ String ] = serverHashes . appending ( " fakehash " )
return SnodeAPI
. send (
request : Snode Request(
return try SnodeAPI
. prepareRequest (
request : Request(
endpoint : . getExpiries ,
publicKey : authInfo . sessionId . hexString ,
body : GetExpiriesRequest (
messageHashes : serverHashes ,
authInfo : authInfo ,
timestampMs : sendTimestamp
timestampMs : UInt64 ( SnodeAPI . currentOffsetTimestampMs ( using : dependencies ) )
)
) ,
to : snode ,
associatedWith : authInfo . sessionId . hexString ,
using : dependencies
responseType : GetExpiriesResponse . self
)
. decoded ( as : GetExpiriesResponse . self , using : dependencies )
. eraseToAnyPublisher ( )
}
// MARK: - S t o r e
public static func sendMessage (
_ message : SnodeMessage ,
in namespace : Namespace ,
authInfo : AuthenticationInfo ,
using dependencies : Dependencies
) -> AnyPublisher < ( ResponseInfoType , SendMessagesResponse ) , Error > {
let sendTimestamp : UInt64 = UInt64 ( SnodeAPI . currentOffsetTimestampMs ( using : dependencies ) )
// C r e a t e a c o n v e n i e n c e m e t h o d t o s e n d a m e s s a g e t o a n i n d i v i d u a l S n o d e
func sendMessage ( to snode : Snode ) throws -> AnyPublisher < ( any ResponseInfoType , SendMessagesResponse ) , Error > {
guard namespace . requiresWriteAuthentication else {
return SnodeAPI
. send (
request : SnodeRequest (
endpoint : . sendMessage ,
body : LegacySendMessagesRequest (
message : message ,
namespace : namespace
)
) ,
to : snode ,
associatedWith : authInfo . sessionId . hexString ,
using : dependencies
)
. decoded ( as : SendMessagesResponse . self , using : dependencies )
. eraseToAnyPublisher ( )
}
return SnodeAPI
. send (
request : SnodeRequest (
endpoint : . sendMessage ,
body : SendMessageRequest (
message : message ,
namespace : namespace ,
authInfo : authInfo ,
timestampMs : sendTimestamp
)
) ,
to : snode ,
associatedWith : authInfo . sessionId . hexString ,
using : dependencies
)
. decoded ( as : SendMessagesResponse . self , using : dependencies )
. eraseToAnyPublisher ( )
}
return getSwarm ( for : authInfo . sessionId . hexString )
. tryFlatMapWithRandomSnode ( retry : maxRetryCount ) { snode -> AnyPublisher < ( ResponseInfoType , SendMessagesResponse ) , Error > in
try sendMessage ( to : snode )
. tryMap { info , response -> ( ResponseInfoType , SendMessagesResponse ) in
try response . validateResultMap (
publicKey : authInfo . sessionId . hexString ,
using : dependencies
)
return ( info , response )
}
. eraseToAnyPublisher ( )
}
}
public static func preparedSendMessage (
_ db : Database ,
message : SnodeMessage ,
@ -693,131 +625,70 @@ public final class SnodeAPI {
// MARK: - E d i t
public static func u pdateExpiry(
public static func preparedU pdateExpiry(
serverHashes : [ String ] ,
updatedExpiryMs : Int64 ,
shortenOnly : Bool ? = nil ,
extendOnly : Bool ? = nil ,
authInfo : AuthenticationInfo ,
using dependencies : Dependencies = Dependencies ( )
) -> AnyPublisher < [ String : UpdateExpiryResponseResult ] , Error > {
) throws -> HTTP . PreparedRequest < [ String : UpdateExpiryResponseResult ] > {
// S h o r t e n O n l y a n d e x t e n d O n l y c a n n o t b e t r u e a t t h e s a m e t i m e
guard shortenOnly = = nil || extendOnly = = nil else {
return Fail ( error : SnodeAPIError . generic )
. eraseToAnyPublisher ( )
}
guard shortenOnly = = nil || extendOnly = = nil else { throw SnodeAPIError . generic }
return getSwarm ( for : authInfo . sessionId . hexString )
. tryFlatMapWithRandomSnode ( retry : maxRetryCount ) { snode -> AnyPublisher < [ String : UpdateExpiryResponseResult ] , Error > in
SnodeAPI
. send (
request : SnodeRequest (
endpoint : . expire ,
body : UpdateExpiryRequest (
messageHashes : serverHashes ,
expiryMs : UInt64 ( updatedExpiryMs ) ,
shorten : shortenOnly ,
extend : extendOnly ,
authInfo : authInfo
)
) ,
to : snode ,
associatedWith : authInfo . sessionId . hexString ,
using : dependencies
return try SnodeAPI
. prepareRequest (
request : Request (
endpoint : . expire ,
publicKey : authInfo . sessionId . hexString ,
body : UpdateExpiryRequest (
messageHashes : serverHashes ,
expiryMs : UInt64 ( updatedExpiryMs ) ,
shorten : shortenOnly ,
extend : extendOnly ,
authInfo : authInfo
)
. decoded ( as : UpdateExpiryResponse . self , using : dependencies )
. tryMap { _ , response -> [ String : UpdateExpiryResponseResult ] in
try response . validResultMap (
publicKey : authInfo . sessionId . hexString ,
validationData : serverHashes ,
using : dependencies
)
}
. eraseToAnyPublisher ( )
) ,
responseType : UpdateExpiryResponse . self
)
. tryMap { _ , response -> [ String : UpdateExpiryResponseResult ] in
try response . validResultMap (
publicKey : authInfo . sessionId . hexString ,
validationData : serverHashes ,
using : dependencies
)
}
}
public static func revokeSubkey(
public static func p reparedR evokeSubkey(
subkeyToRevoke : String ,
authInfo : AuthenticationInfo ,
using dependencies : Dependencies = Dependencies ( )
) -> AnyPublisher < Void , Error > {
return getSwarm ( for : authInfo . sessionId . hexString )
. tryFlatMapWithRandomSnode ( retry : maxRetryCount ) { snode -> AnyPublisher < Void , Error > in
SnodeAPI
. send (
request : SnodeRequest (
endpoint : . revokeSubkey ,
body : RevokeSubkeyRequest (
subkeyToRevoke : subkeyToRevoke ,
authInfo : authInfo
)
) ,
to : snode ,
associatedWith : authInfo . sessionId . hexString ,
using : dependencies
) throws -> HTTP . PreparedRequest < Void > {
return try SnodeAPI
. prepareRequest (
request : Request (
endpoint : . revokeSubkey ,
publicKey : authInfo . sessionId . hexString ,
body : RevokeSubkeyRequest (
subkeyToRevoke : subkeyToRevoke ,
authInfo : authInfo
)
. decoded ( as : RevokeSubkeyResponse . self , using : dependencies )
. tryMap { _ , response -> Void in
try response . validateResultMap (
publicKey : authInfo . sessionId . hexString ,
validationData : subkeyToRevoke ,
using : dependencies
)
return ( )
}
. eraseToAnyPublisher ( )
) ,
responseType : RevokeSubkeyResponse . self
)
. tryMap { _ , response -> Void in
try response . validateResultMap (
publicKey : authInfo . sessionId . hexString ,
validationData : subkeyToRevoke ,
using : dependencies
)
return ( )
}
}
// MARK: D e l e t e
public static func deleteMessages (
serverHashes : [ String ] ,
authInfo : AuthenticationInfo ,
using dependencies : Dependencies = Dependencies ( )
) -> AnyPublisher < [ String : Bool ] , Error > {
return getSwarm ( for : authInfo . sessionId . hexString , using : dependencies )
. tryFlatMapWithRandomSnode ( retry : maxRetryCount ) { snode -> AnyPublisher < [ String : Bool ] , Error > in
SnodeAPI
. send (
request : SnodeRequest (
endpoint : . deleteMessages ,
body : DeleteMessagesRequest (
messageHashes : serverHashes ,
requireSuccessfulDeletion : false ,
authInfo : authInfo
)
) ,
to : snode ,
associatedWith : authInfo . sessionId . hexString ,
using : dependencies
)
. decoded ( as : DeleteMessagesResponse . self , using : dependencies )
. tryMap { _ , response -> [ String : Bool ] in
let validResultMap : [ String : Bool ] = try response . validResultMap (
publicKey : authInfo . sessionId . hexString ,
validationData : serverHashes ,
using : dependencies
)
// I f ` v a l i d R e s u l t M a p ` d i d n ' t t h r o w t h e n a t l e a s t o n e s e r v i c e n o d e
// d e l e t e d s u c c e s s f u l l y s o w e s h o u l d m a r k t h e h a s h a s i n v a l i d s o w e
// d o n ' t t r y t o f e t c h u p d a t e s u s i n g t h a t h a s h g o i n g f o r w a r d ( i f w e
// d o w e w o u l d e n d u p r e - f e t c h i n g a l l o l d m e s s a g e s )
dependencies [ singleton : . storage ] . writeAsync { db in
try ? SnodeReceivedMessageInfo . handlePotentialDeletedOrInvalidHash (
db ,
potentiallyInvalidHashes : serverHashes
)
}
return validResultMap
}
. eraseToAnyPublisher ( )
}
}
// MARK: - D e l e t e
public static func preparedDeleteMessages (
serverHashes : [ String ] ,