Move user and room handling to respective modules
This commit is contained in:
parent
3459bbecd3
commit
6b723db5a1
47
src/app.ts
47
src/app.ts
@ -2,12 +2,11 @@ import dotenv from 'dotenv'
|
|||||||
dotenv.config()
|
dotenv.config()
|
||||||
import lineByLine from 'n-readlines'
|
import lineByLine from 'n-readlines'
|
||||||
import 'reflect-metadata'
|
import 'reflect-metadata'
|
||||||
import { IdMapping } from './entity/IdMapping'
|
import { handle as handleRoom } from './handlers/rooms'
|
||||||
import { RcUser, createUser, userIsExcluded } from './handlers/users'
|
import { handle as handleUser } from './handlers/users'
|
||||||
import log from './helpers/logger'
|
import log from './helpers/logger'
|
||||||
import { getRoomId, getUserId, initStorage, save } from './helpers/storage'
|
import { initStorage } from './helpers/storage'
|
||||||
import { whoami } from './helpers/synapse'
|
import { whoami } from './helpers/synapse'
|
||||||
import { RcRoom, createRoom } from './handlers/rooms'
|
|
||||||
|
|
||||||
log.info('rocketchat2matrix starts.')
|
log.info('rocketchat2matrix starts.')
|
||||||
|
|
||||||
@ -45,47 +44,11 @@ async function loadRcExport(entity: Entities) {
|
|||||||
const item = JSON.parse(line.toString())
|
const item = JSON.parse(line.toString())
|
||||||
switch (entity) {
|
switch (entity) {
|
||||||
case Entities.Users:
|
case Entities.Users:
|
||||||
const rcUser: RcUser = item
|
await handleUser(item)
|
||||||
log.info(`Parsing user: ${rcUser.name}: ${rcUser._id}`)
|
|
||||||
|
|
||||||
if (userIsExcluded(rcUser)) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
const matrixUserId = await getUserId(rcUser._id)
|
|
||||||
if (matrixUserId) {
|
|
||||||
log.debug(`Mapping exists: ${rcUser._id} -> ${matrixUserId}`)
|
|
||||||
} else {
|
|
||||||
const matrixUser = await createUser(rcUser)
|
|
||||||
const mapping = new IdMapping()
|
|
||||||
mapping.rcId = rcUser._id
|
|
||||||
mapping.matrixId = matrixUser.user_id
|
|
||||||
mapping.type = entities[entity].mappingType
|
|
||||||
mapping.accessToken = matrixUser.access_token
|
|
||||||
|
|
||||||
await save(mapping)
|
|
||||||
log.debug('Mapping added:', mapping)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
case Entities.Rooms:
|
case Entities.Rooms:
|
||||||
const rcRoom: RcRoom = item
|
await handleRoom(item)
|
||||||
log.info(`Parsing room ${rcRoom.name || 'with ID: ' + rcRoom._id}`)
|
|
||||||
|
|
||||||
const matrixRoomId = await getRoomId(rcRoom._id)
|
|
||||||
if (matrixRoomId) {
|
|
||||||
log.debug(`Mapping exists: ${rcRoom._id} -> ${matrixRoomId}`)
|
|
||||||
} else {
|
|
||||||
const matrixRoom = await createRoom(rcRoom)
|
|
||||||
const roomMapping = new IdMapping()
|
|
||||||
roomMapping.rcId = rcRoom._id
|
|
||||||
roomMapping.matrixId = matrixRoom.room_id
|
|
||||||
roomMapping.type = entities[entity].mappingType
|
|
||||||
|
|
||||||
await save(roomMapping)
|
|
||||||
log.debug('Mapping added:', roomMapping)
|
|
||||||
}
|
|
||||||
break
|
break
|
||||||
|
|
||||||
case Entities.Messages:
|
case Entities.Messages:
|
||||||
|
|||||||
@ -6,13 +6,15 @@ import { SessionOptions } from '../helpers/synapse'
|
|||||||
import {
|
import {
|
||||||
MatrixRoomPresets,
|
MatrixRoomPresets,
|
||||||
MatrixRoomVisibility,
|
MatrixRoomVisibility,
|
||||||
|
RcRoom,
|
||||||
RcRoomTypes,
|
RcRoomTypes,
|
||||||
acceptInvitation,
|
acceptInvitation,
|
||||||
|
createMapping,
|
||||||
getCreator,
|
getCreator,
|
||||||
getFilteredMembers,
|
getFilteredMembers,
|
||||||
inviteMember,
|
inviteMember,
|
||||||
mapRoom,
|
mapRoom,
|
||||||
parseMemberships,
|
createDirectChatMemberships,
|
||||||
registerRoom,
|
registerRoom,
|
||||||
} from './rooms'
|
} from './rooms'
|
||||||
|
|
||||||
@ -110,10 +112,13 @@ test('getting creator', () => {
|
|||||||
expect(getCreator(rcDirectChat)).toBe('aliceid')
|
expect(getCreator(rcDirectChat)).toBe('aliceid')
|
||||||
expect(getCreator(rcPublicRoom)).toBe(roomCreator._id)
|
expect(getCreator(rcPublicRoom)).toBe(roomCreator._id)
|
||||||
expect(getCreator(rcPrivateRoom)).toBe(roomCreator._id)
|
expect(getCreator(rcPrivateRoom)).toBe(roomCreator._id)
|
||||||
|
expect(getCreator({} as RcRoom)).toBe('')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('creating memberships for direct chats', async () => {
|
test('creating memberships for direct chats', async () => {
|
||||||
await expect(parseMemberships(rcDirectChat)).resolves.toBe(undefined)
|
await expect(createDirectChatMemberships(rcDirectChat)).resolves.toBe(
|
||||||
|
undefined
|
||||||
|
)
|
||||||
expect(mockedStorage.createMembership).toHaveBeenCalledWith(
|
expect(mockedStorage.createMembership).toHaveBeenCalledWith(
|
||||||
rcDirectChat._id,
|
rcDirectChat._id,
|
||||||
rcDirectChat.uids[0]
|
rcDirectChat.uids[0]
|
||||||
@ -127,7 +132,11 @@ test('creating memberships for direct chats', async () => {
|
|||||||
mockedStorage.createMembership.mockClear()
|
mockedStorage.createMembership.mockClear()
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
parseMemberships({ ...rcDirectChat, _id: 'hoihoi', uids: ['hoi', 'hoi'] })
|
createDirectChatMemberships({
|
||||||
|
...rcDirectChat,
|
||||||
|
_id: 'hoihoi',
|
||||||
|
uids: ['hoi', 'hoi'],
|
||||||
|
})
|
||||||
).resolves.toBe(undefined)
|
).resolves.toBe(undefined)
|
||||||
|
|
||||||
expect(mockedStorage.createMembership).toHaveBeenCalledWith('hoihoi', 'hoi')
|
expect(mockedStorage.createMembership).toHaveBeenCalledWith('hoihoi', 'hoi')
|
||||||
@ -210,3 +219,15 @@ test('filtering members', async () => {
|
|||||||
expect(mockedStorage.getMapping).toBeCalledWith('otherExistingUser', 0)
|
expect(mockedStorage.getMapping).toBeCalledWith('otherExistingUser', 0)
|
||||||
expect(mockedStorage.getMapping).toBeCalledWith('excludedUser', 0)
|
expect(mockedStorage.getMapping).toBeCalledWith('excludedUser', 0)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('creating mapping', async () => {
|
||||||
|
await expect(
|
||||||
|
createMapping(rcPublicRoom._id, { ...mapRoom(rcPublicRoom), room_id })
|
||||||
|
).resolves.toBe(undefined)
|
||||||
|
expect(mockedStorage.save).toHaveBeenCalledWith({
|
||||||
|
rcId: rcPublicRoom._id,
|
||||||
|
matrixId: room_id,
|
||||||
|
type: 1,
|
||||||
|
accessToken: undefined,
|
||||||
|
} as IdMapping)
|
||||||
|
})
|
||||||
|
|||||||
@ -4,6 +4,8 @@ import {
|
|||||||
createMembership,
|
createMembership,
|
||||||
getMapping,
|
getMapping,
|
||||||
getMemberships,
|
getMemberships,
|
||||||
|
getRoomId,
|
||||||
|
save,
|
||||||
} from '../helpers/storage'
|
} from '../helpers/storage'
|
||||||
import {
|
import {
|
||||||
SessionOptions,
|
SessionOptions,
|
||||||
@ -101,7 +103,9 @@ export function getCreator(rcRoom: RcRoom): string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function parseMemberships(rcRoom: RcRoom): Promise<void> {
|
export async function createDirectChatMemberships(
|
||||||
|
rcRoom: RcRoom
|
||||||
|
): Promise<void> {
|
||||||
if (rcRoom.t == RcRoomTypes.direct && rcRoom.uids) {
|
if (rcRoom.t == RcRoomTypes.direct && rcRoom.uids) {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
[...new Set(rcRoom.uids)] // Deduplicate users
|
[...new Set(rcRoom.uids)] // Deduplicate users
|
||||||
@ -182,19 +186,45 @@ export async function getFilteredMembers(
|
|||||||
return memberMappings
|
return memberMappings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function createMapping(
|
||||||
|
rcId: string,
|
||||||
|
matrixRoom: MatrixRoom
|
||||||
|
): Promise<void> {
|
||||||
|
const roomMapping = new IdMapping()
|
||||||
|
roomMapping.rcId = rcId
|
||||||
|
roomMapping.matrixId = matrixRoom.room_id
|
||||||
|
roomMapping.type = 1
|
||||||
|
|
||||||
|
await save(roomMapping)
|
||||||
|
log.debug('Mapping added:', roomMapping)
|
||||||
|
}
|
||||||
|
|
||||||
export async function createRoom(rcRoom: RcRoom): Promise<MatrixRoom> {
|
export async function createRoom(rcRoom: RcRoom): Promise<MatrixRoom> {
|
||||||
const room: MatrixRoom = mapRoom(rcRoom)
|
const room: MatrixRoom = mapRoom(rcRoom)
|
||||||
const creatorId = getCreator(rcRoom)
|
const creatorId = getCreator(rcRoom)
|
||||||
await parseMemberships(rcRoom)
|
await createDirectChatMemberships(rcRoom)
|
||||||
const creatorSessionOptions = await getCreatorSessionOptions(creatorId)
|
const creatorSessionOptions = await getCreatorSessionOptions(creatorId)
|
||||||
log.debug('Creating room:', room)
|
log.debug('Creating room:', room)
|
||||||
|
|
||||||
room.room_id = await registerRoom(room, creatorSessionOptions)
|
room.room_id = await registerRoom(room, creatorSessionOptions)
|
||||||
|
|
||||||
const rcMemberIds = await getMemberships(rcRoom._id)
|
await handleMemberships(rcRoom._id, room, creatorId, creatorSessionOptions)
|
||||||
|
|
||||||
|
return room
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleMemberships(
|
||||||
|
rcRoomId: string,
|
||||||
|
room: MatrixRoom,
|
||||||
|
creatorId: string,
|
||||||
|
creatorSessionOptions: object | SessionOptions
|
||||||
|
) {
|
||||||
|
const rcMemberIds = await getMemberships(rcRoomId)
|
||||||
const memberMappings = await getFilteredMembers(rcMemberIds, creatorId)
|
const memberMappings = await getFilteredMembers(rcMemberIds, creatorId)
|
||||||
log.info(
|
log.info(
|
||||||
`Inviting members to room ${rcRoom._id}:`,
|
`Inviting members to room ${
|
||||||
|
room.room_alias_name || room.name || room.room_id
|
||||||
|
}:`,
|
||||||
memberMappings.map((mapping) => mapping.matrixId)
|
memberMappings.map((mapping) => mapping.matrixId)
|
||||||
)
|
)
|
||||||
log.debug(
|
log.debug(
|
||||||
@ -214,6 +244,16 @@ export async function createRoom(rcRoom: RcRoom): Promise<MatrixRoom> {
|
|||||||
await acceptInvitation(memberMapping, room.room_id || '')
|
await acceptInvitation(memberMapping, room.room_id || '')
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
}
|
||||||
return room
|
|
||||||
|
export async function handle(rcRoom: RcRoom): Promise<void> {
|
||||||
|
log.info(`Parsing room ${rcRoom.name || 'with ID: ' + rcRoom._id}`)
|
||||||
|
|
||||||
|
const matrixRoomId = await getRoomId(rcRoom._id)
|
||||||
|
if (matrixRoomId) {
|
||||||
|
log.debug(`Mapping exists: ${rcRoom._id} -> ${matrixRoomId}`)
|
||||||
|
} else {
|
||||||
|
const matrixRoom = await createRoom(rcRoom)
|
||||||
|
await createMapping(rcRoom._id, matrixRoom)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,11 +6,13 @@ import * as storage from '../helpers/storage'
|
|||||||
import {
|
import {
|
||||||
MatrixUser,
|
MatrixUser,
|
||||||
RcUser,
|
RcUser,
|
||||||
|
createMapping,
|
||||||
createUser,
|
createUser,
|
||||||
generateHmac,
|
generateHmac,
|
||||||
mapUser,
|
mapUser,
|
||||||
userIsExcluded,
|
userIsExcluded,
|
||||||
} from '../handlers/users'
|
} from '../handlers/users'
|
||||||
|
import { IdMapping } from '../entity/IdMapping'
|
||||||
|
|
||||||
jest.mock('axios')
|
jest.mock('axios')
|
||||||
const mockedAxios = axios as jest.Mocked<typeof axios>
|
const mockedAxios = axios as jest.Mocked<typeof axios>
|
||||||
@ -96,3 +98,13 @@ test('users are excluded', () => {
|
|||||||
})
|
})
|
||||||
).toBeTruthy()
|
).toBeTruthy()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('creating mapping', async () => {
|
||||||
|
await expect(createMapping(rcUser._id, matrixUser)).resolves.toBe(undefined)
|
||||||
|
expect(mockedStorage.save).toHaveBeenCalledWith({
|
||||||
|
rcId: rcUser._id,
|
||||||
|
matrixId: matrixUser.user_id,
|
||||||
|
type: 0,
|
||||||
|
accessToken: matrixUser.access_token,
|
||||||
|
} as IdMapping)
|
||||||
|
})
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import { createHmac } from 'node:crypto'
|
import { createHmac } from 'node:crypto'
|
||||||
import log from '../helpers/logger'
|
import log from '../helpers/logger'
|
||||||
import { axios } from '../helpers/synapse'
|
import { axios } from '../helpers/synapse'
|
||||||
import { createMembership } from '../helpers/storage'
|
import { createMembership, getUserId, save } from '../helpers/storage'
|
||||||
|
import { IdMapping } from '../entity/IdMapping'
|
||||||
|
|
||||||
export type RcUser = {
|
export type RcUser = {
|
||||||
_id: string
|
_id: string
|
||||||
@ -91,6 +92,20 @@ export function userIsExcluded(rcUser: RcUser): boolean {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function createMapping(
|
||||||
|
rcId: string,
|
||||||
|
matrixUser: MatrixUser
|
||||||
|
): Promise<void> {
|
||||||
|
const mapping = new IdMapping()
|
||||||
|
mapping.rcId = rcId
|
||||||
|
mapping.matrixId = matrixUser.user_id
|
||||||
|
mapping.type = 0
|
||||||
|
mapping.accessToken = matrixUser.access_token
|
||||||
|
|
||||||
|
await save(mapping)
|
||||||
|
log.debug('Mapping added:', mapping)
|
||||||
|
}
|
||||||
|
|
||||||
export async function createUser(rcUser: RcUser): Promise<MatrixUser> {
|
export async function createUser(rcUser: RcUser): Promise<MatrixUser> {
|
||||||
const user = mapUser(rcUser)
|
const user = mapUser(rcUser)
|
||||||
const nonce = await getUserRegistrationNonce()
|
const nonce = await getUserRegistrationNonce()
|
||||||
@ -104,3 +119,19 @@ export async function createUser(rcUser: RcUser): Promise<MatrixUser> {
|
|||||||
|
|
||||||
return user
|
return user
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function handle(rcUser: RcUser): Promise<void> {
|
||||||
|
log.info(`Parsing user: ${rcUser.name}: ${rcUser._id}`)
|
||||||
|
|
||||||
|
if (userIsExcluded(rcUser)) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
const matrixId = await getUserId(rcUser._id)
|
||||||
|
if (matrixId) {
|
||||||
|
log.debug(`Mapping exists: ${rcUser._id} -> ${matrixId}`)
|
||||||
|
} else {
|
||||||
|
const matrixUser = await createUser(rcUser)
|
||||||
|
await createMapping(rcUser._id, matrixUser)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user