Merge branch 'fix-minor-things'

This commit is contained in:
Henrik Hüttemann 2023-06-26 14:36:02 +02:00
commit d251cf658f
No known key found for this signature in database
GPG Key ID: 9F7BD10E0A8A111E
11 changed files with 454 additions and 292 deletions

View File

@ -1,2 +1,2 @@
REGISTRATION_SHARED_SECRET='look in your synapses homeserver.yaml' 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

314
package-lock.json generated
View File

@ -10,20 +10,20 @@
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"dependencies": { "dependencies": {
"axios": "^1.4.0", "axios": "^1.4.0",
"dotenv": "^16.1.4", "dotenv": "^16.3.1",
"n-readlines": "^1.0.1", "n-readlines": "^1.0.1",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
"sqlite3": "^5.1.6", "sqlite3": "^5.1.6",
"typeorm": "^0.3.16", "typeorm": "^0.3.17",
"winston": "^3.9.0" "winston": "^3.9.0"
}, },
"devDependencies": { "devDependencies": {
"@jest/globals": "^29.5.0", "@jest/globals": "^29.5.0",
"@types/n-readlines": "^1.0.3", "@types/n-readlines": "^1.0.3",
"@types/node": "^20.3.1", "@types/node": "^20.3.1",
"@typescript-eslint/eslint-plugin": "^5.59.11", "@typescript-eslint/eslint-plugin": "^5.60.0",
"@typescript-eslint/parser": "^5.59.11", "@typescript-eslint/parser": "^5.60.0",
"eslint": "^8.42.0", "eslint": "^8.43.0",
"eslint-config-prettier": "^8.8.0", "eslint-config-prettier": "^8.8.0",
"eslint-config-standard-with-typescript": "^34.0.1", "eslint-config-standard-with-typescript": "^34.0.1",
"eslint-plugin-import": "^2.27.5", "eslint-plugin-import": "^2.27.5",
@ -714,9 +714,9 @@
} }
}, },
"node_modules/@eslint/js": { "node_modules/@eslint/js": {
"version": "8.42.0", "version": "8.43.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.42.0.tgz", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz",
"integrity": "sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==", "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -1301,9 +1301,9 @@
} }
}, },
"node_modules/@sinonjs/fake-timers": { "node_modules/@sinonjs/fake-timers": {
"version": "10.1.0", "version": "10.3.0",
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.1.0.tgz", "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz",
"integrity": "sha512-w1qd368vtrwttm1PRJWPW1QHlbmHrVDGs1eBH/jZvRPUFS4MNXV9Q33EQdjOdeAxZ7O8+3wM7zxztm2nfUSyKw==", "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@sinonjs/commons": "^3.0.0" "@sinonjs/commons": "^3.0.0"
@ -1466,15 +1466,15 @@
"dev": true "dev": true
}, },
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.59.11", "version": "5.60.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.11.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.0.tgz",
"integrity": "sha512-XxuOfTkCUiOSyBWIvHlUraLw/JT/6Io1365RO6ZuI88STKMavJZPNMU0lFcUTeQXEhHiv64CbxYxBNoDVSmghg==", "integrity": "sha512-78B+anHLF1TI8Jn/cD0Q00TBYdMgjdOn980JfAVa9yw5sop8nyTfVOQAv6LWywkOGLclDBtv5z3oxN4w7jxyNg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@eslint-community/regexpp": "^4.4.0", "@eslint-community/regexpp": "^4.4.0",
"@typescript-eslint/scope-manager": "5.59.11", "@typescript-eslint/scope-manager": "5.60.0",
"@typescript-eslint/type-utils": "5.59.11", "@typescript-eslint/type-utils": "5.60.0",
"@typescript-eslint/utils": "5.59.11", "@typescript-eslint/utils": "5.60.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"grapheme-splitter": "^1.0.4", "grapheme-splitter": "^1.0.4",
"ignore": "^5.2.0", "ignore": "^5.2.0",
@ -1500,14 +1500,14 @@
} }
}, },
"node_modules/@typescript-eslint/parser": { "node_modules/@typescript-eslint/parser": {
"version": "5.59.11", "version": "5.60.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.11.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.60.0.tgz",
"integrity": "sha512-s9ZF3M+Nym6CAZEkJJeO2TFHHDsKAM3ecNkLuH4i4s8/RCPnF5JRip2GyviYkeEAcwGMJxkqG9h2dAsnA1nZpA==", "integrity": "sha512-jBONcBsDJ9UoTWrARkRRCgDz6wUggmH5RpQVlt7BimSwaTkTjwypGzKORXbR4/2Hqjk9hgwlon2rVQAjWNpkyQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "5.59.11", "@typescript-eslint/scope-manager": "5.60.0",
"@typescript-eslint/types": "5.59.11", "@typescript-eslint/types": "5.60.0",
"@typescript-eslint/typescript-estree": "5.59.11", "@typescript-eslint/typescript-estree": "5.60.0",
"debug": "^4.3.4" "debug": "^4.3.4"
}, },
"engines": { "engines": {
@ -1527,13 +1527,13 @@
} }
}, },
"node_modules/@typescript-eslint/scope-manager": { "node_modules/@typescript-eslint/scope-manager": {
"version": "5.59.11", "version": "5.60.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.11.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.0.tgz",
"integrity": "sha512-dHFOsxoLFtrIcSj5h0QoBT/89hxQONwmn3FOQ0GOQcLOOXm+MIrS8zEAhs4tWl5MraxCY3ZJpaXQQdFMc2Tu+Q==", "integrity": "sha512-hakuzcxPwXi2ihf9WQu1BbRj1e/Pd8ZZwVTG9kfbxAMZstKz8/9OoexIwnmLzShtsdap5U/CoQGRCWlSuPbYxQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.59.11", "@typescript-eslint/types": "5.60.0",
"@typescript-eslint/visitor-keys": "5.59.11" "@typescript-eslint/visitor-keys": "5.60.0"
}, },
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -1544,13 +1544,13 @@
} }
}, },
"node_modules/@typescript-eslint/type-utils": { "node_modules/@typescript-eslint/type-utils": {
"version": "5.59.11", "version": "5.60.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.11.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.60.0.tgz",
"integrity": "sha512-LZqVY8hMiVRF2a7/swmkStMYSoXMFlzL6sXV6U/2gL5cwnLWQgLEG8tjWPpaE4rMIdZ6VKWwcffPlo1jPfk43g==", "integrity": "sha512-X7NsRQddORMYRFH7FWo6sA9Y/zbJ8s1x1RIAtnlj6YprbToTiQnM6vxcMu7iYhdunmoC0rUWlca13D5DVHkK2g==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/typescript-estree": "5.59.11", "@typescript-eslint/typescript-estree": "5.60.0",
"@typescript-eslint/utils": "5.59.11", "@typescript-eslint/utils": "5.60.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"tsutils": "^3.21.0" "tsutils": "^3.21.0"
}, },
@ -1571,9 +1571,9 @@
} }
}, },
"node_modules/@typescript-eslint/types": { "node_modules/@typescript-eslint/types": {
"version": "5.59.11", "version": "5.60.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.11.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.0.tgz",
"integrity": "sha512-epoN6R6tkvBYSc+cllrz+c2sOFWkbisJZWkOE+y3xHtvYaOE6Wk6B8e114McRJwFRjGvYdJwLXQH5c9osME/AA==", "integrity": "sha512-ascOuoCpNZBccFVNJRSC6rPq4EmJ2NkuoKnd6LDNyAQmdDnziAtxbCGWCbefG1CNzmDvd05zO36AmB7H8RzKPA==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -1584,13 +1584,13 @@
} }
}, },
"node_modules/@typescript-eslint/typescript-estree": { "node_modules/@typescript-eslint/typescript-estree": {
"version": "5.59.11", "version": "5.60.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.11.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.0.tgz",
"integrity": "sha512-YupOpot5hJO0maupJXixi6l5ETdrITxeo5eBOeuV7RSKgYdU3G5cxO49/9WRnJq9EMrB7AuTSLH/bqOsXi7wPA==", "integrity": "sha512-R43thAuwarC99SnvrBmh26tc7F6sPa2B3evkXp/8q954kYL6Ro56AwASYWtEEi+4j09GbiNAHqYwNNZuNlARGQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.59.11", "@typescript-eslint/types": "5.60.0",
"@typescript-eslint/visitor-keys": "5.59.11", "@typescript-eslint/visitor-keys": "5.60.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"globby": "^11.1.0", "globby": "^11.1.0",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@ -1611,17 +1611,17 @@
} }
}, },
"node_modules/@typescript-eslint/utils": { "node_modules/@typescript-eslint/utils": {
"version": "5.59.11", "version": "5.60.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.11.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.60.0.tgz",
"integrity": "sha512-didu2rHSOMUdJThLk4aZ1Or8IcO3HzCw/ZvEjTTIfjIrcdd5cvSIwwDy2AOlE7htSNp7QIZ10fLMyRCveesMLg==", "integrity": "sha512-ba51uMqDtfLQ5+xHtwlO84vkdjrqNzOnqrnwbMHMRY8Tqeme8C2Q8Fc7LajfGR+e3/4LoYiWXUM6BpIIbHJ4hQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/eslint-utils": "^4.2.0",
"@types/json-schema": "^7.0.9", "@types/json-schema": "^7.0.9",
"@types/semver": "^7.3.12", "@types/semver": "^7.3.12",
"@typescript-eslint/scope-manager": "5.59.11", "@typescript-eslint/scope-manager": "5.60.0",
"@typescript-eslint/types": "5.59.11", "@typescript-eslint/types": "5.60.0",
"@typescript-eslint/typescript-estree": "5.59.11", "@typescript-eslint/typescript-estree": "5.60.0",
"eslint-scope": "^5.1.1", "eslint-scope": "^5.1.1",
"semver": "^7.3.7" "semver": "^7.3.7"
}, },
@ -1637,12 +1637,12 @@
} }
}, },
"node_modules/@typescript-eslint/visitor-keys": { "node_modules/@typescript-eslint/visitor-keys": {
"version": "5.59.11", "version": "5.60.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.11.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.0.tgz",
"integrity": "sha512-KGYniTGG3AMTuKF9QBD7EIrvufkB6O6uX3knP73xbKLMpH+QRPcgnCxjWXSHjMRuOxFLovljqQgQpR0c7GvjoA==", "integrity": "sha512-wm9Uz71SbCyhUKgcaPRauBdTegUyY/ZWl8gLwD/i/ybJqscrrdVSFImpvUz16BLPChIeKBK5Fa9s6KDQjsjyWw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.59.11", "@typescript-eslint/types": "5.60.0",
"eslint-visitor-keys": "^3.3.0" "eslint-visitor-keys": "^3.3.0"
}, },
"engines": { "engines": {
@ -1659,9 +1659,9 @@
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
}, },
"node_modules/acorn": { "node_modules/acorn": {
"version": "8.8.2", "version": "8.9.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz",
"integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==",
"dev": true, "dev": true,
"bin": { "bin": {
"acorn": "bin/acorn" "acorn": "bin/acorn"
@ -2089,9 +2089,9 @@
} }
}, },
"node_modules/browserslist": { "node_modules/browserslist": {
"version": "4.21.8", "version": "4.21.9",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.8.tgz", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz",
"integrity": "sha512-j+7xYe+v+q2Id9qbBeCI8WX5NmZSRe8es1+0xntD/+gaWXznP8tFEkv5IgSaHf5dS1YwVMbX/4W6m937mj+wQw==", "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@ -2108,8 +2108,8 @@
} }
], ],
"dependencies": { "dependencies": {
"caniuse-lite": "^1.0.30001502", "caniuse-lite": "^1.0.30001503",
"electron-to-chromium": "^1.4.428", "electron-to-chromium": "^1.4.431",
"node-releases": "^2.0.12", "node-releases": "^2.0.12",
"update-browserslist-db": "^1.0.11" "update-browserslist-db": "^1.0.11"
}, },
@ -2259,9 +2259,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001503", "version": "1.0.30001508",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001503.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001508.tgz",
"integrity": "sha512-Sf9NiF+wZxPfzv8Z3iS0rXM1Do+iOy2Lxvib38glFX+08TCYYYGR5fRJXk4d77C4AYwhUjgYgMsMudbh2TqCKw==", "integrity": "sha512-sdQZOJdmt3GJs1UMNpCCCyeuS2IEGLXnHyAo9yIO5JJDjbjoVRij4M1qep6P6gFpptD1PqIYgzM+gwJbOi92mw==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@ -2772,9 +2772,9 @@
} }
}, },
"node_modules/dotenv": { "node_modules/dotenv": {
"version": "16.1.4", "version": "16.3.1",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.1.4.tgz", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz",
"integrity": "sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw==", "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==",
"engines": { "engines": {
"node": ">=12" "node": ">=12"
}, },
@ -2789,9 +2789,9 @@
"dev": true "dev": true
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.4.430", "version": "1.4.440",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.430.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.440.tgz",
"integrity": "sha512-FytjTbGwz///F+ToZ5XSeXbbSaXalsVRXsz2mHityI5gfxft7ieW3HqFLkU5V1aIrY42aflICqbmFoDxW10etg==", "integrity": "sha512-r6dCgNpRhPwiWlxbHzZQ/d9swfPaEJGi8ekqRBwQYaR3WmA5VkqQfBWSDDjuJU1ntO+W9tHx8OHV/96Q8e0dVw==",
"dev": true "dev": true
}, },
"node_modules/emittery": { "node_modules/emittery": {
@ -2961,15 +2961,15 @@
} }
}, },
"node_modules/eslint": { "node_modules/eslint": {
"version": "8.42.0", "version": "8.43.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.42.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz",
"integrity": "sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==", "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.4.0", "@eslint-community/regexpp": "^4.4.0",
"@eslint/eslintrc": "^2.0.3", "@eslint/eslintrc": "^2.0.3",
"@eslint/js": "8.42.0", "@eslint/js": "8.43.0",
"@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/config-array": "^0.11.10",
"@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8", "@nodelib/fs.walk": "^1.2.8",
@ -6462,9 +6462,9 @@
} }
}, },
"node_modules/pirates": { "node_modules/pirates": {
"version": "4.0.5", "version": "4.0.6",
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
"integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": ">= 6" "node": ">= 6"
@ -6942,9 +6942,9 @@
"optional": true "optional": true
}, },
"node_modules/semver": { "node_modules/semver": {
"version": "7.5.1", "version": "7.5.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz",
"integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==",
"dependencies": { "dependencies": {
"lru-cache": "^6.0.0" "lru-cache": "^6.0.0"
}, },
@ -7665,9 +7665,9 @@
} }
}, },
"node_modules/typeorm": { "node_modules/typeorm": {
"version": "0.3.16", "version": "0.3.17",
"resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.16.tgz", "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.17.tgz",
"integrity": "sha512-wJ4Qy1oqRKNDdZiBTTaVMqwo/XxC52Q7uNPTjltPgLhvIW173bL6Iad0lhptMOsFlpixFPaUu3PNziaRBwX2Zw==", "integrity": "sha512-UDjUEwIQalO9tWw9O2A4GU+sT3oyoUXheHJy4ft+RFdnRdQctdQ34L9SqE2p7LdwzafHx1maxT+bqXON+Qnmig==",
"dependencies": { "dependencies": {
"@sqltools/formatter": "^1.2.5", "@sqltools/formatter": "^1.2.5",
"app-root-path": "^3.1.0", "app-root-path": "^3.1.0",
@ -8749,9 +8749,9 @@
} }
}, },
"@eslint/js": { "@eslint/js": {
"version": "8.42.0", "version": "8.43.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.42.0.tgz", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz",
"integrity": "sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==", "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==",
"dev": true "dev": true
}, },
"@gar/promisify": { "@gar/promisify": {
@ -9217,9 +9217,9 @@
} }
}, },
"@sinonjs/fake-timers": { "@sinonjs/fake-timers": {
"version": "10.1.0", "version": "10.3.0",
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.1.0.tgz", "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz",
"integrity": "sha512-w1qd368vtrwttm1PRJWPW1QHlbmHrVDGs1eBH/jZvRPUFS4MNXV9Q33EQdjOdeAxZ7O8+3wM7zxztm2nfUSyKw==", "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@sinonjs/commons": "^3.0.0" "@sinonjs/commons": "^3.0.0"
@ -9379,15 +9379,15 @@
"dev": true "dev": true
}, },
"@typescript-eslint/eslint-plugin": { "@typescript-eslint/eslint-plugin": {
"version": "5.59.11", "version": "5.60.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.11.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.0.tgz",
"integrity": "sha512-XxuOfTkCUiOSyBWIvHlUraLw/JT/6Io1365RO6ZuI88STKMavJZPNMU0lFcUTeQXEhHiv64CbxYxBNoDVSmghg==", "integrity": "sha512-78B+anHLF1TI8Jn/cD0Q00TBYdMgjdOn980JfAVa9yw5sop8nyTfVOQAv6LWywkOGLclDBtv5z3oxN4w7jxyNg==",
"dev": true, "dev": true,
"requires": { "requires": {
"@eslint-community/regexpp": "^4.4.0", "@eslint-community/regexpp": "^4.4.0",
"@typescript-eslint/scope-manager": "5.59.11", "@typescript-eslint/scope-manager": "5.60.0",
"@typescript-eslint/type-utils": "5.59.11", "@typescript-eslint/type-utils": "5.60.0",
"@typescript-eslint/utils": "5.59.11", "@typescript-eslint/utils": "5.60.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"grapheme-splitter": "^1.0.4", "grapheme-splitter": "^1.0.4",
"ignore": "^5.2.0", "ignore": "^5.2.0",
@ -9397,53 +9397,53 @@
} }
}, },
"@typescript-eslint/parser": { "@typescript-eslint/parser": {
"version": "5.59.11", "version": "5.60.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.11.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.60.0.tgz",
"integrity": "sha512-s9ZF3M+Nym6CAZEkJJeO2TFHHDsKAM3ecNkLuH4i4s8/RCPnF5JRip2GyviYkeEAcwGMJxkqG9h2dAsnA1nZpA==", "integrity": "sha512-jBONcBsDJ9UoTWrARkRRCgDz6wUggmH5RpQVlt7BimSwaTkTjwypGzKORXbR4/2Hqjk9hgwlon2rVQAjWNpkyQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/scope-manager": "5.59.11", "@typescript-eslint/scope-manager": "5.60.0",
"@typescript-eslint/types": "5.59.11", "@typescript-eslint/types": "5.60.0",
"@typescript-eslint/typescript-estree": "5.59.11", "@typescript-eslint/typescript-estree": "5.60.0",
"debug": "^4.3.4" "debug": "^4.3.4"
} }
}, },
"@typescript-eslint/scope-manager": { "@typescript-eslint/scope-manager": {
"version": "5.59.11", "version": "5.60.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.11.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.0.tgz",
"integrity": "sha512-dHFOsxoLFtrIcSj5h0QoBT/89hxQONwmn3FOQ0GOQcLOOXm+MIrS8zEAhs4tWl5MraxCY3ZJpaXQQdFMc2Tu+Q==", "integrity": "sha512-hakuzcxPwXi2ihf9WQu1BbRj1e/Pd8ZZwVTG9kfbxAMZstKz8/9OoexIwnmLzShtsdap5U/CoQGRCWlSuPbYxQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "5.59.11", "@typescript-eslint/types": "5.60.0",
"@typescript-eslint/visitor-keys": "5.59.11" "@typescript-eslint/visitor-keys": "5.60.0"
} }
}, },
"@typescript-eslint/type-utils": { "@typescript-eslint/type-utils": {
"version": "5.59.11", "version": "5.60.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.11.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.60.0.tgz",
"integrity": "sha512-LZqVY8hMiVRF2a7/swmkStMYSoXMFlzL6sXV6U/2gL5cwnLWQgLEG8tjWPpaE4rMIdZ6VKWwcffPlo1jPfk43g==", "integrity": "sha512-X7NsRQddORMYRFH7FWo6sA9Y/zbJ8s1x1RIAtnlj6YprbToTiQnM6vxcMu7iYhdunmoC0rUWlca13D5DVHkK2g==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/typescript-estree": "5.59.11", "@typescript-eslint/typescript-estree": "5.60.0",
"@typescript-eslint/utils": "5.59.11", "@typescript-eslint/utils": "5.60.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"tsutils": "^3.21.0" "tsutils": "^3.21.0"
} }
}, },
"@typescript-eslint/types": { "@typescript-eslint/types": {
"version": "5.59.11", "version": "5.60.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.11.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.0.tgz",
"integrity": "sha512-epoN6R6tkvBYSc+cllrz+c2sOFWkbisJZWkOE+y3xHtvYaOE6Wk6B8e114McRJwFRjGvYdJwLXQH5c9osME/AA==", "integrity": "sha512-ascOuoCpNZBccFVNJRSC6rPq4EmJ2NkuoKnd6LDNyAQmdDnziAtxbCGWCbefG1CNzmDvd05zO36AmB7H8RzKPA==",
"dev": true "dev": true
}, },
"@typescript-eslint/typescript-estree": { "@typescript-eslint/typescript-estree": {
"version": "5.59.11", "version": "5.60.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.11.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.0.tgz",
"integrity": "sha512-YupOpot5hJO0maupJXixi6l5ETdrITxeo5eBOeuV7RSKgYdU3G5cxO49/9WRnJq9EMrB7AuTSLH/bqOsXi7wPA==", "integrity": "sha512-R43thAuwarC99SnvrBmh26tc7F6sPa2B3evkXp/8q954kYL6Ro56AwASYWtEEi+4j09GbiNAHqYwNNZuNlARGQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "5.59.11", "@typescript-eslint/types": "5.60.0",
"@typescript-eslint/visitor-keys": "5.59.11", "@typescript-eslint/visitor-keys": "5.60.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"globby": "^11.1.0", "globby": "^11.1.0",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@ -9452,28 +9452,28 @@
} }
}, },
"@typescript-eslint/utils": { "@typescript-eslint/utils": {
"version": "5.59.11", "version": "5.60.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.11.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.60.0.tgz",
"integrity": "sha512-didu2rHSOMUdJThLk4aZ1Or8IcO3HzCw/ZvEjTTIfjIrcdd5cvSIwwDy2AOlE7htSNp7QIZ10fLMyRCveesMLg==", "integrity": "sha512-ba51uMqDtfLQ5+xHtwlO84vkdjrqNzOnqrnwbMHMRY8Tqeme8C2Q8Fc7LajfGR+e3/4LoYiWXUM6BpIIbHJ4hQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/eslint-utils": "^4.2.0",
"@types/json-schema": "^7.0.9", "@types/json-schema": "^7.0.9",
"@types/semver": "^7.3.12", "@types/semver": "^7.3.12",
"@typescript-eslint/scope-manager": "5.59.11", "@typescript-eslint/scope-manager": "5.60.0",
"@typescript-eslint/types": "5.59.11", "@typescript-eslint/types": "5.60.0",
"@typescript-eslint/typescript-estree": "5.59.11", "@typescript-eslint/typescript-estree": "5.60.0",
"eslint-scope": "^5.1.1", "eslint-scope": "^5.1.1",
"semver": "^7.3.7" "semver": "^7.3.7"
} }
}, },
"@typescript-eslint/visitor-keys": { "@typescript-eslint/visitor-keys": {
"version": "5.59.11", "version": "5.60.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.11.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.0.tgz",
"integrity": "sha512-KGYniTGG3AMTuKF9QBD7EIrvufkB6O6uX3knP73xbKLMpH+QRPcgnCxjWXSHjMRuOxFLovljqQgQpR0c7GvjoA==", "integrity": "sha512-wm9Uz71SbCyhUKgcaPRauBdTegUyY/ZWl8gLwD/i/ybJqscrrdVSFImpvUz16BLPChIeKBK5Fa9s6KDQjsjyWw==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "5.59.11", "@typescript-eslint/types": "5.60.0",
"eslint-visitor-keys": "^3.3.0" "eslint-visitor-keys": "^3.3.0"
} }
}, },
@ -9483,9 +9483,9 @@
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
}, },
"acorn": { "acorn": {
"version": "8.8.2", "version": "8.9.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz",
"integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==",
"dev": true "dev": true
}, },
"acorn-jsx": { "acorn-jsx": {
@ -9793,13 +9793,13 @@
} }
}, },
"browserslist": { "browserslist": {
"version": "4.21.8", "version": "4.21.9",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.8.tgz", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz",
"integrity": "sha512-j+7xYe+v+q2Id9qbBeCI8WX5NmZSRe8es1+0xntD/+gaWXznP8tFEkv5IgSaHf5dS1YwVMbX/4W6m937mj+wQw==", "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==",
"dev": true, "dev": true,
"requires": { "requires": {
"caniuse-lite": "^1.0.30001502", "caniuse-lite": "^1.0.30001503",
"electron-to-chromium": "^1.4.428", "electron-to-chromium": "^1.4.431",
"node-releases": "^2.0.12", "node-releases": "^2.0.12",
"update-browserslist-db": "^1.0.11" "update-browserslist-db": "^1.0.11"
} }
@ -9913,9 +9913,9 @@
"dev": true "dev": true
}, },
"caniuse-lite": { "caniuse-lite": {
"version": "1.0.30001503", "version": "1.0.30001508",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001503.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001508.tgz",
"integrity": "sha512-Sf9NiF+wZxPfzv8Z3iS0rXM1Do+iOy2Lxvib38glFX+08TCYYYGR5fRJXk4d77C4AYwhUjgYgMsMudbh2TqCKw==", "integrity": "sha512-sdQZOJdmt3GJs1UMNpCCCyeuS2IEGLXnHyAo9yIO5JJDjbjoVRij4M1qep6P6gFpptD1PqIYgzM+gwJbOi92mw==",
"dev": true "dev": true
}, },
"chalk": { "chalk": {
@ -10293,9 +10293,9 @@
} }
}, },
"dotenv": { "dotenv": {
"version": "16.1.4", "version": "16.3.1",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.1.4.tgz", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz",
"integrity": "sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw==" "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ=="
}, },
"eastasianwidth": { "eastasianwidth": {
"version": "0.2.0", "version": "0.2.0",
@ -10304,9 +10304,9 @@
"dev": true "dev": true
}, },
"electron-to-chromium": { "electron-to-chromium": {
"version": "1.4.430", "version": "1.4.440",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.430.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.440.tgz",
"integrity": "sha512-FytjTbGwz///F+ToZ5XSeXbbSaXalsVRXsz2mHityI5gfxft7ieW3HqFLkU5V1aIrY42aflICqbmFoDxW10etg==", "integrity": "sha512-r6dCgNpRhPwiWlxbHzZQ/d9swfPaEJGi8ekqRBwQYaR3WmA5VkqQfBWSDDjuJU1ntO+W9tHx8OHV/96Q8e0dVw==",
"dev": true "dev": true
}, },
"emittery": { "emittery": {
@ -10443,15 +10443,15 @@
"dev": true "dev": true
}, },
"eslint": { "eslint": {
"version": "8.42.0", "version": "8.43.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.42.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz",
"integrity": "sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==", "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==",
"dev": true, "dev": true,
"requires": { "requires": {
"@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.4.0", "@eslint-community/regexpp": "^4.4.0",
"@eslint/eslintrc": "^2.0.3", "@eslint/eslintrc": "^2.0.3",
"@eslint/js": "8.42.0", "@eslint/js": "8.43.0",
"@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/config-array": "^0.11.10",
"@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8", "@nodelib/fs.walk": "^1.2.8",
@ -13009,9 +13009,9 @@
"dev": true "dev": true
}, },
"pirates": { "pirates": {
"version": "4.0.5", "version": "4.0.6",
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
"integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
"dev": true "dev": true
}, },
"pkg-dir": { "pkg-dir": {
@ -13331,9 +13331,9 @@
"optional": true "optional": true
}, },
"semver": { "semver": {
"version": "7.5.1", "version": "7.5.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz",
"integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==",
"requires": { "requires": {
"lru-cache": "^6.0.0" "lru-cache": "^6.0.0"
}, },
@ -13865,9 +13865,9 @@
} }
}, },
"typeorm": { "typeorm": {
"version": "0.3.16", "version": "0.3.17",
"resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.16.tgz", "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.17.tgz",
"integrity": "sha512-wJ4Qy1oqRKNDdZiBTTaVMqwo/XxC52Q7uNPTjltPgLhvIW173bL6Iad0lhptMOsFlpixFPaUu3PNziaRBwX2Zw==", "integrity": "sha512-UDjUEwIQalO9tWw9O2A4GU+sT3oyoUXheHJy4ft+RFdnRdQctdQ34L9SqE2p7LdwzafHx1maxT+bqXON+Qnmig==",
"requires": { "requires": {
"@sqltools/formatter": "^1.2.5", "@sqltools/formatter": "^1.2.5",
"app-root-path": "^3.1.0", "app-root-path": "^3.1.0",

View File

@ -31,9 +31,9 @@
"@jest/globals": "^29.5.0", "@jest/globals": "^29.5.0",
"@types/n-readlines": "^1.0.3", "@types/n-readlines": "^1.0.3",
"@types/node": "^20.3.1", "@types/node": "^20.3.1",
"@typescript-eslint/eslint-plugin": "^5.59.11", "@typescript-eslint/eslint-plugin": "^5.60.0",
"@typescript-eslint/parser": "^5.59.11", "@typescript-eslint/parser": "^5.60.0",
"eslint": "^8.42.0", "eslint": "^8.43.0",
"eslint-config-prettier": "^8.8.0", "eslint-config-prettier": "^8.8.0",
"eslint-config-standard-with-typescript": "^34.0.1", "eslint-config-standard-with-typescript": "^34.0.1",
"eslint-plugin-import": "^2.27.5", "eslint-plugin-import": "^2.27.5",
@ -48,11 +48,11 @@
}, },
"dependencies": { "dependencies": {
"axios": "^1.4.0", "axios": "^1.4.0",
"dotenv": "^16.1.4", "dotenv": "^16.3.1",
"n-readlines": "^1.0.1", "n-readlines": "^1.0.1",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
"sqlite3": "^5.1.6", "sqlite3": "^5.1.6",
"typeorm": "^0.3.16", "typeorm": "^0.3.17",
"winston": "^3.9.0" "winston": "^3.9.0"
} }
} }

