diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7eed50a8d8..67977fa1bf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@
### Improvements
- フォロー/フォロワーを非公開にできるように
+- メールアドレスのバリデーションを強化
### Bugfixes
- クライアント: 長いメニューが画面からはみ出す問題を修正
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 26d57039ce..ababad4f03 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -807,6 +807,13 @@ unmuteThread: "スレッドのミュートを解除"
ffVisibility: "つながりの公開範囲"
ffVisibilityDescription: "自分のフォロー/フォロワー情報の公開範囲を設定できます。"
+_emailUnavailable:
+ used: "既に使用されています"
+ format: "形式が正しくありません"
+ disposable: "恒久的に使用可能なアドレスではありません"
+ mx: "正しいメールサーバーではありません"
+ smtp: "メールサーバーが応答しません"
+
_ffVisibility:
public: "公開"
followers: "フォロワーだけに公開"
diff --git a/package.json b/package.json
index d61001e536..be1496a17d 100644
--- a/package.json
+++ b/package.json
@@ -130,6 +130,7 @@
"cssnano": "5.0.8",
"date-fns": "2.25.0",
"dateformat": "4.5.1",
+ "deep-email-validator": "0.1.18",
"escape-regexp": "0.0.1",
"eslint": "8.1.0",
"eslint-plugin-vue": "7.20.0",
diff --git a/src/client/components/signup.vue b/src/client/components/signup.vue
index cb25eadf06..8d4340fd36 100644
--- a/src/client/components/signup.vue
+++ b/src/client/components/signup.vue
@@ -19,12 +19,17 @@
{{ $ts.tooLong }}
-
+
{{ $ts.emailAddress }}
{{ $ts.checking }}
{{ $ts.available }}
+ {{ $ts._emailUnavailable.used }}
+ {{ $ts._emailUnavailable.format }}
+ {{ $ts._emailUnavailable.disposable }}
+ {{ $ts._emailUnavailable.mx }}
+ {{ $ts._emailUnavailable.smtp }}
{{ $ts.unavailable }}
{{ $ts.error }}
@@ -171,7 +176,13 @@ export default defineComponent({
os.api('email-address/available', {
emailAddress: this.email
}).then(result => {
- this.emailState = result.available ? 'ok' : 'unavailable';
+ this.emailState = result.available ? 'ok' :
+ result.reason === 'used' ? 'unavailable:used' :
+ result.reason === 'format' ? 'unavailable:format' :
+ result.reason === 'disposable' ? 'unavailable:disposable' :
+ result.reason === 'mx' ? 'unavailable:mx' :
+ result.reason === 'smtp' ? 'unavailable:smtp' :
+ 'unavailable';
}).catch(err => {
this.emailState = 'error';
});
diff --git a/src/server/api/endpoints/email-address/available.ts b/src/server/api/endpoints/email-address/available.ts
index 65fe6f9178..f6fccd59b0 100644
--- a/src/server/api/endpoints/email-address/available.ts
+++ b/src/server/api/endpoints/email-address/available.ts
@@ -1,6 +1,6 @@
import $ from 'cafy';
import define from '../../define';
-import { UserProfiles } from '@/models/index';
+import { validateEmailForAccount } from '@/services/validate-email-for-account';
export const meta = {
tags: ['users'],
@@ -20,18 +20,15 @@ export const meta = {
available: {
type: 'boolean' as const,
optional: false as const, nullable: false as const,
- }
+ },
+ reason: {
+ type: 'string' as const,
+ optional: false as const, nullable: true as const,
+ },
}
}
};
export default define(meta, async (ps) => {
- const exist = await UserProfiles.count({
- emailVerified: true,
- email: ps.emailAddress,
- });
-
- return {
- available: exist === 0
- };
+ return await validateEmailForAccount(ps.emailAddress);
});
diff --git a/src/server/api/endpoints/i/update-email.ts b/src/server/api/endpoints/i/update-email.ts
index 14aedad88b..9b6fb9c410 100644
--- a/src/server/api/endpoints/i/update-email.ts
+++ b/src/server/api/endpoints/i/update-email.ts
@@ -8,6 +8,7 @@ import * as bcrypt from 'bcryptjs';
import { Users, UserProfiles } from '@/models/index';
import { sendEmail } from '@/services/send-email';
import { ApiError } from '../../error';
+import { validateEmailForAccount } from '@/services/validate-email-for-account';
export const meta = {
requireCredential: true as const,
@@ -35,6 +36,12 @@ export const meta = {
code: 'INCORRECT_PASSWORD',
id: 'e54c1d7e-e7d6-4103-86b6-0a95069b4ad3'
},
+
+ unavailable: {
+ message: 'Unavailable email address.',
+ code: 'UNAVAILABLE',
+ id: 'a2defefb-f220-8849-0af6-17f816099323'
+ },
}
};
@@ -48,6 +55,13 @@ export default define(meta, async (ps, user) => {
throw new ApiError(meta.errors.incorrectPassword);
}
+ if (ps.email != null) {
+ const available = await validateEmailForAccount(ps.email);
+ if (!available) {
+ throw new ApiError(meta.errors.unavailable);
+ }
+ }
+
await UserProfiles.update(user.id, {
email: ps.email,
emailVerified: false,
diff --git a/src/server/api/private/signup.ts b/src/server/api/private/signup.ts
index 93caaea935..2b6a3eb00c 100644
--- a/src/server/api/private/signup.ts
+++ b/src/server/api/private/signup.ts
@@ -8,6 +8,7 @@ import { signup } from '../common/signup';
import config from '@/config';
import { sendEmail } from '@/services/send-email';
import { genId } from '@/misc/gen-id';
+import { validateEmailForAccount } from '@/services/validate-email-for-account';
export default async (ctx: Koa.Context) => {
const body = ctx.request.body;
@@ -41,6 +42,12 @@ export default async (ctx: Koa.Context) => {
ctx.status = 400;
return;
}
+
+ const available = await validateEmailForAccount(emailAddress);
+ if (!available) {
+ ctx.status = 400;
+ return;
+ }
}
if (instance.disableRegistration) {
diff --git a/src/services/validate-email-for-account.ts b/src/services/validate-email-for-account.ts
new file mode 100644
index 0000000000..1d039fb263
--- /dev/null
+++ b/src/services/validate-email-for-account.ts
@@ -0,0 +1,34 @@
+import validateEmail from 'deep-email-validator';
+import { UserProfiles } from '@/models';
+
+export async function validateEmailForAccount(emailAddress: string): Promise<{
+ available: boolean;
+ reason: null | 'used' | 'format' | 'disposable' | 'mx' | 'smtp';
+}> {
+ const exist = await UserProfiles.count({
+ emailVerified: true,
+ email: emailAddress,
+ });
+
+ const validated = await validateEmail({
+ email: emailAddress,
+ validateRegex: true,
+ validateMx: true,
+ validateTypo: false, // TLDを見ているみたいだけどclubとか弾かれるので
+ validateDisposable: true, // 捨てアドかどうかチェック
+ validateSMTP: false, // 日本だと25ポートが殆どのプロバイダーで塞がれていてタイムアウトになるので
+ });
+
+ const available = exist === 0 && validated.valid;
+
+ return {
+ available,
+ reason: available ? null :
+ exist !== 0 ? 'used' :
+ validated.reason === 'regex' ? 'format' :
+ validated.reason === 'disposable' ? 'disposable' :
+ validated.reason === 'mx' ? 'mx' :
+ validated.reason === 'smtp' ? 'smtp' :
+ null,
+ };
+}
diff --git a/yarn.lock b/yarn.lock
index e8037a8c0b..d8409088f3 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -513,6 +513,11 @@
resolved "https://registry.yarnpkg.com/@types/dateformat/-/dateformat-3.0.1.tgz#98d747a2e5e9a56070c6bf14e27bff56204e34cc"
integrity sha512-KlPPdikagvL6ELjWsljbyDIPzNCeliYkqRpI+zea99vBBbCIA5JNshZAwQKTON139c87y9qvTFVgkFd14rtS4g==
+"@types/disposable-email-domains@^1.0.1":
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/@types/disposable-email-domains/-/disposable-email-domains-1.0.2.tgz#0280f6b38fa7f14e54b056a434135ecd254483b1"
+ integrity sha512-SDKwyYTjk3y5aZBxxc38yRecpJPjsqn57STz1bNxYYlv4k11bBe7QB8w4llXDTmQXKT1mFvgGmJv+8Zdu3YmJw==
+
"@types/escape-regexp@0.0.0":
version "0.0.0"
resolved "https://registry.yarnpkg.com/@types/escape-regexp/-/escape-regexp-0.0.0.tgz#bff0225f9ef30d0dbdbe0e2a24283ee5342990c3"
@@ -2081,6 +2086,13 @@ aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e"
integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==
+axios@^0.19.2:
+ version "0.19.2"
+ resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
+ integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==
+ dependencies:
+ follow-redirects "1.5.10"
+
axios@^0.21.1:
version "0.21.1"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
@@ -2310,6 +2322,13 @@ browserslist@^4.16.6:
escalade "^3.1.1"
node-releases "^1.1.71"
+bs-logger@0.x:
+ version "0.2.6"
+ resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8"
+ integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==
+ dependencies:
+ fast-json-stable-stringify "2.x"
+
buffer-alloc-unsafe@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
@@ -2343,6 +2362,11 @@ buffer-fill@^1.0.0:
resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c"
integrity sha1-+PeLdniYiO858gXNY39o5wISKyw=
+buffer-from@1.x:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
+ integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
+
buffer-from@^1.0.0, buffer-from@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
@@ -3631,6 +3655,13 @@ debug@4.3.2, debug@^4.3.2:
dependencies:
ms "2.1.2"
+debug@=3.1.0, debug@~3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
+ integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
+ dependencies:
+ ms "2.0.0"
+
debug@^3.1.0:
version "3.2.7"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
@@ -3645,13 +3676,6 @@ debug@^3.2.6:
dependencies:
ms "^2.1.1"
-debug@~3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
- integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
- dependencies:
- ms "2.0.0"
-
debuglog@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
@@ -3691,6 +3715,18 @@ decompress-response@^6.0.0:
dependencies:
mimic-response "^3.1.0"
+deep-email-validator@0.1.18:
+ version "0.1.18"
+ resolved "https://registry.yarnpkg.com/deep-email-validator/-/deep-email-validator-0.1.18.tgz#a072a93f28e11863cc6b9ca3ae964e0e45b3ece8"
+ integrity sha512-eo2WEUidQvppg6Qdek8iwOqmXvaxRJ2D2VJKbIOwUgLZNFveDDdJMBsFc+yq0S+lILEUcmzrJRrCWbyoe7QUzQ==
+ dependencies:
+ "@types/disposable-email-domains" "^1.0.1"
+ axios "^0.19.2"
+ disposable-email-domains "^1.0.53"
+ lodash "^4.17.15"
+ mailcheck "^1.1.1"
+ ts-jest "^25.2.1"
+
deep-equal@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
@@ -3842,6 +3878,11 @@ dir-glob@^3.0.1:
dependencies:
path-type "^4.0.0"
+disposable-email-domains@^1.0.53:
+ version "1.0.58"
+ resolved "https://registry.yarnpkg.com/disposable-email-domains/-/disposable-email-domains-1.0.58.tgz#ac9c879c02c4f0898bfb6c0c80b959c0b0b7bc51"
+ integrity sha512-frnNCPqTjk6t/sosPoco6EIFHbP9SazHQkeltJNfZeUyNgewaVf+kFjEfVkVDVd436Vln43YElJPb8JozhBs7Q==
+
doctrine@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
@@ -4609,7 +4650,7 @@ fast-glob@^3.1.1:
micromatch "^4.0.2"
picomatch "^2.2.1"
-fast-json-stable-stringify@^2.0.0:
+fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
@@ -4824,6 +4865,13 @@ flush-write-stream@^1.0.2:
inherits "^2.0.3"
readable-stream "^2.3.6"
+follow-redirects@1.5.10:
+ version "1.5.10"
+ resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
+ integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
+ dependencies:
+ debug "=3.1.0"
+
follow-redirects@^1.10.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43"
@@ -6386,7 +6434,7 @@ json5-loader@4.0.1:
loader-utils "^2.0.0"
schema-utils "^3.0.0"
-json5@2.2.0:
+json5@2.2.0, json5@2.x:
version "2.2.0"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3"
integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==
@@ -6912,7 +6960,7 @@ lodash.map@^4.4.0:
resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3"
integrity sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=
-lodash.memoize@^4.1.2:
+lodash.memoize@4.x, lodash.memoize@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
@@ -6957,7 +7005,7 @@ lodash.uniq@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
-lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.7.0:
+lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.7.0:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -7014,7 +7062,12 @@ magic-string@^0.25.7:
dependencies:
sourcemap-codec "^1.4.4"
-make-error@^1.1.1:
+mailcheck@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/mailcheck/-/mailcheck-1.1.1.tgz#d87cf6ba0b64ba512199dbf93f1489f479591e34"
+ integrity sha1-2Hz2ugtkulEhmdv5PxSJ9HlZHjQ=
+
+make-error@1.x, make-error@^1.1.1:
version "1.3.6"
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
@@ -7152,6 +7205,14 @@ mfm-js@0.20.0:
dependencies:
twemoji-parser "13.1.x"
+micromatch@4.x:
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
+ integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
+ dependencies:
+ braces "^3.0.1"
+ picomatch "^2.2.3"
+
micromatch@^3.0.4, micromatch@^3.1.4:
version "3.1.10"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
@@ -7321,7 +7382,7 @@ mkdirp-classic@^0.5.3:
resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
-mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@~0.5.1:
+mkdirp@0.x, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@~0.5.1:
version "0.5.5"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
@@ -8234,6 +8295,11 @@ picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.0.7, picomatch@^2.2.1:
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==
+picomatch@^2.2.3:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
+ integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
+
pify@^2.0.0, pify@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
@@ -9825,7 +9891,7 @@ semver-greatest-satisfied-range@^1.1.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
-semver@^6.3.0:
+semver@6.x, semver@^6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
@@ -10904,6 +10970,22 @@ tree-kill@^1.2.2:
resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==
+ts-jest@^25.2.1:
+ version "25.5.1"
+ resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-25.5.1.tgz#2913afd08f28385d54f2f4e828be4d261f4337c7"
+ integrity sha512-kHEUlZMK8fn8vkxDjwbHlxXRB9dHYpyzqKIGDNxbzs+Rz+ssNDSDNusEK8Fk/sDd4xE6iKoQLfFkFVaskmTJyw==
+ dependencies:
+ bs-logger "0.x"
+ buffer-from "1.x"
+ fast-json-stable-stringify "2.x"
+ json5 "2.x"
+ lodash.memoize "4.x"
+ make-error "1.x"
+ micromatch "4.x"
+ mkdirp "0.x"
+ semver "6.x"
+ yargs-parser "18.x"
+
ts-loader@9.2.6:
version "9.2.6"
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.6.tgz#9937c4dd0a1e3dbbb5e433f8102a6601c6615d74"
@@ -11934,6 +12016,14 @@ yargonaut@^1.1.4:
figlet "^1.1.1"
parent-require "^1.0.0"
+yargs-parser@18.x:
+ version "18.1.3"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0"
+ integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==
+ dependencies:
+ camelcase "^5.0.0"
+ decamelize "^1.2.0"
+
yargs-parser@20.2.4, yargs-parser@^20.2.2:
version "20.2.4"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54"