@ -20,34 +20,42 @@ extension MessageSender {
public static func createGroup (
name : String ,
description : String ? ,
displayPicture : SignalAttachment ? ,
displayPicture Data: Data ? ,
members : [ ( String , Profile ? ) ] ,
using dependencies : Dependencies = Dependencies ( )
) -> AnyPublisher < SessionThread , Error > {
typealias ImageUploadResponse = ( downloadUrl : String , fileName : String , encryptionKey : Data )
return Just ( ( ) )
. setFailureType ( to : Error . self )
. flatMap { _ -> AnyPublisher < ( url : String , filename : String , encryptionKey : Data ) ? , Error > in
guard let displayPicture : SignalAttachment = displayPicture else {
. flatMap { _ -> AnyPublisher < ImageUploadResponse ? , Error > in
guard let displayPicture Data: Data = displayPictureData else {
return Just ( nil )
. setFailureType ( to : Error . self )
. eraseToAnyPublisher ( )
}
// TODO: U p l o a d g r o u p i m a g e f i r s t
return Just ( nil )
. setFailureType ( to : Error . self )
. eraseToAnyPublisher ( )
return Deferred {
Future < ImageUploadResponse ? , Error > { resolver in
DisplayPictureManager . prepareAndUploadDisplayPicture (
queue : DispatchQueue . global ( qos : . userInitiated ) ,
imageData : displayPictureData ,
success : { resolver ( Result . success ( $0 ) ) } ,
failure : { resolver ( Result . failure ( $0 ) ) } ,
using : dependencies
)
}
} . eraseToAnyPublisher ( )
}
. flatMap { displayPictureInfo -> AnyPublisher < PreparedGroupData , Error > in
dependencies [ singleton : . storage ] . writePublisher ( using : dependencies ) { db -> PreparedGroupData in
// C r e a t e a n d c a c h e t h e l i b S e s s i o n e n t r i e s
let userSessionId : SessionId = getUserSessionId ( db , using : dependencies )
let currentUserProfile : Profile = Profile . fetchOrCreateCurrentUser ( db , using : dependencies )
let createdInfo : SessionUtil . CreatedGroupInfo = try SessionUtil . createGroup (
db ,
name : name ,
description : description ,
displayPictureUrl : displayPictureInfo ? . u rl,
displayPictureFilename : displayPictureInfo ? . file n ame,
displayPictureUrl : displayPictureInfo ? . downloadU rl,
displayPictureFilename : displayPictureInfo ? . file N ame,
displayPictureEncryptionKey : displayPictureInfo ? . encryptionKey ,
members : members ,
using : dependencies
@ -402,9 +410,14 @@ extension MessageSender {
}
// / G e n e r a t e t h e d a t a n e e d e d t o s e n d t h e n e w m e m b e r s i n v i t a t i o n s t o t h e g r o u p
let memberJobData : [ ( id : String , profile : Profile ? , jobDetails : GroupInviteMemberJob . Details )] = try members
let memberJobData : [ ( id : String , profile : Profile ? , jobDetails : GroupInviteMemberJob . Details , subaccountToken : [ UInt8 ] )] = try members
. map { id , profile in
// G e n e r a t e a u t h D a t a f o r t h e n e w l y a d d e d m e m b e r
let subaccountToken : [ UInt8 ] = try SessionUtil . generateSubaccountToken (
groupSessionId : sessionId ,
memberId : id ,
using : dependencies
)
let memberAuthInfo : Authentication . Info = try SessionUtil . generateAuthData (
groupSessionId : sessionId ,
memberId : id ,
@ -415,7 +428,7 @@ extension MessageSender {
authInfo : memberAuthInfo
)
return ( id , profile , inviteDetails )
return ( id , profile , inviteDetails , subaccountToken )
}
// / U n r e v o k e t h e n e w l y a d d e d m e m b e r s j u s t i n c a s e t h e y h a d p r e v i o u s l y g o t t e n t h e i r a c c e s s t o t h e g r o u p
@ -427,9 +440,9 @@ extension MessageSender {
try ? SnodeAPI
. preparedBatch (
db ,
requests : try memberJobDataChunk . map { id , _ , jobDetails in
requests : try memberJobDataChunk . map { id , _ , _ , subaccountToken in
try SnodeAPI . preparedUnrevokeSubaccount (
subaccountToUnrevoke : jobDetails. memberAuthData . toHexString ( ) ,
subaccountToUnrevoke : subaccountToken ,
authMethod : Authentication . groupAdmin (
groupSessionId : sessionId ,
ed25519SecretKey : Array ( groupIdentityPrivateKey )
@ -447,7 +460,7 @@ extension MessageSender {
}
// / M a k e t h e r e q u i r e d c h a n g e s f o r e a c h a d d e d m e m b e r
try memberJobData . forEach { id , profile , inviteJobDetails in
try memberJobData . forEach { id , profile , inviteJobDetails , _ in
// / A d d t h e m e m b e r t o t h e d a t a b a s e
try GroupMember (
groupId : sessionId . hexString ,
@ -518,6 +531,11 @@ extension MessageSender {
. fetchOne ( db )
else { throw MessageSenderError . invalidClosedGroupUpdate }
let subaccountToken : [ UInt8 ] = try SessionUtil . generateSubaccountToken (
groupSessionId : sessionId ,
memberId : memberId ,
using : dependencies
)
let inviteDetails : GroupInviteMemberJob . Details = try GroupInviteMemberJob . Details (
memberSessionIdHexString : memberId ,
authInfo : try SessionUtil . generateAuthData (
@ -531,7 +549,7 @@ extension MessageSender {
// / u n r e v o k e r e q u e s t w h e n i n i t i a l l y a d d e d t h e m f a i l e d ( f i r e - a n d - f o r g e t t h i s r e q u e s t , w e d o n ' t w a n t i t t o b e b l o c k i n g )
try SnodeAPI
. preparedUnrevokeSubaccount (
subaccountToUnrevoke : inviteDetails. memberAuthData . toHexString ( ) ,
subaccountToUnrevoke : subaccountToken ,
authMethod : Authentication . groupAdmin (
groupSessionId : sessionId ,
ed25519SecretKey : Array ( groupIdentityPrivateKey )
@ -658,16 +676,15 @@ extension MessageSender {
requests : memberIdsChunk . compactMap { id -> HTTP . PreparedRequest < Void > ? in
// G e n e r a t e a u t h D a t a f o r t h e r e m o v e d m e m b e r
guard
let memberAuthInfo: Authentication . Info = try ? SessionUtil . generateAuthData (
let subaccountToken: [ UInt8 ] = try ? SessionUtil . generateSubaccountToken (
groupSessionId : groupSessionId ,
memberId : id ,
using : dependencies
) ,
case . groupMember ( _ , let memberAuthData ) = memberAuthInfo
)
else { return nil }
return try ? SnodeAPI . preparedRevokeSubaccount (
subaccountToRevoke : memberAuthData. toHexString ( ) ,
subaccountToRevoke : subaccountToken ,
authMethod : Authentication . groupAdmin (
groupSessionId : groupSessionId ,
ed25519SecretKey : Array ( groupIdentityPrivateKey )