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"