27
src/Entities.ts Normal file
View File

@ -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

View File

@ -2,114 +2,31 @@ 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 } from './handlers/users' import { handle as handleUser } from './handlers/users'
import log from './helpers/logger' import log from './helpers/logger'
import { import { initStorage } from './helpers/storage'
createMembership,
getMapping,
initStorage,
save,
} from './helpers/storage'
import { whoami } from './helpers/synapse' import { whoami } from './helpers/synapse'
import { RcRoom, createRoom } from './handlers/rooms' import { Entity, entities } from './Entities'
log.info('rocketchat2matrix starts.') log.info('rocketchat2matrix starts.')
const enum Entities { async function loadRcExport(entity: Entity) {
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) {
const rl = new lineByLine(`./inputs/${entities[entity].filename}`) const rl = new lineByLine(`./inputs/${entities[entity].filename}`)
let line: false | Buffer let line: false | Buffer
while ((line = rl.next())) { while ((line = rl.next())) {
const item = JSON.parse(line.toString()) const item = JSON.parse(line.toString())
switch (entity) { switch (entity) {
case Entities.Users: case Entity.Users:
const rcUser: RcUser = item await handleUser(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.')
break
}
let mapping = await getMapping(rcUser._id, entities[entity].mappingType)
if (mapping && mapping.matrixId) {
log.debug('Mapping exists:', mapping)
} else {
const matrixUser = await createUser(rcUser)
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)
// 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 break
case Entities.Rooms: case Entity.Rooms:
const rcRoom: RcRoom = item await handleRoom(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)
} else {
const matrixRoom = await createRoom(rcRoom)
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 Entity.Messages:
log.debug(`Message: ${item.name}`) log.debug(`Message: ${item.name}`)
break break
@ -124,9 +41,9 @@ async function main() {
await whoami() await whoami()
await initStorage() await initStorage()
log.info('Parsing users') log.info('Parsing users')
await loadRcExport(Entities.Users) await loadRcExport(Entity.Users)
log.info('Parsing rooms') log.info('Parsing rooms')
await loadRcExport(Entities.Rooms) await loadRcExport(Entity.Rooms)
log.info('Done.') log.info('Done.')
} catch (error) { } catch (error) {
log.error(`Encountered an error while booting up: ${error}`, error) log.error(`Encountered an error while booting up: ${error}`, error)

View File

@ -6,15 +6,18 @@ 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'
import { Entity, entities } from '../Entities'
jest.mock('axios') jest.mock('axios')
const mockedAxios = axios as jest.Mocked<typeof axios> const mockedAxios = axios as jest.Mocked<typeof axios>
@ -110,10 +113,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 +133,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')
@ -168,7 +178,7 @@ test('accepting invitation by joining the room', async () => {
rcId: 'whatever', rcId: 'whatever',
matrixId: 'Neo', matrixId: 'Neo',
accessToken: 'secretAuthToken', accessToken: 'secretAuthToken',
type: 0, type: entities[Entity.Users].mappingType,
}, },
room_id room_id
) )
@ -193,7 +203,7 @@ test('filtering members', async () => {
return { return {
rcId, rcId,
matrixId: `@${rcId}:matrix`, matrixId: `@${rcId}:matrix`,
type: type || 0, type: type || entities[Entity.Users].mappingType,
accessToken: 'accessToken', accessToken: 'accessToken',
} }
} }
@ -206,7 +216,28 @@ test('filtering members', async () => {
mockMapping('existingUser'), mockMapping('existingUser'),
mockMapping('otherExistingUser'), mockMapping('otherExistingUser'),
]) ])
expect(mockedStorage.getMapping).toBeCalledWith('existingUser', 0) expect(mockedStorage.getMapping).toBeCalledWith(
expect(mockedStorage.getMapping).toBeCalledWith('otherExistingUser', 0) 'existingUser',
expect(mockedStorage.getMapping).toBeCalledWith('excludedUser', 0) 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 () => {
await expect(
createMapping(rcPublicRoom._id, { ...mapRoom(rcPublicRoom), room_id })
).resolves.toBe(undefined)
expect(mockedStorage.save).toHaveBeenCalledWith({
rcId: rcPublicRoom._id,
matrixId: room_id,
type: entities[Entity.Rooms].mappingType,
accessToken: undefined,
} as IdMapping)
}) })

View File

@ -1,9 +1,12 @@
import { Entity, entities } from '../Entities'
import { IdMapping } from '../entity/IdMapping' import { IdMapping } from '../entity/IdMapping'
import log from '../helpers/logger' import log from '../helpers/logger'
import { import {
createMembership, createMembership,
getMapping, getMapping,
getMemberships, getMemberships,
getRoomId,
save,
} from '../helpers/storage' } from '../helpers/storage'
import { import {
SessionOptions, SessionOptions,
@ -101,7 +104,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 +187,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 = entities[Entity.Rooms].mappingType
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 +245,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)
}
} }

