From 3e1169235c7fb6ab2ef54844dece73ef1b3715dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20H=C3=BCttemann?= Date: Thu, 22 Jun 2023 15:43:40 +0200 Subject: [PATCH 1/7] Add helper functions to get ID mappings --- src/app.ts | 21 ++++++++++----------- src/helpers/storage.test.ts | 30 ++++++++++++++++++++++++++++++ src/helpers/storage.ts | 12 ++++++++++++ 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/src/app.ts b/src/app.ts index f50a1c3..869c105 100644 --- a/src/app.ts +++ b/src/app.ts @@ -8,6 +8,8 @@ import log from './helpers/logger' import { createMembership, getMapping, + getRoomId, + getUserId, initStorage, save, } from './helpers/storage' @@ -62,12 +64,12 @@ async function loadRcExport(entity: Entities) { break } - let mapping = await getMapping(rcUser._id, entities[entity].mappingType) - if (mapping && mapping.matrixId) { - log.debug('Mapping exists:', mapping) + const matrixUserId = await getUserId(rcUser._id) + if (matrixUserId) { + log.debug(`Mapping exists: ${rcUser._id} -> ${matrixUserId}`) } else { const matrixUser = await createUser(rcUser) - mapping = new IdMapping() + const mapping = new IdMapping() mapping.rcId = rcUser._id mapping.matrixId = matrixUser.user_id mapping.type = entities[entity].mappingType @@ -91,15 +93,12 @@ async function loadRcExport(entity: Entities) { const rcRoom: RcRoom = item log.info(`Parsing room ${rcRoom.name || 'with ID: ' + rcRoom._id}`) - let roomMapping = await getMapping( - rcRoom._id, - entities[entity].mappingType - ) - if (roomMapping && roomMapping.matrixId) { - log.debug('Mapping exists:', roomMapping) + const matrixRoomId = await getRoomId(rcRoom._id) + if (matrixRoomId) { + log.debug(`Mapping exists: ${rcRoom._id} -> ${matrixRoomId}`) } else { const matrixRoom = await createRoom(rcRoom) - roomMapping = new IdMapping() + const roomMapping = new IdMapping() roomMapping.rcId = rcRoom._id roomMapping.matrixId = matrixRoom.room_id roomMapping.type = entities[entity].mappingType diff --git a/src/helpers/storage.test.ts b/src/helpers/storage.test.ts index 81bfb8d..f909dbe 100644 --- a/src/helpers/storage.test.ts +++ b/src/helpers/storage.test.ts @@ -5,6 +5,9 @@ import { getAccessToken, getMapping, getMemberships, + getMessageId, + getRoomId, + getUserId, initStorage, save, } from './storage' @@ -60,3 +63,30 @@ test('get membership', async () => { await expect(getMemberships('inexistent')).resolves.toStrictEqual([]) }) + +test('get member by id', async () => { + await expect(getUserId(mapping.rcId)).resolves.toBe(mapping.matrixId) + await expect(getUserId('inexistent')).resolves.toBeFalsy() +}) + +test('get room by id', async () => { + const room = new IdMapping() + room.rcId = 'rcRoom' + room.matrixId = 'matrixRoom' + room.type = 1 + await save(room) + + await expect(getRoomId(room.rcId)).resolves.toBe(room.matrixId) + await expect(getRoomId('inexistent')).resolves.toBeFalsy() +}) + +test('get message by id', async () => { + const message = new IdMapping() + message.rcId = 'rcMessage' + message.matrixId = 'matrixMessage' + message.type = 2 + await save(message) + + await expect(getMessageId(message.rcId)).resolves.toBe(message.matrixId) + await expect(getMessageId('inexistent')).resolves.toBeFalsy() +}) diff --git a/src/helpers/storage.ts b/src/helpers/storage.ts index fcd9ff8..182a739 100644 --- a/src/helpers/storage.ts +++ b/src/helpers/storage.ts @@ -55,3 +55,15 @@ export async function getMemberships(rcRoomId: string): Promise { }) ).map((entity) => entity.rcUserId) } + +export async function getUserId(rcId: string): Promise { + return (await getMapping(rcId, 0))?.matrixId +} + +export async function getRoomId(rcId: string): Promise { + return (await getMapping(rcId, 1))?.matrixId +} + +export async function getMessageId(rcId: string): Promise { + return (await getMapping(rcId, 2))?.matrixId +} From de87228b8d921263f528b27dc854ebeddd99dfe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20H=C3=BCttemann?= Date: Thu, 22 Jun 2023 16:17:05 +0200 Subject: [PATCH 2/7] Move membership creation to users --- src/app.ts | 17 +---------------- src/handlers/users.test.ts | 16 +++++++++++++++- src/handlers/users.ts | 12 ++++++++++++ 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/app.ts b/src/app.ts index 869c105..f4630b1 100644 --- a/src/app.ts +++ b/src/app.ts @@ -5,14 +5,7 @@ import 'reflect-metadata' import { IdMapping } from './entity/IdMapping' import { RcUser, createUser } from './handlers/users' import log from './helpers/logger' -import { - createMembership, - getMapping, - getRoomId, - getUserId, - initStorage, - save, -} from './helpers/storage' +import { getRoomId, getUserId, initStorage, save } from './helpers/storage' import { whoami } from './helpers/synapse' import { RcRoom, createRoom } from './handlers/rooms' @@ -77,14 +70,6 @@ async function loadRcExport(entity: Entities) { await save(mapping) log.debug('Mapping added:', mapping) - - // Add user to room mapping (specific to users) - await Promise.all( - rcUser.__rooms.map(async (rcRoomId: string) => { - await createMembership(rcRoomId, rcUser._id) - log.debug(`${rcUser.username} membership for ${rcRoomId} created`) - }) - ) } break diff --git a/src/handlers/users.test.ts b/src/handlers/users.test.ts index 2882fa8..cb86e11 100644 --- a/src/handlers/users.test.ts +++ b/src/handlers/users.test.ts @@ -1,6 +1,7 @@ process.env.REGISTRATION_SHARED_SECRET = 'ThisIsSoSecretWow' import { expect, jest, test } from '@jest/globals' import axios from 'axios' +import * as storage from '../helpers/storage' import { MatrixUser, RcUser, @@ -12,12 +13,15 @@ import { jest.mock('axios') const mockedAxios = axios as jest.Mocked +jest.mock('../helpers/storage') +const mockedStorage = storage as jest.Mocked + const rcUser: RcUser = { _id: 'testRc', name: 'Tester McDelme', username: 'testuser', roles: ['user'], - __rooms: [], + __rooms: ['room0', 'room1'], } const matrixUser: MatrixUser = { @@ -65,4 +69,14 @@ test('creating users', async () => { // nonce, // mac: 'be0537407ab3c82de908c5763185556e98a7211c', // }) + + expect(mockedStorage.createMembership).toHaveBeenCalledWith( + rcUser.__rooms[0], + rcUser._id + ) + expect(mockedStorage.createMembership).toHaveBeenCalledWith( + rcUser.__rooms[1], + rcUser._id + ) + expect(mockedStorage.createMembership).toHaveBeenCalledTimes(2) }) diff --git a/src/handlers/users.ts b/src/handlers/users.ts index c6867ed..b6a59bc 100644 --- a/src/handlers/users.ts +++ b/src/handlers/users.ts @@ -1,6 +1,7 @@ import { createHmac } from 'node:crypto' import log from '../helpers/logger' import { axios } from '../helpers/synapse' +import { createMembership } from '../helpers/storage' export type RcUser = { _id: string @@ -64,6 +65,15 @@ async function registerUser(user: MatrixUser): Promise { return (await axios.post('/_synapse/admin/v1/register', user)).data } +async function parseUserMemberships(rcUser: RcUser): Promise { + await Promise.all( + rcUser.__rooms.map(async (rcRoomId: string) => { + await createMembership(rcRoomId, rcUser._id) + log.debug(`${rcUser.username} membership for ${rcRoomId} created`) + }) + ) +} + export async function createUser(rcUser: RcUser): Promise { const user = mapUser(rcUser) user.nonce = await getUserRegistrationNonce() @@ -76,5 +86,7 @@ export async function createUser(rcUser: RcUser): Promise { delete user.nonce delete user.mac + await parseUserMemberships(rcUser) + return user } From 463daefedae8d38a26f64a24f3ecc4bbfb8a9295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20H=C3=BCttemann?= Date: Thu, 22 Jun 2023 16:34:03 +0200 Subject: [PATCH 3/7] Fix broken and deactivated user creation test --- src/handlers/users.test.ts | 18 +++++++----------- src/handlers/users.ts | 9 +++------ 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/src/handlers/users.test.ts b/src/handlers/users.test.ts index cb86e11..b15b354 100644 --- a/src/handlers/users.test.ts +++ b/src/handlers/users.test.ts @@ -33,15 +33,14 @@ const matrixUser: MatrixUser = { } const nonce = 'test-nonce' +const mac = 'be0537407ab3c82de908c5763185556e98a7211c' test('mapping users', () => { expect(mapUser(rcUser)).toStrictEqual(matrixUser) }) test('generating correct hmac', () => { - expect(generateHmac({ ...matrixUser, nonce })).toStrictEqual( - 'be0537407ab3c82de908c5763185556e98a7211c' - ) + expect(generateHmac({ ...matrixUser, nonce })).toStrictEqual(mac) }) test('creating users', async () => { @@ -61,14 +60,11 @@ test('creating users', async () => { }) expect(mockedAxios.get).toHaveBeenCalledWith('/_synapse/admin/v1/register') - expect(mockedAxios.post).toHaveBeenCalled() - // The following test fails with an incorrect return value, for whatever reason. - // Probably because of mutated call logs in jest due to the `delete` or sth. - // expect(mockedAxios.post).toHaveBeenCalledWith('/_synapse/admin/v1/register', { - // ...matrixUser, - // nonce, - // mac: 'be0537407ab3c82de908c5763185556e98a7211c', - // }) + expect(mockedAxios.post).toHaveBeenCalledWith('/_synapse/admin/v1/register', { + ...matrixUser, + nonce, + mac, + }) expect(mockedStorage.createMembership).toHaveBeenCalledWith( rcUser.__rooms[0], diff --git a/src/handlers/users.ts b/src/handlers/users.ts index b6a59bc..85680fb 100644 --- a/src/handlers/users.ts +++ b/src/handlers/users.ts @@ -76,16 +76,13 @@ async function parseUserMemberships(rcUser: RcUser): Promise { export async function createUser(rcUser: RcUser): Promise { const user = mapUser(rcUser) - user.nonce = await getUserRegistrationNonce() - user.mac = generateHmac(user) - const accessToken = await registerUser(user) + const nonce = await getUserRegistrationNonce() + const mac = generateHmac({ ...user, nonce }) + const accessToken = await registerUser({ ...user, nonce, mac }) user.user_id = accessToken.user_id user.access_token = accessToken.access_token log.info(`User ${rcUser.username} created:`, user) - delete user.nonce - delete user.mac - await parseUserMemberships(rcUser) return user From 3459bbecd3177a75fe70bb69ecfb5340409e1819 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20H=C3=BCttemann?= Date: Thu, 22 Jun 2023 17:12:48 +0200 Subject: [PATCH 4/7] Move user exclusion test to user handler --- .env.example | 2 +- src/app.ts | 9 ++------- src/handlers/users.test.ts | 20 ++++++++++++++++++++ src/handlers/users.ts | 17 +++++++++++++++++ src/helpers/storage.test.ts | 2 +- 5 files changed, 41 insertions(+), 9 deletions(-) diff --git a/.env.example b/.env.example index c447e32..52181c2 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1,2 @@ REGISTRATION_SHARED_SECRET='look in your synapses homeserver.yaml' -EXCLUDED_USERS='rocket.cat' # Comma-separated list +EXCLUDED_USERS='rocket.cat' # Comma-separated list of usernames or IDs diff --git a/src/app.ts b/src/app.ts index f4630b1..8f91a84 100644 --- a/src/app.ts +++ b/src/app.ts @@ -3,7 +3,7 @@ dotenv.config() import lineByLine from 'n-readlines' import 'reflect-metadata' import { IdMapping } from './entity/IdMapping' -import { RcUser, createUser } from './handlers/users' +import { RcUser, createUser, userIsExcluded } from './handlers/users' import log from './helpers/logger' import { getRoomId, getUserId, initStorage, save } from './helpers/storage' import { whoami } from './helpers/synapse' @@ -48,12 +48,7 @@ async function loadRcExport(entity: Entities) { const rcUser: RcUser = item log.info(`Parsing user: ${rcUser.name}: ${rcUser._id}`) - // Check for exclusion - if ( - rcUser.roles.some((e) => ['app', 'bot'].includes(e)) || - (process.env.EXCLUDED_USERS || '').split(',').includes(rcUser._id) - ) { - log.debug('User excluded. Skipping.') + if (userIsExcluded(rcUser)) { break } diff --git a/src/handlers/users.test.ts b/src/handlers/users.test.ts index b15b354..811ca78 100644 --- a/src/handlers/users.test.ts +++ b/src/handlers/users.test.ts @@ -1,4 +1,5 @@ process.env.REGISTRATION_SHARED_SECRET = 'ThisIsSoSecretWow' +process.env.EXCLUDED_USERS = 'excludedUser1,excludedUser2' import { expect, jest, test } from '@jest/globals' import axios from 'axios' import * as storage from '../helpers/storage' @@ -8,6 +9,7 @@ import { createUser, generateHmac, mapUser, + userIsExcluded, } from '../handlers/users' jest.mock('axios') @@ -76,3 +78,21 @@ test('creating users', async () => { ) expect(mockedStorage.createMembership).toHaveBeenCalledTimes(2) }) + +test('users are excluded', () => { + expect(userIsExcluded(rcUser)).toBeFalsy() + expect(userIsExcluded({ ...rcUser, _id: 'excludedUser1' })).toBeTruthy() + expect(userIsExcluded({ ...rcUser, username: 'excludedUser2' })).toBeTruthy() + expect(userIsExcluded({ ...rcUser, roles: ['bot'] })).toBeTruthy() + expect( + userIsExcluded({ ...rcUser, roles: [...rcUser.__rooms, 'app'] }) + ).toBeTruthy() + expect( + userIsExcluded({ + ...rcUser, + _id: 'excludedUser2', + username: 'excludedUser1', + roles: [...rcUser.__rooms, 'app', 'bot'], + }) + ).toBeTruthy() +}) diff --git a/src/handlers/users.ts b/src/handlers/users.ts index 85680fb..74b5566 100644 --- a/src/handlers/users.ts +++ b/src/handlers/users.ts @@ -74,6 +74,23 @@ async function parseUserMemberships(rcUser: RcUser): Promise { ) } +export function userIsExcluded(rcUser: RcUser): boolean { + const reasons: string[] = [] + const excludedUsers = (process.env.EXCLUDED_USERS || '').split(',') + if (rcUser.roles.includes('app')) reasons.push('has role "app"') + if (rcUser.roles.includes('bot')) reasons.push('has role "bot"') + if (excludedUsers.includes(rcUser._id)) + reasons.push(`id "${rcUser._id}" is on exclusion list`) + if (excludedUsers.includes(rcUser.username)) + reasons.push(`username "${rcUser.username}" is on exclusion list`) + + if (reasons.length > 0) { + log.debug(`User ${rcUser.name} is excluded: ${reasons.join(', ')}`) + return true + } + return false +} + export async function createUser(rcUser: RcUser): Promise { const user = mapUser(rcUser) const nonce = await getUserRegistrationNonce() diff --git a/src/helpers/storage.test.ts b/src/helpers/storage.test.ts index f909dbe..d579979 100644 --- a/src/helpers/storage.test.ts +++ b/src/helpers/storage.test.ts @@ -28,7 +28,7 @@ beforeAll(async () => { await initStorage() }) -test('save mapping', async () => { +test('create mapping', async () => { await expect(save(mapping)).resolves.toBe(undefined) }) From 6b723db5a195a5d7ba7b7350260a37e042923e81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20H=C3=BCttemann?= Date: Fri, 23 Jun 2023 15:26:39 +0200 Subject: [PATCH 5/7] Move user and room handling to respective modules --- src/app.ts | 47 ++++------------------------------ src/handlers/rooms.test.ts | 27 +++++++++++++++++--- src/handlers/rooms.ts | 52 +++++++++++++++++++++++++++++++++----- src/handlers/users.test.ts | 12 +++++++++ src/handlers/users.ts | 33 +++++++++++++++++++++++- 5 files changed, 119 insertions(+), 52 deletions(-) diff --git a/src/app.ts b/src/app.ts index 8f91a84..c71c06c 100644 --- a/src/app.ts +++ b/src/app.ts @@ -2,12 +2,11 @@ import dotenv from 'dotenv' dotenv.config() import lineByLine from 'n-readlines' import 'reflect-metadata' -import { IdMapping } from './entity/IdMapping' -import { RcUser, createUser, userIsExcluded } from './handlers/users' +import { handle as handleRoom } from './handlers/rooms' +import { handle as handleUser } from './handlers/users' import log from './helpers/logger' -import { getRoomId, getUserId, initStorage, save } from './helpers/storage' +import { initStorage } from './helpers/storage' import { whoami } from './helpers/synapse' -import { RcRoom, createRoom } from './handlers/rooms' log.info('rocketchat2matrix starts.') @@ -45,47 +44,11 @@ async function loadRcExport(entity: Entities) { const item = JSON.parse(line.toString()) switch (entity) { case Entities.Users: - const rcUser: RcUser = 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) - } - + await handleUser(item) break case Entities.Rooms: - const rcRoom: RcRoom = 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) - } + await handleRoom(item) break case Entities.Messages: diff --git a/src/handlers/rooms.test.ts b/src/handlers/rooms.test.ts index bf3e80a..6a7008f 100644 --- a/src/handlers/rooms.test.ts +++ b/src/handlers/rooms.test.ts @@ -6,13 +6,15 @@ import { SessionOptions } from '../helpers/synapse' import { MatrixRoomPresets, MatrixRoomVisibility, + RcRoom, RcRoomTypes, acceptInvitation, + createMapping, getCreator, getFilteredMembers, inviteMember, mapRoom, - parseMemberships, + createDirectChatMemberships, registerRoom, } from './rooms' @@ -110,10 +112,13 @@ test('getting creator', () => { expect(getCreator(rcDirectChat)).toBe('aliceid') expect(getCreator(rcPublicRoom)).toBe(roomCreator._id) expect(getCreator(rcPrivateRoom)).toBe(roomCreator._id) + expect(getCreator({} as RcRoom)).toBe('') }) 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( rcDirectChat._id, rcDirectChat.uids[0] @@ -127,7 +132,11 @@ test('creating memberships for direct chats', async () => { mockedStorage.createMembership.mockClear() await expect( - parseMemberships({ ...rcDirectChat, _id: 'hoihoi', uids: ['hoi', 'hoi'] }) + createDirectChatMemberships({ + ...rcDirectChat, + _id: 'hoihoi', + uids: ['hoi', 'hoi'], + }) ).resolves.toBe(undefined) expect(mockedStorage.createMembership).toHaveBeenCalledWith('hoihoi', 'hoi') @@ -210,3 +219,15 @@ test('filtering members', async () => { expect(mockedStorage.getMapping).toBeCalledWith('otherExistingUser', 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) +}) diff --git a/src/handlers/rooms.ts b/src/handlers/rooms.ts index 0ed2897..4c1f980 100644 --- a/src/handlers/rooms.ts +++ b/src/handlers/rooms.ts @@ -4,6 +4,8 @@ import { createMembership, getMapping, getMemberships, + getRoomId, + save, } from '../helpers/storage' import { SessionOptions, @@ -101,7 +103,9 @@ export function getCreator(rcRoom: RcRoom): string { } } -export async function parseMemberships(rcRoom: RcRoom): Promise { +export async function createDirectChatMemberships( + rcRoom: RcRoom +): Promise { if (rcRoom.t == RcRoomTypes.direct && rcRoom.uids) { await Promise.all( [...new Set(rcRoom.uids)] // Deduplicate users @@ -182,19 +186,45 @@ export async function getFilteredMembers( return memberMappings } +export async function createMapping( + rcId: string, + matrixRoom: MatrixRoom +): Promise { + 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 { const room: MatrixRoom = mapRoom(rcRoom) const creatorId = getCreator(rcRoom) - await parseMemberships(rcRoom) + await createDirectChatMemberships(rcRoom) const creatorSessionOptions = await getCreatorSessionOptions(creatorId) log.debug('Creating room:', room) 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) 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) ) log.debug( @@ -214,6 +244,16 @@ export async function createRoom(rcRoom: RcRoom): Promise { await acceptInvitation(memberMapping, room.room_id || '') }) ) - - return room +} + +export async function handle(rcRoom: RcRoom): Promise { + 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) + } } diff --git a/src/handlers/users.test.ts b/src/handlers/users.test.ts index 811ca78..c53995b 100644 --- a/src/handlers/users.test.ts +++ b/src/handlers/users.test.ts @@ -6,11 +6,13 @@ import * as storage from '../helpers/storage' import { MatrixUser, RcUser, + createMapping, createUser, generateHmac, mapUser, userIsExcluded, } from '../handlers/users' +import { IdMapping } from '../entity/IdMapping' jest.mock('axios') const mockedAxios = axios as jest.Mocked @@ -96,3 +98,13 @@ test('users are excluded', () => { }) ).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) +}) diff --git a/src/handlers/users.ts b/src/handlers/users.ts index 74b5566..ac4a9d2 100644 --- a/src/handlers/users.ts +++ b/src/handlers/users.ts @@ -1,7 +1,8 @@ import { createHmac } from 'node:crypto' import log from '../helpers/logger' 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 = { _id: string @@ -91,6 +92,20 @@ export function userIsExcluded(rcUser: RcUser): boolean { return false } +export async function createMapping( + rcId: string, + matrixUser: MatrixUser +): Promise { + 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 { const user = mapUser(rcUser) const nonce = await getUserRegistrationNonce() @@ -104,3 +119,19 @@ export async function createUser(rcUser: RcUser): Promise { return user } + +export async function handle(rcUser: RcUser): Promise { + 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) + } +} From 8ba2ce4cab2443f361388ecc6e50fba02c98473b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20H=C3=BCttemann?= Date: Fri, 23 Jun 2023 15:43:31 +0200 Subject: [PATCH 6/7] Edit mapping types to use constants --- src/Entities.ts | 27 +++++++++++++++++++++++++ src/app.ts | 39 +++++++------------------------------ src/handlers/rooms.test.ts | 22 +++++++++++++++------ src/handlers/rooms.ts | 3 ++- src/handlers/users.test.ts | 3 ++- src/handlers/users.ts | 3 ++- src/helpers/storage.test.ts | 7 ++++--- src/helpers/storage.ts | 10 ++++++---- 8 files changed, 66 insertions(+), 48 deletions(-) create mode 100644 src/Entities.ts diff --git a/src/Entities.ts b/src/Entities.ts new file mode 100644 index 0000000..331b44e --- /dev/null +++ b/src/Entities.ts @@ -0,0 +1,27 @@ +export const enum Entity { + Users = 'users', + Rooms = 'rooms', + Messages = 'messages', +} + +type EntityConfig = { + filename: string + mappingType: number +} + +export const entities: { + [key in Entity]: EntityConfig +} = { + users: { + filename: 'users.json', + mappingType: 0, + }, + rooms: { + filename: 'rocketchat_room.json', + mappingType: 1, + }, + messages: { + filename: 'rocketchat_message.json', + mappingType: 2, + }, +} as const diff --git a/src/app.ts b/src/app.ts index c71c06c..2661191 100644 --- a/src/app.ts +++ b/src/app.ts @@ -7,51 +7,26 @@ import { handle as handleUser } from './handlers/users' import log from './helpers/logger' import { initStorage } from './helpers/storage' import { whoami } from './helpers/synapse' +import { Entity, entities } from './Entities' log.info('rocketchat2matrix starts.') -const enum Entities { - Users = 'users', - Rooms = 'rooms', - Messages = 'messages', -} - -type EntityConfig = { - filename: string - mappingType: number -} - -const entities: { [key in Entities]: EntityConfig } = { - users: { - filename: 'users.json', - mappingType: 0, - }, - rooms: { - filename: 'rocketchat_room.json', - mappingType: 1, - }, - messages: { - filename: 'rocketchat_message.json', - mappingType: 2, - }, -} - -async function loadRcExport(entity: Entities) { +async function loadRcExport(entity: Entity) { const rl = new lineByLine(`./inputs/${entities[entity].filename}`) let line: false | Buffer while ((line = rl.next())) { const item = JSON.parse(line.toString()) switch (entity) { - case Entities.Users: + case Entity.Users: await handleUser(item) break - case Entities.Rooms: + case Entity.Rooms: await handleRoom(item) break - case Entities.Messages: + case Entity.Messages: log.debug(`Message: ${item.name}`) break @@ -66,9 +41,9 @@ async function main() { await whoami() await initStorage() log.info('Parsing users') - await loadRcExport(Entities.Users) + await loadRcExport(Entity.Users) log.info('Parsing rooms') - await loadRcExport(Entities.Rooms) + await loadRcExport(Entity.Rooms) log.info('Done.') } catch (error) { log.error(`Encountered an error while booting up: ${error}`, error) diff --git a/src/handlers/rooms.test.ts b/src/handlers/rooms.test.ts index 6a7008f..d2f3fc6 100644 --- a/src/handlers/rooms.test.ts +++ b/src/handlers/rooms.test.ts @@ -17,6 +17,7 @@ import { createDirectChatMemberships, registerRoom, } from './rooms' +import { Entity, entities } from '../Entities' jest.mock('axios') const mockedAxios = axios as jest.Mocked @@ -177,7 +178,7 @@ test('accepting invitation by joining the room', async () => { rcId: 'whatever', matrixId: 'Neo', accessToken: 'secretAuthToken', - type: 0, + type: entities[Entity.Users].mappingType, }, room_id ) @@ -202,7 +203,7 @@ test('filtering members', async () => { return { rcId, matrixId: `@${rcId}:matrix`, - type: type || 0, + type: type || entities[Entity.Users].mappingType, accessToken: 'accessToken', } } @@ -215,9 +216,18 @@ test('filtering members', async () => { mockMapping('existingUser'), mockMapping('otherExistingUser'), ]) - expect(mockedStorage.getMapping).toBeCalledWith('existingUser', 0) - expect(mockedStorage.getMapping).toBeCalledWith('otherExistingUser', 0) - expect(mockedStorage.getMapping).toBeCalledWith('excludedUser', 0) + expect(mockedStorage.getMapping).toBeCalledWith( + 'existingUser', + entities[Entity.Users].mappingType + ) + expect(mockedStorage.getMapping).toBeCalledWith( + 'otherExistingUser', + entities[Entity.Users].mappingType + ) + expect(mockedStorage.getMapping).toBeCalledWith( + 'excludedUser', + entities[Entity.Users].mappingType + ) }) test('creating mapping', async () => { @@ -227,7 +237,7 @@ test('creating mapping', async () => { expect(mockedStorage.save).toHaveBeenCalledWith({ rcId: rcPublicRoom._id, matrixId: room_id, - type: 1, + type: entities[Entity.Rooms].mappingType, accessToken: undefined, } as IdMapping) }) diff --git a/src/handlers/rooms.ts b/src/handlers/rooms.ts index 4c1f980..9568372 100644 --- a/src/handlers/rooms.ts +++ b/src/handlers/rooms.ts @@ -1,3 +1,4 @@ +import { Entity, entities } from '../Entities' import { IdMapping } from '../entity/IdMapping' import log from '../helpers/logger' import { @@ -193,7 +194,7 @@ export async function createMapping( const roomMapping = new IdMapping() roomMapping.rcId = rcId roomMapping.matrixId = matrixRoom.room_id - roomMapping.type = 1 + roomMapping.type = entities[Entity.Rooms].mappingType await save(roomMapping) log.debug('Mapping added:', roomMapping) diff --git a/src/handlers/users.test.ts b/src/handlers/users.test.ts index c53995b..612aad2 100644 --- a/src/handlers/users.test.ts +++ b/src/handlers/users.test.ts @@ -13,6 +13,7 @@ import { userIsExcluded, } from '../handlers/users' import { IdMapping } from '../entity/IdMapping' +import { Entity, entities } from '../Entities' jest.mock('axios') const mockedAxios = axios as jest.Mocked @@ -104,7 +105,7 @@ test('creating mapping', async () => { expect(mockedStorage.save).toHaveBeenCalledWith({ rcId: rcUser._id, matrixId: matrixUser.user_id, - type: 0, + type: entities[Entity.Users].mappingType, accessToken: matrixUser.access_token, } as IdMapping) }) diff --git a/src/handlers/users.ts b/src/handlers/users.ts index ac4a9d2..9c3ae1c 100644 --- a/src/handlers/users.ts +++ b/src/handlers/users.ts @@ -3,6 +3,7 @@ import log from '../helpers/logger' import { axios } from '../helpers/synapse' import { createMembership, getUserId, save } from '../helpers/storage' import { IdMapping } from '../entity/IdMapping' +import { Entity, entities } from '../Entities' export type RcUser = { _id: string @@ -99,7 +100,7 @@ export async function createMapping( const mapping = new IdMapping() mapping.rcId = rcId mapping.matrixId = matrixUser.user_id - mapping.type = 0 + mapping.type = entities[Entity.Users].mappingType mapping.accessToken = matrixUser.access_token await save(mapping) diff --git a/src/helpers/storage.test.ts b/src/helpers/storage.test.ts index d579979..b4de1cf 100644 --- a/src/helpers/storage.test.ts +++ b/src/helpers/storage.test.ts @@ -13,11 +13,12 @@ import { } from './storage' import { IdMapping } from '../entity/IdMapping' import { Membership } from '../entity/Membership' +import { Entity, entities } from '../Entities' const mapping = new IdMapping() mapping.rcId = 'rcId' mapping.matrixId = 'matrixId' -mapping.type = 0 +mapping.type = entities[Entity.Users].mappingType mapping.accessToken = 'accessToken' const membership = new Membership() @@ -73,7 +74,7 @@ test('get room by id', async () => { const room = new IdMapping() room.rcId = 'rcRoom' room.matrixId = 'matrixRoom' - room.type = 1 + room.type = entities[Entity.Rooms].mappingType await save(room) await expect(getRoomId(room.rcId)).resolves.toBe(room.matrixId) @@ -84,7 +85,7 @@ test('get message by id', async () => { const message = new IdMapping() message.rcId = 'rcMessage' message.matrixId = 'matrixMessage' - message.type = 2 + message.type = entities[Entity.Messages].mappingType await save(message) await expect(getMessageId(message.rcId)).resolves.toBe(message.matrixId) diff --git a/src/helpers/storage.ts b/src/helpers/storage.ts index 182a739..df99642 100644 --- a/src/helpers/storage.ts +++ b/src/helpers/storage.ts @@ -1,6 +1,7 @@ import { DataSource } from 'typeorm' import { IdMapping } from '../entity/IdMapping' import { Membership } from '../entity/Membership' +import { Entity, entities } from '../Entities' const AppDataSource = new DataSource({ type: 'sqlite', @@ -29,7 +30,7 @@ export async function save(entity: IdMapping | Membership): Promise { } export async function getAccessToken(id: string): Promise { - return (await getMapping(id, 0))?.accessToken + return (await getMapping(id, entities[Entity.Users].mappingType))?.accessToken } export async function createMembership( @@ -57,13 +58,14 @@ export async function getMemberships(rcRoomId: string): Promise { } export async function getUserId(rcId: string): Promise { - return (await getMapping(rcId, 0))?.matrixId + return (await getMapping(rcId, entities[Entity.Users].mappingType))?.matrixId } export async function getRoomId(rcId: string): Promise { - return (await getMapping(rcId, 1))?.matrixId + return (await getMapping(rcId, entities[Entity.Rooms].mappingType))?.matrixId } export async function getMessageId(rcId: string): Promise { - return (await getMapping(rcId, 2))?.matrixId + return (await getMapping(rcId, entities[Entity.Messages].mappingType)) + ?.matrixId } From fae5c34adfbae2631f519f084c069ff0a5d42021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20H=C3=BCttemann?= Date: Fri, 23 Jun 2023 15:53:30 +0200 Subject: [PATCH 7/7] Update dependencies --- package-lock.json | 314 +++++++++++++++++++++++----------------------- package.json | 10 +- 2 files changed, 162 insertions(+), 162 deletions(-) diff --git a/package-lock.json b/package-lock.json index 36070a2..8e2a6cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,20 +10,20 @@ "license": "AGPL-3.0-or-later", "dependencies": { "axios": "^1.4.0", - "dotenv": "^16.1.4", + "dotenv": "^16.3.1", "n-readlines": "^1.0.1", "reflect-metadata": "^0.1.13", "sqlite3": "^5.1.6", - "typeorm": "^0.3.16", + "typeorm": "^0.3.17", "winston": "^3.9.0" }, "devDependencies": { "@jest/globals": "^29.5.0", "@types/n-readlines": "^1.0.3", "@types/node": "^20.3.1", - "@typescript-eslint/eslint-plugin": "^5.59.11", - "@typescript-eslint/parser": "^5.59.11", - "eslint": "^8.42.0", + "@typescript-eslint/eslint-plugin": "^5.60.0", + "@typescript-eslint/parser": "^5.60.0", + "eslint": "^8.43.0", "eslint-config-prettier": "^8.8.0", "eslint-config-standard-with-typescript": "^34.0.1", "eslint-plugin-import": "^2.27.5", @@ -714,9 +714,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.42.0.tgz", - "integrity": "sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz", + "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1301,9 +1301,9 @@ } }, "node_modules/@sinonjs/fake-timers": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.1.0.tgz", - "integrity": "sha512-w1qd368vtrwttm1PRJWPW1QHlbmHrVDGs1eBH/jZvRPUFS4MNXV9Q33EQdjOdeAxZ7O8+3wM7zxztm2nfUSyKw==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, "dependencies": { "@sinonjs/commons": "^3.0.0" @@ -1466,15 +1466,15 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.11.tgz", - "integrity": "sha512-XxuOfTkCUiOSyBWIvHlUraLw/JT/6Io1365RO6ZuI88STKMavJZPNMU0lFcUTeQXEhHiv64CbxYxBNoDVSmghg==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.0.tgz", + "integrity": "sha512-78B+anHLF1TI8Jn/cD0Q00TBYdMgjdOn980JfAVa9yw5sop8nyTfVOQAv6LWywkOGLclDBtv5z3oxN4w7jxyNg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.11", - "@typescript-eslint/type-utils": "5.59.11", - "@typescript-eslint/utils": "5.59.11", + "@typescript-eslint/scope-manager": "5.60.0", + "@typescript-eslint/type-utils": "5.60.0", + "@typescript-eslint/utils": "5.60.0", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -1500,14 +1500,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.11.tgz", - "integrity": "sha512-s9ZF3M+Nym6CAZEkJJeO2TFHHDsKAM3ecNkLuH4i4s8/RCPnF5JRip2GyviYkeEAcwGMJxkqG9h2dAsnA1nZpA==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.60.0.tgz", + "integrity": "sha512-jBONcBsDJ9UoTWrARkRRCgDz6wUggmH5RpQVlt7BimSwaTkTjwypGzKORXbR4/2Hqjk9hgwlon2rVQAjWNpkyQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.59.11", - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/typescript-estree": "5.59.11", + "@typescript-eslint/scope-manager": "5.60.0", + "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/typescript-estree": "5.60.0", "debug": "^4.3.4" }, "engines": { @@ -1527,13 +1527,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.11.tgz", - "integrity": "sha512-dHFOsxoLFtrIcSj5h0QoBT/89hxQONwmn3FOQ0GOQcLOOXm+MIrS8zEAhs4tWl5MraxCY3ZJpaXQQdFMc2Tu+Q==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.0.tgz", + "integrity": "sha512-hakuzcxPwXi2ihf9WQu1BbRj1e/Pd8ZZwVTG9kfbxAMZstKz8/9OoexIwnmLzShtsdap5U/CoQGRCWlSuPbYxQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/visitor-keys": "5.59.11" + "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/visitor-keys": "5.60.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1544,13 +1544,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.11.tgz", - "integrity": "sha512-LZqVY8hMiVRF2a7/swmkStMYSoXMFlzL6sXV6U/2gL5cwnLWQgLEG8tjWPpaE4rMIdZ6VKWwcffPlo1jPfk43g==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.60.0.tgz", + "integrity": "sha512-X7NsRQddORMYRFH7FWo6sA9Y/zbJ8s1x1RIAtnlj6YprbToTiQnM6vxcMu7iYhdunmoC0rUWlca13D5DVHkK2g==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.59.11", - "@typescript-eslint/utils": "5.59.11", + "@typescript-eslint/typescript-estree": "5.60.0", + "@typescript-eslint/utils": "5.60.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -1571,9 +1571,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.11.tgz", - "integrity": "sha512-epoN6R6tkvBYSc+cllrz+c2sOFWkbisJZWkOE+y3xHtvYaOE6Wk6B8e114McRJwFRjGvYdJwLXQH5c9osME/AA==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.0.tgz", + "integrity": "sha512-ascOuoCpNZBccFVNJRSC6rPq4EmJ2NkuoKnd6LDNyAQmdDnziAtxbCGWCbefG1CNzmDvd05zO36AmB7H8RzKPA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1584,13 +1584,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.11.tgz", - "integrity": "sha512-YupOpot5hJO0maupJXixi6l5ETdrITxeo5eBOeuV7RSKgYdU3G5cxO49/9WRnJq9EMrB7AuTSLH/bqOsXi7wPA==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.0.tgz", + "integrity": "sha512-R43thAuwarC99SnvrBmh26tc7F6sPa2B3evkXp/8q954kYL6Ro56AwASYWtEEi+4j09GbiNAHqYwNNZuNlARGQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/visitor-keys": "5.59.11", + "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/visitor-keys": "5.60.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1611,17 +1611,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.11.tgz", - "integrity": "sha512-didu2rHSOMUdJThLk4aZ1Or8IcO3HzCw/ZvEjTTIfjIrcdd5cvSIwwDy2AOlE7htSNp7QIZ10fLMyRCveesMLg==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.60.0.tgz", + "integrity": "sha512-ba51uMqDtfLQ5+xHtwlO84vkdjrqNzOnqrnwbMHMRY8Tqeme8C2Q8Fc7LajfGR+e3/4LoYiWXUM6BpIIbHJ4hQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.11", - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/typescript-estree": "5.59.11", + "@typescript-eslint/scope-manager": "5.60.0", + "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/typescript-estree": "5.60.0", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -1637,12 +1637,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.11.tgz", - "integrity": "sha512-KGYniTGG3AMTuKF9QBD7EIrvufkB6O6uX3knP73xbKLMpH+QRPcgnCxjWXSHjMRuOxFLovljqQgQpR0c7GvjoA==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.0.tgz", + "integrity": "sha512-wm9Uz71SbCyhUKgcaPRauBdTegUyY/ZWl8gLwD/i/ybJqscrrdVSFImpvUz16BLPChIeKBK5Fa9s6KDQjsjyWw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.11", + "@typescript-eslint/types": "5.60.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -1659,9 +1659,9 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz", + "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -2089,9 +2089,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.8", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.8.tgz", - "integrity": "sha512-j+7xYe+v+q2Id9qbBeCI8WX5NmZSRe8es1+0xntD/+gaWXznP8tFEkv5IgSaHf5dS1YwVMbX/4W6m937mj+wQw==", + "version": "4.21.9", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", + "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", "dev": true, "funding": [ { @@ -2108,8 +2108,8 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001502", - "electron-to-chromium": "^1.4.428", + "caniuse-lite": "^1.0.30001503", + "electron-to-chromium": "^1.4.431", "node-releases": "^2.0.12", "update-browserslist-db": "^1.0.11" }, @@ -2259,9 +2259,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001503", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001503.tgz", - "integrity": "sha512-Sf9NiF+wZxPfzv8Z3iS0rXM1Do+iOy2Lxvib38glFX+08TCYYYGR5fRJXk4d77C4AYwhUjgYgMsMudbh2TqCKw==", + "version": "1.0.30001508", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001508.tgz", + "integrity": "sha512-sdQZOJdmt3GJs1UMNpCCCyeuS2IEGLXnHyAo9yIO5JJDjbjoVRij4M1qep6P6gFpptD1PqIYgzM+gwJbOi92mw==", "dev": true, "funding": [ { @@ -2772,9 +2772,9 @@ } }, "node_modules/dotenv": { - "version": "16.1.4", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.1.4.tgz", - "integrity": "sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw==", + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", "engines": { "node": ">=12" }, @@ -2789,9 +2789,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.430", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.430.tgz", - "integrity": "sha512-FytjTbGwz///F+ToZ5XSeXbbSaXalsVRXsz2mHityI5gfxft7ieW3HqFLkU5V1aIrY42aflICqbmFoDxW10etg==", + "version": "1.4.440", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.440.tgz", + "integrity": "sha512-r6dCgNpRhPwiWlxbHzZQ/d9swfPaEJGi8ekqRBwQYaR3WmA5VkqQfBWSDDjuJU1ntO+W9tHx8OHV/96Q8e0dVw==", "dev": true }, "node_modules/emittery": { @@ -2961,15 +2961,15 @@ } }, "node_modules/eslint": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.42.0.tgz", - "integrity": "sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz", + "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.42.0", + "@eslint/js": "8.43.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -6462,9 +6462,9 @@ } }, "node_modules/pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "dev": true, "engines": { "node": ">= 6" @@ -6942,9 +6942,9 @@ "optional": true }, "node_modules/semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -7665,9 +7665,9 @@ } }, "node_modules/typeorm": { - "version": "0.3.16", - "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.16.tgz", - "integrity": "sha512-wJ4Qy1oqRKNDdZiBTTaVMqwo/XxC52Q7uNPTjltPgLhvIW173bL6Iad0lhptMOsFlpixFPaUu3PNziaRBwX2Zw==", + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.17.tgz", + "integrity": "sha512-UDjUEwIQalO9tWw9O2A4GU+sT3oyoUXheHJy4ft+RFdnRdQctdQ34L9SqE2p7LdwzafHx1maxT+bqXON+Qnmig==", "dependencies": { "@sqltools/formatter": "^1.2.5", "app-root-path": "^3.1.0", @@ -8749,9 +8749,9 @@ } }, "@eslint/js": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.42.0.tgz", - "integrity": "sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz", + "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==", "dev": true }, "@gar/promisify": { @@ -9217,9 +9217,9 @@ } }, "@sinonjs/fake-timers": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.1.0.tgz", - "integrity": "sha512-w1qd368vtrwttm1PRJWPW1QHlbmHrVDGs1eBH/jZvRPUFS4MNXV9Q33EQdjOdeAxZ7O8+3wM7zxztm2nfUSyKw==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, "requires": { "@sinonjs/commons": "^3.0.0" @@ -9379,15 +9379,15 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.11.tgz", - "integrity": "sha512-XxuOfTkCUiOSyBWIvHlUraLw/JT/6Io1365RO6ZuI88STKMavJZPNMU0lFcUTeQXEhHiv64CbxYxBNoDVSmghg==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.0.tgz", + "integrity": "sha512-78B+anHLF1TI8Jn/cD0Q00TBYdMgjdOn980JfAVa9yw5sop8nyTfVOQAv6LWywkOGLclDBtv5z3oxN4w7jxyNg==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.11", - "@typescript-eslint/type-utils": "5.59.11", - "@typescript-eslint/utils": "5.59.11", + "@typescript-eslint/scope-manager": "5.60.0", + "@typescript-eslint/type-utils": "5.60.0", + "@typescript-eslint/utils": "5.60.0", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -9397,53 +9397,53 @@ } }, "@typescript-eslint/parser": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.11.tgz", - "integrity": "sha512-s9ZF3M+Nym6CAZEkJJeO2TFHHDsKAM3ecNkLuH4i4s8/RCPnF5JRip2GyviYkeEAcwGMJxkqG9h2dAsnA1nZpA==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.60.0.tgz", + "integrity": "sha512-jBONcBsDJ9UoTWrARkRRCgDz6wUggmH5RpQVlt7BimSwaTkTjwypGzKORXbR4/2Hqjk9hgwlon2rVQAjWNpkyQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.59.11", - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/typescript-estree": "5.59.11", + "@typescript-eslint/scope-manager": "5.60.0", + "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/typescript-estree": "5.60.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.11.tgz", - "integrity": "sha512-dHFOsxoLFtrIcSj5h0QoBT/89hxQONwmn3FOQ0GOQcLOOXm+MIrS8zEAhs4tWl5MraxCY3ZJpaXQQdFMc2Tu+Q==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.0.tgz", + "integrity": "sha512-hakuzcxPwXi2ihf9WQu1BbRj1e/Pd8ZZwVTG9kfbxAMZstKz8/9OoexIwnmLzShtsdap5U/CoQGRCWlSuPbYxQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/visitor-keys": "5.59.11" + "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/visitor-keys": "5.60.0" } }, "@typescript-eslint/type-utils": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.11.tgz", - "integrity": "sha512-LZqVY8hMiVRF2a7/swmkStMYSoXMFlzL6sXV6U/2gL5cwnLWQgLEG8tjWPpaE4rMIdZ6VKWwcffPlo1jPfk43g==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.60.0.tgz", + "integrity": "sha512-X7NsRQddORMYRFH7FWo6sA9Y/zbJ8s1x1RIAtnlj6YprbToTiQnM6vxcMu7iYhdunmoC0rUWlca13D5DVHkK2g==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.59.11", - "@typescript-eslint/utils": "5.59.11", + "@typescript-eslint/typescript-estree": "5.60.0", + "@typescript-eslint/utils": "5.60.0", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.11.tgz", - "integrity": "sha512-epoN6R6tkvBYSc+cllrz+c2sOFWkbisJZWkOE+y3xHtvYaOE6Wk6B8e114McRJwFRjGvYdJwLXQH5c9osME/AA==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.0.tgz", + "integrity": "sha512-ascOuoCpNZBccFVNJRSC6rPq4EmJ2NkuoKnd6LDNyAQmdDnziAtxbCGWCbefG1CNzmDvd05zO36AmB7H8RzKPA==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.11.tgz", - "integrity": "sha512-YupOpot5hJO0maupJXixi6l5ETdrITxeo5eBOeuV7RSKgYdU3G5cxO49/9WRnJq9EMrB7AuTSLH/bqOsXi7wPA==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.0.tgz", + "integrity": "sha512-R43thAuwarC99SnvrBmh26tc7F6sPa2B3evkXp/8q954kYL6Ro56AwASYWtEEi+4j09GbiNAHqYwNNZuNlARGQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/visitor-keys": "5.59.11", + "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/visitor-keys": "5.60.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -9452,28 +9452,28 @@ } }, "@typescript-eslint/utils": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.11.tgz", - "integrity": "sha512-didu2rHSOMUdJThLk4aZ1Or8IcO3HzCw/ZvEjTTIfjIrcdd5cvSIwwDy2AOlE7htSNp7QIZ10fLMyRCveesMLg==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.60.0.tgz", + "integrity": "sha512-ba51uMqDtfLQ5+xHtwlO84vkdjrqNzOnqrnwbMHMRY8Tqeme8C2Q8Fc7LajfGR+e3/4LoYiWXUM6BpIIbHJ4hQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.11", - "@typescript-eslint/types": "5.59.11", - "@typescript-eslint/typescript-estree": "5.59.11", + "@typescript-eslint/scope-manager": "5.60.0", + "@typescript-eslint/types": "5.60.0", + "@typescript-eslint/typescript-estree": "5.60.0", "eslint-scope": "^5.1.1", "semver": "^7.3.7" } }, "@typescript-eslint/visitor-keys": { - "version": "5.59.11", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.11.tgz", - "integrity": "sha512-KGYniTGG3AMTuKF9QBD7EIrvufkB6O6uX3knP73xbKLMpH+QRPcgnCxjWXSHjMRuOxFLovljqQgQpR0c7GvjoA==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.0.tgz", + "integrity": "sha512-wm9Uz71SbCyhUKgcaPRauBdTegUyY/ZWl8gLwD/i/ybJqscrrdVSFImpvUz16BLPChIeKBK5Fa9s6KDQjsjyWw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.11", + "@typescript-eslint/types": "5.60.0", "eslint-visitor-keys": "^3.3.0" } }, @@ -9483,9 +9483,9 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz", + "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==", "dev": true }, "acorn-jsx": { @@ -9793,13 +9793,13 @@ } }, "browserslist": { - "version": "4.21.8", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.8.tgz", - "integrity": "sha512-j+7xYe+v+q2Id9qbBeCI8WX5NmZSRe8es1+0xntD/+gaWXznP8tFEkv5IgSaHf5dS1YwVMbX/4W6m937mj+wQw==", + "version": "4.21.9", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", + "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001502", - "electron-to-chromium": "^1.4.428", + "caniuse-lite": "^1.0.30001503", + "electron-to-chromium": "^1.4.431", "node-releases": "^2.0.12", "update-browserslist-db": "^1.0.11" } @@ -9913,9 +9913,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001503", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001503.tgz", - "integrity": "sha512-Sf9NiF+wZxPfzv8Z3iS0rXM1Do+iOy2Lxvib38glFX+08TCYYYGR5fRJXk4d77C4AYwhUjgYgMsMudbh2TqCKw==", + "version": "1.0.30001508", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001508.tgz", + "integrity": "sha512-sdQZOJdmt3GJs1UMNpCCCyeuS2IEGLXnHyAo9yIO5JJDjbjoVRij4M1qep6P6gFpptD1PqIYgzM+gwJbOi92mw==", "dev": true }, "chalk": { @@ -10293,9 +10293,9 @@ } }, "dotenv": { - "version": "16.1.4", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.1.4.tgz", - "integrity": "sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw==" + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==" }, "eastasianwidth": { "version": "0.2.0", @@ -10304,9 +10304,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.4.430", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.430.tgz", - "integrity": "sha512-FytjTbGwz///F+ToZ5XSeXbbSaXalsVRXsz2mHityI5gfxft7ieW3HqFLkU5V1aIrY42aflICqbmFoDxW10etg==", + "version": "1.4.440", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.440.tgz", + "integrity": "sha512-r6dCgNpRhPwiWlxbHzZQ/d9swfPaEJGi8ekqRBwQYaR3WmA5VkqQfBWSDDjuJU1ntO+W9tHx8OHV/96Q8e0dVw==", "dev": true }, "emittery": { @@ -10443,15 +10443,15 @@ "dev": true }, "eslint": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.42.0.tgz", - "integrity": "sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz", + "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.42.0", + "@eslint/js": "8.43.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -13009,9 +13009,9 @@ "dev": true }, "pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "dev": true }, "pkg-dir": { @@ -13331,9 +13331,9 @@ "optional": true }, "semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "requires": { "lru-cache": "^6.0.0" }, @@ -13865,9 +13865,9 @@ } }, "typeorm": { - "version": "0.3.16", - "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.16.tgz", - "integrity": "sha512-wJ4Qy1oqRKNDdZiBTTaVMqwo/XxC52Q7uNPTjltPgLhvIW173bL6Iad0lhptMOsFlpixFPaUu3PNziaRBwX2Zw==", + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.17.tgz", + "integrity": "sha512-UDjUEwIQalO9tWw9O2A4GU+sT3oyoUXheHJy4ft+RFdnRdQctdQ34L9SqE2p7LdwzafHx1maxT+bqXON+Qnmig==", "requires": { "@sqltools/formatter": "^1.2.5", "app-root-path": "^3.1.0", diff --git a/package.json b/package.json index 4815f8d..de6177c 100644 --- a/package.json +++ b/package.json @@ -31,9 +31,9 @@ "@jest/globals": "^29.5.0", "@types/n-readlines": "^1.0.3", "@types/node": "^20.3.1", - "@typescript-eslint/eslint-plugin": "^5.59.11", - "@typescript-eslint/parser": "^5.59.11", - "eslint": "^8.42.0", + "@typescript-eslint/eslint-plugin": "^5.60.0", + "@typescript-eslint/parser": "^5.60.0", + "eslint": "^8.43.0", "eslint-config-prettier": "^8.8.0", "eslint-config-standard-with-typescript": "^34.0.1", "eslint-plugin-import": "^2.27.5", @@ -48,11 +48,11 @@ }, "dependencies": { "axios": "^1.4.0", - "dotenv": "^16.1.4", + "dotenv": "^16.3.1", "n-readlines": "^1.0.1", "reflect-metadata": "^0.1.13", "sqlite3": "^5.1.6", - "typeorm": "^0.3.16", + "typeorm": "^0.3.17", "winston": "^3.9.0" } }