@ -197,7 +197,7 @@ public final class OpenGroupAPIV2: NSObject {
// MARK: - C a p a b i l i t i e s
public static func capabilities ( on server : String ) -> Promise < ( OnionRequestResponseInfoType , Capabilities ) > {
public static func capabilities ( on server : String , using dependencies : Dependencies = Dependencies ( ) ) -> Promise < ( OnionRequestResponseInfoType , Capabilities ) > {
let request : Request = Request (
server : server ,
endpoint : . capabilities ,
@ -205,45 +205,39 @@ public final class OpenGroupAPIV2: NSObject {
)
// TODO: H a n d l e a ` 4 1 2 ` r e s p o n s e ( i e . a r e q u i r e d c a p a b i l i t y i s n ' t s u p p o r t e d ) .
return send ( request )
return send ( request , using : dependencies )
. decoded ( as : Capabilities . self , on : OpenGroupAPIV2 . workQueue , error : Error . parsingFailed )
}
// MARK: - R o o m
public static func rooms (
for server : String ,
through api : OnionRequestAPIType . Type = OnionRequestAPI . self ,
using storage : SessionMessagingKitStorageProtocol = SNMessagingKitConfiguration . shared . storage ,
nonceGenerator : NonceGenerator16ByteType = NonceGenerator16Byte ( ) ,
date : Date = Date ( )
) -> Promise < ( OnionRequestResponseInfoType , [ Room ] ) > {
public static func rooms ( for server : String , using dependencies : Dependencies = Dependencies ( ) ) -> Promise < ( OnionRequestResponseInfoType , [ Room ] ) > {
let request : Request = Request (
server : server ,
endpoint : . rooms
)
return send ( request , through: api , using : storage , nonceGenerator : nonceGenerator , date : date )
return send ( request , using : dependencies )
. decoded ( as : [ Room ] . self , on : OpenGroupAPIV2 . workQueue , error : Error . parsingFailed )
}
public static func room ( for roomToken : String , on server : String ) -> Promise < ( OnionRequestResponseInfoType , Room ) > {
public static func room ( for roomToken : String , on server : String , using dependencies : Dependencies = Dependencies ( ) ) -> Promise < ( OnionRequestResponseInfoType , Room ) > {
let request : Request = Request (
server : server ,
endpoint : . room ( roomToken )
)
return send ( request )
return send ( request , using : dependencies )
. decoded ( as : Room . self , on : OpenGroupAPIV2 . workQueue , error : Error . parsingFailed )
}
public static func roomPollInfo ( lastUpdated : Int64 , for roomToken : String , on server : String ) -> Promise < ( OnionRequestResponseInfoType , RoomPollInfo ) > {
public static func roomPollInfo ( lastUpdated : Int64 , for roomToken : String , on server : String , using dependencies : Dependencies = Dependencies ( ) ) -> Promise < ( OnionRequestResponseInfoType , RoomPollInfo ) > {
let request : Request = Request (
server : server ,
endpoint : . roomPollInfo ( roomToken , lastUpdated )
)
return send ( request )
return send ( request , using : dependencies )
. decoded ( as : RoomPollInfo . self , on : OpenGroupAPIV2 . workQueue , error : Error . parsingFailed )
}
@ -255,7 +249,8 @@ public final class OpenGroupAPIV2: NSObject {
on server : String ,
whisperTo : String ? ,
whisperMods : Bool ,
with serverPublicKey : String
with serverPublicKey : String ,
using dependencies : Dependencies = Dependencies ( )
) -> Promise < ( OnionRequestResponseInfoType , Message ) > {
// TODO: C h a n g e t h i s t o u s e ' . b l i n d e d ' o n c e i t ' s w o r k i n g .
guard let signedRequest : ( data : Data , signature : Data ) = SendMessageRequest . sign ( message : plaintext , for : . standard , with : serverPublicKey ) else {
@ -281,12 +276,11 @@ public final class OpenGroupAPIV2: NSObject {
body : body
)
return send ( request )
return send ( request , using : dependencies )
. decoded ( as : Message . self , on : OpenGroupAPIV2 . workQueue , error : Error . parsingFailed )
}
public static func recentMessages ( in roomToken : String , on server : String ) -> Promise < ( OnionRequestResponseInfoType , [ Message ] ) > {
// TODO: R e c e n t v s . S i n c e ?
public static func recentMessages ( in roomToken : String , on server : String , using dependencies : Dependencies = Dependencies ( ) ) -> Promise < ( OnionRequestResponseInfoType , [ Message ] ) > {
let request : Request = Request (
server : server ,
endpoint : . roomMessagesRecent ( roomToken )
@ -296,15 +290,15 @@ public final class OpenGroupAPIV2: NSObject {
// ] . c o m p a c t M a p V a l u e s { $ 0 }
)
return send ( request )
return send ( request , using : dependencies )
. decoded ( as : [ Message ] . self , on : OpenGroupAPIV2 . workQueue , error : Error . parsingFailed )
. then ( on : OpenGroupAPIV2 . workQueue ) { responseInfo , messages -> Promise < ( OnionRequestResponseInfoType , [ Message ] ) > in
process ( messages : messages , for : roomToken , on : server )
process ( messages : messages , for : roomToken , on : server , using : dependencies )
. map { processedMessages in ( responseInfo , processedMessages ) }
}
}
public static func messagesBefore ( messageId : Int64 , in roomToken : String , on server : String ) -> Promise < ( OnionRequestResponseInfoType , [ Message ] ) > {
public static func messagesBefore ( messageId : Int64 , in roomToken : String , on server : String , using dependencies : Dependencies = Dependencies ( ) ) -> Promise < ( OnionRequestResponseInfoType , [ Message ] ) > {
// TODO: R e c e n t v s . S i n c e ?
let request : Request = Request (
server : server ,
@ -315,10 +309,10 @@ public final class OpenGroupAPIV2: NSObject {
// ] . c o m p a c t M a p V a l u e s { $ 0 }
)
return send ( request )
return send ( request , using : dependencies )
. decoded ( as : [ Message ] . self , on : OpenGroupAPIV2 . workQueue , error : Error . parsingFailed )
. then ( on : OpenGroupAPIV2 . workQueue ) { responseInfo , messages -> Promise < ( OnionRequestResponseInfoType , [ Message ] ) > in
process ( messages : messages , for : roomToken , on : server )
process ( messages : messages , for : roomToken , on : server , using : dependencies )
. map { processedMessages in ( responseInfo , processedMessages ) }
}
}
@ -334,53 +328,53 @@ public final class OpenGroupAPIV2: NSObject {
// ] . c o m p a c t M a p V a l u e s { $ 0 }
)
return send ( request )
return send ( request , using : dependencies )
. decoded ( as : [ Message ] . self , on : OpenGroupAPIV2 . workQueue , error : Error . parsingFailed )
. then ( on : OpenGroupAPIV2 . workQueue ) { responseInfo , messages -> Promise < ( OnionRequestResponseInfoType , [ Message ] ) > in
process ( messages : messages , for : roomToken , on : server )
process ( messages : messages , for : roomToken , on : server , using : dependencies )
. map { processedMessages in ( responseInfo , processedMessages ) }
}
}
// MARK: - P i n n i n g
public static func pinMessage ( id : Int64 , in roomToken : String , on server : String ) -> Promise < OnionRequestResponseInfoType > {
public static func pinMessage ( id : Int64 , in roomToken : String , on server : String , using dependencies : Dependencies = Dependencies ( ) ) -> Promise < OnionRequestResponseInfoType > {
let request : Request = Request (
method : . post ,
server : server ,
endpoint : . roomPinMessage ( roomToken , id : id )
)
return send ( request )
return send ( request , using : dependencies )
. map { responseInfo , _ in responseInfo }
}
public static func unpinMessage ( id : Int64 , in roomToken : String , on server : String ) -> Promise < OnionRequestResponseInfoType > {
public static func unpinMessage ( id : Int64 , in roomToken : String , on server : String , using dependencies : Dependencies = Dependencies ( ) ) -> Promise < OnionRequestResponseInfoType > {
let request : Request = Request (
method : . post ,
server : server ,
endpoint : . roomUnpinMessage ( roomToken , id : id )
)
return send ( request )
return send ( request , using : dependencies )
. map { responseInfo , _ in responseInfo }
}
public static func unpinAll ( in roomToken : String , on server : String ) -> Promise < OnionRequestResponseInfoType > {
public static func unpinAll ( in roomToken : String , on server : String , using dependencies : Dependencies = Dependencies ( ) ) -> Promise < OnionRequestResponseInfoType > {
let request : Request = Request (
method : . post ,
server : server ,
endpoint : . roomUnpinAll ( roomToken )
)
return send ( request )
return send ( request , using : dependencies )
. map { responseInfo , _ in responseInfo }
}
// MARK: - F i l e s
// TODO: S h i f t t h i s l o g i c t o t h e ` O p e n G r o u p M a n a g e r ` ( m a k e s m o r e s e n s e s i n c e i t ' s n o t A P I l o g i c )
public static func roomImage ( _ fileId : Int64 , for roomToken : String , on server : String ) -> Promise < Data > {
public static func roomImage ( _ fileId : Int64 , for roomToken : String , on server : String , using dependencies : Dependencies = Dependencies ( ) ) -> Promise < Data > {
// N o r m a l l y t h e i m a g e f o r a g i v e n g r o u p i s s t o r e d w i t h t h e g r o u p t h r e a d , s o i t ' s o n l y
// f e t c h e d o n c e . H o w e v e r , o n t h e j o i n o p e n g r o u p s c r e e n w e s h o w i m a g e s f o r g r o u p s t h e
// u s e r * h a s n ' t * j o i n e d y e t . W e d o n ' t w a n t t o r e - f e t c h t h e s e i m a g e s e v e r y t i m e t h e
@ -391,11 +385,11 @@ public final class OpenGroupAPIV2: NSObject {
// d o n ' t d o u b l e u p o n f e t c h r e q u e s t s b y s t o r i n g t h e e x i s t i n g r e q u e s t a s a p r o m i s e i f
// t h e r e i s o n e .
let lastOpenGroupImageUpdate : Date ? = UserDefaults . standard [ . lastOpenGroupImageUpdate ]
let now : Date = Date( )
let now : Date = dependencies. date
let timeSinceLastUpdate : TimeInterval = ( given ( lastOpenGroupImageUpdate ) { now . timeIntervalSince ( $0 ) } ? ? . greatestFiniteMagnitude )
let updateInterval : TimeInterval = ( 7 * 24 * 60 * 60 )
if let data = Storage. shared . getOpenGroupImage ( for : roomToken , on : server ) , server = = defaultServer , timeSinceLastUpdate < updateInterval {
if let data = dependencies. storage . getOpenGroupImage ( for : roomToken , on : server ) , server = = defaultServer , timeSinceLastUpdate < updateInterval {
return Promise . value ( data )
}
@ -403,12 +397,12 @@ public final class OpenGroupAPIV2: NSObject {
return promise
}
let promise : Promise < Data > = downloadFile ( fileId , from : roomToken , on : server )
let promise : Promise < Data > = downloadFile ( fileId , from : roomToken , on : server , using : dependencies )
. map { _ , data in data }
_ = promise . done ( on : OpenGroupAPIV2 . workQueue ) { imageData in
if server = = defaultServer {
Storage. shared . write { transaction in
Storage. shared . setOpenGroupImage ( to : imageData , for : roomToken , on : server , using : transaction )
dependencies. storage . write { transaction in
dependencies. storage . setOpenGroupImage ( to : imageData , for : roomToken , on : server , using : transaction )
}
UserDefaults . standard [ . lastOpenGroupImageUpdate ] = now
}
@ -418,41 +412,41 @@ public final class OpenGroupAPIV2: NSObject {
return promise
}
public static func uploadFile ( _ bytes : [ UInt8 ] , fileName : String ? = nil , to roomToken : String , on server : String ) -> Promise < ( OnionRequestResponseInfoType , FileUploadResponse ) > {
public static func uploadFile ( _ bytes : [ UInt8 ] , fileName : String ? = nil , to roomToken : String , on server : String , using dependencies : Dependencies = Dependencies ( ) ) -> Promise < ( OnionRequestResponseInfoType , FileUploadResponse ) > {
let request : Request = Request (
method : . post ,
server : server ,
endpoint : . roomFile ( roomToken ) ,
queryParamet ers: [ . fileName : fileName ] . compactMapValues { $0 } ,
head ers: [ . fileName : fileName ] . compactMapValues { $0 } ,
body : Data ( bytes )
)
return send ( request )
return send ( request , using : dependencies )
. decoded ( as : FileUploadResponse . self , on : OpenGroupAPIV2 . workQueue , error : Error . parsingFailed )
}
// / W a r n i n g : T h i s a p p r o a c h i s l e s s e f f i c i e n t a s i t e x p e c t s t h e d a t a t o b e b a s e 6 4 E n c o d e d ( w i t h i s 3 3 % l a r g e r t h a n b i n a r y ) , p l e a s e u s e t h e b i n a r y a p p r o a c h
// / w h e n e v e r p o s s i b l e
public static func uploadFile ( _ base64EncodedString : String , fileName : String ? = nil , to roomToken : String , on server : String ) -> Promise < ( OnionRequestResponseInfoType , FileUploadResponse ) > {
public static func uploadFile ( _ base64EncodedString : String , fileName : String ? = nil , to roomToken : String , on server : String , using dependencies : Dependencies = Dependencies ( ) ) -> Promise < ( OnionRequestResponseInfoType , FileUploadResponse ) > {
let request : Request = Request (
method : . post ,
server : server ,
endpoint : . roomFileJson ( roomToken ) ,
queryParamet ers: [ . fileName : fileName ] . compactMapValues { $0 } ,
head ers: [ . fileName : fileName ] . compactMapValues { $0 } ,
body : Data ( base64Encoded : base64EncodedString )
)
return send ( request )
return send ( request , using : dependencies )
. decoded ( as : FileUploadResponse . self , on : OpenGroupAPIV2 . workQueue , error : Error . parsingFailed )
}
public static func downloadFile ( _ fileId : Int64 , from roomToken : String , on server : String ) -> Promise < ( OnionRequestResponseInfoType , Data ) > {
public static func downloadFile ( _ fileId : Int64 , from roomToken : String , on server : String , using dependencies : Dependencies = Dependencies ( ) ) -> Promise < ( OnionRequestResponseInfoType , Data ) > {
let request : Request = Request (
server : server ,
endpoint : . roomFileIndividual ( roomToken , fileId )
)
return send ( request )
return send ( request , using : dependencies )
. map { responseInfo , maybeData in
guard let data : Data = maybeData else { throw Error . parsingFailed }
@ -460,19 +454,19 @@ public final class OpenGroupAPIV2: NSObject {
}
}
public static func downloadFileJson ( _ fileId : Int64 , from roomToken : String , on server : String ) -> Promise < ( OnionRequestResponseInfoType , FileDownloadResponse ) > {
public static func downloadFileJson ( _ fileId : Int64 , from roomToken : String , on server : String , using dependencies : Dependencies = Dependencies ( ) ) -> Promise < ( OnionRequestResponseInfoType , FileDownloadResponse ) > {
let request : Request = Request (
server : server ,
endpoint : . roomFileIndividualJson ( roomToken , fileId )
)
// TODO: T h i s e n d p o i n t i s g e t t i n g r e w r i t t e n t o r e t u r n j u s t d a t a ( p r o p e r t i e s w o u l d c o m e t h r o u g h a s h e a d e r s )
return send ( request )
return send ( request , using : dependencies )
. decoded ( as : FileDownloadResponse . self , on : OpenGroupAPIV2 . workQueue , error : Error . parsingFailed )
}
// MARK: - U s e r s
public static func userBan ( _ sessionId : String , for timeout : TimeInterval ? = nil , from roomTokens : [ String ] ? = nil , on server : String ) -> Promise < ( OnionRequestResponseInfoType , Data ? ) > {
public static func userBan ( _ sessionId : String , for timeout : TimeInterval ? = nil , from roomTokens : [ String ] ? = nil , on server : String , using dependencies : Dependencies = Dependencies ( ) ) -> Promise < ( OnionRequestResponseInfoType , Data ? ) > {
let requestBody : UserBanRequest = UserBanRequest (
rooms : roomTokens ,
global : ( roomTokens = = nil ? true : nil ) ,
@ -490,10 +484,10 @@ public final class OpenGroupAPIV2: NSObject {
body : body
)
return send ( request )
return send ( request , using : dependencies )
}
public static func userUnban ( _ sessionId : String , from roomTokens : [ String ] ? = nil , on server : String ) -> Promise < ( OnionRequestResponseInfoType , Data ? ) > {
public static func userUnban ( _ sessionId : String , from roomTokens : [ String ] ? = nil , on server : String , using dependencies : Dependencies = Dependencies ( ) ) -> Promise < ( OnionRequestResponseInfoType , Data ? ) > {
let requestBody : UserUnbanRequest = UserUnbanRequest (
rooms : roomTokens ,
global : ( roomTokens = = nil ? true : nil )
@ -510,10 +504,10 @@ public final class OpenGroupAPIV2: NSObject {
body : body
)
return send ( request )
return send ( request , using : dependencies )
}
public static func userPermissionUpdate ( _ sessionId : String , read : Bool , write : Bool , upload : Bool , for roomTokens : [ String ] , timeout : TimeInterval , on server : String ) -> Promise < ( OnionRequestResponseInfoType , Data ? ) > {
public static func userPermissionUpdate ( _ sessionId : String , read : Bool , write : Bool , upload : Bool , for roomTokens : [ String ] , timeout : TimeInterval , on server : String , using dependencies : Dependencies = Dependencies ( ) ) -> Promise < ( OnionRequestResponseInfoType , Data ? ) > {
let requestBody : UserPermissionsRequest = UserPermissionsRequest (
rooms : roomTokens ,
timeout : timeout ,
@ -533,10 +527,10 @@ public final class OpenGroupAPIV2: NSObject {
body : body
)
return send ( request )
return send ( request , using : dependencies )
}
public static func userModeratorUpdate ( _ sessionId : String , moderator : Bool , admin : Bool , visible : Bool , for roomTokens : [ String ] ? = nil , on server : String ) -> Promise < ( OnionRequestResponseInfoType , Data ? ) > {
public static func userModeratorUpdate ( _ sessionId : String , moderator : Bool , admin : Bool , visible : Bool , for roomTokens : [ String ] ? = nil , on server : String , using dependencies : Dependencies = Dependencies ( ) ) -> Promise < ( OnionRequestResponseInfoType , Data ? ) > {
let requestBody : UserModeratorRequest = UserModeratorRequest (
rooms : roomTokens ,
global : ( roomTokens = = nil ? true : nil ) ,
@ -556,10 +550,10 @@ public final class OpenGroupAPIV2: NSObject {
body : body
)
return send ( request )
return send ( request , using : dependencies )
}
public static func userDeleteMessages ( _ sessionId : String , for roomTokens : [ String ] ? = nil , on server : String ) -> Promise < ( OnionRequestResponseInfoType , UserDeleteMessagesResponse ) > {
public static func userDeleteMessages ( _ sessionId : String , for roomTokens : [ String ] ? = nil , on server : String , using dependencies : Dependencies = Dependencies ( ) ) -> Promise < ( OnionRequestResponseInfoType , UserDeleteMessagesResponse ) > {
let requestBody : UserDeleteMessagesRequest = UserDeleteMessagesRequest (
rooms : roomTokens ,
global : ( roomTokens = = nil ? true : nil )
@ -576,26 +570,25 @@ public final class OpenGroupAPIV2: NSObject {
body : body
)
return send ( request )
return send ( request , using : dependencies )
. decoded ( as : UserDeleteMessagesResponse . self , on : OpenGroupAPIV2 . workQueue , error : Error . parsingFailed )
}
// MARK: - P r o c e s s i n g
// TODO: M o v e t h e s e m e t h o d s t o t h e O p e n G r o u p M a n a g e r ? ( s e e m s o d d f o r t h e m t o b e i n t h e A P I )
private static func process ( messages : [ Message ] ? , for room : String , on server : String ) -> Promise < [ Message ] > {
private static func process ( messages : [ Message ] ? , for room : String , on server : String , using dependencies : Dependencies = Dependencies ( ) ) -> Promise < [ Message ] > {
guard let messages : [ Message ] = messages , ! messages . isEmpty else { return Promise . value ( [ ] ) }
let storage = SNMessagingKitConfiguration . shared . storage
let seqNo : Int64 = ( messages . compactMap { $0 . seqNo } . max ( ) ? ? 0 )
let lastMessageSeqNo : Int64 = ( storage. getLastMessageServerID ( for : room , on : server ) ? ? 0 )
let lastMessageSeqNo : Int64 = ( dependencies. storage. getLastMessageServerID ( for : room , on : server ) ? ? 0 )
if seqNo > lastMessageSeqNo {
let ( promise , seal ) = Promise < [ Message ] > . pending ( )
storage. write (
dependencies. storage. write (
with : { transaction in
storage. setLastMessageServerID ( for : room , on : server , to : seqNo , using : transaction )
dependencies. storage. setLastMessageServerID ( for : room , on : server , to : seqNo , using : transaction )
} ,
completion : {
seal . fulfill ( messages )
@ -608,19 +601,18 @@ public final class OpenGroupAPIV2: NSObject {
return Promise . value ( messages )
}
private static func process ( deletions : [ Deletion ] ? , for room : String , on server : String ) -> Promise < [ Deletion ] > {
private static func process ( deletions : [ Deletion ] ? , for room : String , on server : String , using dependencies : Dependencies = Dependencies ( ) ) -> Promise < [ Deletion ] > {
guard let deletions : [ Deletion ] = deletions else { return Promise . value ( [ ] ) }
let storage = SNMessagingKitConfiguration . shared . storage
let serverID : Int64 = ( deletions . compactMap { $0 . id } . max ( ) ? ? 0 )
let lastDeletionServerID : Int64 = ( storage. getLastDeletionServerID ( for : room , on : server ) ? ? 0 )
let lastDeletionServerID : Int64 = ( dependencies. storage. getLastDeletionServerID ( for : room , on : server ) ? ? 0 )
if serverID > lastDeletionServerID {
let ( promise , seal ) = Promise < [ Deletion ] > . pending ( )
storage. write (
dependencies. storage. write (
with : { transaction in
storage. setLastDeletionServerID ( for : room , on : server , to : serverID , using : transaction )
dependencies. storage. setLastDeletionServerID ( for : room , on : server , to : serverID , using : transaction )
} ,
completion : {
seal . fulfill ( deletions )
@ -639,14 +631,15 @@ public final class OpenGroupAPIV2: NSObject {
// MARK: - G e n e r a l
public static func getDefaultRoomsIfNeeded ( ) {
// TODO: S h i f t t h i s t o t h e O p e n G r o u p M a n a g e r V 2 ? ( s e e m s m o r e a t p l a c e t h e r e t h a n i n t h e A P I )
public static func getDefaultRoomsIfNeeded ( using dependencies : Dependencies = Dependencies ( ) ) {
Storage . shared . write (
with : { transaction in
Storage. shared . setOpenGroupPublicKey ( for : defaultServer , to : defaultServerPublicKey , using : transaction )
dependencies. storage . setOpenGroupPublicKey ( for : defaultServer , to : defaultServerPublicKey , using : transaction )
} ,
completion : {
let promise = attempt ( maxRetryCount : 8 , recoveringOn : DispatchQueue . main ) {
OpenGroupAPIV2 . rooms ( for : defaultServer )
OpenGroupAPIV2 . rooms ( for : defaultServer , using : dependencies )
. map { _ , data in data }
}
_ = promise . done ( on : OpenGroupAPIV2 . workQueue ) { items in
@ -657,7 +650,7 @@ public final class OpenGroupAPIV2: NSObject {
return ( imageId , room . token )
}
. forEach { imageId , roomToken in
roomImage ( imageId , for : roomToken , on : defaultServer )
roomImage ( imageId , for : roomToken , on : defaultServer , using : dependencies )
. retainUntilComplete ( )
}
}
@ -671,26 +664,18 @@ public final class OpenGroupAPIV2: NSObject {
// MARK: - A u t h e n t i c a t i o n
// TODO: T u r n ' S o d i u m ' i n t o a p r o t o c o l f o r u n i t t e s t i n g
static func sign (
_ request : URLRequest ,
with publicKey : String ,
using storage : SessionMessagingKitStorageProtocol = SNMessagingKitConfiguration . shared . storage ,
sodium : Sodium = Sodium ( ) ,
nonceGenerator : NonceGenerator16ByteType = NonceGenerator16Byte ( ) ,
date : Date = Date ( )
) -> URLRequest ? {
private static func sign ( _ request : URLRequest , with publicKey : String , using dependencies : Dependencies = Dependencies ( ) ) -> URLRequest ? {
guard let url : URL = request . url else { return nil }
var updatedRequest : URLRequest = request
let path : String = url . path
. appending ( url . query . map { value in " ? \( value ) " } )
let method : String = ( request . httpMethod ? ? " GET " )
let timestamp : Int = Int ( floor ( d ate. timeIntervalSince1970 ) )
let nonce : Data = Data ( nonceGenerator. nonce ( ) )
let timestamp : Int = Int ( floor ( dependencies . date . timeIntervalSince1970 ) )
let nonce : Data = Data ( dependencies . nonceGenerator . nonce ( ) )
guard let publicKeyData : Data = publicKey . dataFromHex ( ) else { return nil }
guard let userKeyPair : ECKeyPair = storage. getUserKeyPair ( ) else {
guard let userKeyPair : ECKeyPair = dependencies. storage. getUserKeyPair ( ) else {
return nil
}
// g u a r d l e t b l i n d e d K e y P a i r : E C K e y P a i r = t r y ? u s e r K e y P a i r . c o n v e r t ( t o : . b l i n d e d , w i t h : p u b l i c K e y ) e l s e {
@ -702,7 +687,7 @@ public final class OpenGroupAPIV2: NSObject {
// / G e n e r a t e t h e s h a r e d S e c r e t b y " a B | | A | | B " w h e r e
// / a , A a r e t h e u s e r s p r i v a t e a n d p u b l i c k e y s r e s p e c t i v e l y ,
// / B i s t h e S O G S p u b l i c k e y
let maybeSharedSecret : Data ? = sodium. sharedSecret ( blindedKeyPair . privateKey . bytes , publicKeyData . bytes ) ?
let maybeSharedSecret : Data ? = dependencies. sodium. sharedSecret ( blindedKeyPair . privateKey . bytes , publicKeyData . bytes ) ?
. appending ( blindedKeyPair . publicKey )
. appending ( publicKeyData . bytes )
@ -721,10 +706,10 @@ public final class OpenGroupAPIV2: NSObject {
. appending ( request . httpBody ? . bytes ? ? [ ] ) // TODO: M i g h t n e e d t o d o t h e ' h t t p B o d y S t r e a m ' a s w e l l ? ? ?
guard let sharedSecret : Data = maybeSharedSecret else { return nil }
guard let intermediateHash : Bytes = sodium . genericHash . hashSaltPersonal ( message : sharedSecret . bytes , outputLength : 42 , key : nil , salt : nonce . bytes , personal : Personalization . sharedKeys . bytes ) else {
guard let intermediateHash : Bytes = dependencies . genericHash . hashSaltPersonal ( message : sharedSecret . bytes , outputLength : 42 , key : nil , salt : nonce . bytes , personal : Personalization . sharedKeys . bytes ) else {
return nil
}
guard let secretHash : Bytes = sodium . genericHash . hashSaltPersonal ( message : secretHashMessage , outputLength : 42 , key : intermediateHash , salt : nonce . bytes , personal : Personalization . authHeader . bytes ) else {
guard let secretHash : Bytes = dependencies . genericHash . hashSaltPersonal ( message : secretHashMessage , outputLength : 42 , key : intermediateHash , salt : nonce . bytes , personal : Personalization . authHeader . bytes ) else {
return nil
}
@ -741,13 +726,7 @@ public final class OpenGroupAPIV2: NSObject {
// MARK: - C o n v e n i e n c e
private static func send (
_ request : Request ,
through api : OnionRequestAPIType . Type = OnionRequestAPI . self ,
using storage : SessionMessagingKitStorageProtocol = SNMessagingKitConfiguration . shared . storage ,
nonceGenerator : NonceGenerator16ByteType = NonceGenerator16Byte ( ) ,
date : Date = Date ( )
) -> Promise < ( OnionRequestResponseInfoType , Data ? ) > {
private static func send ( _ request : Request , using dependencies : Dependencies = Dependencies ( ) ) -> Promise < ( OnionRequestResponseInfoType , Data ? ) > {
guard let url : URL = request . url else { return Promise ( error : Error . invalidURL ) }
var urlRequest : URLRequest = URLRequest ( url : url )
@ -758,21 +737,21 @@ public final class OpenGroupAPIV2: NSObject {
urlRequest . httpBody = request . body
if request . useOnionRouting {
guard let publicKey = storage. getOpenGroupPublicKey ( for : request . server ) else {
guard let publicKey = dependencies. storage. getOpenGroupPublicKey ( for : request . server ) else {
return Promise ( error : Error . noPublicKey )
}
if request . isAuthRequired {
// A t t e m p t t o s i g n t h e r e q u e s t w i t h t h e n e w a u t h
guard let signedRequest : URLRequest = sign ( urlRequest , with : publicKey , using : storage, nonceGenerator : nonceGenerator , date : date ) else {
guard let signedRequest : URLRequest = sign ( urlRequest , with : publicKey , using : dependencies ) else {
return Promise ( error : Error . signingFailed )
}
// TODO: ' r e m o v e A u t h T o k e n ' a s a m i g r a t i o n ? ? ? ( w o u l d p r e v i o u s l y d o t h i s w h e n g e t t i n g a ` 4 0 1 ` ) .
return api. sendOnionRequest ( signedRequest , to : request . server , with : publicKey )
return dependencies. api. sendOnionRequest ( signedRequest , to : request . server , with : publicKey )
}
return api. sendOnionRequest ( urlRequest , to : request . server , with : publicKey )
return dependencies. api. sendOnionRequest ( urlRequest , to : request . server , with : publicKey )
}
preconditionFailure ( " It's currently not allowed to send non onion routed requests. " )
@ -866,11 +845,11 @@ public final class OpenGroupAPIV2: NSObject {
server : server ,
room : room ,
endpoint : . legacyAuthTokenClaim ( legacyAuth : true ) ,
body : body ,
headers : [
// S e t e x p l i c i t l y h e r e b e c a u s e i s i s n ' t i n t h e d a t a b a s e y e t a t t h i s p o i n t
. authorization : authToken
] ,
body : body ,
isAuthRequired : false
)