View File

@ -1,23 +1,32 @@
process.env.REGISTRATION_SHARED_SECRET = 'ThisIsSoSecretWow' process.env.REGISTRATION_SHARED_SECRET = 'ThisIsSoSecretWow'
process.env.EXCLUDED_USERS = 'excludedUser1,excludedUser2'
import { expect, jest, test } from '@jest/globals' import { expect, jest, test } from '@jest/globals'
import axios from 'axios' import axios from 'axios'
import * as storage from '../helpers/storage'
import { import {
MatrixUser, MatrixUser,
RcUser, RcUser,
createMapping,
createUser, createUser,
generateHmac, generateHmac,
mapUser, mapUser,
userIsExcluded,
} from '../handlers/users' } from '../handlers/users'
import { IdMapping } from '../entity/IdMapping'
import { Entity, entities } from '../Entities'
jest.mock('axios') jest.mock('axios')
const mockedAxios = axios as jest.Mocked<typeof axios> const mockedAxios = axios as jest.Mocked<typeof axios>
jest.mock('../helpers/storage')
const mockedStorage = storage as jest.Mocked<typeof storage>
const rcUser: RcUser = { const rcUser: RcUser = {
_id: 'testRc', _id: 'testRc',
name: 'Tester McDelme', name: 'Tester McDelme',
username: 'testuser', username: 'testuser',
roles: ['user'], roles: ['user'],
__rooms: [], __rooms: ['room0', 'room1'],
} }
const matrixUser: MatrixUser = { const matrixUser: MatrixUser = {
@ -29,15 +38,14 @@ const matrixUser: MatrixUser = {
} }
const nonce = 'test-nonce' const nonce = 'test-nonce'
const mac = 'be0537407ab3c82de908c5763185556e98a7211c'
test('mapping users', () => { test('mapping users', () => {
expect(mapUser(rcUser)).toStrictEqual(matrixUser) expect(mapUser(rcUser)).toStrictEqual(matrixUser)
}) })
test('generating correct hmac', () => { test('generating correct hmac', () => {
expect(generateHmac({ ...matrixUser, nonce })).toStrictEqual( expect(generateHmac({ ...matrixUser, nonce })).toStrictEqual(mac)
'be0537407ab3c82de908c5763185556e98a7211c'
)
}) })
test('creating users', async () => { test('creating users', async () => {
@ -57,12 +65,47 @@ test('creating users', async () => {
}) })
expect(mockedAxios.get).toHaveBeenCalledWith('/_synapse/admin/v1/register') expect(mockedAxios.get).toHaveBeenCalledWith('/_synapse/admin/v1/register')
expect(mockedAxios.post).toHaveBeenCalled() expect(mockedAxios.post).toHaveBeenCalledWith('/_synapse/admin/v1/register', {
// The following test fails with an incorrect return value, for whatever reason. ...matrixUser,
// Probably because of mutated call logs in jest due to the `delete` or sth. nonce,
// expect(mockedAxios.post).toHaveBeenCalledWith('/_synapse/admin/v1/register', { mac,
// ...matrixUser, })
// 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)
})
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()
})
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: entities[Entity.Users].mappingType,
accessToken: matrixUser.access_token,
} as IdMapping)
}) })

