Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug/Deleting general channel does't work consistently #1525

Merged
merged 41 commits into from
May 25, 2023
Merged
Show file tree
Hide file tree
Changes from 40 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
6cc6f1e
initial change
Kacper-RF May 15, 2023
7f848e5
use address as main id
Kacper-RF May 15, 2023
bfd8d92
general channel selector
Kacper-RF May 15, 2023
0932580
next part of state manager refactor
Kacper-RF May 16, 2023
21bbde4
fix deleteChannel payload
vinkabuki May 16, 2023
ca9c8c7
fix payload
Kacper-RF May 16, 2023
838129f
merge
Kacper-RF May 16, 2023
7271b6c
fix state manager tests
Kacper-RF May 16, 2023
a8a4c50
fix createGeneralChannel test
Kacper-RF May 16, 2023
cda682f
fix markUnreadChannel test
vinkabuki May 16, 2023
55784b5
fix publicChannels.selectors.test
Kacper-RF May 16, 2023
fd110cc
fix channelsReplicated.saga.test.ts
Kacper-RF May 17, 2023
5e3fdcc
fix backend unit test
Kacper-RF May 17, 2023
6d698a7
fix storage backend test file
Kacper-RF May 17, 2023
a69ab29
fix desktop tets, saga and currentChannelAddress selector
Kacper-RF May 17, 2023
94b1ed6
fix sidebar container and story
Kacper-RF May 17, 2023
ee5c347
fix mobile test
Kacper-RF May 17, 2023
4ce8068
fix mobile package
Kacper-RF May 17, 2023
418e0e9
creation and deletion fixes on mobile
Kacper-RF May 17, 2023
bc28939
fix rtl tests
Kacper-RF May 18, 2023
79c3e80
mobile - channel creation and channel deletion fixes
Kacper-RF May 18, 2023
b2d37e2
Remove channel deletion leftover
vinkabuki May 19, 2023
321051f
refactor channel.address to channel.id
Kacper-RF May 19, 2023
afe474c
Merge branch 'bug/1523' of github.com:TryQuiet/quiet into bug/1523
Kacper-RF May 19, 2023
99d7b9f
fix notifications
Kacper-RF May 19, 2023
edb27c9
E2E test - correct channel replication after removal in user's absence
Kacper-RF May 19, 2023
731a8b5
fix typo
Kacper-RF May 22, 2023
fbe2691
fix conflicts
Kacper-RF May 22, 2023
eadc4dd
temporary adjust storage to support both old and new channels and mes…
vinkabuki May 22, 2023
0aad486
transform channel on replication
vinkabuki May 22, 2023
f8c5fbb
state channels transform
Kacper-RF May 23, 2023
cb4e5a7
messages state transform
Kacper-RF May 23, 2023
6fc117f
fix messages adapter problem
Kacper-RF May 23, 2023
825c95b
fix channel.main.test.tsx
Kacper-RF May 23, 2023
b6233cb
fix rtl test snapshot
vinkabuki May 23, 2023
8cc19fb
general deletion saga fix
Kacper-RF May 23, 2023
968cb7e
Merge branch 'bug/1523' of github.com:TryQuiet/quiet into bug/1523
Kacper-RF May 23, 2023
52c2f58
fix mobile deletion, lint, rtl test snapshot
Kacper-RF May 24, 2023
0e73dd2
merge
Kacper-RF May 24, 2023
e489f8e
Merge branch 'bug/1523' of github.com:TryQuiet/quiet into bug/1523
Kacper-RF May 24, 2023
dd0dd16
CR fixes
Kacper-RF May 24, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions packages/backend/src/libp2p/connectionsManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ export class ConnectionsManager extends EventEmitter {
await this.storage?.sendMessage(args.message)
})
this.dataServer.on(SocketActionTypes.ASK_FOR_MESSAGES, async (args: AskForMessagesPayload) => {
await this.storage?.askForMessages(args.channelAddress, args.ids)
await this.storage?.askForMessages(args.channelId, args.ids)
})

