diff --git a/Sources/XXDatabase/Migration.swift b/Sources/XXDatabase/Migration.swift index 9bb5a8aef97de50f0ca0da48126d7252ad52215a..0714967fba4a3a7ae68762a3259a21edf9e32e62 100644 --- a/Sources/XXDatabase/Migration.swift +++ b/Sources/XXDatabase/Migration.swift @@ -69,6 +69,12 @@ extension Sequence where Element == Migration { t.column("fileTransferId", .blob) .references("fileTransfers", column: "id", onDelete: .cascade, onUpdate: .cascade) } - } + }, + Migration(id: "1") { db in + try db.alter(table: "contacts") { t in + t.add(column: "isBlocked", .boolean).defaults(to: false) + t.add(column: "isBanned", .boolean).defaults(to: false) + } + }, ]} } diff --git a/Sources/XXDatabase/Models/Contact+GRDB.swift b/Sources/XXDatabase/Models/Contact+GRDB.swift index 978849d765760fb2f21811169d1623955d7af906..1f9133625d33fbb197d5e66be5a4152e967ae917 100644 --- a/Sources/XXDatabase/Models/Contact+GRDB.swift +++ b/Sources/XXDatabase/Models/Contact+GRDB.swift @@ -12,6 +12,8 @@ extension Contact: FetchableRecord, PersistableRecord { case photo case authStatus case isRecent + case isBlocked + case isBanned case createdAt } @@ -58,6 +60,14 @@ extension Contact: FetchableRecord, PersistableRecord { request = request.filter(Column.isRecent == isRecent) } + if let isBlocked = query.isBlocked { + request = request.filter(Column.isBlocked == isBlocked) + } + + if let isBanned = query.isBanned { + request = request.filter(Column.isBanned == isBanned) + } + switch query.sortBy { case .username(desc: false): request = request.order(Column.username) diff --git a/Sources/XXDatabase/Models/ContactChatInfo+GRDB.swift b/Sources/XXDatabase/Models/ContactChatInfo+GRDB.swift index 47315f4fcb4652ee8ab55eb4f6000eec6534ab70..6f50587b1bd3e7b9301d26a7c0782fff2f38ee8a 100644 --- a/Sources/XXDatabase/Models/ContactChatInfo+GRDB.swift +++ b/Sources/XXDatabase/Models/ContactChatInfo+GRDB.swift @@ -17,6 +17,16 @@ extension ContactChatInfo: FetchableRecord { _ = sqlArguments.append(contentsOf: sqlArgumentsAuthStatus(authStatus)) } + if let isBlocked = query.isBlocked { + sqlWhere.append("AND c2.isBlocked = :isBlocked") + _ = sqlArguments.append(contentsOf: StatementArguments(["isBlocked": isBlocked])) + } + + if let isBanned = query.isBanned { + sqlWhere.append("AND c2.isBanned = :isBanned") + _ = sqlArguments.append(contentsOf: StatementArguments(["isBanned": isBanned])) + } + let sql = """ SELECT -- All contact columns: diff --git a/Sources/XXDatabase/Models/Group+GRDB.swift b/Sources/XXDatabase/Models/Group+GRDB.swift index 5cd9090097654c298fc722dba7a9efd5273825d6..42455defa8293928e67ebd087808dfc6a239cf50 100644 --- a/Sources/XXDatabase/Models/Group+GRDB.swift +++ b/Sources/XXDatabase/Models/Group+GRDB.swift @@ -58,6 +58,19 @@ extension Group: PersistableRecord, FetchableRecord { request = request.filter(authStatus.map(\.rawValue).contains(Column.authStatus)) } + if query.isLeaderBlocked != nil || query.isLeaderBanned != nil { + let leader = TableAlias(name: "leader") + request = request.joining(required: Association.leader.aliased(leader)) + + if let isLeaderBlocked = query.isLeaderBlocked { + request = request.filter(leader[Contact.Column.isBlocked] == isLeaderBlocked) + } + + if let isLeaderBanned = query.isLeaderBanned { + request = request.filter(leader[Contact.Column.isBanned] == isLeaderBanned) + } + } + switch query.sortBy { case .createdAt(desc: false): request = request.order(Column.createdAt) diff --git a/Sources/XXDatabase/Models/GroupChatInfo+GRDB.swift b/Sources/XXDatabase/Models/GroupChatInfo+GRDB.swift index f8a549e06863143cc0829f0b7e2bc767d733ff4a..a44b98df23f271de5c26009ac75c0a7da2d9a1b2 100644 --- a/Sources/XXDatabase/Models/GroupChatInfo+GRDB.swift +++ b/Sources/XXDatabase/Models/GroupChatInfo+GRDB.swift @@ -9,6 +9,7 @@ extension GroupChatInfo: FetchableRecord { } static func request(_ query: Query) -> AdaptedFetchRequest<SQLRequest<GroupChatInfo>> { + var sqlJoins: [String] = ["INNER JOIN groups g ON g.id = m.groupId"] var sqlWhere: [String] = [] var sqlArguments: StatementArguments = [:] @@ -17,6 +18,36 @@ extension GroupChatInfo: FetchableRecord { _ = sqlArguments.append(contentsOf: sqlArgumentsAuthStatus(authStatus)) } + if query.isLeaderBlocked != nil || query.isLeaderBanned != nil { + sqlJoins.append("INNER JOIN contacts l ON g.leaderId = l.id") + + if let isLeaderBlocked = query.isLeaderBlocked { + sqlWhere.append("l.isBlocked = :isLeaderBlocked") + _ = sqlArguments.append(contentsOf: StatementArguments([ + "isLeaderBlocked": isLeaderBlocked + ])) + } + + if let isLeaderBanned = query.isLeaderBanned { + sqlWhere.append("l.isBanned = :isLeaderBanned") + _ = sqlArguments.append(contentsOf: StatementArguments([ + "isLeaderBanned": isLeaderBanned + ])) + } + } + + if query.excludeBlockedContactsMessages || query.excludeBannedContactsMessages { + sqlJoins.append("INNER JOIN contacts s ON m.senderId = s.id") + + if query.excludeBlockedContactsMessages { + sqlWhere.append("s.isBlocked != 1") + } + + if query.excludeBannedContactsMessages { + sqlWhere.append("s.isBanned != 1") + } + } + let sql = """ SELECT -- All group columns: @@ -29,9 +60,8 @@ extension GroupChatInfo: FetchableRecord { MAX(m.date) AS date FROM messages m - INNER JOIN groups g - ON g.id = m.groupId - \(sqlWhere.isEmpty ? "" : "WHERE\n \(sqlWhere.joined(separator: "\n "))") + \(sqlJoins.joined(separator: "\n")) + \(sqlWhere.isEmpty ? "" : "WHERE\n \(sqlWhere.joined(separator: "\n AND "))") GROUP BY g.id ORDER BY diff --git a/Sources/XXDatabase/Models/Message+GRDB.swift b/Sources/XXDatabase/Models/Message+GRDB.swift index bb0196b005c05e7b14393320aa091293845ebc29..d242a67d2a48510bf27a123b8b8441546a715d05 100644 --- a/Sources/XXDatabase/Models/Message+GRDB.swift +++ b/Sources/XXDatabase/Models/Message+GRDB.swift @@ -17,6 +17,13 @@ extension Message: FetchableRecord, MutablePersistableRecord { case fileTransferId } + enum Association { + static let sender = belongsTo( + Contact.self, + using: .init([Column.senderId], to: [Contact.Column.id]) + ) + } + public static let databaseTableName = "messages" static func request(_ query: Query) -> QueryInterfaceRequest<Message> { @@ -74,6 +81,19 @@ extension Message: FetchableRecord, MutablePersistableRecord { break } + if query.isSenderBlocked != nil || query.isSenderBanned != nil { + let sender = TableAlias(name: "sender") + request = request.joining(required: Association.sender.aliased(sender)) + + if let isSenderBlocked = query.isSenderBlocked { + request = request.filter(sender[Contact.Column.isBlocked] == isSenderBlocked) + } + + if let isSenderBanned = query.isSenderBanned { + request = request.filter(sender[Contact.Column.isBanned] == isSenderBanned) + } + } + switch query.sortBy { case .date(desc: false): request = request.order(Column.date) diff --git a/Sources/XXModels/Models/Contact.swift b/Sources/XXModels/Models/Contact.swift index 9e43b69b743b2df02e50a95a63ce6b5d7ffd0f3b..b4579734f581a425ff2accfb6a90e0ffba435210 100644 --- a/Sources/XXModels/Models/Contact.swift +++ b/Sources/XXModels/Models/Contact.swift @@ -53,6 +53,8 @@ public struct Contact: Identifiable, Equatable, Hashable, Codable { /// - photo: Photo data (defaults to `nil`) /// - authStatus: Contact authorization status (defaults to `.stranger`) /// - isRecent: Flag determining recent contact status (defaults to `false`) + /// - isBlocked: Flag determining blocked status (defaults to `false`) + /// - isBanned: Flag determining banned status (defaults to `false`) /// - createdAt: Creation date (defaults to current date) public init( id: ID, @@ -64,6 +66,8 @@ public struct Contact: Identifiable, Equatable, Hashable, Codable { photo: Data? = nil, authStatus: AuthStatus = .stranger, isRecent: Bool = false, + isBlocked: Bool = false, + isBanned: Bool = false, createdAt: Date = Date() ) { self.id = id @@ -75,6 +79,8 @@ public struct Contact: Identifiable, Equatable, Hashable, Codable { self.photo = photo self.authStatus = authStatus self.isRecent = isRecent + self.isBlocked = isBlocked + self.isBanned = isBanned self.createdAt = createdAt } @@ -105,6 +111,12 @@ public struct Contact: Identifiable, Equatable, Hashable, Codable { /// Flag determining recent contact status public var isRecent: Bool + /// Flag determining blocked status + public var isBlocked: Bool + + /// Flag determining banned status + public var isBanned: Bool + /// Creation date public var createdAt: Date } @@ -161,6 +173,14 @@ extension Contact { /// If `true`, only recent contacts are included. /// If `false`, only non-recent contacts are included. /// If `nil` (default), the filter is not used. + /// - isBlocked: Filter by `isBlocked` status. + /// If `true`, only blocked contacts are included. + /// If `false`, only non-blocked contacts are included. + /// If `nil` (default), the filter is not used. + /// - isBanned: Filter by `isBanned` status. + /// If `true`, only banned contacts are included. + /// If `false`, only non-banned contacts are included. + /// If `nil` (default), the filter is not used. /// - sortBy: Sort order (defaults to `.username()`). public init( id: Set<Contact.ID>? = nil, @@ -168,6 +188,8 @@ extension Contact { text: String? = nil, authStatus: Set<AuthStatus>? = nil, isRecent: Bool? = nil, + isBlocked: Bool? = nil, + isBanned: Bool? = nil, sortBy: SortOrder = .username() ) { self.id = id @@ -175,6 +197,8 @@ extension Contact { self.text = text self.authStatus = authStatus self.isRecent = isRecent + self.isBlocked = isBlocked + self.isBanned = isBanned self.sortBy = sortBy } @@ -208,6 +232,20 @@ extension Contact { /// If `nil`, the filter is not used. public var isRecent: Bool? + /// Filter by `isBlocked` status + /// + /// If `true`, only blocked contacts are included. + /// If `false`, only non-blocked contacts are included. + /// If `nil`, the filter is not used. + public var isBlocked: Bool? + + /// Filter by `isBanned` status + /// + /// If `true`, only banned contacts are included. + /// If `false`, only non-banned contacts are included. + /// If `nil`, the filter is not used. + public var isBanned: Bool? + /// Contacts sort order public var sortBy: SortOrder } diff --git a/Sources/XXModels/Models/ContactChatInfo.swift b/Sources/XXModels/Models/ContactChatInfo.swift index b7eb7134a036cf2ff4c269a441b144a83106aa50..37f2f505c5089928d5da827c703e0ede2aba965a 100644 --- a/Sources/XXModels/Models/ContactChatInfo.swift +++ b/Sources/XXModels/Models/ContactChatInfo.swift @@ -51,12 +51,24 @@ extension ContactChatInfo { /// If set, only chats with contacts that have any of the provided /// auth statuses will be included. /// If `nil` (default), the filter is not used. + /// - isBlocked: Filter by other contact's `isBlocked` status. + /// If `true`, only chats with blocked contacts are included. + /// If `false`, only chats with non-blocked contacts are included. + /// If `nil` (default), the filter is not used. + /// - isBanned: Filter by other contact's `isBanned` status + /// If `true`, only chats with banned contacts are included. + /// If `false`, only chats with non-banned contacts are included. + /// If `nil` (default), the filter is not used. public init( userId: Contact.ID, - authStatus: Set<Contact.AuthStatus>? = nil + authStatus: Set<Contact.AuthStatus>? = nil, + isBlocked: Bool? = nil, + isBanned: Bool? = nil ) { self.userId = userId self.authStatus = authStatus + self.isBlocked = isBlocked + self.isBanned = isBanned } /// Current user's contact ID @@ -68,5 +80,19 @@ extension ContactChatInfo { /// auth statuses will be included. /// If `nil`, the filter is not used. public var authStatus: Set<Contact.AuthStatus>? + + /// Filter by other contact's `isBlocked` status + /// + /// If `true`, only chats with blocked contacts are included. + /// If `false`, only chats with non-blocked contacts are included. + /// If `nil`, the filter is not used. + public var isBlocked: Bool? + + /// Filter by other contact's `isBanned` status + /// + /// If `true`, only chats with banned contacts are included. + /// If `false`, only chats with non-banned contacts are included. + /// If `nil`, the filter is not used. + public var isBanned: Bool? } } diff --git a/Sources/XXModels/Models/Group.swift b/Sources/XXModels/Models/Group.swift index 4ac7e79228dfbe3d8e79485bd399be5a225898a1..b7f9b0d0641115c0ec44aeeffcd97abe74874668 100644 --- a/Sources/XXModels/Models/Group.swift +++ b/Sources/XXModels/Models/Group.swift @@ -99,16 +99,28 @@ extension Group { /// - authStatus: Filter groups by auth status. /// If set, only groups with any of the provided auth statuses will be fetched. /// If `nil` (default), the filter is not used. + /// - isLeaderBlocked: Filter by leader contact's `isBlocked` status. + /// If `true`, only groups with blocked leader contacts are included. + /// If `false`, only groups with non-blocked contacts are included. + /// If `nil` (default), the filter is not used. + /// - isLeaderBanned: Filter by leader contact's `isBlocked` status. + /// If `true`, only groups with blocked leader contacts are included. + /// If `false`, only groups with non-blocked contacts are included. + /// If `nil` (default), the filter is not used. /// - sortBy: Sort order (defaults to `.createdAt(desc: true)`). public init( id: Set<Group.ID>? = nil, withMessages: Bool? = nil, authStatus: Set<AuthStatus>? = nil, + isLeaderBlocked: Bool? = nil, + isLeaderBanned: Bool? = nil, sortBy: SortOrder = .createdAt(desc: true) ) { self.id = id self.withMessages = withMessages self.authStatus = authStatus + self.isLeaderBlocked = isLeaderBlocked + self.isLeaderBanned = isLeaderBanned self.sortBy = sortBy } @@ -128,6 +140,20 @@ extension Group { /// If `nil`, the filter is not used. public var authStatus: Set<AuthStatus>? + /// Filter by leader contact's `isBlocked` status + /// + /// If `true`, only groups with blocked leader contacts are included. + /// If `false`, only groups with non-blocked contacts are included. + /// If `nil`, the filter is not used. + public var isLeaderBlocked: Bool? + + /// Filter by leader contact's `isBanned` status + /// + /// If `true`, only groups with banned leader contacts are included. + /// If `false`, only groups with non-banned leader contacts are included. + /// If `nil`, the filter is not used. + public var isLeaderBanned: Bool? + /// Groups sort order public var sortBy: SortOrder } diff --git a/Sources/XXModels/Models/GroupChatInfo.swift b/Sources/XXModels/Models/GroupChatInfo.swift index a9db76634871e70b6fa6ffd9e7ce84a4d52b39a2..4e5f4c592f4176072817198ad4f4afefa16b5aeb 100644 --- a/Sources/XXModels/Models/GroupChatInfo.swift +++ b/Sources/XXModels/Models/GroupChatInfo.swift @@ -49,10 +49,30 @@ extension GroupChatInfo { /// - authStatus: Filter groups by auth status. /// If set, only groups with any of the provided auth statuses will be included. /// If `nil`, the filter is not used. + /// - isLeaderBlocked: Filter by leader contact's `isBlocked` status. + /// If `true`, only groups with blocked leader contacts are included. + /// If `false`, only groups with non-blocked contacts are included. + /// If `nil` (default), the filter is not used. + /// - isLeaderBanned: Filter by leader contact's `isBlocked` status. + /// If `true`, only groups with blocked leader contacts are included. + /// If `false`, only groups with non-blocked contacts are included. + /// If `nil` (default), the filter is not used. + /// - excludeBlockedContactsMessages: Exclude messages from blocked contacts + /// (defaults to `false`). + /// - excludeBannedContactsMessages: Exclude messages from banned contacts + /// (defaults to `false`). public init( - authStatus: Set<Group.AuthStatus>? = nil + authStatus: Set<Group.AuthStatus>? = nil, + isLeaderBlocked: Bool? = nil, + isLeaderBanned: Bool? = nil, + excludeBlockedContactsMessages: Bool = false, + excludeBannedContactsMessages: Bool = false ) { self.authStatus = authStatus + self.isLeaderBlocked = isLeaderBlocked + self.isLeaderBanned = isLeaderBanned + self.excludeBlockedContactsMessages = excludeBlockedContactsMessages + self.excludeBannedContactsMessages = excludeBannedContactsMessages } /// Filter groups by auth status @@ -60,5 +80,25 @@ extension GroupChatInfo { /// If set, only groups with any of the provided auth statuses will be included. /// If `nil`, the filter is not used. public var authStatus: Set<Group.AuthStatus>? + + /// Filter by leader contact's `isBlocked` status + /// + /// If `true`, only groups with blocked leader contacts are included. + /// If `false`, only groups with non-blocked contacts are included. + /// If `nil`, the filter is not used. + public var isLeaderBlocked: Bool? + + /// Filter by leader contact's `isBanned` status + /// + /// If `true`, only groups with banned leader contacts are included. + /// If `false`, only groups with non-banned leader contacts are included. + /// If `nil`, the filter is not used. + public var isLeaderBanned: Bool? + + /// Exclude messages from blocked contacts. + public var excludeBlockedContactsMessages: Bool + + /// Exclude messages from banned contacts. + public var excludeBannedContactsMessages: Bool } } diff --git a/Sources/XXModels/Models/Message.swift b/Sources/XXModels/Models/Message.swift index 9e75dd783458eec82f1697c956c72d44dcd6befe..cc5645d5f15353acf69ad6abf1180fd17aabe239 100644 --- a/Sources/XXModels/Models/Message.swift +++ b/Sources/XXModels/Models/Message.swift @@ -176,6 +176,14 @@ extension Message { /// If `true`, get only unread messages. /// If `false`, get only read messages. /// If `nil` (default), disable the filter. + /// - isBlocked: Filter by sender's contact `isBlocked` status. + /// If `true`, include only messages from blocked senders. + /// If `false`, include only messages from non-blocked senders. + /// If `nil` (default), disable the filter. + /// - isBanned: Filter by sender's contact `isBanned` status. + /// If `true`, include only messages from banned senders. + /// If `false`, include only messages from non-banned senders. + /// If `nil` (default), disable the filter. /// - fileTransferId: Filter by file transfer id. /// If `.some(.some(fileTransferId))`, get messages with provided `fileTransferId`. /// If `.some(.none)`, get messages without `fileTransferId`. @@ -187,6 +195,8 @@ extension Message { chat: Chat? = nil, status: Set<Status>? = nil, isUnread: Bool? = nil, + isSenderBlocked: Bool? = nil, + isSenderBanned: Bool? = nil, fileTransferId: FileTransfer.ID?? = nil, sortBy: SortOrder = .date() ) { @@ -195,6 +205,8 @@ extension Message { self.chat = chat self.status = status self.isUnread = isUnread + self.isSenderBlocked = isSenderBlocked + self.isSenderBanned = isSenderBanned self.fileTransferId = fileTransferId self.sortBy = sortBy } @@ -229,6 +241,20 @@ extension Message { /// If `nil`, disable the filter. public var isUnread: Bool? + /// Filter by sender's contact `isBlocked` status + /// + /// If `true`, include only messages from blocked senders. + /// If `false`, include only messages from non-blocked senders. + /// If `nil`, disable the filter. + public var isSenderBlocked: Bool? + + /// Filter by sender's contact `isBanned` status + /// + /// If `true`, include only messages from banned senders. + /// If `false`, include only messages from non-banned senders. + /// If `nil`, disable the filter. + public var isSenderBanned: Bool? + /// Filter by file transfer id /// /// If `.some(.some(fileTransferId))`, get messages with provided `fileTransferId`. diff --git a/Tests/XXDatabaseTests/Contact+GRDBTests.swift b/Tests/XXDatabaseTests/Contact+GRDBTests.swift index 58ee5c8a19618240437927d8c75bb1b5f395a68f..ea441558e1fadb088b94cd393e1837200cbdffcc 100644 --- a/Tests/XXDatabaseTests/Contact+GRDBTests.swift +++ b/Tests/XXDatabaseTests/Contact+GRDBTests.swift @@ -452,4 +452,68 @@ final class ContactGRDBTests: XCTestCase { contactF, ]) } + + func testFetchingByBlockedStatus() throws { + // Mock up contacts: + + let contactA = try db.saveContact(.stub("A").withBlocked(false)) + let contactB = try db.saveContact(.stub("B").withBlocked(true)) + let contactC = try db.saveContact(.stub("C").withBlocked(false)) + let contactD = try db.saveContact(.stub("D").withBlocked(true)) + + // Fetch blocked contacts: + + XCTAssertNoDifference(try db.fetchContacts(.init(isBlocked: true)), [ + contactB, + contactD, + ]) + + // Fetch not blocked contacts: + + XCTAssertNoDifference(try db.fetchContacts(.init(isBlocked: false)), [ + contactA, + contactC, + ]) + + // Fetch contacts regardless blocked status: + + XCTAssertNoDifference(try db.fetchContacts(.init(isBlocked: nil)), [ + contactA, + contactB, + contactC, + contactD, + ]) + } + + func testFetchingByBannedStatus() throws { + // Mock up contacts: + + let contactA = try db.saveContact(.stub("A").withBanned(false)) + let contactB = try db.saveContact(.stub("B").withBanned(true)) + let contactC = try db.saveContact(.stub("C").withBanned(false)) + let contactD = try db.saveContact(.stub("D").withBanned(true)) + + // Fetch banned contacts: + + XCTAssertNoDifference(try db.fetchContacts(.init(isBanned: true)), [ + contactB, + contactD, + ]) + + // Fetch not banned contacts: + + XCTAssertNoDifference(try db.fetchContacts(.init(isBanned: false)), [ + contactA, + contactC, + ]) + + // Fetch contacts regardless banned status: + + XCTAssertNoDifference(try db.fetchContacts(.init(isBanned: nil)), [ + contactA, + contactB, + contactC, + contactD, + ]) + } } diff --git a/Tests/XXDatabaseTests/ContactChatInfo+GRDBTests.swift b/Tests/XXDatabaseTests/ContactChatInfo+GRDBTests.swift index 05a1cb0c2294efe6e0a906f7e41786f4eac75940..b142b68e0e4e833598f1da2fcb18e40b1adc1cda 100644 --- a/Tests/XXDatabaseTests/ContactChatInfo+GRDBTests.swift +++ b/Tests/XXDatabaseTests/ContactChatInfo+GRDBTests.swift @@ -259,4 +259,258 @@ final class ContactChatInfoGRDBTests: XCTestCase { ] ) } + + func testFetchingByContactBlockedStatus() throws { + // Mock up contacts: + + let contactA = try db.saveContact(.stub("A").withBlocked(false)) + let contactB = try db.saveContact(.stub("B").withBlocked(true)) + let contactC = try db.saveContact(.stub("C").withBlocked(false)) + let contactD = try db.saveContact(.stub("D").withBlocked(true)) + + // Mock up conversation between contact A and B: + + try db.saveMessage(.stub( + from: contactA, + to: contactB, + at: 1, + isUnread: false + )) + + try db.saveMessage(.stub( + from: contactB, + to: contactA, + at: 2, + isUnread: true + )) + + let lastMessage_betweenAandB_at3 = try db.saveMessage(.stub( + from: contactA, + to: contactB, + at: 3, + isUnread: true + )) + + // Mock up conversation between contact A and C: + + try db.saveMessage(.stub( + from: contactA, + to: contactC, + at: 4, + isUnread: false + )) + + let lastMessage_betweenAandC_at5 = try db.saveMessage(.stub( + from: contactC, + to: contactA, + at: 5, + isUnread: true + )) + + // Mock up conversation between contact A and D: + + try db.saveMessage(.stub( + from: contactA, + to: contactD, + at: 6, + isUnread: false + )) + + let lastMessage_betweenAandD_at7 = try db.saveMessage(.stub( + from: contactD, + to: contactA, + at: 7, + isUnread: false + )) + + // Fetch chats between contact A and blocked contacts: + + XCTAssertNoDifference( + try db.fetchContactChatInfos(ContactChatInfo.Query( + userId: contactA.id, + isBlocked: true + )), + [ + ContactChatInfo( + contact: contactD, + lastMessage: lastMessage_betweenAandD_at7, + unreadCount: 0 + ), + ContactChatInfo( + contact: contactB, + lastMessage: lastMessage_betweenAandB_at3, + unreadCount: 2 + ), + ] + ) + + // Fetch chats between contact A and non-blocked contacts: + + XCTAssertNoDifference( + try db.fetchContactChatInfos(ContactChatInfo.Query( + userId: contactA.id, + isBlocked: false + )), + [ + ContactChatInfo( + contact: contactC, + lastMessage: lastMessage_betweenAandC_at5, + unreadCount: 1 + ), + ] + ) + + // Fetch chats between contact A and other contacts, regardless its `isBlocked` status: + + XCTAssertNoDifference( + try db.fetchContactChatInfos(ContactChatInfo.Query( + userId: contactA.id, + isBlocked: nil + )), + [ + ContactChatInfo( + contact: contactD, + lastMessage: lastMessage_betweenAandD_at7, + unreadCount: 0 + ), + ContactChatInfo( + contact: contactC, + lastMessage: lastMessage_betweenAandC_at5, + unreadCount: 1 + ), + ContactChatInfo( + contact: contactB, + lastMessage: lastMessage_betweenAandB_at3, + unreadCount: 2 + ), + ] + ) + } + + func testFetchingByContactBannedStatus() throws { + // Mock up contacts: + + let contactA = try db.saveContact(.stub("A").withBanned(false)) + let contactB = try db.saveContact(.stub("B").withBanned(true)) + let contactC = try db.saveContact(.stub("C").withBanned(false)) + let contactD = try db.saveContact(.stub("D").withBanned(true)) + + // Mock up conversation between contact A and B: + + try db.saveMessage(.stub( + from: contactA, + to: contactB, + at: 1, + isUnread: false + )) + + try db.saveMessage(.stub( + from: contactB, + to: contactA, + at: 2, + isUnread: true + )) + + let lastMessage_betweenAandB_at3 = try db.saveMessage(.stub( + from: contactA, + to: contactB, + at: 3, + isUnread: true + )) + + // Mock up conversation between contact A and C: + + try db.saveMessage(.stub( + from: contactA, + to: contactC, + at: 4, + isUnread: false + )) + + let lastMessage_betweenAandC_at5 = try db.saveMessage(.stub( + from: contactC, + to: contactA, + at: 5, + isUnread: true + )) + + // Mock up conversation between contact A and D: + + try db.saveMessage(.stub( + from: contactA, + to: contactD, + at: 6, + isUnread: false + )) + + let lastMessage_betweenAandD_at7 = try db.saveMessage(.stub( + from: contactD, + to: contactA, + at: 7, + isUnread: false + )) + + // Fetch chats between contact A and banned contacts: + + XCTAssertNoDifference( + try db.fetchContactChatInfos(ContactChatInfo.Query( + userId: contactA.id, + isBanned: true + )), + [ + ContactChatInfo( + contact: contactD, + lastMessage: lastMessage_betweenAandD_at7, + unreadCount: 0 + ), + ContactChatInfo( + contact: contactB, + lastMessage: lastMessage_betweenAandB_at3, + unreadCount: 2 + ), + ] + ) + + // Fetch chats between contact A and non-banned contacts: + + XCTAssertNoDifference( + try db.fetchContactChatInfos(ContactChatInfo.Query( + userId: contactA.id, + isBanned: false + )), + [ + ContactChatInfo( + contact: contactC, + lastMessage: lastMessage_betweenAandC_at5, + unreadCount: 1 + ), + ] + ) + + // Fetch chats between contact A and other contacts, regardless its `isBanned` status: + + XCTAssertNoDifference( + try db.fetchContactChatInfos(ContactChatInfo.Query( + userId: contactA.id, + isBanned: nil + )), + [ + ContactChatInfo( + contact: contactD, + lastMessage: lastMessage_betweenAandD_at7, + unreadCount: 0 + ), + ContactChatInfo( + contact: contactC, + lastMessage: lastMessage_betweenAandC_at5, + unreadCount: 1 + ), + ContactChatInfo( + contact: contactB, + lastMessage: lastMessage_betweenAandB_at3, + unreadCount: 2 + ), + ] + ) + } } diff --git a/Tests/XXDatabaseTests/Group+GRDBTests.swift b/Tests/XXDatabaseTests/Group+GRDBTests.swift index 1a255b6db1611eed32f69c03824e7e2a438188fa..ad3786a7f8de7725b4b884fa8275473834fad2ad 100644 --- a/Tests/XXDatabaseTests/Group+GRDBTests.swift +++ b/Tests/XXDatabaseTests/Group+GRDBTests.swift @@ -159,4 +159,84 @@ final class GroupGRDBTests: XCTestCase { [groupA, groupB] ) } + + func testFetchingWithBlockedLeaders() throws { + // Mock up contacts: + + let contactA = try db.saveContact(.stub("A").withBlocked(false)) + let contactB = try db.saveContact(.stub("B").withBlocked(true)) + + // Mock up groups: + + let groupA = try db.saveGroup(.stub( + "A", + leaderId: contactA.id, + createdAt: .stub(1) + )) + + let groupB = try db.saveGroup(.stub( + "B", + leaderId: contactB.id, + createdAt: .stub(2) + )) + + // Fetch groups with blocked leaders: + + XCTAssertNoDifference(try db.fetchGroups(.init(isLeaderBlocked: true)), [ + groupB, + ]) + + // Fetch groups with non-blocked leaders: + + XCTAssertNoDifference(try db.fetchGroups(.init(isLeaderBlocked: false)), [ + groupA, + ]) + + // Fetch groups regardless leader's blocked status: + + XCTAssertNoDifference(try db.fetchGroups(.init(isLeaderBlocked: nil)), [ + groupB, + groupA, + ]) + } + + func testFetchingWithBannedLeaders() throws { + // Mock up contacts: + + let contactA = try db.saveContact(.stub("A").withBanned(false)) + let contactB = try db.saveContact(.stub("B").withBanned(true)) + + // Mock up groups: + + let groupA = try db.saveGroup(.stub( + "A", + leaderId: contactA.id, + createdAt: .stub(1) + )) + + let groupB = try db.saveGroup(.stub( + "B", + leaderId: contactB.id, + createdAt: .stub(2) + )) + + // Fetch groups with banned leaders: + + XCTAssertNoDifference(try db.fetchGroups(.init(isLeaderBanned: true)), [ + groupB, + ]) + + // Fetch groups with non-banned leaders: + + XCTAssertNoDifference(try db.fetchGroups(.init(isLeaderBanned: false)), [ + groupA, + ]) + + // Fetch groups regardless leader's banned status: + + XCTAssertNoDifference(try db.fetchGroups(.init(isLeaderBanned: nil)), [ + groupB, + groupA, + ]) + } } diff --git a/Tests/XXDatabaseTests/GroupChatInfo+GRDBTests.swift b/Tests/XXDatabaseTests/GroupChatInfo+GRDBTests.swift index ffc5c4a82a27b43e3e0541c59acdbc3a8b38c3c5..8618df81c6a9294548e754a1987f76c84dae876b 100644 --- a/Tests/XXDatabaseTests/GroupChatInfo+GRDBTests.swift +++ b/Tests/XXDatabaseTests/GroupChatInfo+GRDBTests.swift @@ -139,4 +139,436 @@ final class GroupChatInfoGRDBTests: XCTestCase { ] ) } + + func testExcludeMessagesFromBlockedContacts() throws { + // Mock up contacts: + + let contactA = try db.saveContact(.stub("A")) + let contactB = try db.saveContact(.stub("B")) + let contactC = try db.saveContact(.stub("C").withBlocked(true)) + + // Mock up groups: + + let groupA = try db.saveGroup(.stub( + "A", + leaderId: contactA.id, + createdAt: .stub(1) + )) + + try db.saveGroupMember(GroupMember(groupId: groupA.id, contactId: contactA.id)) + try db.saveGroupMember(GroupMember(groupId: groupA.id, contactId: contactB.id)) + try db.saveGroupMember(GroupMember(groupId: groupA.id, contactId: contactC.id)) + + let groupB = try db.saveGroup(.stub( + "B", + leaderId: contactB.id, + createdAt: .stub(2) + )) + + try db.saveGroupMember(GroupMember(groupId: groupB.id, contactId: contactA.id)) + try db.saveGroupMember(GroupMember(groupId: groupB.id, contactId: contactB.id)) + try db.saveGroupMember(GroupMember(groupId: groupB.id, contactId: contactC.id)) + + let groupC = try db.saveGroup(.stub( + "C", + leaderId: contactC.id, + createdAt: .stub(3) + )) + + try db.saveGroupMember(GroupMember(groupId: groupC.id, contactId: contactA.id)) + try db.saveGroupMember(GroupMember(groupId: groupC.id, contactId: contactB.id)) + try db.saveGroupMember(GroupMember(groupId: groupC.id, contactId: contactC.id)) + + // Mock up messages in group A: + + try db.saveMessage(.stub( + from: contactA, + to: groupA, + at: 1, + isUnread: true + )) + + let groupA_message_fromB_at2 = try db.saveMessage(.stub( + from: contactB, + to: groupA, + at: 2, + isUnread: true + )) + + let groupA_message_fromC_at3 = try db.saveMessage(.stub( + from: contactC, + to: groupA, + at: 3, + isUnread: true + )) + + // Mock up messages in group B: + + let groupB_message_fromC_at4 = try db.saveMessage(.stub( + from: contactC, + to: groupB, + at: 4, + isUnread: true + )) + + // Mock up messages in group C: + + let groupC_message_fromA_at5 = try db.saveMessage(.stub( + from: contactA, + to: groupC, + at: 5, + isUnread: true + )) + + let groupC_message_fromC_at6 = try db.saveMessage(.stub( + from: contactC, + to: groupC, + at: 6, + isUnread: true + )) + + // Fetch group chats excluding messages from blocked contacts: + + XCTAssertNoDifference(try db.fetchGroupChatInfos(.init(excludeBlockedContactsMessages: true)), [ + GroupChatInfo( + group: groupC, + lastMessage: groupC_message_fromA_at5, + unreadCount: 1 + ), + GroupChatInfo( + group: groupA, + lastMessage: groupA_message_fromB_at2, + unreadCount: 2 + ), + ]) + + // Fetch group chats including messages from blocked contacts: + + XCTAssertNoDifference(try db.fetchGroupChatInfos(.init(excludeBlockedContactsMessages: false)), [ + GroupChatInfo( + group: groupC, + lastMessage: groupC_message_fromC_at6, + unreadCount: 2 + ), + GroupChatInfo( + group: groupB, + lastMessage: groupB_message_fromC_at4, + unreadCount: 1 + ), + GroupChatInfo( + group: groupA, + lastMessage: groupA_message_fromC_at3, + unreadCount: 3 + ), + ]) + } + + func testExcludeMessagesFromBannedContacts() throws { + // Mock up contacts: + + let contactA = try db.saveContact(.stub("A")) + let contactB = try db.saveContact(.stub("B")) + let contactC = try db.saveContact(.stub("C").withBanned(true)) + + // Mock up groups: + + let groupA = try db.saveGroup(.stub( + "A", + leaderId: contactA.id, + createdAt: .stub(1) + )) + + try db.saveGroupMember(GroupMember(groupId: groupA.id, contactId: contactA.id)) + try db.saveGroupMember(GroupMember(groupId: groupA.id, contactId: contactB.id)) + try db.saveGroupMember(GroupMember(groupId: groupA.id, contactId: contactC.id)) + + let groupB = try db.saveGroup(.stub( + "B", + leaderId: contactB.id, + createdAt: .stub(2) + )) + + try db.saveGroupMember(GroupMember(groupId: groupB.id, contactId: contactA.id)) + try db.saveGroupMember(GroupMember(groupId: groupB.id, contactId: contactB.id)) + try db.saveGroupMember(GroupMember(groupId: groupB.id, contactId: contactC.id)) + + let groupC = try db.saveGroup(.stub( + "C", + leaderId: contactC.id, + createdAt: .stub(3) + )) + + try db.saveGroupMember(GroupMember(groupId: groupC.id, contactId: contactA.id)) + try db.saveGroupMember(GroupMember(groupId: groupC.id, contactId: contactB.id)) + try db.saveGroupMember(GroupMember(groupId: groupC.id, contactId: contactC.id)) + + // Mock up messages in group A: + + try db.saveMessage(.stub( + from: contactA, + to: groupA, + at: 1, + isUnread: true + )) + + let groupA_message_fromB_at2 = try db.saveMessage(.stub( + from: contactB, + to: groupA, + at: 2, + isUnread: true + )) + + let groupA_message_fromC_at3 = try db.saveMessage(.stub( + from: contactC, + to: groupA, + at: 3, + isUnread: true + )) + + // Mock up messages in group B: + + let groupB_message_fromC_at4 = try db.saveMessage(.stub( + from: contactC, + to: groupB, + at: 4, + isUnread: true + )) + + // Mock up messages in group C: + + let groupC_message_fromA_at5 = try db.saveMessage(.stub( + from: contactA, + to: groupC, + at: 5, + isUnread: true + )) + + let groupC_message_fromC_at6 = try db.saveMessage(.stub( + from: contactC, + to: groupC, + at: 6, + isUnread: true + )) + + // Fetch group chats excluding messages from banned contacts: + + XCTAssertNoDifference(try db.fetchGroupChatInfos(.init(excludeBannedContactsMessages: true)), [ + GroupChatInfo( + group: groupC, + lastMessage: groupC_message_fromA_at5, + unreadCount: 1 + ), + GroupChatInfo( + group: groupA, + lastMessage: groupA_message_fromB_at2, + unreadCount: 2 + ), + ]) + + // Fetch group chats including messages from banned contacts: + + XCTAssertNoDifference(try db.fetchGroupChatInfos(.init(excludeBannedContactsMessages: false)), [ + GroupChatInfo( + group: groupC, + lastMessage: groupC_message_fromC_at6, + unreadCount: 2 + ), + GroupChatInfo( + group: groupB, + lastMessage: groupB_message_fromC_at4, + unreadCount: 1 + ), + GroupChatInfo( + group: groupA, + lastMessage: groupA_message_fromC_at3, + unreadCount: 3 + ), + ]) + } + + func testFilterGroupsWithBlockedLeaders() throws { + // Mock up contacts: + + let contactA = try db.saveContact(.stub("A")) + let contactB = try db.saveContact(.stub("B")) + let contactC = try db.saveContact(.stub("C").withBlocked(true)) + + // Mock up groups: + + let groupA = try db.saveGroup(.stub( + "A", + leaderId: contactA.id, + createdAt: .stub(1) + )) + + let groupB = try db.saveGroup(.stub( + "B", + leaderId: contactB.id, + createdAt: .stub(2) + )) + + let groupC = try db.saveGroup(.stub( + "C", + leaderId: contactC.id, + createdAt: .stub(3) + )) + + // Mock up messages: + + let groupA_message_fromA_at1 = try db.saveMessage(.stub( + from: contactA, + to: groupA, + at: 1 + )) + + let groupB_message_fromA_at2 = try db.saveMessage(.stub( + from: contactA, + to: groupB, + at: 2 + )) + + let groupC_message_fromA_at3 = try db.saveMessage(.stub( + from: contactA, + to: groupC, + at: 3 + )) + + // Fetch group chats with blocked leaders: + + XCTAssertNoDifference(try db.fetchGroupChatInfos(.init(isLeaderBlocked: true)), [ + GroupChatInfo( + group: groupC, + lastMessage: groupC_message_fromA_at3, + unreadCount: 0 + ), + ]) + + // Fetch group chats with non-blocked leaders: + + XCTAssertNoDifference(try db.fetchGroupChatInfos(.init(isLeaderBlocked: false)), [ + GroupChatInfo( + group: groupB, + lastMessage: groupB_message_fromA_at2, + unreadCount: 0 + ), + GroupChatInfo( + group: groupA, + lastMessage: groupA_message_fromA_at1, + unreadCount: 0 + ), + ]) + + // Fetch group chats with regardless leader's blocked status: + + XCTAssertNoDifference(try db.fetchGroupChatInfos(.init(isLeaderBlocked: nil)), [ + GroupChatInfo( + group: groupC, + lastMessage: groupC_message_fromA_at3, + unreadCount: 0 + ), + GroupChatInfo( + group: groupB, + lastMessage: groupB_message_fromA_at2, + unreadCount: 0 + ), + GroupChatInfo( + group: groupA, + lastMessage: groupA_message_fromA_at1, + unreadCount: 0 + ), + ]) + } + + func testFilterGroupsWithBannedLeaders() throws { + // Mock up contacts: + + let contactA = try db.saveContact(.stub("A")) + let contactB = try db.saveContact(.stub("B")) + let contactC = try db.saveContact(.stub("C").withBanned(true)) + + // Mock up groups: + + let groupA = try db.saveGroup(.stub( + "A", + leaderId: contactA.id, + createdAt: .stub(1) + )) + + let groupB = try db.saveGroup(.stub( + "B", + leaderId: contactB.id, + createdAt: .stub(2) + )) + + let groupC = try db.saveGroup(.stub( + "C", + leaderId: contactC.id, + createdAt: .stub(3) + )) + + // Mock up messages: + + let groupA_message_fromA_at1 = try db.saveMessage(.stub( + from: contactA, + to: groupA, + at: 1 + )) + + let groupB_message_fromA_at2 = try db.saveMessage(.stub( + from: contactA, + to: groupB, + at: 2 + )) + + let groupC_message_fromA_at3 = try db.saveMessage(.stub( + from: contactA, + to: groupC, + at: 3 + )) + + // Fetch group chats with banned leaders: + + XCTAssertNoDifference(try db.fetchGroupChatInfos(.init(isLeaderBanned: true)), [ + GroupChatInfo( + group: groupC, + lastMessage: groupC_message_fromA_at3, + unreadCount: 0 + ), + ]) + + // Fetch group chats with non-banned leaders: + + XCTAssertNoDifference(try db.fetchGroupChatInfos(.init(isLeaderBanned: false)), [ + GroupChatInfo( + group: groupB, + lastMessage: groupB_message_fromA_at2, + unreadCount: 0 + ), + GroupChatInfo( + group: groupA, + lastMessage: groupA_message_fromA_at1, + unreadCount: 0 + ), + ]) + + // Fetch group chats with regardless leader's banned status: + + XCTAssertNoDifference(try db.fetchGroupChatInfos(.init(isLeaderBanned: nil)), [ + GroupChatInfo( + group: groupC, + lastMessage: groupC_message_fromA_at3, + unreadCount: 0 + ), + GroupChatInfo( + group: groupB, + lastMessage: groupB_message_fromA_at2, + unreadCount: 0 + ), + GroupChatInfo( + group: groupA, + lastMessage: groupA_message_fromA_at1, + unreadCount: 0 + ), + ]) + } } diff --git a/Tests/XXDatabaseTests/Message+GRDBTests.swift b/Tests/XXDatabaseTests/Message+GRDBTests.swift index f77d31c6996d3521b486f2cb2a441409f180394c..00a2c995d8d074db12f6d8899d6033ffd9ff053e 100644 --- a/Tests/XXDatabaseTests/Message+GRDBTests.swift +++ b/Tests/XXDatabaseTests/Message+GRDBTests.swift @@ -474,6 +474,94 @@ final class MessageGRDBTests: XCTestCase { ) } + func testFetchingBySenderBlockedStatus() throws { + // Mock up contacts: + + let contactA = try db.saveContact(.stub("A").withBlocked(false)) + let contactB = try db.saveContact(.stub("B").withBlocked(true)) + let contactC = try db.saveContact(.stub("C").withBlocked(false)) + + // Mock up messages: + + let message_AtoB_at1 = try db.saveMessage(.stub(from: contactA, to: contactB, at: 1)) + let message_AtoC_at2 = try db.saveMessage(.stub(from: contactA, to: contactC, at: 2)) + let message_BtoA_at3 = try db.saveMessage(.stub(from: contactB, to: contactA, at: 3)) + let message_BtoC_at4 = try db.saveMessage(.stub(from: contactB, to: contactC, at: 4)) + let message_CtoA_at5 = try db.saveMessage(.stub(from: contactC, to: contactA, at: 5)) + let message_CtoB_at6 = try db.saveMessage(.stub(from: contactC, to: contactB, at: 6)) + + // Fetch messages from blocked contacts: + + XCTAssertNoDifference(try db.fetchMessages(.init(isSenderBlocked: true)), [ + message_BtoA_at3, + message_BtoC_at4, + ]) + + // Fetch messages from non-blocked contacts: + + XCTAssertNoDifference(try db.fetchMessages(.init(isSenderBlocked: false)), [ + message_AtoB_at1, + message_AtoC_at2, + message_CtoA_at5, + message_CtoB_at6, + ]) + + // Fetch messages regardless sender contact's `isBlocked` status: + + XCTAssertNoDifference(try db.fetchMessages(.init(isSenderBlocked: nil)), [ + message_AtoB_at1, + message_AtoC_at2, + message_BtoA_at3, + message_BtoC_at4, + message_CtoA_at5, + message_CtoB_at6, + ]) + } + + func testFetchingBySenderBannedStatus() throws { + // Mock up contacts: + + let contactA = try db.saveContact(.stub("A").withBanned(false)) + let contactB = try db.saveContact(.stub("B").withBanned(true)) + let contactC = try db.saveContact(.stub("C").withBanned(false)) + + // Mock up messages: + + let message_AtoB_at1 = try db.saveMessage(.stub(from: contactA, to: contactB, at: 1)) + let message_AtoC_at2 = try db.saveMessage(.stub(from: contactA, to: contactC, at: 2)) + let message_BtoA_at3 = try db.saveMessage(.stub(from: contactB, to: contactA, at: 3)) + let message_BtoC_at4 = try db.saveMessage(.stub(from: contactB, to: contactC, at: 4)) + let message_CtoA_at5 = try db.saveMessage(.stub(from: contactC, to: contactA, at: 5)) + let message_CtoB_at6 = try db.saveMessage(.stub(from: contactC, to: contactB, at: 6)) + + // Fetch messages from banned contacts: + + XCTAssertNoDifference(try db.fetchMessages(.init(isSenderBanned: true)), [ + message_BtoA_at3, + message_BtoC_at4, + ]) + + // Fetch messages from non-banned contacts: + + XCTAssertNoDifference(try db.fetchMessages(.init(isSenderBanned: false)), [ + message_AtoB_at1, + message_AtoC_at2, + message_CtoA_at5, + message_CtoB_at6, + ]) + + // Fetch messages regardless sender contact's `isBanned` status: + + XCTAssertNoDifference(try db.fetchMessages(.init(isSenderBanned: nil)), [ + message_AtoB_at1, + message_AtoC_at2, + message_BtoA_at3, + message_BtoC_at4, + message_CtoA_at5, + message_CtoB_at6, + ]) + } + func testDeletingMany() throws { // Mock up contacts diff --git a/Tests/XXDatabaseTests/Stubs.swift b/Tests/XXDatabaseTests/Stubs.swift index 45bee51e4299a85980de0ddc807efca2a33c24bf..780cbf60f4f51023a6a5bcda3d779a3a79a63d8e 100644 --- a/Tests/XXDatabaseTests/Stubs.swift +++ b/Tests/XXDatabaseTests/Stubs.swift @@ -62,6 +62,18 @@ extension Contact { contact.createdAt = createdAt return contact } + + func withBlocked(_ isBlocked: Bool) -> Contact { + var contact = self + contact.isBlocked = isBlocked + return contact + } + + func withBanned(_ isBanned: Bool) -> Contact { + var contact = self + contact.isBanned = isBanned + return contact + } } extension Group { diff --git a/Tests/XXLegacyDatabaseMigratorTests/__Snapshots__/MigratorTests/testMigratingLegacyDatabase1.contacts.json b/Tests/XXLegacyDatabaseMigratorTests/__Snapshots__/MigratorTests/testMigratingLegacyDatabase1.contacts.json index 6a4d011aada153fc5194706035d082a4688f510d..d1ced1fe373b30ea1f47703f61134c2565dea357 100644 --- a/Tests/XXLegacyDatabaseMigratorTests/__Snapshots__/MigratorTests/testMigratingLegacyDatabase1.contacts.json +++ b/Tests/XXLegacyDatabaseMigratorTests/__Snapshots__/MigratorTests/testMigratingLegacyDatabase1.contacts.json @@ -3,6 +3,8 @@ "authStatus" : "friend", "createdAt" : "1970-01-01T00:20:34Z", "id" : "bXktY29udGFjdC1pZA==", + "isBanned" : false, + "isBlocked" : false, "isRecent" : false, "marshaled" : "PHh4YygyKUd4Q1pwL0d2NW1UUDM1Q1FjUTEyNHdsbnZxVCtiMjBMZnRacDJjby84V2NEa0FaaUI5a1pvK0RsM1VqTVB1SlRwcHc4TDBPcnI3NnpTSlNyTG1mZ0kxRS9yNTQwRS9Ic3A3MXJaYW1HSWVkVitDVW5VVWgrVWVkOWRFQ3FxbnBnMjBLZVBKcUozMXlSN1ZQM0tWbXAza1NwMk0zM1dUOGgrUkU4TTJmcnVRRmFIQXg1MmY0QVhCalVhRlhYY25LK3J5WmJIemhRL0s2Q0w3NFJrbzdPdERoWDN0VXVna0kxWTdpekRaVDJ4RmZRZEN5T1lDbW96aUxQNm5UTDB3d2FycHFxSWxLeHl4TXl2QWErRWl4S3NzcGRPMktJNHNxTkkzYURsS2xZSzMrMUhrdVZSTENvNG90Y2xaMHRaY3VJb0Jkclc2UURwK2U5N216Wi93djN5UWNYSEIweWVxOFZsV0NidmJvelg3cWpjRUFPM3hNYWpSMEJnckVCSDJidDI0dEVGdm5VNFRwcW9jaWVveTdlM1c1RVZUaHhlWk5WTk1Zd01sM1pFb3R1VnBmQVN2NVJORkFJN0w5MTU1d2pmaStId0xrOEQrMjdmcEJ0STN1Q2tWa3JzY0tYMnNjY05VU1BKQ0JEQnlNRjVZZUNDTGF0Z01WY2VHWVZIV2VvcGxyZTdhY2Rrb2p6RC9wa1Bha1VwVGlsYURTQllRVVpQc3pVVS9wRkpNNURXRDBpdUI5NldzL0h4UUFBQWdBN1VpMTk2a0VIWE1WV0l2VkZvMjEwdEE9PXh4Yz4=" }, @@ -10,6 +12,8 @@ "authStatus" : "friend", "createdAt" : "2022-06-21T11:37:56Z", "id" : "JPm+zBboFVIEPrfsDz5Ue3fst77oxCwoLxNXrdqg+1MD", + "isBanned" : false, + "isBlocked" : false, "isRecent" : false, "marshaled" : "PHh4YygyKUpQbSt6QmJvRlZJRVByZnNEejVVZTNmc3Q3N294Q3dvTHhOWHJkcWcrMU1Ea0FaaUI5a1pvK0RsM1o5UjRZdC83ejFzTU9pT21qY2VyT0d2TWs5QW43NGhGUFF5M2lGNHJ6eDJRQy9HU1dYeWhVODhBdmdrL09DL2Qzeld0ZHM2VXpDSzlJQm5EczZ0c25JenlqdHFrb1JuRmkvUDBqWnltSjhUcCt1OUEvcmdhMWltdm9vcGRqQVUvakFtR2FWQXc5MjA4R2hKNUxSd3puandOeCtHamV2bWhRaUFaUW1lNnFaMXpQRjVNL3RyWjV2RS9iRUo4RHozRW91QWNTT0FNbWV0Q1ZSejZId0ZIcVhhK0g5ZStDKzJjM3lCUTAxQ1NVZDVBODkwOUY0TEExSGJNZFdYT1Z0SjkxRW80LzlSbTZHeTZmZzR1TDh0NXNqZ0VKYzBxOW9JSjlYcUZhWDcrOEo4SUpMWFZkeVBZYlB5ZVZxd1ljMkhxandnaUZMZ1lMTy9VeXdnRjA2U3NqUnpLci9xK1lVV3ptU2Y1cVJhelpXcUZIb3VORTkzNXFvVG02bzcrazlUWkczcXV2a3QzK00zUGNMc0oyU0lQNkd0VnNna0g1NG0vVGZGZXVyNXl5RGxBY1k4ZVZGTFFXRVZtcjl5ekhnK2xQZ2h5RFZaQ3hRTW5wZ0JYU0ZYUjNBQVNPMGtMNTNLZWR6WVp2WUYwYkFKUHVOMzkzVy9HeUtSMHd5L2p6clJJQUFBSUFCVmNYZGxjak0xTEZWeGQyVnlNelU3d3hiNTUydlFXTVU1RW5EUEtjZ2xiUT09eHhjPg==", "nickname" : "qwer35", @@ -19,6 +23,8 @@ "authStatus" : "friend", "createdAt" : "2022-06-21T11:46:18Z", "id" : "2qcF7Xl/QEn6Zu6cdQC0fteI6EeoEX9IY0nkBdmBbRYD", + "isBanned" : false, + "isBlocked" : false, "isRecent" : false, "marshaled" : "PHh4YygyKTJxY0Y3WGwvUUVuNlp1NmNkUUMwZnRlSTZFZW9FWDlJWTBua0JkbUJiUllEa0FaaUI5a1pvK0RsM2VIR2Q2WmRRbXBudlJGU2tKdnRLcndhNTFiYnIrbjNobEhHREJOVXN5eWJuOUI0eEk2cW53ajJWRWpUZ3I3OHY1L2ZadmVLZ2I4SGxUM0owY2hWYkxMREM1VnI3WEYrMklwYzlPYmF6L0xNMFgvNlNrRDlrN2ZjeENmblpoR1dpYW1iMmVZVU5XZGswZXNVbm9ua2tjS3dIK0hwSUd2eXJvcDBjUXpFbC9EVDZVTXVLMkRKNGFFT2R3YlVxZWhhazZvYjUwdDlpTm9nVytjZ2taT2ZSaTNJakxBVHVDdWx6WHYrVm9LK2lkcFU5Q2xOaFhlc1U0Rzk5eFRpUFRENXNQVDE2T1NXaFpxZjBJdGxrc05NRStuTVV2eWlLYXBOdzRNcTVFRTZOU3dwUVV2c2JiVGthZkpsc3RCdFl2WXNrVDBnWUg0R0t6YVZham5kZWhaQ090ejhsd0VzTFVGa2lyeEg3SEUvQldFRDdzTmZUZW1QTFRjd1BnU3NDTFgyanlvakgwMVRvMkxlK2FzUG1GYUhzNHhXaFlSVlpyUHJvRytLeS9ZdHJXY1ozdGN3U1AvUU1JOW9HSTVmRVFaL3ArVEtrSzBMKzVKbEVnb3huQ1NEWXZOSGp3Mk43THQwN2JVUnBQMHEycnVsdGNXQVpZUUN5UnJsN0wwbG05bm1GVUFBRFNlWCtOUUFuZ0ppZldQSnpHWDdIQ0R0MjdndDJmNnd2a3V0d1JBN29yWU1BRlZzYTJwb096amVKNzdWT2RyeDRuV3l5a1AzQU1JPXh4Yz4=", "nickname" : "lkjh", @@ -28,12 +34,16 @@ "authStatus" : "stranger", "createdAt" : "2022-06-21T11:47:51Z", "id" : "PHh4YygyKUd4Q1pwL0d2NW1UUDM1Q1FjUTEyNHdsbnZxVCtiMjBMZnRacDJjby84V2NEa0FaaUI5a1pvK0RsM1VqTVB1SlRwcHc4TDBPcnI3NnpTSlNyTG1mZ0kxRS9yNTQwRS9Ic3A3MXJaYW1HSWVkVitDVW5VVWgrVWVkOWRFQ3FxbnBnMjBLZVBKcUozMXlSN1ZQM0tWbXAza1NwMk0zM1dUOGgrUkU4TTJmcnVRRmFIQXg1MmY0QVhCalVhRlhYY25LK3J5WmJIemhRL0s2Q0w3NFJrbzdPdERoWDN0VXVna0kxWTdpekRaVDJ4RmZRZEN5T1lDbW96aUxQNm5UTDB3d2FycHFxSWxLeHl4TXl2QWErRWl4S3NzcGRPMktJNHNxTkkzYURsS2xZSzMrMUhrdVZSTENvNG90Y2xaMHRaY3VJb0Jkclc2UURwK2U5N216Wi93djN5UWNYSEIweWVxOFZsV0NidmJvelg3cWpjRUFPM3hNYWpSMEJnckVCSDJidDI0dEVGdm5VNFRwcW9jaWVveTdlM1c1RVZUaHhlWk5WTk1Zd01sM1pFb3R1VnBmQVN2NVJORkFJN0w5MTU1d2pmaStId0xrOEQrMjdmcEJ0STN1Q2tWa3JzY0tYMnNjY05VU1BKQ0JEQnlNRjVZZUNDTGF0Z01WY2VHWVZIV2VvcGxyZTdhY2Rrb2p6RC9wa1Bha1VwVGlsYURTQllRVVpQc3pVVS9wRkpNNURXRDBpdUI5NldzL0h4UUFBQWdBN1VpMTk2a0VIWE1WV0l2VkZvMjEwdEE9PXh4Yz4=", + "isBanned" : false, + "isBlocked" : false, "isRecent" : false }, { "authStatus" : "verified", "createdAt" : "2022-06-21T11:54:47Z", "id" : "QE7xGfzgsHBfyYmclvj79XmGL5fMFyTu54n0L7sNXFAD", + "isBanned" : false, + "isBlocked" : false, "isRecent" : false, "marshaled" : "PHh4YygyKVFFN3hHZnpnc0hCZnlZbWNsdmo3OVhtR0w1Zk1GeVR1NTRuMEw3c05YRkFEa0FaaUI5a1pvK0RsM1g1SEc2bmdaUHI1cjcwWjFIV0J2VXdrdWZyMkpucWtNK2Nxb1NPeUVCZ3JsZVF3OE9TSE5HUG5xcEkvendMM1p4VWFmNHYyd1NkYWdYeVB3S05lMFUvc1NvbWRrZ0gvT3pheWhKcDc5N0s3bEQwNzR5UjJHZldoSUNhNElNWVJTam5CUDFtUXcxeTBUcWE2cFQ3YlVUSi9HT01rUGx6eE5UZGd0UzFnZHhISWZndDlDb2RSYVRhbEdVbUlBSFBkUGlsbnZJZEdwZVF5Z1NQemtZMXAyRzFVQ3A0VnhzajlLejcwM2VoVWlHOGVMQmIxWkRQV3k3WmE1VUNqeEN6Wk1ZeUhJYVEyZ2d4SDN1aXVUYkpLZy9FM2Eyc1VkSjB5Y01DUmNqV2o2WnFuRXd1YmN6QVFjQmlmRGN0c1lka0RyNFNtaFRVU3QrdzBsNm1NaHdDSUpxSVhkcXJXcEtYeGhGa0JtYVkwNGdHZG9ndVhOeXA3M1lQYVU3TWtPdkZ3aFdzYTRjaFowZEs4NDJaUG5oVVNseTdQTzdaSjMyRU42Qm9HQTJXR1RON2hnWlQranZhMzdtRUVDd0dHNnVSdkN2R0ZJNTJpMlgrdlgzTTdxQUpwZy9OeTBrLytWK2U3bzIwNGtlQ2ViUkdxdnZRdUc5M2NyQ09pVlZVajhSLytlMEFBWjZMRkM2c3M2ZnMzSFFxSUlFVXB4eGlPOXBZL1ZDYmRJbWE3Tk13QzU0VVFBRlZ3YjJscmJETTd5ZktXNTBnd0lmZ1I3M0tqYkVKd2xnPT14eGM+", "username" : "poikl3" @@ -42,6 +52,8 @@ "authStatus" : "hidden", "createdAt" : "2022-06-21T11:57:42Z", "id" : "A2ehoC0Upl2n/pc0aRsArosO3hUKotgwjbUhotnuTU0D", + "isBanned" : false, + "isBlocked" : false, "isRecent" : false, "marshaled" : "PHh4YygyKUEyZWhvQzBVcGwybi9wYzBhUnNBcm9zTzNoVUtvdGd3amJVaG90bnVUVTBEa0FaaUI5a1pvK0RsM1JRNGpMalVuZGlsOHpWVG1DY1ZyMDQ4QnFOOEJtU1Z4SFNPaHRHekY2bmlVMzlXYmU5dlU4ZllWMjJnZFJnTGl5QTRjOHo3Y3ZtcUZHdEdOZEVzQ0pYdFpac3ZvRGxGbHB1SG1SL2tURXV1a2ZCQUs0dXd6a3FtV1BaUW83V05FVjZzYXRDSFdHRnhXRFpKSmM4R3dRR0RCUU9FQXUvais3cE1qcWJVeU5TOXNuNmtScEgra3VuYVBwRVFNUDBLNVI0UU12WEY2MXBneTFJbE5MdGhEWm5mRWlrV2ZyN29PMHlHVmZ3UVZyNjViSDh0Zm1Fd0hCL01vcldERFlGY3Eyd0g5bnZXUmI4N0tEMjhLWUxjQlNOVk96TnpBQXZLQWhBOW1zTHk1cnhTWFA3NWkzNXljMkRhQmNKR3Vma0hUUlV1Yktyc29TZS9GTTl1Uk5pT2ZwRkp6ZWZFU2dua2FIb0cxa2YyY0ZrRGNKSHY5WTJ5NW00UDAzV3p6M0tZOHdyQ0M3cEt0MmVFUEE2b2dRbm9pNlppKzdzV1FPSlRRbjlQeFI3TUsvSFpZU2NPeEdSZXA2bzFjTUpCR0c0djBRRnVsY09kY1RrVGMxYklhQzdOM0RMZXBCY3VBNVd6SDdxeU9kZC9lSmwwSHVxRll2QjAzZ2xyMHU1ZjBUK3NSMEFBYURPdE5oZWFiNFBpZ3UzVStQckV3d3lFN2RPZFZGY0dmWkVxY3pJUU9CWU9BRlY1YUdkMGREdEhWNGZUeWo4WjdvZnJWbGNVNWg0MXh4Yz4=", "username" : "yhgtt" @@ -50,6 +62,8 @@ "authStatus" : "requested", "createdAt" : "2022-06-21T11:59:21Z", "id" : "Tj/jHtrRO1Gvp9gI6uo98LrBjWng5HYflg3h/Op83KED", + "isBanned" : false, + "isBlocked" : false, "isRecent" : false, "marshaled" : "PHh4YygyKVRqL2pIdHJSTzFHdnA5Z0k2dW85OExyQmpXbmc1SFlmbGczaC9PcDgzS0VEa0FaaUI5a1pvK0RsM1ovQ3E5U3YyLzYyeWQ4SHNCMndXeWd2NzVkNXIxVk96Zm9URW1ENnl4TXJzbitLbHlhVzZ2a00vSnRpVVZtUVBIaU5vZFg4elZ6Q3pJNWVNV0RtWnRpTnA1a1l0dDVGTERZSzZaNlhOaFlmakJFWUVyVjcrMHpYK0R2MjNtV1BhMGFXeHJnNTlaeHR5S2hPd2RvOU5jVlpOR2liM0EvbTZDUy9WZjRZakxBQlFHUnZOazJMSVpPTmEwTmU3dkV4WEo2ek1oQk80MVlZUzhrNVhVaVg0RzQ2RXhqMk1TdGQyU1RGWkpONlArdGRvdnhzMU1mY0g3N3JmU2RtVCtoYmJLWjlFSkdPUVpoMEhlTis5ZlZzQXpib2gzTUhkR2kzRXpFZGhhaElNeTFRc0F2Zk00YWJzYmpvdEVSeml4blRSTkY4ZmRJUTRmRnZyNnp4SjBOamlLZTVua2V3ZVVVcHloS202em5mekZ4NkRxTlhtcGNTYVRBT2xKaVlFZlA5a0h6cjRpd3RsVkdBTjZUcEErVWFHWkF6a3lrWWUvdURDKy90OXkyYUcrZ2l0L1NWOUVzN1kxQlpVeWxuckh0UlJNczYvck1ZUllLbDY4ellKam9NOXlmd3A0K2I3cm1LMmJsUm1hTXZvSnhIdUllTjNmeXFKcXZMMyt2cW1ybDJjZ0FBTkFCVmRHVnpkR1Z5WkhWa1lUSXNWWFJsYzNSbGNtUjFaR0V5TzlHZ0hGKzdmZ24xaHpiaU1QaFJhS0E9eHhjPg==", "nickname" : "testerduda2", @@ -60,6 +74,8 @@ "createdAt" : "2022-06-21T12:07:13Z", "email" : "ginesa4628@syswift.com", "id" : "iwfjSEQhsup/r9O+aH19mC+67O9mYLydC2j5LtyW4iYD", + "isBanned" : false, + "isBlocked" : false, "isRecent" : true, "marshaled" : "PHh4YygyKWl3ZmpTRVFoc3VwL3I5TythSDE5bUMrNjdPOW1ZTHlkQzJqNUx0eVc0aVlEa0FaaUI5a1pvK0RsM1VsQTBUdHo2ZEd1cnp5dWZlM2I1ZWhkOHlScDV0ZjFvQlBPWjVlaU8yRWNrMm1ZazVxUDVnUE15OWZ6d3J4Rm96Rm9BcTdoNTVBUUhZS0VXakhGTTNTYW5FNHpMc0lCSVBkYzA3ZG5JZkhnQTBucGVIWEJhdGJ1enRqbVhrRjlKMlh1QjQ2NFVWMlZRVTEwbVV0RlRGMFBPaVcyQ1JSSUFuMDJCYmxibTJuQmNCYUphVllxU1NrZHFRZjVHMFNOS1FoajgxZ3ZCdURreVg0b1hiQVJFbUh2SjJ5M1NwUVpId3JNVVh4MTc4Y0c3UjJmajhmbzNGWm0yeWtxWngyQWNuN0l5Z2ZmNmhydlcwa1RSTW13S0VEaVg1OXRwZ2RvaWs3UEJZQkRYYk5URmJxaHZHMWI2cmIyRXI3TzB3OUtyb1N0UmVvMUE2bTQ2eEkrc2FuRm5yOXJyN29od2lmUVVZa09SWEpiR2N1YWVydWpIbHNEWDRQUkVXWkh6Nm9CRlRVb0c0RkYyUG5iT1l2d3Y1TUh3SGVDZlN1VlJ6Q0pnOEpsTHBCbXVpbm81dkh2dDd3M2NHV0IrMSsxQTFmVTIyR3FVL0NEYU0xOHlEdTJ2NGZ2Y3p6enF5TG5BaE5sck9XYm4wVHNobmExdnQ3UGs1WmUvc0FaenNXTHB0SmRma0FBQWt1U0lUczZ3NUxWMXlSYXBOVnFoRG4wRjcwdzN5NUwrY3NtMHNPNmlGRm9BRlYwWlhOMFpYSmtkV1JoTXl4RloybHVaWE5oTkRZeU9FQnplWE4zYVdaMExtTnZiU3hRT0RFNU9UazBORE00TnpKQ1VqdW9hMmlsYTRPekV3eGpRZitJZ1IySHh4Yz4=", "nickname" : "testerduda3", diff --git a/Tests/XXLegacyDatabaseMigratorTests/__Snapshots__/MigratorTests/testMigratingLegacyDatabase2.contacts.json b/Tests/XXLegacyDatabaseMigratorTests/__Snapshots__/MigratorTests/testMigratingLegacyDatabase2.contacts.json index 1b29e194e6e21eb159f5929945d9169dfe212994..6d8dd2ab397678f294068f1b2cc1fde0b50df226 100644 --- a/Tests/XXLegacyDatabaseMigratorTests/__Snapshots__/MigratorTests/testMigratingLegacyDatabase2.contacts.json +++ b/Tests/XXLegacyDatabaseMigratorTests/__Snapshots__/MigratorTests/testMigratingLegacyDatabase2.contacts.json @@ -3,6 +3,8 @@ "authStatus" : "friend", "createdAt" : "1970-01-01T00:20:34Z", "id" : "bXktY29udGFjdC1pZA==", + "isBanned" : false, + "isBlocked" : false, "isRecent" : false, "marshaled" : "PHh4YygyKWl3ZmpTRVFoc3VwL3I5TythSDE5bUMrNjdPOW1ZTHlkQzJqNUx0eVc0aVlEa0FaaUI5a1pvK0RsM1o1TzREU3VCMDN3TVAxZzZqWGtTZUxrTUtTRitQNEZmSkVKTnl5WTNjN0FMdXh5cStScUVIWkRUcnRpb3NJemhkYisrTmZ2dnNUVVVzZC9CK1lSU2pEVHcrbGg2NHE0cHpCaXlTNlNJRFI0K0lBZTJHdXpzTGZYejkzMmg2OWQzY1JlQi9HQ3RGWnlUekNIRUYrQ1RUQ29ILys0MUcydE0wc2UvQlF6UWpPNi9NUVd5cTlHWlZPR016aGFYNklHZkVWdmNRczBvTVdiWTdFdjFmeWVyMGxIL3dmdFhLR2NsQ0l2TGc2aStjRG1qd0gyeDlTQ09MUEFQSjF1L2kyM29lYWlCQ0poTWREMTZzOUhGUXpMTmJUR3FHYlh6bVR3RU5rR0JlK2JwdDRxRnB4SUxGQWI4NUdxeGdwSHkrNFp3OGhicExKMGhlY0NxSFpKTXExbFVjVzJmWldWeHVhcEUwdGlTb0RXNVE1YW5XT2VtYUVYRE1jZTZ2OFhNUkFkQmUvdlliNk8rT0xPcjdvT0xWRjQxOTE3WFRJWEZVcEZ1MmFmRGhXbkRXZlVQclNDOElNTlVWODBmNlYvZVl2bDcyWThBTWNneGZIeUZCZ0NvUG5kWUIrRldaTEh5c3dKa0g0eGpmWHh4Z2M2Uk5sN0Q2RWhNcHFSeDVweFdnUHdjUUFBQWdBN1c1a2pDb0NWWlFZSTRWWEhUTXhUeEE9PXh4Yz4=" }, @@ -10,6 +12,8 @@ "authStatus" : "friend", "createdAt" : "2022-06-21T12:07:20Z", "id" : "GxCZp/Gv5mTP35CQcQ124wlnvqT+b20LftZp2co/8WcD", + "isBanned" : false, + "isBlocked" : false, "isRecent" : false, "marshaled" : "PHh4YygyKUd4Q1pwL0d2NW1UUDM1Q1FjUTEyNHdsbnZxVCtiMjBMZnRacDJjby84V2NEa0FaaUI5a1pvK0RsM1VqTVB1SlRwcHc4TDBPcnI3NnpTSlNyTG1mZ0kxRS9yNTQwRS9Ic3A3MXJaYW1HSWVkVitDVW5VVWgrVWVkOWRFQ3FxbnBnMjBLZVBKcUozMXlSN1ZQM0tWbXAza1NwMk0zM1dUOGgrUkU4TTJmcnVRRmFIQXg1MmY0QVhCalVhRlhYY25LK3J5WmJIemhRL0s2Q0w3NFJrbzdPdERoWDN0VXVna0kxWTdpekRaVDJ4RmZRZEN5T1lDbW96aUxQNm5UTDB3d2FycHFxSWxLeHl4TXl2QWErRWl4S3NzcGRPMktJNHNxTkkzYURsS2xZSzMrMUhrdVZSTENvNG90Y2xaMHRaY3VJb0Jkclc2UURwK2U5N216Wi93djN5UWNYSEIweWVxOFZsV0NidmJvelg3cWpjRUFPM3hNYWpSMEJnckVCSDJidDI0dEVGdm5VNFRwcW9jaWVveTdlM1c1RVZUaHhlWk5WTk1Zd01sM1pFb3R1VnBmQVN2NVJORkFJN0w5MTU1d2pmaStId0xrOEQrMjdmcEJ0STN1Q2tWa3JzY0tYMnNjY05VU1BKQ0JEQnlNRjVZZUNDTGF0Z01WY2VHWVZIV2VvcGxyZTdhY2Rrb2p6RC9wa1Bha1VwVGlsYURTQllRVVpQc3pVVS9wRkpNNURXRDBpdUI5NldzL0h4UUFBTUFCVmRHVnpkR1Z5WkhWa1lTeFZkR1Z6ZEdWeVpIVmtZVHRTSUVzeTk2dE5NcXhLMitqdXllMS94eGM+", "nickname" : "testerduda", @@ -19,6 +23,8 @@ "authStatus" : "stranger", "createdAt" : "2022-06-21T12:23:39Z", "id" : "2qcF7Xl/QEn6Zu6cdQC0fteI6EeoEX9IY0nkBdmBbRYD", + "isBanned" : false, + "isBlocked" : false, "isRecent" : false, "username" : "lkjh" }, @@ -26,6 +32,8 @@ "authStatus" : "stranger", "createdAt" : "2022-06-21T12:23:39Z", "id" : "JPm+zBboFVIEPrfsDz5Ue3fst77oxCwoLxNXrdqg+1MD", + "isBanned" : false, + "isBlocked" : false, "isRecent" : false, "username" : "qwer35" }, @@ -34,6 +42,8 @@ "createdAt" : "2022-06-21T12:35:44Z", "email" : "femapiw539@syswift.com", "id" : "ybmgdlemAJ3EReCyt8Lwn419CrlG59R79iJ5fFa1Rj8D", + "isBanned" : false, + "isBlocked" : false, "isRecent" : false, "marshaled" : "PHh4YygyKXlibWdkbGVtQUozRVJlQ3l0OEx3bjQxOUNybEc1OVI3OWlKNWZGYTFSajhEa0FaaUI5a1pvK0RsM2VwY0xWaTVrMWluWTE4NjBxU3RoQnpLejhVTjkvV1VXaXVJVlJBa1NRKzhBb2l0QUhYbVFJWlVQUmdyWmdpUm5FTnZFeXhNNm8yRWpFK2VnOVppZytoZFcrZ3Facmk5UkpoaTZFTzZHVDY2eGdCcFZNQXNJZUJkS256RTJvbURJdHdWRk81MWtBZGw3UStNTFNQVWNIbkFsOEZ2b040ZS9HL1FCRGZFaVRWM3ZiR0NPNDVVb2toRVhPZXJmWnFSdW9PdnczV3RMQjZPZ1J0MmpEcFJ4bE44ZDJ6MTYrNHR1K1ovQlNzaEd4NUdtTVVJV3JwTTNlelpBekFxMVp6bEMyR1J3c1d1L0lzekhBS29QNjh2QzJNUUpETXdNNks1RExSd0VrTVFlTU5XYXVDMFZ0Q0lDRVlvcDZUM3daTkl4cXZsYmsyOTlXejhUNXY3czBzQ01KSS9LRVR3MmxJaDJpSUphN2Q2V2xCRzh4cUdseGZ5OHZEeE96S3F6azczYVJ4VlpVWXBzalI2aXAyL2h3cTdHbkhhVkZlSEZXZlRmNDNIbE90UzdLcnpXV0JyWk5ram5QWDhoc0RSVUsyWStjSytFT0JQd0hMSTFXQTcyTzBwUnMxd25UUTZvRWp6WExrZXdpdVNHdzNRbmRXSUdKVW44S3k4MmFJVU0xc1VIMEFBMDdERGc5ckRaWmxqK09DdHNIYUlHckU4bHFzUXNZUzZXMTJSWGRremlMTktBRlYwWlhOMFpYSmtkV1JoTkN4RlptVnRZWEJwZHpVek9VQnplWE4zYVdaMExtTnZiVHNkbzhtZExaUmRLUGJVNjdMeHY1a3V4eGM+", "nickname" : "testerduda4", @@ -43,12 +53,16 @@ "authStatus" : "stranger", "createdAt" : "2022-06-21T13:12:01Z", "id" : "PHh4YygyKWl3ZmpTRVFoc3VwL3I5TythSDE5bUMrNjdPOW1ZTHlkQzJqNUx0eVc0aVlEa0FaaUI5a1pvK0RsM1o1TzREU3VCMDN3TVAxZzZqWGtTZUxrTUtTRitQNEZmSkVKTnl5WTNjN0FMdXh5cStScUVIWkRUcnRpb3NJemhkYisrTmZ2dnNUVVVzZC9CK1lSU2pEVHcrbGg2NHE0cHpCaXlTNlNJRFI0K0lBZTJHdXpzTGZYejkzMmg2OWQzY1JlQi9HQ3RGWnlUekNIRUYrQ1RUQ29ILys0MUcydE0wc2UvQlF6UWpPNi9NUVd5cTlHWlZPR016aGFYNklHZkVWdmNRczBvTVdiWTdFdjFmeWVyMGxIL3dmdFhLR2NsQ0l2TGc2aStjRG1qd0gyeDlTQ09MUEFQSjF1L2kyM29lYWlCQ0poTWREMTZzOUhGUXpMTmJUR3FHYlh6bVR3RU5rR0JlK2JwdDRxRnB4SUxGQWI4NUdxeGdwSHkrNFp3OGhicExKMGhlY0NxSFpKTXExbFVjVzJmWldWeHVhcEUwdGlTb0RXNVE1YW5XT2VtYUVYRE1jZTZ2OFhNUkFkQmUvdlliNk8rT0xPcjdvT0xWRjQxOTE3WFRJWEZVcEZ1MmFmRGhXbkRXZlVQclNDOElNTlVWODBmNlYvZVl2bDcyWThBTWNneGZIeUZCZ0NvUG5kWUIrRldaTEh5c3dKa0g0eGpmWHh4Z2M2Uk5sN0Q2RWhNcHFSeDVweFdnUHdjUUFBQWdBN1c1a2pDb0NWWlFZSTRWWEhUTXhUeEE9PXh4Yz4=", + "isBanned" : false, + "isBlocked" : false, "isRecent" : false }, { "authStatus" : "verified", "createdAt" : "2022-06-21T13:17:23Z", "id" : "BstcMDaL3RRuX3jx7YeaAbl0uGwly9/M5c8BQpFuuQUD", + "isBanned" : false, + "isBlocked" : false, "isRecent" : false, "marshaled" : "PHh4YygyKUJzdGNNRGFMM1JSdVgzang3WWVhQWJsMHVHd2x5OS9NNWM4QlFwRnV1UVVEa0FaaUI5a1pvK0RsM1F0bWpEZnpjUVdMeVF0QUtQUU1INThqRnBRU2FXMXptdndJa0pyOElSR0ljRklkK2xSR0I4cWtOQmZZODdJdzJod2F2UElZVE5jdm9rdlZ1N0VJazRjc2pRSjY1QTAzb1JlVVVhcXJYNEFyOThTdVk3MXdIZ2lWczVRRFptcmlUQVZJdGgyVDVScmEvK1BaN0ZNUVY1eGthcWxwdUo1R01ndVFlMURNRExTNUdtU1ljdWJYY2JXK2xlUFhKcWhBVG96SEYzRG9oYVpZMlB4VmM3bjdkaW96MEVYUzQxVDltMEYwaVExeHQwQkJWT3M0cnFrQks1c2pOQ2Z2RkdyMlJaa1RsOW5BTnozaXY0eE9ENS9PTW4xT1Q4dzFvT1JBU1RhczZ4bFBLYUw4Z2NXSnJITUxRVGdScTZaYXFBRzNiSHp1bzNQR1o0NE1uNG9XTUZnMERReFAzekp1cmtBSXNjV1kxSHVWZzE4LzRQYjM1bFJwcEYzdlc4T1hxUHU3NThDa01EcHdMWUJOWkJuVlVFU1R4TDlCZEZ0NGZjSlA2THQrKzhpS3BkT1hCeStOQVZtaXA4ajRGaG1GNGkyOEMrRWJTUWJRQUhlTWJUbUZlWm1IdzBSbUtXZ3hsMWcyNHlzVktWbVpxc0N1UlpHblNkWlhxUmdYRDV6L1lDZEJnMEFBam85VUVtRHJCeDN2S0wrb1dXcVNkbWtTVFlnV3QzdFlWbURkSnRCR015TWFBRlYwWlhOMFpYSmtkV1JoTmp1TVNzY3F6MkhxQVBUL1cvQWo1ckRQeHhjPg==", "username" : "testerduda6" @@ -57,6 +71,8 @@ "authStatus" : "hidden", "createdAt" : "2022-06-21T13:19:13Z", "id" : "V+Kh5TJTR3vJF7EeYpUv6AmXgWwI6fND/b5U4IEYc0YD", + "isBanned" : false, + "isBlocked" : false, "isRecent" : false, "marshaled" : "PHh4YygyKVYrS2g1VEpUUjN2SkY3RWVZcFV2NkFtWGdXd0k2Zk5EL2I1VTRJRVljMFlEa0FaaUI5a1pvK0RsM1dycjhWSWMra1FxSXE3Z2psWDUvNHRLWFRzY1piUW9WanlVdXQ1Z3RDVXNzcm5hL3FHYmNFQkh5K1AxaE9RSU9YMFpSY1NiMjdVMmlVY1pONzJpZzZhb3lJNE45S0REWHNlZWlFUjJJRjhSVThpNThPT1NqVnVjZithN3JzNmE4MENxcWRxdWRGV0lsNnRzdWh3RlRKN2htUFRrZWNRQ1VRQkxQYVg2Qy84OXN0RVB3Z2RKeTc5SStVdXlTeWZoN0pkS0c0SzJ5NjlOalRnVXFxTU1mOU9HaUxaMUVPRmVHK0JMSnFPUklYc3pseE9YZ1NGNTBKYytVRzNvSmFvRWVNZ2hMTnJvRCs0WTlya0JqZHJnUFJNckZoRkxIUlhoWHZZOVQzRU5zalF3cG55clN5a0lWajB1TW5CVmEwQWI1djAvM3dHT21ONHhMWE9sWnlHS1RjRnJ4RE9MbjI2a0I3ZS9TbHM4cUZlNXFPMnQ2SVUybUkxQVNkWUtuaGF0ZXlkS1drM2x5RmpoN21PQVRIY1ZmRUtyckJrUzFzcFRyR252MjBoOXhrZE81N3lmVUYwWjhBbXp2aHcyK3lqN0UzVWlYTlVyeWRkRUdWbDRGV1I0RThkWm00SXN4Nk1HS0U2Uk82S1dwbUhBblpvZFVJdXBndUFCVjY3MHJTWll6MEFBZXNMY091dUFaUUVpNmtYbnBtQ2MzdDY4S0ErcjRuSXNvTVVkWkVHQWVGa2FBRlYwWlhOMFpYSmtkV1JoTnp0dldXRTFGOGxpZmMzMFN3YU9yNjhneHhjPg==", "username" : "testerduda7" @@ -65,6 +81,8 @@ "authStatus" : "friend", "createdAt" : "2022-06-21T13:20:28Z", "id" : "qD25S4VcTHLblBErCwftF/gV2Z+7sYW3PrD/1Sn0nKAD", + "isBanned" : false, + "isBlocked" : false, "isRecent" : false, "marshaled" : "PHh4YygyKXFEMjVTNFZjVEhMYmxCRXJDd2Z0Ri9nVjJaKzdzWVczUHJELzFTbjBuS0FEa0FaaUI5a1pvK0RsM2R5T3A4QzBpM3NBTWhHc0tJR1N3bnhJbXhqLzN3S1BWQitoN1JsaTJyY1ZlOFUwcGhPdm1EZjZIMi9PRFIxWjBpN3p1cjUxaVpGT213bGs1UEo4TXg3SzFGOEd4em5MM1dtQUFDY1dBVTVSbFVoZXVWT0dydFdHRjZDVkRPWGZtMEdNclNRZ1h2aXU2OTNFTFUwL1VPbVo3ZGhnUWdOcml3V0VxbUVHa0M0V0duNGNZeGJ1a2NRQ2NzdHlzTitBaVhrcHhmVlFTTHIrcFlmcGNHa2dGWGRSQTdwMFBGMGZlSmExamYxNkVKSVoyb1hkKzk3YnlrWm5YMFY3Q0Nrc0VvK3RUQ3orRlRDRHVCdy9jNGJ5QnFvQ3l5YlVCVk82d0RDckpaOVBSZ1Q2UDhIWTB2d0tYSUlwamgrUEhZbFpxTytvTVJTak9ZTFF6QkNIY3FIVXFndFNCVTRIenRUemtxSm1oNlJXSFRVS0h2aHZITGhmUDByUkZVbE11L1ByWmlOMlZ3SytBNERHQ2dVb084eDZlU3kweGhpVllvSEJKQnFyNTdOS1VnRitYKy9QdEp2WS9xS0lIVy9adzQva0JXWks0MkRSTzdnaDhFaFZuaEN3M3dZNVZNT3ZPcE43aHNtMWtxWXV3OVllMERJODRaY2xaUFFCOVc5Z2g1dE9PMEFBbU9POHNYR003US9WNjB0ZVJMRUo2ZllJSXpyOElnOFRIemQ4bnV0WHZ6WWFBRlYwWlhOMFpYSmtkV1JoTlR1dlZza1ZqcXB6SkREWStOR1VTVWlzeHhjPg==", "nickname" : "testerduda5", @@ -74,6 +92,8 @@ "authStatus" : "requested", "createdAt" : "2022-06-21T13:21:21Z", "id" : "JJT70wMTOxSEVDZXiWw/9lv5ZXr8R9kKFWGiZhHgJ4gD", + "isBanned" : false, + "isBlocked" : false, "isRecent" : false, "marshaled" : "PHh4YygyKUpKVDcwd01UT3hTRVZEWlhpV3cvOWx2NVpYcjhSOWtLRldHaVpoSGdKNGdEa0FaaUI5a1pvK0RsM1Q3RDJVR2hOb2RYS3NkWnRON0prYkNOQUlvSkdUYzJSY002c0xtWnEvVW4wY2V4L2hEQ1N0bnVtYVFjbk5pVGJ0VUREY1A1bUFZVkdEQVNwQXdrWlRDOVE3WUpUbjZpT2loMWsyRnJxZGw0UDBJSDZMa004cGYzWnpYMlBMMHg1MVFwVG84S1B4Z1BBSGlkRTFaL29tdE9FQ3Q0QS9wcW5yU2pnK1ZJNXpVZzZJL1phZ0Q1OHhOZysrL1E0QVI0dUxHWmpQdm00Mm55QVE0NUJwWXRBQVpoWEFXZVA0c21PRkJYTTNiK1B4bHBHYUxnd2VscllFTnZlSEpsZ3VxTmp2WkR3dHpldmJnbXdEeE5wNXFPU3FXMEdqdThPcnkyVUtZMk5XODBNdDBDMkg0UWovNGpiamJ1QjlDZ05XdGpVeWhrYk5qN2Q4a2hWNzdYZktVZ2pmK3JsWHZwWjh2K0JqQTZHMzY5YXpsd0M5ZjQ5TWFMcmljOEYvR1hDbXVOVHcrNFlvWHJpazM2MXUzOVV4VDFpUldBK2Z4U2YwSm4xci9HOWNSeHBPcldLbXdpNG5SRHNXL1FOd2F1MlBnNnNvTEs5WlZ1bTc3Ym83Mzd2My8vcTlYS1ROaUtWNmpIeGRLSkc0RXdYaUphREoyQTdkTjJ6MzhJc2M2dk4yS0c5Z0FBTkFCVmRHVnpkR1Z5WkhWa1lUZ3NWWFJsYzNSbGNtUjFaR0U0TzJ2UkZVNklsWFpDaVB0WnUxVTF6RkU9eHhjPg==", "nickname" : "testerduda8", @@ -83,6 +103,8 @@ "authStatus" : "requested", "createdAt" : "2022-06-21T13:26:00Z", "id" : "zhXeSR76/3PoNYIm/bDJ06frKDpFCOgfIZh6h9umnlID", + "isBanned" : false, + "isBlocked" : false, "isRecent" : false, "marshaled" : "PHh4YygyKXpoWGVTUjc2LzNQb05ZSW0vYkRKMDZmcktEcEZDT2dmSVpoNmg5dW1ubElEa0FaaUI5a1pvK0RsM2FHR3FqS3BKR0diT1pTc2hqbm9yQUcxQnd6blR6dXROQVRucVdwb2ZuejczUHdTcGN6N1ZuTlVVcTlBVXdxVVNFQ1FRTzNENUN2U1QwdWNxRm5sbjBSNEg0MW11QU9pOXh2b3ZGS1RiUktXaWVXck1HejZucDVpQUVEWXpRbHl1cHgzRzZlbkhmbWZ6cU41dXJ6enZzVk91VUlWTmFGb0FkVmJOanFYSDNlMk5keFNPR0NML3lrcHZDekI2L0Y2T29RYitCbmJZRnh6b0RtVENGbUl0QUNocWZqblNYMWttSy9LVUlyTDdtdTFwR2JzM2lrWmpUMTdKZnV1RFdtUWkvUGphSExHK0FBR290L3dieTcwMlk0NlgxUUdiREhoNUhPc2pXWGMwZTRlM2VzbU1oTWVtV1dTc1l4N1gxaktjdGdVL0xhYjFON3ovWDE2QWVQeEdFZDE4RHZQSmMzZGdaZDBDcnloTDREbER1bWloMnpuUjh1b2ltM2RKeWp1UW5uY2tRbkxkeXJpNGUyVG5mbWJjRVg0NnNVd21XNWp4N2J3YkNGNXhkZHhDQzhWcEFMbHhmSHFuQVVTazc4UnRMUmVBUEthUW5lSHJTZ1F1aERtSWtLUUdVT2h0cDZ3NlBESmxWWWRtampqM0ozN1JwS0U2d1RSNFRPalY1L0dTd0FBTkFCVmRHVnpkR1Z5WkhWa1lUa3NWWFJsYzNSbGNtUjFaR0U1T3dhR2VFR3hqMjhOS0Rub2I4WGtJNEk9eHhjPg==", "nickname" : "testerduda9", @@ -92,6 +114,8 @@ "authStatus" : "friend", "createdAt" : "2022-06-21T13:28:11Z", "id" : "fethB60FQ0SacWygirJaThKGYeQwl7CSUCZPqft48b0D", + "isBanned" : false, + "isBlocked" : false, "isRecent" : true, "marshaled" : "PHh4YygyKWZldGhCNjBGUTBTYWNXeWdpckphVGhLR1llUXdsN0NTVUNaUHFmdDQ4YjBEa0FaaUI5a1pvK0RsM1hTNEVZdHFtWnNpaVBGa21qNlR4ZVVVaVNsMlVFcW56R2o5RHZqd1lUZ2Vhem5tNEZPU3Q2VlF3T0orS1VYNncwTVIyU3hpZ1Y2RXAzQVZEa0diYmN6RHNBUEhuOHpnQ0w3L1pMdDJ0OGlTclRBakdwTHJwVXRVaHJEMU1PcWpkeGszRGN4OEJTSG1HZENGd0tsK3ljUGhiWDh0Q3pzS3luWFpDWUl3T1JsYnNTUGt4UmtINy82a3VRdUZYVE55dVdRR25OSE82TmJqQjFPSGIrZjlOdDhOMWFKZnZ3QlpJS2NUcGdTTGZ2T1VQbkdHazBHK2dZS0RIdmF0OHJDc3BsWlA5czdrY3NrWDhRZTlwOFIvTFJjK0doYkR0L1ZtVGhOaEgrUEVPMHkvRE5Pb1JUcFBPakVHb2RYUkIvcmZEalZmQVNaWElUSEdwN2Q5ZXlWNno3L2c5MlBUYXlwQmtVWWxyamRWR0lyU3lYdGhUZVhIY3JDUlJ2aTRnZnRpTXpBQVBBMWJDUFl2R1hyb0hjVWhVd1Iza3VFQlJIS0YyRnhZaUUwbGpDTnE3eW03UlB0bkdsSlJwa0J2eGZjNi9GRSsvdHVXSGMvWXFTSHpXUHZFZVgyREJXLzhWcldYQTIrWGRtUUVzeVR6a1h1aldkQXgvZVNxRFR2cTRvU1N4QUFBT0FCVmRHVnpkR1Z5WkhWa1lURXdMRlYwWlhOMFpYSmtkV1JoTVRBN1daK0M0ejFNNVdBbWxSQWJDcVVFS0E9PXh4Yz4=", "nickname" : "testerduda10", @@ -101,6 +125,8 @@ "authStatus" : "requested", "createdAt" : "2022-06-21T13:31:54Z", "id" : "Og7HnMukzfn0e1bbAk/pohjLvOCYb/N+UUBwZgmZfy8D", + "isBanned" : false, + "isBlocked" : false, "isRecent" : false, "marshaled" : "PHh4YygyKU9nN0huTXVremZuMGUxYmJBay9wb2hqTHZPQ1liL04rVVVCd1pnbVpmeThEa0FaaUI5a1pvK0RsM1dCbzFqQStqbktVUEtsVUFwbG9zUkc4ZklTQnY4em4zVjlSdEx5UEtSNUwyZWlrK3B6VGtpUUZPRFpkKzQ5OStocUtSWFRidUloSlJ0UkdkQkFRNmF0dmxhTzBvdmVnYU1JbjZKM1BkQjFFUDgwZzFFZUV2UXJUbkRhNXJ0eUt6eTBlSTBzWlhTL2FhZXBsTUQ5THJsNGhNcnFYa2tnYjlMVVRDcDREcW8yczdpSkQ0SDV2d1FaODNzVFRsUDhjZytKa2hoRmUrN3padjVQNVo1T0kydzJtcE5tQ251WmZsa1RqWTM4YWRsTlpTSVV5d2Zta3M5dE9CUEQxQUFacG5JUkMzZGsvSUVjbHJHclVNWVhadEo3NEc4WEVMeFEyTk9MM25rOFlnenJLMXBBRithSGVseEFvZ3NrWU00d2N3c2taNFA1a2RvQ3c4TSt0UDJLQXNPVitiYU9sKzFTL0NJa2lGMXVtNHRFUklSaTA4d2d5ekJ3ejFKSEc2dnNUY3JJOUZBL0t3cUtTSmlmQ3h6Mk9qbFBEOG13djk5d0ZDVnptc1VISmR4aElEa0x6OGljRmt3US9QS1BKb3dqSEJobzB2eEZzTmpwVTQvM29FV1EzUFQzNDRnQUt5VmVzN1kxTVpuYnpEUjNQRVlYMDRZU2JoS2xYRDYzYXNBN0ZDd0FBT0FCVmRHVnpkR1Z5WkhWa1lURXlMRlYwWlhOMFpYSmtkV1JoTVRJNzBSdm9UNnREdEpBUW5xVlc3MFFwdEE9PXh4Yz4=", "nickname" : "testerduda12", @@ -111,6 +137,8 @@ "createdAt" : "2022-06-21T13:41:35Z", "email" : "wewiyil598@runqx.com", "id" : "L+JUu+FVT3JAFjyb0MLPRhLsDx06/3vhGmGOhOALqiED", + "isBanned" : false, + "isBlocked" : false, "isRecent" : false, "marshaled" : "PHh4YygyKUwrSlV1K0ZWVDNKQUZqeWIwTUxQUmhMc0R4MDYvM3ZoR21HT2hPQUxxaUVEa0FaaUI5a1pvK0RsM2FOSmpIeGFCbHpaTVdMUFU5SVJBdkxNaytPcThwOG5SQ25McDh5eE5pdGNlbkF5RXZpM0duTHRVY2dhOHRpM3J0U2N6VWkvMVJlQkcrZzVncVJWSC9mdTZGSEVQRTFBbXNoeVY5Sm91TTFybmRyQnRqZDRKeFRxVFdnQTJ2STRGMlVvNUd1ZUtQSCtyYWdDemhJenpvSTZHM3J0YzJ0eWNGNHZKdCtHU2Rham0zTkpnNkppRjNxMEZ0SFpDUER4enNWbGEzSW9yL3J5YTFBUEZTZGtaTkJ2R3RKQnhKck1SOGhWMlFWeUhwTFRzQnZLb3hEQ2s0VVcyQm1xSFdQY2sxa1VYVzRyRU9tZk5FTUljeU1EalJoeCt6ang3OXJQWGJRbys4Sk9nY0JGeWk1anRlSVdKdEN6N1ZhNFdBdjdFSTdpQU1pemxtdllDWmlRcnpLdG5jVElUWitlcGhBbkl3dGxEMnZJYjY5TUlSV041bHB4SnYvNGZxMExrVXZHaDgyNVhGR0llaFM4N0Y4SnA5MmtPWmlLMktWeUNXN2dGa2lEZ1Q3ZVdhMWRwaDh5V1o0VFBYU3p2NjFlZVRaRUFFOEIveU1xTmpCa3piTlNqbHBEa2JqUVgrY3AycVRhNTVlUWMwbDdEVXY4T1VPSDRsdlVZOHRTMk9NY0l3Qnkwa0FBZ1J0N2J0ZGRTbEtkSVpKeUxIQmNFN2dGbXJ5YnZ4MWdwSmdncWI3Y2VpTklBRlYwWlhOMFpYSmtkV1JoTVRNc1JYZGxkMmw1YVd3MU9UaEFjblZ1Y1hndVkyOXRPNGxwSUR2U0VFVFI4MDFQQmZyQUtraz14eGM+", "nickname" : "testerduda13", @@ -120,6 +148,8 @@ "authStatus" : "requested", "createdAt" : "2022-06-21T14:03:05Z", "id" : "SEQunIrXkgzW7poDlU7hb1i8s2IZ0ZTehvwC3yP4cKQD", + "isBanned" : false, + "isBlocked" : false, "isRecent" : false, "marshaled" : "PHh4YygyKVNFUXVuSXJYa2d6Vzdwb0RsVTdoYjFpOHMySVowWlRlaHZ3QzN5UDRjS1FEa0FaaUI5a1pvK0RsM2RCeTJPSm9rV1ZVcnRITVl6NmYzUzgramlsVTgzenQ3TlgyQVcyWXoyOEJpN25kWUpRZlhocHRWZTJqNHR3K2k3SGFodFdKQmNUZ1JQS1FEUFBDSGZoSmNoeGJNL0VHT0tDbkYrU3liZE5nelR2elYrVXBZTmh6YnZBbGtJSnV3anhXY0h4dkE1Tnhvb0JNd3ViYVpiUUVTblJLRW9VQStoOXlYTUhITjdVZCs1QUthRkxZNE53K0NuVU9GeWZFYWtLbCt0dDY3Q2JUNXVhaU9aNW4waVFBZENKVHNqdTJ5bS9Edjd4TXBLNW9oSSsyTm9HRFh6TXZWd045bndKWWRVY2VMQkk5NXoxUnBTVVlXZW4rVWhIR3QwOU5iTVMzWTBHbTE0a1lxejZiV2thOUFLZUtQSHd3UFFVby9CUUZqZ1ZTZ1dGZkFQbkhwakhMa0dSSW9xdmZPNW9KVzljdmw5NURIQ1FqWkNidlNhOHFPTnpxNmJwc01WYjJMMzdUdm1sUGtPbDlZbmdHQm5jZ0RIUUJ6Z2ZxUTR2TVdXZmFJTlA0OHNmSG1WaDVCS1B6SU0zd3M2aE8zc3NzV3V0bml4Z1lVOHVtay8rSi9PUHluMWhDNC9yR3hkckljOFM0VlBBSnNFYlZOaFExLzU0azVTZ2hXakNaczFoOWZFSVhGd0FBT0FCVmRHVnpkR1Z5WkhWa1lURTFMRlYwWlhOMFpYSmtkV1JoTVRVN0NxdWVQdDcydkYxS3hTbmZIUStZcEE9PXh4Yz4=", "nickname" : "testerduda15", @@ -129,6 +159,8 @@ "authStatus" : "hidden", "createdAt" : "2022-06-21T14:11:46Z", "id" : "tRpK4sI1Zr6321Yz/6HKZBmbTkkOX7KxlATLY7WuOcwD", + "isBanned" : false, + "isBlocked" : false, "isRecent" : false, "marshaled" : "PHh4YygyKXRScEs0c0kxWnI2MzIxWXovNkhLWkJtYlRra09YN0t4bEFUTFk3V3VPY3dEa0FaaUI5a1pvK0RsM1VvK0g5L1VwT2ZBdnZ4aGIvUmR3SVBieDdoSE93bmtiU2EzWnc0dkw1ZWtYelhSOUV0QjA1dTh1V3ZLN0owZTRUSzNuUHdwZkVxcUVTMHNOc1pacHVyMzRmbEFNNkhOUm4wUkI2MU01L3J0STNyZGc4NDZTM0xpSldBZDYzNWp6SWg5b1JpZkpvb2MzRmVqdXE3cFhNQTQ2NUFpTzJUQVFhTjNCZ2tuelVZUldZOCtTa1BjbHVmU1RGSDdveTJSMWYxcnZJNHRWOFdibDhNNzNTNnFpUmptOHI4N0R2U2w4MHlSckJnR2lJNDI2d0w4cDRBZXVtMk1vMFRQVEZ2N3NJcmk3bE04eC84bEtEWFJjbXdYWnVjU2ZUcWUrcVNEUWwva3VhZGd1eWtqUXNnQW1YYjBSMnkrOElFZWlwdDJNVTlBZjllV1hNZzV1RU4yL2dIUWVENHc0clRheEdOc2E5VU1ld0hjT0FSckRBUnZGZzdNMGxLWW94ZW9SOWhSNng4RGNxZStVSWU0K202VDVqRThMQVFZSU1KMHRjY1dLQmhaVWN3UDBNS3RsaEdMUUg0elNvRkgyYXV6OU15VU1mNGJMUXVhcWIyMDFTTmJWaFRVYytFMVhRWUk1VmU1SjZ1aEtZMjBsT1NtMUQ0eEFBWWwrTEhlS0NtbU9pSEhza0FBTlBnRmZSblduSDZFVmowUkdzUHdITGx2RktZMVREZHZqMTRSV2QyMEtKNGNBRlYwWlhOMFpYSmtkV1JoTVRjN3MydHNaUjlpWjJONHlMaUt3MkEwM2c9PXh4Yz4=", "username" : "testerduda17"