View File

@ -1,6 +1,9 @@
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, getUserId, save } from '../helpers/storage'
import { IdMapping } from '../entity/IdMapping'
import { Entity, entities } from '../Entities'
export type RcUser = { export type RcUser = {
_id: string _id: string
@ -64,17 +67,72 @@ async function registerUser(user: MatrixUser): Promise<AccessToken> {
return (await axios.post('/_synapse/admin/v1/register', user)).data return (await axios.post('/_synapse/admin/v1/register', user)).data
} }
async function parseUserMemberships(rcUser: RcUser): Promise<void> {
await Promise.all(
rcUser.__rooms.map(async (rcRoomId: string) => {
await createMembership(rcRoomId, rcUser._id)
log.debug(`${rcUser.username} membership for ${rcRoomId} created`)
})
)
}
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 createMapping(
rcId: string,
matrixUser: MatrixUser
): Promise<void> {
const mapping = new IdMapping()
mapping.rcId = rcId
mapping.matrixId = matrixUser.user_id
mapping.type = entities[Entity.Users].mappingType
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)
user.nonce = await getUserRegistrationNonce() const nonce = await getUserRegistrationNonce()
user.mac = generateHmac(user) const mac = generateHmac({ ...user, nonce })
const accessToken = await registerUser(user) const accessToken = await registerUser({ ...user, nonce, mac })
user.user_id = accessToken.user_id user.user_id = accessToken.user_id
user.access_token = accessToken.access_token user.access_token = accessToken.access_token
log.info(`User ${rcUser.username} created:`, user) log.info(`User ${rcUser.username} created:`, user)
delete user.nonce await parseUserMemberships(rcUser)
delete user.mac
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)
}
}