// Files
Expand Down Expand Up @@ -595,8 +595,8 @@ export class ConnectionsManager extends EventEmitter {
})
this.dataServer.on(
SocketActionTypes.SEND_DIRECT_MESSAGE,
async (channelAddress: string, messagePayload) => {
await this.storage?.sendDirectMessage(channelAddress, messagePayload)
async (channelId: string, messagePayload) => {
await this.storage?.sendDirectMessage(channelId, messagePayload)
}
)
this.dataServer.on(
Expand All @@ -615,14 +615,14 @@ export class ConnectionsManager extends EventEmitter {
this.dataServer.on(SocketActionTypes.CLOSE, async () => {
await this.closeAllServices()
})
this.dataServer.on(SocketActionTypes.DELETE_CHANNEL, async (payload: {channel: string}) => {
this.dataServer.on(SocketActionTypes.DELETE_CHANNEL, async (payload: {channelId: string}) => {
await this.storage?.deleteChannel(payload)
})

this.dataServer.on(SocketActionTypes.DELETE_FILES_FROM_CHANNEL, async (payload: DeleteFilesFromChannelSocketPayload) => {
log('DELETE_FILES_FROM_CHANNEL : payload', payload)
await this.deleteFilesFromChannel(payload)
await this.deleteFilesFromTemporaryDir()
// await this.deleteFilesFromTemporaryDir() //crashes on mobile, will be fixes in next versions
})
}

Expand Down Expand Up @@ -712,7 +712,7 @@ export class ConnectionsManager extends EventEmitter {
this.storage.on(StorageEvents.CHECK_FOR_MISSING_FILES, (payload: CommunityId) => {
this.io.emit(SocketActionTypes.CHECK_FOR_MISSING_FILES, payload)
})
this.storage.on(StorageEvents.CHANNEL_DELETION_RESPONSE, (payload: any) => {
this.storage.on(StorageEvents.CHANNEL_DELETION_RESPONSE, (payload: {channelId: string}) => {
console.log('emitting deleted channel event back to state manager')
this.io.emit(SocketActionTypes.CHANNEL_DELETION_RESPONSE, payload)
})
Expand Down
12 changes: 6 additions & 6 deletions packages/backend/src/socket/DataServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,15 @@ export class DataServer extends EventEmitter {
SocketActionTypes.SEND_DIRECT_MESSAGE,
async (
peerId: string,
{ channelAddress, message }: { channelAddress: string; message: string }
{ channelId, message }: { channelId: string; message: string }
) => {
this.emit(SocketActionTypes.SEND_DIRECT_MESSAGE, { channelAddress, message })
this.emit(SocketActionTypes.SEND_DIRECT_MESSAGE, { channelId, message })
}
)
socket.on(
SocketActionTypes.SUBSCRIBE_FOR_DIRECT_MESSAGE_THREAD,
async (peerId: string, channelAddress: string) => {
this.emit(SocketActionTypes.SUBSCRIBE_FOR_DIRECT_MESSAGE_THREAD, { peerId, channelAddress })
async (peerId: string, channelId: string) => {
this.emit(SocketActionTypes.SUBSCRIBE_FOR_DIRECT_MESSAGE_THREAD, { peerId, channelId })
}
)
socket.on(
Expand Down Expand Up @@ -156,8 +156,8 @@ export class DataServer extends EventEmitter {
log('leaving community')
this.emit(SocketActionTypes.LEAVE_COMMUNITY)
})
socket.on(SocketActionTypes.DELETE_CHANNEL, async (payload: {channel: string}) => {
log('deleting channel ', payload.channel)
socket.on(SocketActionTypes.DELETE_CHANNEL, async (payload: {channelId: string}) => {
log('deleting channel ', payload.channelId)
this.emit(SocketActionTypes.DELETE_CHANNEL, payload)
})
socket.on(SocketActionTypes.DELETE_FILES_FROM_CHANNEL, async (payload: DeleteFilesFromChannelSocketPayload) => {
Expand Down
36 changes: 18 additions & 18 deletions packages/backend/src/storage/ipfsFileManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ describe('Ipfs file manager', () => {
cid: 'uploading_id',
message: {
id: 'id',
channelAddress: 'channelAddress'
channelId: 'channelId'
}
}

Expand All @@ -70,7 +70,7 @@ describe('Ipfs file manager', () => {
expect(eventSpy).toHaveBeenNthCalledWith(1, StorageEvents.REMOVE_DOWNLOAD_STATUS, { cid: 'uploading_id' })
})
await waitForExpect(() => {
expect(eventSpy).toHaveBeenNthCalledWith(2, StorageEvents.UPLOADED_FILE, expect.objectContaining({ cid: cid, ext: '.png', height: 44, message: { channelAddress: 'channelAddress', id: 'id' }, name: 'test-image', size: 15858, width: 824 })
expect(eventSpy).toHaveBeenNthCalledWith(2, StorageEvents.UPLOADED_FILE, expect.objectContaining({ cid: cid, ext: '.png', height: 44, message: { channelId: 'channelId', id: 'id' }, name: 'test-image', size: 15858, width: 824 })
)
})
await waitForExpect(() => {
Expand All @@ -93,7 +93,7 @@ describe('Ipfs file manager', () => {
cid: 'uploading_id',
message: {
id: 'id',
channelAddress: 'channelAddress'
channelId: 'channelId'
}
}

Expand All @@ -103,15 +103,15 @@ describe('Ipfs file manager', () => {
expect(eventSpy).toHaveBeenNthCalledWith(1, StorageEvents.REMOVE_DOWNLOAD_STATUS, { cid: 'uploading_id' })
})
await waitForExpect(() => {
expect(eventSpy).toHaveBeenNthCalledWith(2, StorageEvents.UPLOADED_FILE, expect.objectContaining({ cid: cid, ext: '.pdf', height: undefined, message: { channelAddress: 'channelAddress', id: 'id' }, name: 'test-file', size: 761991, width: undefined }
expect(eventSpy).toHaveBeenNthCalledWith(2, StorageEvents.UPLOADED_FILE, expect.objectContaining({ cid: cid, ext: '.pdf', height: undefined, message: { channelId: 'channelId', id: 'id' }, name: 'test-file', size: 761991, width: undefined }
)
)
})
await waitForExpect(() => {
expect(eventSpy).toHaveBeenNthCalledWith(3, StorageEvents.UPDATE_DOWNLOAD_PROGRESS, { cid: cid, downloadProgress: undefined, downloadState: 'hosted', mid: 'id' })
})
await waitForExpect(() => {
expect(eventSpy).toHaveBeenNthCalledWith(4, StorageEvents.UPDATE_MESSAGE_MEDIA, expect.objectContaining({ cid: cid, ext: '.pdf', height: undefined, message: { channelAddress: 'channelAddress', id: 'id' }, name: 'test-file', size: 761991, width: undefined })
expect(eventSpy).toHaveBeenNthCalledWith(4, StorageEvents.UPDATE_MESSAGE_MEDIA, expect.objectContaining({ cid: cid, ext: '.pdf', height: undefined, message: { channelId: 'channelId', id: 'id' }, name: 'test-file', size: 761991, width: undefined })
)
})
})
Expand All @@ -130,7 +130,7 @@ describe('Ipfs file manager', () => {
cid: 'uploading_id',
message: {
id: 'id',
channelAddress: 'channelAddress'
channelId: 'channelId'
}
}

Expand All @@ -157,7 +157,7 @@ describe('Ipfs file manager', () => {
cid: 'uploading_id',
message: {
id: 'id',
channelAddress: 'channelAddress'
channelId: 'channelId'
}
}

Expand All @@ -167,13 +167,13 @@ describe('Ipfs file manager', () => {
expect(eventSpy).toHaveBeenNthCalledWith(1, StorageEvents.REMOVE_DOWNLOAD_STATUS, { cid: 'uploading_id' })
})
await waitForExpect(() => {
expect(eventSpy).toHaveBeenNthCalledWith(2, StorageEvents.UPLOADED_FILE, expect.objectContaining({ cid: cid, ext: '.pdf', height: undefined, message: { channelAddress: 'channelAddress', id: 'id' }, name: 'test-file', size: 761991, width: undefined }))
expect(eventSpy).toHaveBeenNthCalledWith(2, StorageEvents.UPLOADED_FILE, expect.objectContaining({ cid: cid, ext: '.pdf', height: undefined, message: { channelId: 'channelId', id: 'id' }, name: 'test-file', size: 761991, width: undefined }))
})
await waitForExpect(() => {
expect(eventSpy).toHaveBeenNthCalledWith(3, StorageEvents.UPDATE_DOWNLOAD_PROGRESS, { cid: cid, downloadProgress: undefined, downloadState: 'hosted', mid: 'id' })
})
await waitForExpect(() => {
expect(eventSpy).toHaveBeenNthCalledWith(4, StorageEvents.UPDATE_MESSAGE_MEDIA, expect.objectContaining({ cid: cid, ext: '.pdf', height: undefined, message: { channelAddress: 'channelAddress', id: 'id' }, name: 'test-file', size: 761991, width: undefined }))
expect(eventSpy).toHaveBeenNthCalledWith(4, StorageEvents.UPDATE_MESSAGE_MEDIA, expect.objectContaining({ cid: cid, ext: '.pdf', height: undefined, message: { channelId: 'channelId', id: 'id' }, name: 'test-file', size: 761991, width: undefined }))
})

// Downloading
Expand Down Expand Up @@ -212,7 +212,7 @@ describe('Ipfs file manager', () => {
cid,
message: {
id: 'id',
channelAddress: 'channelAddress'
channelId: 'channelId'
}
}

Expand All @@ -223,15 +223,15 @@ describe('Ipfs file manager', () => {
expect(eventSpy).toHaveBeenNthCalledWith(1, StorageEvents.REMOVE_DOWNLOAD_STATUS, { cid })
})
await waitForExpect(() => {
expect(eventSpy).toHaveBeenNthCalledWith(2, StorageEvents.UPLOADED_FILE, expect.objectContaining({ cid: cid, ext: '.pdf', height: undefined, message: { channelAddress: 'channelAddress', id: 'id' }, name: 'test-file', size: 761797, width: undefined })
expect(eventSpy).toHaveBeenNthCalledWith(2, StorageEvents.UPLOADED_FILE, expect.objectContaining({ cid: cid, ext: '.pdf', height: undefined, message: { channelId: 'channelId', id: 'id' }, name: 'test-file', size: 761797, width: undefined })
)
})
await waitForExpect(() => {
expect(eventSpy).toHaveBeenNthCalledWith(3, StorageEvents.UPDATE_DOWNLOAD_PROGRESS, { cid: cid, downloadProgress: undefined, downloadState: 'hosted', mid: 'id' }
)
})
await waitForExpect(() => {
expect(eventSpy).toHaveBeenNthCalledWith(4, StorageEvents.UPDATE_MESSAGE_MEDIA, expect.objectContaining({ cid: cid, ext: '.pdf', height: undefined, message: { channelAddress: 'channelAddress', id: 'id' }, name: 'test-file', size: 761797, width: undefined })
expect(eventSpy).toHaveBeenNthCalledWith(4, StorageEvents.UPDATE_MESSAGE_MEDIA, expect.objectContaining({ cid: cid, ext: '.pdf', height: undefined, message: { channelId: 'channelId', id: 'id' }, name: 'test-file', size: 761797, width: undefined })
)
})

Expand Down Expand Up @@ -272,7 +272,7 @@ describe('Ipfs file manager', () => {
cid: 'uploading_id',
message: {
id: 'id',
channelAddress: 'channelAddress'
channelId: 'channelId'
}
}

Expand All @@ -281,13 +281,13 @@ describe('Ipfs file manager', () => {
expect(eventSpy).toHaveBeenNthCalledWith(1, StorageEvents.REMOVE_DOWNLOAD_STATUS, { cid: 'uploading_id' }
)

expect(eventSpy).toHaveBeenNthCalledWith(2, StorageEvents.UPLOADED_FILE, expect.objectContaining({ cid: cid, ext: '.png', height: 44, message: { channelAddress: 'channelAddress', id: 'id' }, name: 'test-image', size: 15858, width: 824 })
expect(eventSpy).toHaveBeenNthCalledWith(2, StorageEvents.UPLOADED_FILE, expect.objectContaining({ cid: cid, ext: '.png', height: 44, message: { channelId: 'channelId', id: 'id' }, name: 'test-image', size: 15858, width: 824 })
)

expect(eventSpy).toHaveBeenNthCalledWith(3, StorageEvents.UPDATE_DOWNLOAD_PROGRESS, { cid: cid, downloadProgress: undefined, downloadState: 'hosted', mid: 'id' }
)

expect(eventSpy).toHaveBeenNthCalledWith(4, StorageEvents.UPDATE_MESSAGE_MEDIA, expect.objectContaining({ cid: cid, ext: '.png', height: 44, message: { channelAddress: 'channelAddress', id: 'id' }, name: 'test-image', size: 15858, width: 824 })
expect(eventSpy).toHaveBeenNthCalledWith(4, StorageEvents.UPDATE_MESSAGE_MEDIA, expect.objectContaining({ cid: cid, ext: '.png', height: 44, message: { channelId: 'channelId', id: 'id' }, name: 'test-image', size: 15858, width: 824 })
)

// Downloading
Expand All @@ -308,7 +308,7 @@ describe('Ipfs file manager', () => {
expect(eventSpy).toHaveBeenNthCalledWith(7, StorageEvents.UPDATE_DOWNLOAD_PROGRESS, { cid: cid, downloadProgress: { downloaded: 15855, size: 15858, transferSpeed: 0 }, downloadState: 'completed', mid: 'id' }
)
}, 20000)
expect(eventSpy).toHaveBeenNthCalledWith(8, StorageEvents.UPDATE_MESSAGE_MEDIA, expect.objectContaining({ cid: cid, ext: '.png', height: 44, message: { channelAddress: 'channelAddress', id: 'id' }, name: 'test-image', size: 15858, width: 824 })
expect(eventSpy).toHaveBeenNthCalledWith(8, StorageEvents.UPDATE_MESSAGE_MEDIA, expect.objectContaining({ cid: cid, ext: '.png', height: 44, message: { channelId: 'channelId', id: 'id' }, name: 'test-image', size: 15858, width: 824 })
)
})
it('downloaded file matches uploaded file', async () => {
Expand All @@ -326,7 +326,7 @@ describe('Ipfs file manager', () => {
cid: 'uploading_id',
message: {
id: 'id',
channelAddress: 'channelAddress'
channelId: 'channelId'
}
}

Expand Down Expand Up @@ -370,7 +370,7 @@ describe('Ipfs file manager', () => {
cid: 'uploading_id',
message: {
id: 'id',
channelAddress: 'channelAddress'
channelId: 'channelId'
}
}

Expand Down
53 changes: 39 additions & 14 deletions packages/backend/src/storage/storage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ import { jest, beforeEach, describe, it, expect, afterEach, beforeAll } from '@j
import { sleep } from '../sleep'
import { StorageEvents } from './types'
import type { Storage as StorageType } from './storage'
import { ChannelMessage, Community, Identity, PublicChannel, TestMessage } from '@quiet/types'
import { ChannelMessage, Community, Identity, MessageType, PublicChannel, TestMessage } from '@quiet/types'
import { Store, getFactory, prepareStore, publicChannels } from '@quiet/state-manager'
import { DateTime } from 'luxon'

const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
Expand Down Expand Up @@ -57,6 +58,23 @@ let utils: ComonUtilsModuleType

jest.setTimeout(50000)

const generateMessageFactoryContent = () => {
const obj = {
message: {
id: (Math.random() * 10 ** 18).toString(36),
type: MessageType.Basic,
message: (Math.random() * 10 ** 18).toString(36),
createdAt: DateTime.utc().valueOf(),
channelId: channel.id,
signature: '',
pubKey: ''
},
verifyAutomatically: false
}

return obj
}

beforeAll(async () => {
store = prepareStore().store
factory = await getFactory(store)
Expand All @@ -70,7 +88,7 @@ beforeAll(async () => {
description: channel.description,
owner: channel.owner,
timestamp: channel.timestamp,
address: channel.address
id: channel.id
}

alice = await factory.create<Identity>(
Expand All @@ -87,7 +105,8 @@ beforeAll(async () => {
await factory.create<TestMessage>(
'Message',
{
identity: alice
identity: alice,
...generateMessageFactoryContent()
}
)
).message
Expand Down Expand Up @@ -170,10 +189,10 @@ describe('Channels', () => {

const eventSpy = jest.spyOn(storage, 'emit')

await storage.deleteChannel({ channel: channelio.address })
await storage.deleteChannel({ channelId: channelio.id })

expect(eventSpy).toBeCalledWith('channelDeletionResponse', {
channel: channelio.address
channelId: channelio.id
})
})
})
Expand Down Expand Up @@ -312,7 +331,8 @@ describe('Certificate', () => {
const aliceMessage = await factory.create<
ReturnType<typeof publicChannels.actions.test_message>['payload']
>('Message', {
identity: alice
identity: alice,
...generateMessageFactoryContent()
})

storage = new Storage(tmpAppDataPath, community.id, { createPaths: false })
Expand All @@ -326,7 +346,8 @@ describe('Certificate', () => {
await storage.subscribeToChannel(channelio)

const eventSpy = jest.spyOn(storage, 'emit')
const publicChannelRepo = storage.publicChannelsRepos.get(message.channelAddress)
console.log('storage.publicChannelsRepos.get(message.channelId)', storage.publicChannelsRepos.get(message.channelId))
const publicChannelRepo = storage.publicChannelsRepos.get(message.channelId)
expect(publicChannelRepo).not.toBeUndefined()
// @ts-expect-error
const db = publicChannelRepo.db
Expand Down Expand Up @@ -358,13 +379,16 @@ describe('Certificate', () => {
const aliceMessage = await factory.create<
ReturnType<typeof publicChannels.actions.test_message>['payload']
>('Message', {
identity: alice
identity: alice,
...generateMessageFactoryContent()
})

const johnMessage = await factory.create<
ReturnType<typeof publicChannels.actions.test_message>['payload']
>('Message', {
identity: john
identity: john,
...generateMessageFactoryContent()

})

const aliceMessageWithJohnsPublicKey: ChannelMessage = {
Expand All @@ -382,7 +406,7 @@ describe('Certificate', () => {
await storage.subscribeToChannel(channelio)

const spyOnEmit = jest.spyOn(storage, 'emit')
const publicChannelRepo = storage.publicChannelsRepos.get(message.channelAddress)
const publicChannelRepo = storage.publicChannelsRepos.get(message.channelId)
expect(publicChannelRepo).not.toBeUndefined()
// @ts-expect-error
const db = publicChannelRepo.db
Expand Down Expand Up @@ -443,7 +467,7 @@ describe('Message access controller', () => {

await storage.subscribeToChannel(channelio)

const publicChannelRepo = storage.publicChannelsRepos.get(message.channelAddress)
const publicChannelRepo = storage.publicChannelsRepos.get(message.channelId)
expect(publicChannelRepo).not.toBeUndefined()
// @ts-expect-error
const db = publicChannelRepo.db
Expand All @@ -468,15 +492,16 @@ describe('Message access controller', () => {
const aliceMessage = await factory.create<
ReturnType<typeof publicChannels.actions.test_message>['payload']
>('Message', {
identity: alice
identity: alice,
...generateMessageFactoryContent()
})
// @ts-expect-error userCertificate can be undefined
const johnCertificate: string = john.userCertificate
const johnPublicKey = keyFromCertificate(parseCertificate(johnCertificate))

const spoofedMessage = {
...aliceMessage.message,
channelAddress: channelio.address,
channelId: channelio.id,
pubKey: johnPublicKey
}
delete spoofedMessage.media // Media 'undefined' is not accepted by db.add
Expand All @@ -492,7 +517,7 @@ describe('Message access controller', () => {

await storage.subscribeToChannel(channelio)

const publicChannelRepo = storage.publicChannelsRepos.get(message.channelAddress)
const publicChannelRepo = storage.publicChannelsRepos.get(message.channelId)
expect(publicChannelRepo).not.toBeUndefined()
// @ts-expect-error
const db = publicChannelRepo.db
Expand Down
Loading