WebReceiversResponse.swift 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. // _____ _
  2. // |_ _| |_ _ _ ___ ___ _ __ __ _
  3. // | | | ' \| '_/ -_) -_) ' \/ _` |_
  4. // |_| |_||_|_| \___\___|_|_|_\__,_(_)
  5. //
  6. // Threema iOS Client
  7. // Copyright (c) 2018-2020 Threema GmbH
  8. //
  9. // This program is free software: you can redistribute it and/or modify
  10. // it under the terms of the GNU Affero General Public License, version 3,
  11. // as published by the Free Software Foundation.
  12. //
  13. // This program is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. // GNU Affero General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Affero General Public License
  19. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. import Foundation
  21. class WebReceiversResponse: WebAbstractMessage {
  22. var contacts: [[AnyHashable: Any]] = [[AnyHashable: Any]]()
  23. var groups: [Any] = [Any]()
  24. var distributionList: [Any] = [Any]()
  25. init(requestId: String?, allContacts: [Contact], allGroupConversations: [Conversation]) {
  26. for c in allContacts {
  27. let webcontact = WebContact.init(c)
  28. contacts.append(webcontact.objectDict())
  29. }
  30. let entityManager = EntityManager()
  31. for conversation in allGroupConversations {
  32. if conversation.isGroup() {
  33. if let groupProxy = GroupProxy.init(for: conversation, entityManager: entityManager) {
  34. let group = WebGroup.init(group: groupProxy)
  35. groups.append(group.objectDict())
  36. }
  37. }
  38. }
  39. let tmpData:[AnyHashable:Any?] = ["contact": contacts, "group": groups, "distributionList": distributionList] as [String : Any]
  40. let tmpAck = requestId != nil ? WebAbstractMessageAcknowledgement.init(requestId, true, nil) : nil
  41. super.init(messageType: "response", messageSubType: "receivers", requestId: nil, ack: tmpAck, args: nil, data: tmpData)
  42. }
  43. }
  44. struct WebContact {
  45. var id: String
  46. var displayName: String
  47. var color: String? // not available in iOS
  48. var firstName: String?
  49. var lastName: String?
  50. var publicNickname: String?
  51. var verificationLevel: Int
  52. var state: String
  53. var featureMask: Int
  54. var isWork: Bool?
  55. var identityType: Int = 0
  56. var publicKey: Data
  57. var locked: Bool
  58. var visible: Bool
  59. var hidden: Bool
  60. var isBlocked: Bool = false
  61. var access: Access
  62. init(_ contact: Contact) {
  63. id = contact.identity
  64. displayName = contact.displayName
  65. color = "#181818"
  66. firstName = contact.firstName
  67. lastName = contact.lastName
  68. publicNickname = contact.publicNickname
  69. verificationLevel = contact.verificationLevel.intValue + 1 // iOS begins with 0
  70. state = contact.isActive() ? "ACTIVE" : "INACTIVE"
  71. if let fM = contact.featureMask() {
  72. featureMask = Int(truncating: fM)
  73. } else {
  74. featureMask = 0
  75. }
  76. isWork = contact.workContact == NSNumber.init(value: true)
  77. if let identity = contact.identity {
  78. identityType = UserSettings.shared().workIdentities.contains(identity) ? 1 : 0
  79. }
  80. publicKey = contact.publicKey
  81. locked = false // only for private chats
  82. visible = true // only for private chats
  83. hidden = false // for contacts where are added by group chats
  84. if let identity = contact.identity {
  85. isBlocked = UserSettings.shared().blacklist.contains(identity)
  86. }
  87. let entityManager = EntityManager()
  88. let groups = entityManager.entityFetcher.groupConversations(for: contact)
  89. let canDelete = groups?.count == 0 ? true : false
  90. var canChangeFirstName = true
  91. var canChangeLastName = true
  92. var canChangeAvatar: Bool = true
  93. if contact.contactImage != nil && UserSettings.shared().showProfilePictures {
  94. canChangeAvatar = false
  95. } else if contact.imageData != nil {
  96. canChangeAvatar = true
  97. }
  98. if contact.isGatewayId() {
  99. canChangeAvatar = false
  100. canChangeFirstName = false
  101. canChangeLastName = false
  102. }
  103. access = Access.init(canDelete: canDelete, canChangeAvatar: canChangeAvatar, canChangeFirstName: canChangeFirstName, canChangeLastName: canChangeLastName)
  104. // work fix --> set verificationLevel to 2 when verification level is 1 and contact is in same work package
  105. if isWork == true && verificationLevel == 1 {
  106. verificationLevel = 2
  107. }
  108. }
  109. func objectDict() -> [String: Any] {
  110. var objectDict:[String: Any] = ["id": id, "displayName": displayName, "featureMask": featureMask, "verificationLevel": verificationLevel, "state": state, "identityType": identityType, "publicKey": publicKey, "locked": locked, "visible": visible, "hidden": hidden, "isBlocked": isBlocked, "access": access.objectDict()]
  111. if firstName != nil {
  112. objectDict.updateValue(firstName!, forKey: "firstName")
  113. }
  114. if lastName != nil {
  115. objectDict.updateValue(lastName!, forKey: "lastName")
  116. }
  117. if publicNickname != nil {
  118. objectDict.updateValue(publicNickname!, forKey: "publicNickname")
  119. }
  120. if isWork != nil {
  121. objectDict.updateValue(isWork!, forKey: "isWork")
  122. }
  123. if color != nil {
  124. objectDict.updateValue(color!, forKey: "color")
  125. }
  126. return objectDict
  127. }
  128. }
  129. struct Access {
  130. var canDelete: Bool
  131. var canChangeAvatar: Bool
  132. var canChangeFirstName: Bool
  133. var canChangeLastName: Bool
  134. func objectDict() -> [String: Any] {
  135. return ["canDelete": canDelete, "canChangeAvatar": canChangeAvatar, "canChangeFirstName": canChangeFirstName, "canChangeLastName": canChangeLastName]
  136. }
  137. }
  138. struct WebGroup {
  139. var id: String
  140. var displayName: String
  141. var color: String? // not available in iOS
  142. var disabled: Bool?
  143. var members: [String]
  144. var administrator: String
  145. var createdAt: String?
  146. var locked: Bool // only for private chats
  147. var visible: Bool // only for private chats
  148. var access: GroupAccess
  149. init(group: GroupProxy) {
  150. if group.groupId != nil {
  151. id = group.groupId.hexEncodedString()
  152. } else {
  153. id = group.name.replacingOccurrences(of: " ", with: "")
  154. }
  155. displayName = group.name
  156. color = "#181818"
  157. disabled = false
  158. if group.activeMemberIds.count > 0 {
  159. members = group.activeMemberIds.map({ String(describing: $0) })
  160. } else {
  161. members = []
  162. }
  163. if group.isOwnGroup() {
  164. administrator = MyIdentityStore.shared().identity
  165. }
  166. else if group.creator != nil {
  167. administrator = group.creator.identity
  168. }
  169. else {
  170. administrator = group.conversation().groupMyIdentity ?? "Unknown"
  171. }
  172. locked = false
  173. visible = true
  174. access = GroupAccess.init(canDelete: true, canChangeAvatar: group.isOwnGroup(), canChangeName: group.isOwnGroup(), canChangeMembers: group.isOwnGroup(), canLeave: !group.didLeaveGroup(), canSync: group.isOwnGroup())
  175. }
  176. func objectDict() -> [String: Any] {
  177. var objectDict:[String: Any] = ["id": id, "displayName": displayName, "members": members, "administrator": administrator, "locked": locked, "visible": visible, "access": access.objectDict()]
  178. if disabled != nil {
  179. objectDict.updateValue(disabled!, forKey: "disabled")
  180. }
  181. if createdAt != nil {
  182. objectDict.updateValue(createdAt!, forKey: "createdAt")
  183. }
  184. if color != nil {
  185. objectDict.updateValue(color!, forKey: "color")
  186. }
  187. return objectDict
  188. }
  189. }
  190. struct GroupAccess {
  191. var canDelete: Bool
  192. var canChangeAvatar: Bool
  193. var canChangeName: Bool
  194. var canChangeMembers: Bool?
  195. var canLeave: Bool?
  196. var canSync: Bool?
  197. func objectDict() -> [String: Any] {
  198. var objectDict:[String: Any] = ["canDelete": canDelete, "canChangeAvatar": canChangeAvatar, "canChangeName": canChangeName]
  199. if canChangeMembers != nil {
  200. objectDict.updateValue(canChangeMembers!, forKey: "canChangeMembers")
  201. }
  202. if canLeave != nil {
  203. objectDict.updateValue(canLeave!, forKey: "canLeave")
  204. }
  205. if canSync != nil {
  206. objectDict.updateValue(canSync!, forKey: "canSync")
  207. }
  208. return objectDict
  209. }
  210. }