View File

@ -5,16 +5,20 @@ import {
getAccessToken, getAccessToken,
getMapping, getMapping,
getMemberships, getMemberships,
getMessageId,
getRoomId,
getUserId,
initStorage, initStorage,
save, save,
} from './storage' } from './storage'
import { IdMapping } from '../entity/IdMapping' import { IdMapping } from '../entity/IdMapping'
import { Membership } from '../entity/Membership' import { Membership } from '../entity/Membership'
import { Entity, entities } from '../Entities'
const mapping = new IdMapping() const mapping = new IdMapping()
mapping.rcId = 'rcId' mapping.rcId = 'rcId'
mapping.matrixId = 'matrixId' mapping.matrixId = 'matrixId'
mapping.type = 0 mapping.type = entities[Entity.Users].mappingType
mapping.accessToken = 'accessToken' mapping.accessToken = 'accessToken'
const membership = new Membership() const membership = new Membership()
@ -25,7 +29,7 @@ beforeAll(async () => {
await initStorage() await initStorage()
}) })
test('save mapping', async () => { test('create mapping', async () => {
await expect(save(mapping)).resolves.toBe(undefined) await expect(save(mapping)).resolves.toBe(undefined)
}) })
@ -60,3 +64,30 @@ test('get membership', async () => {
await expect(getMemberships('inexistent')).resolves.toStrictEqual([]) 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 = entities[Entity.Rooms].mappingType
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 = entities[Entity.Messages].mappingType
await save(message)
await expect(getMessageId(message.rcId)).resolves.toBe(message.matrixId)
await expect(getMessageId('inexistent')).resolves.toBeFalsy()
})

View File

@ -1,6 +1,7 @@
import { DataSource } from 'typeorm' import { DataSource } from 'typeorm'
import { IdMapping } from '../entity/IdMapping' import { IdMapping } from '../entity/IdMapping'
import { Membership } from '../entity/Membership' import { Membership } from '../entity/Membership'
import { Entity, entities } from '../Entities'
const AppDataSource = new DataSource({ const AppDataSource = new DataSource({
type: 'sqlite', type: 'sqlite',
@ -29,7 +30,7 @@ export async function save(entity: IdMapping | Membership): Promise<void> {
} }
export async function getAccessToken(id: string): Promise<string | undefined> { export async function getAccessToken(id: string): Promise<string | undefined> {
return (await getMapping(id, 0))?.accessToken return (await getMapping(id, entities[Entity.Users].mappingType))?.accessToken
} }
export async function createMembership( export async function createMembership(
@ -55,3 +56,16 @@ export async function getMemberships(rcRoomId: string): Promise<string[]> {
}) })
).map((entity) => entity.rcUserId) ).map((entity) => entity.rcUserId)
} }
export async function getUserId(rcId: string): Promise<string | undefined> {
return (await getMapping(rcId, entities[Entity.Users].mappingType))?.matrixId
}
export async function getRoomId(rcId: string): Promise<string | undefined> {
return (await getMapping(rcId, entities[Entity.Rooms].mappingType))?.matrixId
}
export async function getMessageId(rcId: string): Promise<string | undefined> {
return (await getMapping(rcId, entities[Entity.Messages].mappingType))
?.matrixId
}