diff --git a/app-config/package.json b/app-config/package.json index 553eaba65bc..63325449c35 100644 --- a/app-config/package.json +++ b/app-config/package.json @@ -1,7 +1,7 @@ { "dependencies": { - "wire-web-config-default-ey": "https://github.com/wireapp/wire-web-config-ey.git#v0.24.82-0", - "wire-web-config-default-master": "https://github.com/wireapp/wire-web-config-wire#v0.24.82-0", - "wire-web-config-default-staging": "https://github.com/wireapp/wire-web-config-default#v0.24.81" + "wire-web-config-default-ey": "https://github.com/wireapp/wire-web-config-ey.git#v0.24.83-0", + "wire-web-config-default-master": "https://github.com/wireapp/wire-web-config-wire#v0.24.83-0", + "wire-web-config-default-staging": "https://github.com/wireapp/wire-web-config-default#v0.24.82" } } diff --git a/package.json b/package.json index f576319d7f4..e623a12c6d7 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "raygun4js": "2.20.0", "react": "16.13.1", "react-dom": "16.13.1", - "react-intl": "4.6.9", + "react-intl": "4.7.5", "react-intl-po": "2.2.2", "react-redux": "7.2.0", "react-router": "5.2.0", @@ -36,7 +36,7 @@ "redux-logdown": "1.0.4", "redux-thunk": "2.3.0", "sdp-transform": "2.14.0", - "simplebar": "5.2.0", + "simplebar": "5.2.1", "speakingurl": "14.0.1", "switch-path": "1.2.0", "tsyringe": "4.3.0", @@ -65,7 +65,7 @@ "@types/faker": "4.1.12", "@types/generate-changelog": "1.8.0", "@types/highlight.js": "9.12.4", - "@types/jasmine": "3.5.10", + "@types/jasmine": "3.5.11", "@types/js-cookie": "2.2.6", "@types/keyboardjs": "2.5.0", "@types/libsodium-wrappers-sumo": "0.7.3", @@ -74,10 +74,10 @@ "@types/open-graph": "0.2.0", "@types/platform": "1.3.2", "@types/raygun4js": "2.13.3", - "@types/react": "16.9.38", + "@types/react": "16.9.41", "@types/react-dom": "16.9.8", "@types/react-redux": "7.1.9", - "@types/react-router": "5.1.7", + "@types/react-router": "5.1.8", "@types/react-router-dom": "5.1.5", "@types/redux-mock-store": "1.0.2", "@types/sdp-transform": "2.4.3", @@ -86,16 +86,16 @@ "@types/uint32": "0.2.0", "@types/underscore": "1.10.1", "@types/webpack-env": "1.15.2", - "@typescript-eslint/eslint-plugin": "3.3.0", - "@typescript-eslint/parser": "3.3.0", + "@typescript-eslint/eslint-plugin": "3.4.0", + "@typescript-eslint/parser": "3.4.0", "@wireapp/copy-config": "1.0.12", "@wireapp/eslint-config": "1.7.1", "@wireapp/prettier-config": "0.3.0", - "adm-zip": "0.4.14", - "autoprefixer": "9.8.1", + "adm-zip": "0.4.16", + "autoprefixer": "9.8.4", "babel-eslint": "10.1.0", "babel-loader": "8.1.0", - "babel-plugin-react-intl": "7.5.21", + "babel-plugin-react-intl": "7.5.24", "concurrently": "5.2.0", "cross-env": "7.0.2", "cspell": "4.0.63", @@ -104,11 +104,11 @@ "enzyme": "3.11.0", "enzyme-adapter-react-16": "1.15.2", "enzyme-to-json": "3.5.0", - "eslint": "7.3.0", + "eslint": "7.3.1", "eslint-config-prettier": "6.11.0", "eslint-plugin-babel": "5.3.0", - "eslint-plugin-import": "2.21.2", - "eslint-plugin-jsdoc": "28.0.0", + "eslint-plugin-import": "2.22.0", + "eslint-plugin-jsdoc": "28.5.1", "eslint-plugin-no-unsanitized": "3.1.2", "eslint-plugin-prettier": "3.1.4", "eslint-plugin-react": "7.20.0", @@ -155,7 +155,7 @@ "redux-devtools-extension": "2.13.8", "redux-logger": "3.0.6", "redux-mock-store": "1.5.4", - "simple-git": "2.9.0", + "simple-git": "2.11.0", "sinon": "9.0.2", "snabbdom": "0.7.4", "sort-json": "2.0.0", diff --git a/server/package.json b/server/package.json index 9d4af592fc1..9376acb62a6 100644 --- a/server/package.json +++ b/server/package.json @@ -13,7 +13,7 @@ "fs-extra": "9.0.1", "geolite2": "1.3.0", "hbs": "4.1.1", - "helmet": "3.23.1", + "helmet": "3.23.3", "logdown": "3.3.1", "maxmind": "4.1.3", "opn": "6.0.0", @@ -26,7 +26,7 @@ "@types/fs-extra": "8.1.1", "@types/hbs": "4.0.1", "@types/helmet": "0.0.47", - "@types/jasmine": "3.5.10", + "@types/jasmine": "3.5.11", "@types/node": "~10", "jasmine": "3.5.0", "nyc": "15.1.0", diff --git a/server/yarn.lock b/server/yarn.lock index 8e3c1c6c984..f972ac450fc 100644 --- a/server/yarn.lock +++ b/server/yarn.lock @@ -313,10 +313,10 @@ dependencies: "@types/express" "*" -"@types/jasmine@3.5.10": - version "3.5.10" - resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-3.5.10.tgz#a1a41012012b5da9d4b205ba9eba58f6cce2ab7b" - integrity sha512-3F8qpwBAiVc5+HPJeXJpbrl+XjawGmciN5LgiO7Gv1pl1RHtjoMNqZpqEksaPJW05ViKe8snYInRs6xB25Xdew== +"@types/jasmine@3.5.11": + version "3.5.11" + resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-3.5.11.tgz#ba8e80639dffbe277f49c708b45373a320d158e2" + integrity sha512-fg1rOd/DehQTIJTifGqGVY6q92lDgnLfs7C6t1ccSwQrMyoTGSoH6wWzhJDZb6ezhsdwAX4EIBLe8w5fXWmEng== "@types/mime@*": version "2.0.1" @@ -941,11 +941,6 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.1.tgz#0c667cb467ebbb5cea7f14f135cc2dba7780a8ff" integrity sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q== -dns-prefetch-control@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/dns-prefetch-control/-/dns-prefetch-control-0.2.0.tgz#73988161841f3dcc81f47686d539a2c702c88624" - integrity sha512-hvSnros73+qyZXhHFjx2CMLwoj3Fe7eR9EJsFsqmcI1bB2OBWL/+0YzaEaKssCHnj/6crawNnUyw74Gm2EKe+Q== - dont-sniff-mimetype@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/dont-sniff-mimetype/-/dont-sniff-mimetype-1.1.0.tgz#c7d0427f8bcb095762751252af59d148b0a623b2" @@ -1110,11 +1105,6 @@ eventemitter2@~0.4.14: resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-0.4.14.tgz#8f61b75cde012b2e9eb284d4545583b5643b61ab" integrity sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas= -expect-ct@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/expect-ct/-/expect-ct-0.2.0.tgz#3a54741b6ed34cc7a93305c605f63cd268a54a62" - integrity sha512-6SK3MG/Bbhm8MsgyJAylg+ucIOU71/FzyFalcfu5nY19dH8y/z0tBJU0wrNBXD4B27EoQtqPF/9wqH0iYAd04g== - express-sitemap-xml@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/express-sitemap-xml/-/express-sitemap-xml-1.1.0.tgz#f440f16f39ca2bc7a09fd526774801fc78d48753" @@ -1265,11 +1255,6 @@ forwarded@~0.1.2: resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= -frameguard@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/frameguard/-/frameguard-3.1.0.tgz#bd1442cca1d67dc346a6751559b6d04502103a22" - integrity sha512-TxgSKM+7LTA6sidjOiSZK9wxY0ffMPY3Wta//MqwmX0nZuEHc8QrkV8Fh3ZhMJeiH+Uyh/tcaarImRy8u77O7g== - fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" @@ -1478,17 +1463,14 @@ helmet-csp@2.10.0: content-security-policy-builder "2.1.0" dasherize "2.0.0" -helmet@3.23.1: - version "3.23.1" - resolved "https://registry.yarnpkg.com/helmet/-/helmet-3.23.1.tgz#97067661c678d6c8d730dda001406f1946a6c6d1" - integrity sha512-e034HHfRK4065BFjYbffn5jXaTWWrhTNgmLIppsGEOjpdDB1MBQkWlAFW/auULXAu6uKk2X76n7a7gvz5sSjkg== +helmet@3.23.3: + version "3.23.3" + resolved "https://registry.yarnpkg.com/helmet/-/helmet-3.23.3.tgz#5ba30209c5f73ded4ab65746a3a11bedd4579ab7" + integrity sha512-U3MeYdzPJQhtvqAVBPntVgAvNSOJyagwZwyKsFdyRa8TV3pOKVFljalPOCxbw5Wwf2kncGhmP0qHjyazIdNdSA== dependencies: depd "2.0.0" - dns-prefetch-control "0.2.0" dont-sniff-mimetype "1.1.0" - expect-ct "0.2.0" feature-policy "0.3.0" - frameguard "3.1.0" helmet-crossdomain "0.4.0" helmet-csp "2.10.0" hide-powered-by "1.1.0" diff --git a/src/page/template/content/preferences-account.htm b/src/page/template/content/preferences-account.htm index 47b20383b8a..056b03c6f43 100644 --- a/src/page/template/content/preferences-account.htm +++ b/src/page/template/content/preferences-account.htm @@ -54,11 +54,11 @@
- +
- +
@@ -91,7 +91,7 @@ @@ -186,7 +186,7 @@ - +
diff --git a/src/page/template/list/temporary-guest.htm b/src/page/template/list/temporary-guest.htm index f479a43f79f..8529fd5d157 100644 --- a/src/page/template/list/temporary-guest.htm +++ b/src/page/template/list/temporary-guest.htm @@ -9,14 +9,12 @@ conversation: getConversationById(activeCall.conversationId), multitasking: multitasking, callingRepository: callingRepository, + temporaryUserStyle: true, callActions: callActions, hasAccessToCamera: hasAccessToCamera()" data-uie-name="item-call"> - -
-
diff --git a/src/script/components/list/conversationListCallingCell.ts b/src/script/components/list/conversationListCallingCell.ts index 32574dd39f8..bba4e67f973 100644 --- a/src/script/components/list/conversationListCallingCell.ts +++ b/src/script/components/list/conversationListCallingCell.ts @@ -66,6 +66,7 @@ class ConversationListCallingCell { readonly dispose: () => void; readonly isConnecting: ko.PureComputed; readonly isDeclined: ko.PureComputed; + readonly isStillOngoing: ko.PureComputed; readonly isIdle: ko.PureComputed; readonly isIncoming: ko.PureComputed; readonly isMuted: ko.Observable; @@ -79,6 +80,7 @@ class ConversationListCallingCell { readonly showParticipants: ko.Observable; readonly showParticipantsButton: ko.PureComputed; readonly showVideoButton: ko.PureComputed; + readonly showJoinButton: ko.PureComputed; readonly showVideoGrid: ko.PureComputed; readonly temporaryUserStyle: boolean; readonly videoGrid: ko.PureComputed; @@ -126,6 +128,8 @@ class ConversationListCallingCell { [CALL_REASON.STILL_ONGOING, CALL_REASON.ANSWERED_ELSEWHERE].includes(call.reason()), ); + this.isStillOngoing = ko.pureComputed(() => [CALL_REASON.STILL_ONGOING].includes(call.reason())); + this.isMuted = callingRepository.isMuted; this.callDuration = ko.observable(); @@ -157,6 +161,7 @@ class ConversationListCallingCell { }); this.showVideoButton = ko.pureComputed(() => call.initialType === CALL_TYPE.VIDEO || this.isOngoing()); + this.showJoinButton = ko.pureComputed(() => conversation() && this.isStillOngoing() && temporaryUserStyle); this.disableScreenButton = !this.callingRepository.supportsScreenSharing; this.disableVideoButton = ko.pureComputed(() => { const selfParticipant = call.getSelfParticipant(); @@ -189,6 +194,10 @@ class ConversationListCallingCell { return this.isIncoming() ? this.callActions.reject(call) : this.callActions.leave(call); } + joinCall(call: Call) { + this.callActions.answer(call); + } + showFullscreenVideoGrid(): void { this.multitasking.autoMinimize(false); this.multitasking.isMinimized(false); @@ -213,6 +222,9 @@ class ConversationListCallingCell { ko.components.register('conversation-list-calling-cell', { template: ` + +
+
diff --git a/src/script/conversation/ConversationRepository.js b/src/script/conversation/ConversationRepository.js index 32d2447e7ca..7708080d756 100644 --- a/src/script/conversation/ConversationRepository.js +++ b/src/script/conversation/ConversationRepository.js @@ -1590,19 +1590,19 @@ export class ConversationRepository { * @param {Date} isoDate Date of member removal * @returns {Promise} No return value */ - teamMemberLeave(teamId, userId, isoDate = this.serverTimeHandler.toServerTimestamp()) { - return this.userRepository.getUserById(userId).then(userEntity => { - this.conversations() - .filter(conversationEntity => { - const conversationInTeam = conversationEntity.team_id === teamId; - const userIsParticipant = conversationEntity.participating_user_ids().includes(userId); - return conversationInTeam && userIsParticipant && !conversationEntity.removed_from_conversation(); - }) - .forEach(conversationEntity => { - const leaveEvent = EventBuilder.buildTeamMemberLeave(conversationEntity, userEntity, isoDate); - this.eventRepository.injectEvent(leaveEvent); - }); - }); + async teamMemberLeave(teamId, userId, isoDate = this.serverTimeHandler.toServerTimestamp()) { + const userEntity = await this.userRepository.getUserById(userId); + this.conversations() + .filter(conversationEntity => { + const conversationInTeam = conversationEntity.team_id === teamId; + const userIsParticipant = conversationEntity.participating_user_ids().includes(userId); + return conversationInTeam && userIsParticipant && !conversationEntity.removed_from_conversation(); + }) + .forEach(conversationEntity => { + const leaveEvent = EventBuilder.buildTeamMemberLeave(conversationEntity, userEntity, isoDate); + this.eventRepository.injectEvent(leaveEvent); + }); + userEntity.isDeleted = true; } /** @@ -4167,8 +4167,7 @@ export class ConversationRepository { const asset_et = message_et.get_first_asset(); if (asset_et) { - const is_proper_asset = asset_et.is_audio() || asset_et.is_file() || asset_et.is_video(); - if (!is_proper_asset) { + if (!asset_et.is_downloadable()) { throw new Error(`Tried to update message with wrong asset type as upload failed '${asset_et.type}'`); } diff --git a/src/script/entity/message/Asset.ts b/src/script/entity/message/Asset.ts index ffd4a6aecbb..c9433f61bb2 100644 --- a/src/script/entity/message/Asset.ts +++ b/src/script/entity/message/Asset.ts @@ -43,6 +43,10 @@ export class Asset { this.type = ''; } + is_downloadable(): boolean { + return this.is_audio() || this.is_file() || this.is_video() || this.is_image(); + } + is_image(): this is MediumImageAsset { return this.type === AssetType.IMAGE; } diff --git a/src/script/main/globals.ts b/src/script/main/globals.ts index 08324946d77..6584a0bb33b 100644 --- a/src/script/main/globals.ts +++ b/src/script/main/globals.ts @@ -67,7 +67,6 @@ import '../view_model/bindings/MessageListBindings'; import '../view_model/bindings/VideoCallingBindings'; import '../view_model/content/InputBarViewModel'; import '../view_model/content/PreferencesAboutViewModel'; -import '../view_model/content/PreferencesAccountViewModel'; import '../view_model/content/PreferencesDeviceDetailsViewModel'; import '../view_model/content/PreferencesDevicesViewModel'; import '../view_model/content/TitleBarViewModel'; diff --git a/src/script/notification/PreferenceNotificationRepository.ts b/src/script/notification/PreferenceNotificationRepository.ts index a285ec125ff..79919afc841 100644 --- a/src/script/notification/PreferenceNotificationRepository.ts +++ b/src/script/notification/PreferenceNotificationRepository.ts @@ -29,7 +29,7 @@ import type {User} from '../entity/User'; import {BackendEvent} from '../event/Backend'; import {PropertiesRepository} from '../properties/PropertiesRepository'; -interface Notification { +export interface Notification { data: ClientEntity | boolean; type: string; } diff --git a/src/script/properties/PropertiesRepository.ts b/src/script/properties/PropertiesRepository.ts index 75d84d68aab..6e819c33e89 100644 --- a/src/script/properties/PropertiesRepository.ts +++ b/src/script/properties/PropertiesRepository.ts @@ -53,7 +53,7 @@ export class PropertiesRepository { private readonly logger: Logger; private readonly propertiesService: PropertiesService; - private readonly receiptMode: ko.Observable; + public readonly receiptMode: ko.Observable; private readonly selfService: SelfService; private readonly selfUser: ko.Observable; public properties: WebappProperties; diff --git a/src/script/team/TeamRepository.ts b/src/script/team/TeamRepository.ts index 37819e36312..755fb99cfe9 100644 --- a/src/script/team/TeamRepository.ts +++ b/src/script/team/TeamRepository.ts @@ -73,7 +73,7 @@ export class TeamRepository { private readonly supportsLegalHold: ko.Observable; private readonly teamMapper: TeamMapper; readonly teamMembers: ko.PureComputed; - private readonly teamName: ko.PureComputed; + public readonly teamName: ko.PureComputed; readonly teamUsers: ko.PureComputed; private readonly userRepository: UserRepository; private readonly assetRepository: AssetRepository; @@ -298,7 +298,7 @@ export class TeamRepository { return; } - const members = await this.teamService.getTeamMembersByIds(teamEntity.id, memberIds); + const members = await this.teamService.getTeamMembersByIds(teamId, memberIds); const mappedMembers = this.teamMapper.mapMemberFromArray(members); memberIds = mappedMembers.map(member => member.userId); diff --git a/src/script/user/UserRepository.ts b/src/script/user/UserRepository.ts index 604462f2b64..c869fae1c42 100644 --- a/src/script/user/UserRepository.ts +++ b/src/script/user/UserRepository.ts @@ -90,7 +90,7 @@ export class UserRepository { private readonly userMapper: UserMapper; private readonly userService: UserService; private readonly users: ko.ObservableArray; - private should_set_username: boolean; + public should_set_username: boolean; readonly connect_requests: ko.PureComputed; readonly isActivatedAccount: ko.PureComputed; readonly isTemporaryGuest: ko.PureComputed; @@ -659,23 +659,16 @@ export class UserRepository { /** * Update a local user from the backend by ID. */ - updateUserById(userId: string): Promise { - const getLocalUser = () => { - return this.findUserById(userId) || new User(); - }; - - return Promise.all([getLocalUser(), this.userService.getUser(userId)]) - .then(([localUserEntity, updatedUserData]) => - this.userMapper.updateUserFromObject(localUserEntity, updatedUserData), - ) - .then(userEntity => { - if (this.isTeam()) { - this.mapGuestStatus([userEntity]); - } - if (userEntity.inTeam() && userEntity.isDeleted) { - amplify.publish(WebAppEvents.TEAM.MEMBER_LEAVE, userEntity.teamId, userEntity.id); - } - }); + async updateUserById(userId: string): Promise { + const localUserEntity = this.findUserById(userId) || new User(); + const updatedUserData = await this.userService.getUser(userId); + const updatedUserEntity = this.userMapper.updateUserFromObject(localUserEntity, updatedUserData); + if (this.isTeam()) { + this.mapGuestStatus([updatedUserEntity]); + } + if (updatedUserEntity.inTeam() && updatedUserEntity.isDeleted) { + amplify.publish(WebAppEvents.TEAM.MEMBER_LEAVE, updatedUserEntity.teamId, updatedUserEntity.id); + } } /** diff --git a/src/script/util/util.ts b/src/script/util/util.ts index a583411a028..49c589d760f 100644 --- a/src/script/util/util.ts +++ b/src/script/util/util.ts @@ -261,7 +261,7 @@ export const downloadFile = (url: string, fileName: string, mimeType?: string): }, 100); }; -export const createRandomUuid = (): string => UUID.generate(); +export const createRandomUuid = (): string => UUID.genV4().toString(); // Note IE10 listens to "transitionend" instead of "animationend" export const alias = { diff --git a/src/script/view_model/ContentViewModel.js b/src/script/view_model/ContentViewModel.js index 82cd5ebd982..134d78ff989 100644 --- a/src/script/view_model/ContentViewModel.js +++ b/src/script/view_model/ContentViewModel.js @@ -41,6 +41,7 @@ import {CollectionDetailsViewModel} from './content/CollectionDetailsViewModel'; import {GiphyViewModel} from './content/GiphyViewModel'; import {HistoryImportViewModel} from './content/HistoryImportViewModel'; import {HistoryExportViewModel} from './content/HistoryExportViewModel'; +import {PreferencesAccountViewModel} from './content/PreferencesAccountViewModel'; export class ContentViewModel { static get STATE() { @@ -107,7 +108,14 @@ export class ContentViewModel { ); this.preferencesAbout = new z.viewModel.content.PreferencesAboutViewModel(mainViewModel, this, repositories); - this.preferencesAccount = new z.viewModel.content.PreferencesAccountViewModel(mainViewModel, this, repositories); + this.preferencesAccount = new PreferencesAccountViewModel( + repositories.client, + repositories.conversation, + repositories.preferenceNotification, + repositories.properties, + repositories.team, + repositories.user, + ); this.preferencesAV = new PreferencesAVViewModel(repositories.media, repositories.user, { mediaSourceChanged: repositories.calling.changeMediaSource.bind(repositories.calling), willChangeMediaSource: repositories.calling.stopMediaSource.bind(repositories.calling), diff --git a/src/script/view_model/content/CollectionDetailsViewModel.ts b/src/script/view_model/content/CollectionDetailsViewModel.ts index c2dab066016..e85e261d7fe 100644 --- a/src/script/view_model/content/CollectionDetailsViewModel.ts +++ b/src/script/view_model/content/CollectionDetailsViewModel.ts @@ -46,7 +46,7 @@ export class CollectionDetailsViewModel { this.removedFromView = this.removedFromView.bind(this); this.setConversation = this.setConversation.bind(this); - this.logger = getLogger('z.viewModel.CollectionDetailsViewModel'); + this.logger = getLogger('CollectionDetailsViewModel'); this.template = ko.observable(); this.conversationEntity = ko.observable(); diff --git a/src/script/view_model/content/PreferencesAccountViewModel.js b/src/script/view_model/content/PreferencesAccountViewModel.ts similarity index 60% rename from src/script/view_model/content/PreferencesAccountViewModel.js rename to src/script/view_model/content/PreferencesAccountViewModel.ts index 1a34c4ca88b..da46e5e18b9 100644 --- a/src/script/view_model/content/PreferencesAccountViewModel.js +++ b/src/script/view_model/content/PreferencesAccountViewModel.ts @@ -19,15 +19,18 @@ import {Availability, Confirmation} from '@wireapp/protocol-messaging'; import {WebAppEvents} from '@wireapp/webapp-events'; - -import {getLogger} from 'Util/Logger'; +import {amplify} from 'amplify'; +import ko from 'knockout'; +import {WebappProperties} from '@wireapp/api-client/dist/user/data'; import {t} from 'Util/LocalizerUtil'; import {isTemporaryClientAndNonPersistent, validateProfileImageResolution} from 'Util/util'; import {Environment} from 'Util/Environment'; import {isKey, KEY} from 'Util/KeyboardUtil'; import {safeWindowOpen} from 'Util/SanitizationUtil'; +import type {RichInfoField} from '@wireapp/api-client/dist/user/RichInfo'; +import {ChangeEvent} from 'react'; -import {PreferenceNotificationRepository} from '../../notification/PreferenceNotificationRepository'; +import {PreferenceNotificationRepository, Notification} from '../../notification/PreferenceNotificationRepository'; import {getAccountPagesUrl, getCreateTeamUrl, getManageTeamUrl, URL_PATH} from '../../externalRoute'; import {PropertiesRepository} from '../../properties/PropertiesRepository'; import {PROPERTIES_TYPE} from '../../properties/PropertiesType'; @@ -45,6 +48,8 @@ import {AvailabilityContextMenu} from '../../ui/AvailabilityContextMenu'; import {MotionDuration} from '../../motion/MotionDuration'; import {EventName} from '../../tracking/EventName'; import {ContentViewModel} from '../ContentViewModel'; +import {Logger} from '@wireapp/commons'; +import {getLogger} from 'Util/Logger'; import 'Components/availabilityState'; import {isAppLockEnabled} from './AppLockViewModel'; @@ -52,12 +57,46 @@ import {loadValue} from 'Util/StorageUtil'; import {StorageKey} from '../../storage'; import {UserError} from '../../error/UserError'; import {HistoryExportViewModel} from './HistoryExportViewModel'; +import {ClientRepository} from '../../client/ClientRepository'; +import {ConversationRepository} from '../../conversation/ConversationRepository'; +import {TeamRepository} from '../../team/TeamRepository'; +import {AccentColorID} from '@wireapp/commons/dist/commonjs/util/AccentColor'; +import {TeamEntity} from '../../team/TeamEntity'; + +export class PreferencesAccountViewModel { + logger: Logger; + fileExtension: string; + isDesktop: boolean; + brandName: string; + isActivatedAccount: ko.PureComputed; + selfUser: ko.Observable; + name: ko.PureComputed; + availability: ko.PureComputed; + availabilityLabel: ko.PureComputed; + username: ko.PureComputed; + enteredUsername: ko.Observable; + submittedUsername: ko.Observable; + usernameState: ko.Observable; + richProfileFields: ko.Observable; + nameSaved: ko.Observable; + usernameSaved: ko.Observable; + isTeam: ko.PureComputed; + team: ko.Observable; + teamName: ko.PureComputed; + optionPrivacy: ko.Observable; + optionReadReceipts: ko.Observable; + optionMarketingConsent: ko.Observable; + optionResetAppLock: boolean; + ParticipantAvatar: typeof ParticipantAvatar; + isMacOsWrapper: boolean; + manageTeamUrl: string; + createTeamUrl: string; + isTemporaryAndNonPersistent: boolean; + isConsentCheckEnabled: () => boolean; + canEditProfile: (user: User) => boolean; + Config: typeof PreferencesAccountViewModel.CONFIG; + UserNameState: typeof PreferencesAccountViewModel.USERNAME_STATE; -window.z = window.z || {}; -window.z.viewModel = z.viewModel || {}; -window.z.viewModel.content = z.viewModel.content || {}; - -z.viewModel.content.PreferencesAccountViewModel = class PreferencesAccountViewModel { static get CONFIG() { return { PROFILE_IMAGE: { @@ -74,25 +113,23 @@ z.viewModel.content.PreferencesAccountViewModel = class PreferencesAccountViewMo }; } - constructor(mainViewModel, contentViewModel, repositories) { - this.changeAccentColor = this.changeAccentColor.bind(this); - this.removedFromView = this.removedFromView.bind(this); - - this.logger = getLogger('z.viewModel.content.PreferencesAccountViewModel'); + constructor( + private readonly clientRepository: ClientRepository, + private readonly conversationRepository: ConversationRepository, + private readonly preferenceNotificationRepository: PreferenceNotificationRepository, + private readonly propertiesRepository: PropertiesRepository, + private readonly teamRepository: TeamRepository, + private readonly userRepository: UserRepository, + ) { + this.logger = getLogger('PreferencesAccountViewModel'); this.fileExtension = HistoryExportViewModel.CONFIG.FILE_EXTENSION; - this.mainViewModel = mainViewModel; - this.backupRepository = repositories.backup; - this.clientRepository = repositories.client; - this.conversationRepository = repositories.conversation; - this.preferenceNotificationRepository = repositories.preferenceNotification; - this.propertiesRepository = repositories.properties; - this.teamRepository = repositories.team; - this.userRepository = repositories.user; - this.Environment = Environment; + this.isDesktop = Environment.desktop; this.brandName = Config.getConfig().BRAND_NAME; this.isActivatedAccount = this.userRepository.isActivatedAccount; this.selfUser = this.userRepository.self; + this.Config = PreferencesAccountViewModel.CONFIG; + this.UserNameState = PreferencesAccountViewModel.USERNAME_STATE; this.name = ko.pureComputed(() => this.selfUser().name()); this.availability = ko.pureComputed(() => this.selfUser().availability()); @@ -144,15 +181,15 @@ z.viewModel.content.PreferencesAccountViewModel = class PreferencesAccountViewMo this._initSubscriptions(); } - _initSubscriptions() { + _initSubscriptions = () => { amplify.subscribe(WebAppEvents.PROPERTIES.UPDATED, this.updateProperties); - } + }; - changeAccentColor(id) { + changeAccentColor = (id: AccentColorID) => { this.userRepository.changeAccentColor(id); - } + }; - changeName(viewModel, event) { + changeName = async (viewModel: unknown, event: ChangeEvent): Promise => { const newName = event.target.value.trim(); const isUnchanged = newName === this.selfUser().name(); @@ -162,15 +199,18 @@ z.viewModel.content.PreferencesAccountViewModel = class PreferencesAccountViewMo const isValidName = newName.length >= UserRepository.CONFIG.MINIMUM_NAME_LENGTH; if (isValidName) { - this.userRepository.changeName(newName).then(() => { + try { + await this.userRepository.changeName(newName); this.nameSaved(true); event.target.blur(); window.setTimeout(() => this.nameSaved(false), PreferencesAccountViewModel.CONFIG.SAVE_ANIMATION_TIMEOUT); - }); + } catch (error) { + this.logger.warn('Failed to update name', error); + } } - } + }; - changeUsername(username, event) { + changeUsername = async (username: string, event: ChangeEvent): Promise => { const enteredUsername = event.target.value; const normalizedUsername = enteredUsername.toLowerCase().replace(/[^a-z0-9_]/g, ''); @@ -190,69 +230,76 @@ z.viewModel.content.PreferencesAccountViewModel = class PreferencesAccountViewMo } this.submittedUsername(normalizedUsername); - this.userRepository - .changeUsername(normalizedUsername) - .then(() => { - const isCurrentRequest = this.enteredUsername() === this.submittedUsername(); - if (isCurrentRequest) { - this.usernameState(null); - this.usernameSaved(true); - - event.target.blur(); - window.setTimeout(() => this.usernameSaved(false), PreferencesAccountViewModel.CONFIG.SAVE_ANIMATION_TIMEOUT); - } - }) - .catch(error => { - const isUsernameTaken = error.type === UserError.TYPE.USERNAME_TAKEN; - const isCurrentRequest = this.enteredUsername() === this.submittedUsername(); - if (isUsernameTaken && isCurrentRequest) { - this.usernameState(PreferencesAccountViewModel.USERNAME_STATE.TAKEN); - } - }); - } + try { + await this.userRepository.changeUsername(normalizedUsername); + + const isCurrentRequest = this.enteredUsername() === this.submittedUsername(); + if (isCurrentRequest) { + this.usernameState(null); + this.usernameSaved(true); + + event.target.blur(); + window.setTimeout(() => this.usernameSaved(false), PreferencesAccountViewModel.CONFIG.SAVE_ANIMATION_TIMEOUT); + } + } catch (error) { + const isUsernameTaken = error.type === UserError.TYPE.USERNAME_TAKEN; + const isCurrentRequest = this.enteredUsername() === this.submittedUsername(); + if (isUsernameTaken && isCurrentRequest) { + this.usernameState(PreferencesAccountViewModel.USERNAME_STATE.TAKEN); + } + } + }; - checkUsernameInput(username, keyboardEvent) { + checkUsernameInput = (username: string, keyboardEvent: KeyboardEvent) => { if (isKey(keyboardEvent, KEY.BACKSPACE)) { return true; } // Automation: KeyboardEvent triggered during tests is missing key property - const inputChar = keyboardEvent.key || String.fromCharCode(event.charCode); + const inputChar = keyboardEvent.key || String.fromCharCode(keyboardEvent.charCode); return validateCharacter(inputChar.toLowerCase()); - } + }; - popNotification() { + popNotification = () => { this.preferenceNotificationRepository .getNotifications() .forEach(({type, notification}) => this._showNotification(type, notification)); - } + }; - _showNotification(type, aggregatedNotifications) { + _showNotification = (type: string, aggregatedNotifications: Notification[]) => { switch (type) { case PreferenceNotificationRepository.CONFIG.NOTIFICATION_TYPES.NEW_CLIENT: { - modals.showModal(ModalsViewModel.TYPE.ACCOUNT_NEW_DEVICES, { - data: aggregatedNotifications.map(notification => notification.data), - preventClose: true, - secondaryAction: { - action: () => { - amplify.publish(WebAppEvents.CONTENT.SWITCH, ContentViewModel.STATE.PREFERENCES_DEVICES); + modals.showModal( + ModalsViewModel.TYPE.ACCOUNT_NEW_DEVICES, + { + data: aggregatedNotifications.map(notification => notification.data), + preventClose: true, + secondaryAction: { + action: () => { + amplify.publish(WebAppEvents.CONTENT.SWITCH, ContentViewModel.STATE.PREFERENCES_DEVICES); + }, }, }, - }); + undefined, + ); break; } case PreferenceNotificationRepository.CONFIG.NOTIFICATION_TYPES.READ_RECEIPTS_CHANGED: { - modals.showModal(ModalsViewModel.TYPE.ACCOUNT_READ_RECEIPTS_CHANGED, { - data: aggregatedNotifications.pop().data, - preventClose: true, - }); + modals.showModal( + ModalsViewModel.TYPE.ACCOUNT_READ_RECEIPTS_CHANGED, + { + data: aggregatedNotifications.pop().data, + preventClose: true, + }, + undefined, + ); break; } } - } + }; - clickOnChangePicture(files) { + clickOnChangePicture = (files: File[]) => { const [newUserPicture] = Array.from(files); this.setPicture(newUserPicture).catch(error => { @@ -261,89 +308,104 @@ z.viewModel.content.PreferencesAccountViewModel = class PreferencesAccountViewMo throw error; } }); - } + }; - clickOnAvailability(viewModel, event) { + clickOnAvailability = (viewModel: unknown, event: MouseEvent) => { AvailabilityContextMenu.show(event, 'settings', 'preferences-account-availability-menu'); - } + }; - clickOnBackupExport() { + clickOnBackupExport = (): void => { amplify.publish(WebAppEvents.CONTENT.SWITCH, ContentViewModel.STATE.HISTORY_EXPORT); amplify.publish(WebAppEvents.BACKUP.EXPORT.START); - } + }; - onImportFileChange(viewModel, event) { + onImportFileChange = (viewModel: unknown, event: ChangeEvent): void => { const file = event.target.files[0]; if (file) { amplify.publish(WebAppEvents.CONTENT.SWITCH, ContentViewModel.STATE.HISTORY_IMPORT); amplify.publish(WebAppEvents.BACKUP.IMPORT.START, file); } - } + }; - clickOnDeleteAccount() { - modals.showModal(ModalsViewModel.TYPE.CONFIRM, { - primaryAction: { - action: () => this.userRepository.deleteMe(), - text: t('modalAccountDeletionAction'), - }, - text: { - message: t('modalAccountDeletionMessage'), - title: t('modalAccountDeletionHeadline'), + clickOnDeleteAccount = (): void => { + modals.showModal( + ModalsViewModel.TYPE.CONFIRM, + { + primaryAction: { + action: () => this.userRepository.deleteMe(), + text: t('modalAccountDeletionAction'), + }, + text: { + message: t('modalAccountDeletionMessage'), + title: t('modalAccountDeletionHeadline'), + }, }, - }); - } + undefined, + ); + }; - clickOnLeaveGuestRoom() { - modals.showModal(ModalsViewModel.TYPE.CONFIRM, { - preventClose: true, - primaryAction: { - action: () => this.conversationRepository.leaveGuestRoom().then(() => this.clientRepository.logoutClient()), - text: t('modalAccountLeaveGuestRoomAction'), - }, - text: { - message: t('modalAccountLeaveGuestRoomMessage'), - title: t('modalAccountLeaveGuestRoomHeadline'), + clickOnLeaveGuestRoom = (): void => { + modals.showModal( + ModalsViewModel.TYPE.CONFIRM, + { + preventClose: true, + primaryAction: { + action: async (): Promise => { + try { + await this.conversationRepository.leaveGuestRoom(); + this.clientRepository.logoutClient(); + } catch (error) { + this.logger.warn('Error while leaving room', error); + } + }, + text: t('modalAccountLeaveGuestRoomAction'), + }, + text: { + message: t('modalAccountLeaveGuestRoomMessage'), + title: t('modalAccountLeaveGuestRoomHeadline'), + }, }, - }); - } + undefined, + ); + }; - clickOnLogout() { + clickOnLogout = (): void => { this.clientRepository.logoutClient(); - } + }; - clickOpenManageTeam() { + clickOpenManageTeam = (): void => { if (this.manageTeamUrl) { safeWindowOpen(this.manageTeamUrl); amplify.publish(WebAppEvents.ANALYTICS.EVENT, EventName.SETTINGS.OPENED_MANAGE_TEAM); } - } + }; - clickOnResetPassword() { + clickOnResetPassword = (): void => { safeWindowOpen(getAccountPagesUrl(URL_PATH.PASSWORD_RESET)); - } + }; - clickOnResetAppLockPassphrase() { + clickOnResetAppLockPassphrase = (): void => { amplify.publish(WebAppEvents.PREFERENCES.CHANGE_APP_LOCK_PASSPHRASE); - } + }; - removedFromView() { + removedFromView = (): void => { this._resetUsernameInput(); - } + }; - resetNameInput() { + resetNameInput = (): void => { if (!this.nameSaved()) { this.name.notifySubscribers(); } - } + }; - resetUsernameInput() { + resetUsernameInput = (): void => { if (!this.usernameSaved()) { this._resetUsernameInput(); this.username.notifySubscribers(); } - } + }; - setPicture(newUserPicture) { + setPicture = async (newUserPicture: File): Promise => { const isTooLarge = newUserPicture.size > Config.getConfig().MAXIMUM_IMAGE_FILE_SIZE; if (isTooLarge) { const maximumSizeInMB = Config.getConfig().MAXIMUM_IMAGE_FILE_SIZE / 1024 / 1024; @@ -364,7 +426,8 @@ z.viewModel.content.PreferencesAccountViewModel = class PreferencesAccountViewMo const minHeight = UserRepository.CONFIG.MINIMUM_PICTURE_SIZE.HEIGHT; const minWidth = UserRepository.CONFIG.MINIMUM_PICTURE_SIZE.WIDTH; - return validateProfileImageResolution(newUserPicture, minWidth, minHeight).then(isValid => { + try { + const isValid = await validateProfileImageResolution(newUserPicture, minWidth, minHeight); if (isValid) { return this.userRepository.changePicture(newUserPicture); } @@ -372,14 +435,15 @@ z.viewModel.content.PreferencesAccountViewModel = class PreferencesAccountViewMo const messageString = t('modalPictureTooSmallMessage'); const titleString = t('modalPictureTooSmallHeadline'); return this._showUploadWarning(titleString, messageString); - }); - } + } catch (error) { + this.logger.error('Failed to validate profile image', error); + return false; + } + }; - shouldFocusUsername() { - return this.userRepository.should_set_username; - } + shouldFocusUsername = (): boolean => this.userRepository.should_set_username; - verifyUsername(username, event) { + verifyUsername = (username: string, event: ChangeEvent): void => { const enteredUsername = event.target.value.toLowerCase().replace(/[^a-z0-9_]/g, ''); const usernameTooShort = enteredUsername.length < UserRepository.CONFIG.MINIMUM_USERNAME_LENGTH; @@ -407,36 +471,36 @@ z.viewModel.content.PreferencesAccountViewModel = class PreferencesAccountViewMo } }); } - } + }; - _showUploadWarning(title, message) { + _showUploadWarning = (title: string, message: string): Promise => { const modalOptions = {text: {message, title}}; - modals.showModal(ModalsViewModel.TYPE.ACKNOWLEDGE, modalOptions); + modals.showModal(ModalsViewModel.TYPE.ACKNOWLEDGE, modalOptions, undefined); return Promise.reject(new UserError(UserError.TYPE.INVALID_UPDATE, UserError.MESSAGE.INVALID_UPDATE)); - } + }; - _resetUsernameInput() { + _resetUsernameInput = (): void => { this.usernameState(null); this.enteredUsername(null); this.submittedUsername(null); - } + }; - onReadReceiptsChange(viewModel, event) { + onReadReceiptsChange = (viewModel: unknown, event: ChangeEvent): boolean => { const isChecked = event.target.checked; const mode = isChecked ? Confirmation.Type.READ : Confirmation.Type.DELIVERED; this.propertiesRepository.updateProperty(PropertiesRepository.CONFIG.WIRE_RECEIPT_MODE.key, mode); return true; - } + }; - onMarketingConsentChange(viewModel, event) { + onMarketingConsentChange = (viewModel: unknown, event: ChangeEvent): boolean => { const isChecked = event.target.checked; const mode = isChecked ? ConsentValue.GIVEN : ConsentValue.NOT_GIVEN; this.propertiesRepository.updateProperty(PropertiesRepository.CONFIG.WIRE_MARKETING_CONSENT.key, mode); return true; - } + }; - updateProperties = ({settings}) => { + updateProperties = ({settings}: WebappProperties): void => { this.optionPrivacy(settings.privacy.improve_wire); }; -}; +} diff --git a/src/script/view_model/list/TemporaryGuestViewModel.js b/src/script/view_model/list/TemporaryGuestViewModel.js index bd4d69640d4..10e4383d53b 100644 --- a/src/script/view_model/list/TemporaryGuestViewModel.js +++ b/src/script/view_model/list/TemporaryGuestViewModel.js @@ -17,7 +17,6 @@ * */ -import {REASON as CALL_REASON, STATE as CALL_STATE} from '@wireapp/avs'; import {WebAppEvents} from '@wireapp/webapp-events'; import {getLogger} from 'Util/Logger'; @@ -33,9 +32,8 @@ class TemporaryGuestViewModel { * @param {MainViewModel} mainViewModel Main view model * @param {z.viewModel.ListViewModel} listViewModel List view model * @param {Object} repositories Object containing all repositories - * @param {Function} onJoinCall Callback called when the user wants to join a call */ - constructor(mainViewModel, listViewModel, repositories, onJoinCall) { + constructor(mainViewModel, listViewModel, repositories) { this.conversationRepository = repositories.conversation; this.userRepository = repositories.user; this.callingRepository = repositories.calling; @@ -48,8 +46,6 @@ class TemporaryGuestViewModel { this.selfUser = this.userRepository.self; this.isAccountCreationEnabled = Config.getConfig().FEATURE.ENABLE_ACCOUNT_REGISTRATION; - - this.onJoinCall = onJoinCall; } clickOnPreferencesButton() { @@ -70,20 +66,6 @@ class TemporaryGuestViewModel { }); } - hasJoinableCall = ko.pureComputed(() => { - const activeConversation = this.conversationRepository.active_conversation(); - if (activeConversation) { - const call = this.callingRepository.findCall(activeConversation.id); - return call && call.state() === CALL_STATE.INCOMING && call.reason() !== CALL_REASON.ANSWERED_ELSEWHERE; - } - }); - - onClickJoinCall = (viewModel, event) => { - event.preventDefault(); - const activeConversation = this.conversationRepository.active_conversation(); - this.onJoinCall(activeConversation); - }; - isSelectedConversation() { return true; } diff --git a/src/script/view_model/panel/AddParticipantsViewModel.ts b/src/script/view_model/panel/AddParticipantsViewModel.ts index ebb86c3ffc3..8126e212b42 100644 --- a/src/script/view_model/panel/AddParticipantsViewModel.ts +++ b/src/script/view_model/panel/AddParticipantsViewModel.ts @@ -85,7 +85,7 @@ export class AddParticipantsViewModel extends BasePanelViewModel { this.userRepository = user; this.MotionDuration = MotionDuration; - this.logger = getLogger('z.viewModel.panel.AddParticipantsViewModel'); + this.logger = getLogger('AddParticipantsViewModel'); this.isTeam = this.teamRepository.isTeam; this.selfUser = this.userRepository.self; diff --git a/src/script/view_model/panel/ConversationDetailsViewModel.ts b/src/script/view_model/panel/ConversationDetailsViewModel.ts index 504dd401144..272def8c1de 100644 --- a/src/script/view_model/panel/ConversationDetailsViewModel.ts +++ b/src/script/view_model/panel/ConversationDetailsViewModel.ts @@ -112,7 +112,7 @@ export class ConversationDetailsViewModel extends BasePanelViewModel { this.actionsViewModel = mainViewModel.actions; - this.logger = getLogger('z.viewModel.panel.ConversationDetailsViewModel'); + this.logger = getLogger('ConversationDetailsViewModel'); this.isActivatedAccount = this.userRepository.isActivatedAccount; this.isTeam = this.teamRepository.isTeam; diff --git a/src/script/view_model/panel/GroupParticipantServiceViewModel.ts b/src/script/view_model/panel/GroupParticipantServiceViewModel.ts index 5d0cd18ff33..644c300e55a 100644 --- a/src/script/view_model/panel/GroupParticipantServiceViewModel.ts +++ b/src/script/view_model/panel/GroupParticipantServiceViewModel.ts @@ -45,7 +45,7 @@ export class GroupParticipantServiceViewModel extends BasePanelViewModel { this.integrationRepository = repositories.integration; this.actionsViewModel = mainViewModel.actions; - this.logger = getLogger('z.viewModel.panel.GroupParticipantServiceViewModel'); + this.logger = getLogger('GroupParticipantServiceViewModel'); this.selectedParticipant = ko.observable(undefined); this.selectedService = ko.observable(undefined); diff --git a/test/helper/UserGenerator.ts b/test/helper/UserGenerator.ts index 5c1061ee237..325e290b256 100644 --- a/test/helper/UserGenerator.ts +++ b/test/helper/UserGenerator.ts @@ -18,13 +18,13 @@ */ import * as faker from 'faker'; -import UUID from 'pure-uuid'; import type {User as APIClientUser} from '@wireapp/api-client/dist/user'; import {UserAssetType} from '@wireapp/api-client/dist/user'; import type {User} from '../../src/script/entity/User'; import {serverTimeHandler} from '../../src/script/time/serverTimeHandler'; import {UserMapper} from '../../src/script/user/UserMapper'; +import {createRandomUuid} from 'Util/util'; export class UserGenerator { static getRandomUser(): User | void { @@ -32,18 +32,18 @@ export class UserGenerator { accent_id: Math.floor(Math.random() * 7 + 1), assets: [ { - key: `3-1-${new UUID(4).format()}`, + key: `3-1-${createRandomUuid()}`, size: UserAssetType.PREVIEW, type: 'image', }, { - key: `3-1-${new UUID(4).format()}`, + key: `3-1-${createRandomUuid()}`, size: UserAssetType.COMPLETE, type: 'image', }, ], handle: faker.internet.userName(), - id: new UUID(4).format(), + id: createRandomUuid(), name: faker.name.findName(), }; diff --git a/test/unit_tests/calling/CallingRepositorySpec.js b/test/unit_tests/calling/CallingRepositorySpec.js index 927a764ced1..c9e8bfd201f 100644 --- a/test/unit_tests/calling/CallingRepositorySpec.js +++ b/test/unit_tests/calling/CallingRepositorySpec.js @@ -18,7 +18,6 @@ */ import {WebAppEvents} from '@wireapp/webapp-events'; -import UUID from 'pure-uuid'; import {CONV_TYPE, CALL_TYPE, STATE as CALL_STATE, REASON} from '@wireapp/avs'; import {CallingRepository} from 'src/script/calling/CallingRepository'; @@ -31,6 +30,7 @@ import {Conversation} from 'src/script/entity/Conversation'; import {ModalsViewModel} from 'src/script/view_model/ModalsViewModel'; import {serverTimeHandler} from 'src/script/time/serverTimeHandler'; import {TestFactory} from '../../helper/TestFactory'; +import {createRandomUuid} from 'Util/util'; const createSelfParticipant = () => { const selfUser = new User(); @@ -43,8 +43,8 @@ describe('CallingRepository', () => { let callingRepository; let wCall; let wUser; - const selfUser = new User(genUUID()); - const clientId = genUUID(); + const selfUser = new User(createRandomUuid()); + const clientId = createRandomUuid(); beforeAll(() => { return testFactory.exposeCallingActors().then(injectedCallingRepository => { @@ -66,11 +66,17 @@ describe('CallingRepository', () => { describe('startCall', () => { it('warns the user that there is an ongoing call before starting a new one', done => { - const activeCall = new Call(selfUser.id, genUUID(), CONV_TYPE.ONEONONE, new Participant(), CALL_TYPE.NORMAL); + const activeCall = new Call( + selfUser.id, + createRandomUuid(), + CONV_TYPE.ONEONONE, + new Participant(), + CALL_TYPE.NORMAL, + ); activeCall.state(CALL_STATE.MEDIA_ESTAB); spyOn(callingRepository, 'activeCalls').and.returnValue([activeCall]); spyOn(amplify, 'publish').and.returnValue(undefined); - const conversationId = genUUID(); + const conversationId = createRandomUuid(); const conversationType = CONV_TYPE.ONEONONE; const callType = CALL_TYPE.NORMAL; spyOn(wCall, 'start'); @@ -88,7 +94,7 @@ describe('CallingRepository', () => { }); it('starts a normal call in a 1:1 conversation', () => { - const conversationId = genUUID(); + const conversationId = createRandomUuid(); const conversationType = CONV_TYPE.ONEONONE; const callType = CALL_TYPE.NORMAL; spyOn(wCall, 'start'); @@ -354,10 +360,6 @@ xdescribe('e2e audio call', () => { }); }); -function genUUID() { - return new UUID(4).format(); -} - function silence() { const ctx = new AudioContext(); const oscillator = ctx.createOscillator(); @@ -384,8 +386,8 @@ function extractAudioStats(stats) { } function createAutoAnsweringWuser(wCall, remoteCallingRepository) { - const selfUserId = genUUID(); - const selfClientId = genUUID(); + const selfUserId = createRandomUuid(); + const selfClientId = createRandomUuid(); const sendMsg = (context, conversationId, userId, clientId, destinationUserId, destinationClientId, payload) => { const event = { content: JSON.parse(payload), diff --git a/test/unit_tests/components/messageSpec.js b/test/unit_tests/components/messageSpec.js index 4940269b7a0..9f520e6bae3 100644 --- a/test/unit_tests/components/messageSpec.js +++ b/test/unit_tests/components/messageSpec.js @@ -17,17 +17,17 @@ * */ -import UUID from 'pure-uuid'; import {instantiateComponent} from '../../helper/knockoutHelpers'; +import {TestFactory} from '../../helper/TestFactory'; import {Conversation} from 'src/script/entity/Conversation'; import {ContentMessage} from 'src/script/entity/message/ContentMessage'; import {LinkPreview} from 'src/script/entity/message/LinkPreview'; import {Text} from 'src/script/entity/message/Text'; import {User} from 'src/script/entity/User'; -import {TestFactory} from '../../helper/TestFactory'; import 'src/script/components/message'; import {t} from 'Util/LocalizerUtil'; +import {createRandomUuid} from 'Util/util'; describe('message', () => { const testFactory = new TestFactory(); @@ -62,7 +62,7 @@ describe('message', () => { onClickTimestamp: () => {}, onLike: () => {}, onMessageMarked: () => {}, - selfId: () => new UUID(4).format(), + selfId: () => createRandomUuid(), shouldShowAvatar: true, shouldShowInvitePeople: true, }; diff --git a/test/unit_tests/components/panel/enrichedFieldsSpec.js b/test/unit_tests/components/panel/enrichedFieldsSpec.js index 671703de8e7..a6b7e55a96e 100644 --- a/test/unit_tests/components/panel/enrichedFieldsSpec.js +++ b/test/unit_tests/components/panel/enrichedFieldsSpec.js @@ -19,17 +19,18 @@ import {container} from 'tsyringe'; import {instantiateComponent} from '../../../helper/knockoutHelpers'; -import UUID from 'pure-uuid'; + import 'src/script/components/panel/enrichedFields'; import {RichProfileRepository} from 'src/script/user/RichProfileRepository'; import {APIClientSingleton} from 'src/script/service/APIClientSingleton'; +import {createRandomUuid} from 'Util/util'; const entriesListSelector = '.enriched-fields__entry'; describe('enriched-fields', () => { it('displays all the given fields', () => { const richProfileRepository = new RichProfileRepository(container.resolve(APIClientSingleton).getClient()); - const userId = new UUID(4).format(); + const userId = createRandomUuid(); const params = {richProfileRepository, user: () => ({email: () => {}, id: userId})}; spyOn(richProfileRepository, 'getUserRichProfile').and.returnValue( @@ -48,7 +49,7 @@ describe('enriched-fields', () => { it('displays the email if set on user', () => { const richProfileRepository = new RichProfileRepository(container.resolve(APIClientSingleton).getClient()); - const userId = new UUID(4).format(); + const userId = createRandomUuid(); const params = {richProfileRepository, user: () => ({email: () => 'user@inter.net', id: userId})}; spyOn(richProfileRepository, 'getUserRichProfile').and.returnValue( @@ -67,7 +68,7 @@ describe('enriched-fields', () => { it('calls the `onFieldsLoaded` function when fields are loaded', () => { const richProfileRepository = new RichProfileRepository(container.resolve(APIClientSingleton).getClient()); - const userId = new UUID(4).format(); + const userId = createRandomUuid(); const params = {onFieldsLoaded: () => {}, richProfileRepository, user: () => ({email: () => {}, id: userId})}; const richProfile = { fields: [ diff --git a/test/unit_tests/conversation/ConversationMapperSpec.js b/test/unit_tests/conversation/ConversationMapperSpec.js index b84c12981d8..62a4d2c30ae 100644 --- a/test/unit_tests/conversation/ConversationMapperSpec.js +++ b/test/unit_tests/conversation/ConversationMapperSpec.js @@ -17,8 +17,6 @@ * */ -import UUID from 'pure-uuid'; - import {createRandomUuid} from 'Util/util'; import {Conversation} from 'src/script/entity/Conversation'; @@ -267,18 +265,17 @@ describe('Conversation Mapper', () => { const self_status = {last_read_timestamp: '1480339377099'}; const last_read_timestamp_number = window.parseInt(self_status.last_read_timestamp, 10); const updated_conversation_et = conversation_mapper.updateSelfStatus(conversation_et, self_status); - expect(updated_conversation_et.last_read_timestamp()).toBe(last_read_timestamp_number); }); }); describe('mergeConversation', () => { function getDataWithReadReceiptMode(localReceiptMode, remoteReceiptMode) { - const conversationCreatorId = new UUID(4).format(); - const conversationId = new UUID(4).format(); + const conversationCreatorId = createRandomUuid(); + const conversationId = createRandomUuid(); const conversationName = 'Hello, World!'; - const selfUserId = new UUID(4).format(); - const teamId = new UUID(4).format(); + const selfUserId = createRandomUuid(); + const teamId = createRandomUuid(); const localData = { archived_state: false, diff --git a/test/unit_tests/event/preprocessor/ReceiptsMiddlewareSpec.js b/test/unit_tests/event/preprocessor/ReceiptsMiddlewareSpec.js index ca5d5dc2232..c8d0a59edc7 100644 --- a/test/unit_tests/event/preprocessor/ReceiptsMiddlewareSpec.js +++ b/test/unit_tests/event/preprocessor/ReceiptsMiddlewareSpec.js @@ -17,15 +17,14 @@ * */ -import UUID from 'pure-uuid'; - import {noop} from 'Util/util'; +import {createRandomUuid} from 'Util/util'; import {ReceiptsMiddleware} from 'src/script/event/preprocessor/ReceiptsMiddleware'; import {ClientEvent} from 'src/script/event/Client'; describe('ReceiptsMiddleware', () => { - const selfId = new UUID(4).format(); + const selfId = createRandomUuid(); let readReceiptMiddleware; const eventService = {loadEvents: noop, replaceEvent: noop}; const userRepository = { @@ -66,7 +65,7 @@ describe('ReceiptsMiddleware', () => { it('ignores read receipts for messages that are not mine', () => { const event = createConfirmationEvent(4); - const originaleEvent = {from: new UUID(4).format()}; + const originaleEvent = {from: createRandomUuid()}; spyOn(eventService, 'loadEvents').and.returnValue(Promise.resolve([originaleEvent])); spyOn(eventService, 'replaceEvent'); return readReceiptMiddleware.processEvent(event).then(() => { @@ -112,13 +111,13 @@ describe('ReceiptsMiddleware', () => { function createConfirmationEvent(status, moreMessageIds = []) { return { - conversation: new UUID(4).format(), + conversation: createRandomUuid(), data: { - message_id: new UUID(4).format(), + message_id: createRandomUuid(), more_message_ids: moreMessageIds, status, }, - from: new UUID(4).format(), + from: createRandomUuid(), time: '12-12-12', type: ClientEvent.CONVERSATION.CONFIRMATION, }; diff --git a/test/unit_tests/notification/PreferenceNotificationRepositorySpec.js b/test/unit_tests/notification/PreferenceNotificationRepositorySpec.js index 75f94c40266..4f0fadc7b0f 100644 --- a/test/unit_tests/notification/PreferenceNotificationRepositorySpec.js +++ b/test/unit_tests/notification/PreferenceNotificationRepositorySpec.js @@ -18,15 +18,15 @@ */ import {amplify} from 'amplify'; -import UUID from 'pure-uuid'; import {WebAppEvents} from '@wireapp/webapp-events'; import {PreferenceNotificationRepository} from 'src/script/notification/PreferenceNotificationRepository'; import {PropertiesRepository} from 'src/script/properties/PropertiesRepository'; import {BackendEvent} from 'src/script/event/Backend'; +import {createRandomUuid} from 'Util/util'; describe('PreferenceNotificationRepository', () => { - const user = {id: new UUID(4).format()}; + const user = {id: createRandomUuid()}; const userObservable = () => user; beforeEach(() => { @@ -75,7 +75,7 @@ describe('PreferenceNotificationRepository', () => { const preferenceNotificationRepository = new PreferenceNotificationRepository(userObservable); const newClientData = {}; - amplify.publish(WebAppEvents.USER.CLIENT_ADDED, new UUID(4).format(), newClientData); + amplify.publish(WebAppEvents.USER.CLIENT_ADDED, createRandomUuid(), newClientData); expect(preferenceNotificationRepository.notifications().length).toBe(0); }); diff --git a/test/unit_tests/user/RichProfileRepositorySpec.js b/test/unit_tests/user/RichProfileRepositorySpec.js index d3beae12db2..6497405119a 100644 --- a/test/unit_tests/user/RichProfileRepositorySpec.js +++ b/test/unit_tests/user/RichProfileRepositorySpec.js @@ -19,9 +19,9 @@ import {container} from 'tsyringe'; -import UUID from 'pure-uuid'; import {RichProfileRepository} from 'src/script/user/RichProfileRepository'; import {APIClientSingleton} from 'src/script/service/APIClientSingleton'; +import {createRandomUuid} from 'Util/util'; describe('RichProfileRepository', () => { let richProfileRepository; @@ -32,7 +32,7 @@ describe('RichProfileRepository', () => { describe('getUserRichProfile', () => { it("fetches the user's rich profile if it is not already in cache", () => { - const userId = new UUID(4).format(); + const userId = createRandomUuid(); const response = []; spyOn(richProfileRepository.apiClient.user.api, 'getRichInfo').and.returnValue(Promise.resolve(response)); diff --git a/test/unit_tests/util/ValidationUtilSpec.js b/test/unit_tests/util/ValidationUtilSpec.js index 85953e2e13e..d330b4c5520 100644 --- a/test/unit_tests/util/ValidationUtilSpec.js +++ b/test/unit_tests/util/ValidationUtilSpec.js @@ -17,8 +17,6 @@ * */ -import UUID from 'pure-uuid'; - import {createRandomUuid} from 'Util/util'; import { isBearerToken, @@ -149,7 +147,7 @@ describe('ValidationUtil', () => { describe('"isUUID"', () => { it('detects a correct UUID', () => { - const uuid = new UUID(4).format(); + const uuid = createRandomUuid(); const actual = isUUID(uuid); expect(actual).toBe(true); diff --git a/test/unit_tests/util/messageComparatorSpec.js b/test/unit_tests/util/messageComparatorSpec.js index 51bb3374bb9..7c23a2aaa6f 100644 --- a/test/unit_tests/util/messageComparatorSpec.js +++ b/test/unit_tests/util/messageComparatorSpec.js @@ -17,16 +17,15 @@ * */ -import UUID from 'pure-uuid'; - import {areMentionsDifferent, isTextDifferent} from 'Util/messageComparator'; +import {createRandomUuid} from 'Util/util'; import {Text} from 'src/script/entity/message/Text'; describe('MessageComparator', () => { it('areMentionsDifferent', () => { - const mentionUser1 = {userId: new UUID(4).format()}; - const mentionUser2 = {userId: new UUID(4).format()}; + const mentionUser1 = {userId: createRandomUuid()}; + const mentionUser2 = {userId: createRandomUuid()}; const tests = [ {expected: false, newMentions: [], originalMentions: []}, diff --git a/test/unit_tests/view_model/panel/GroupParticipantUserViewModelSpec.js b/test/unit_tests/view_model/panel/GroupParticipantUserViewModelSpec.js index 605e629d6fa..1692846e127 100644 --- a/test/unit_tests/view_model/panel/GroupParticipantUserViewModelSpec.js +++ b/test/unit_tests/view_model/panel/GroupParticipantUserViewModelSpec.js @@ -17,9 +17,8 @@ * */ -import UUID from 'pure-uuid'; - import {noop} from 'Util/util'; +import {createRandomUuid} from 'Util/util'; import {GroupParticipantUserViewModel} from 'src/script/view_model/panel/GroupParticipantUserViewModel'; import {User} from 'src/script/entity/User'; @@ -48,7 +47,7 @@ describe('GroupParticipantUserViewModel', () => { }); it('returns the id of the entity attached', () => { - const userId = new UUID(4).format(); + const userId = createRandomUuid(); const user = new User(userId); groupParticipantUserViewModel.initView({entity: user}); diff --git a/yarn.lock b/yarn.lock index ab8bb98e734..d4928c0c311 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1127,52 +1127,53 @@ resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46" integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA== -"@formatjs/intl-displaynames@^2.2.6": - version "2.2.6" - resolved "https://registry.yarnpkg.com/@formatjs/intl-displaynames/-/intl-displaynames-2.2.6.tgz#de1b456b6bae99cce884b28784a05663ebf0c6f0" - integrity sha512-rhUf6f/A1ztx81mR0xC9qPMrcbzGORxCwSaawicDnBTrrqZPaUYcTjIa54AvF1ODRoMMdG60s5X/5GSP7vcvmA== +"@formatjs/intl-datetimeformat@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@formatjs/intl-datetimeformat/-/intl-datetimeformat-1.3.2.tgz#97b2600137864e7d047b97b96183e9c9fcba7356" + integrity sha512-cf8xQ9ITnnGwiFvph6VTYK/b4rTBRMZvYfahBwBntmCxBFOsfELETDQAhNkUyPdQ9FlSvwlJK+GKoImb2VxUxQ== dependencies: - "@formatjs/intl-utils" "^3.3.1" + "@formatjs/intl-getcanonicallocales" "1.2.6" + "@formatjs/intl-utils" "^3.4.1" -"@formatjs/intl-listformat@^2.2.6": - version "2.2.6" - resolved "https://registry.yarnpkg.com/@formatjs/intl-listformat/-/intl-listformat-2.2.6.tgz#4817ae8a6983694ce4bd3673eb200edef342bb50" - integrity sha512-drQKHa3aOJkp6BnMBfjbSNVPJLlLs1QU93KYtvDhtBHXuvY8mEZv1xdboC0gRET582jh7TGFwwf9c74IfL7v4A== +"@formatjs/intl-displaynames@^2.2.8": + version "2.2.8" + resolved "https://registry.yarnpkg.com/@formatjs/intl-displaynames/-/intl-displaynames-2.2.8.tgz#4903ecd5a6949b4cca2e5898a180c90349b4b1d0" + integrity sha512-9DbfyzylOpbf6XldkGD81U7JZdky9elxE67uPfUrQo/m3Q0/UMWAD1m04Ol7Pfd65pvGCdMKgATl7b9avKKNrQ== dependencies: - "@formatjs/intl-utils" "^3.3.1" + "@formatjs/intl-utils" "^3.4.1" -"@formatjs/intl-numberformat@^4.2.6": - version "4.2.6" - resolved "https://registry.yarnpkg.com/@formatjs/intl-numberformat/-/intl-numberformat-4.2.6.tgz#a1ae188919ce54fc2eda8ff3e2b83c1bbaa0704d" - integrity sha512-LcV9pJ5XiiNwt3kbhsWIbeLd3zQZejs3iE3q98HiuV3yx9fAJR0I7n3XF67KCvIW64+hpo5V831EAbGvwhUUmQ== +"@formatjs/intl-getcanonicallocales@1.2.6": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@formatjs/intl-getcanonicallocales/-/intl-getcanonicallocales-1.2.6.tgz#7aea999dc3130bd2a04b6eea490f3ec22759d04b" + integrity sha512-ZO38NUZoGHAeIn0B4ZXMdpcgdH5i2pZUIMvrf/l2XLAB339x8Yxx+P6WHTD66bQhyntuFpry5iN6zPBqnMubdA== dependencies: - "@formatjs/intl-utils" "^3.3.1" + cldr-core "36.0.0" -"@formatjs/intl-numberformat@^4.2.7": - version "4.2.7" - resolved "https://registry.yarnpkg.com/@formatjs/intl-numberformat/-/intl-numberformat-4.2.7.tgz#7c4976312a0cbfc174a5902281dde50cd3719cd1" - integrity sha512-eXBWegYQUANkPqHSAZ1cQ2ajYGBscQ3Aue+xVl1Fc9jEUmQSR4LBgAv0+GEHTlwtqAVaRQ+NYSDbOk7SORnESA== +"@formatjs/intl-listformat@^2.2.8": + version "2.2.8" + resolved "https://registry.yarnpkg.com/@formatjs/intl-listformat/-/intl-listformat-2.2.8.tgz#9ef57a752f7cdfbe40977c223069956dd4c60809" + integrity sha512-qtbXw24Ns2h74Y7Ph5eeTXUd1FoKhEJzsZm7ajdCWORumAu4tz4eIbV1TOhvaYvY/D1zYxsQcHMI7GtkaWygIQ== dependencies: - "@formatjs/intl-utils" "^3.4.0" + "@formatjs/intl-utils" "^3.4.1" -"@formatjs/intl-relativetimeformat@^5.2.6": - version "5.2.6" - resolved "https://registry.yarnpkg.com/@formatjs/intl-relativetimeformat/-/intl-relativetimeformat-5.2.6.tgz#3d67b75a900e7b5416615beeb2d0eeff33a1e01a" - integrity sha512-UPCY7IoyeqieUxdbfhINVjbCGXCzRr4xZpoiNsr1da4Fwm4uV6l53OXsx1zDRXoiNmMtDuKCKkRzlSfBL89L1g== +"@formatjs/intl-numberformat@^4.2.10": + version "4.2.10" + resolved "https://registry.yarnpkg.com/@formatjs/intl-numberformat/-/intl-numberformat-4.2.10.tgz#2c05add2233bb87e58e992778f9eb39996703421" + integrity sha512-mdubK3/Ml16LB/sS9LGSqCsXZ2CAHd7B3CvFhLTiPYFZSwNE9YUxp7n0VK3P/g8H5C9oweegI05onILkRCp6XQ== dependencies: - "@formatjs/intl-utils" "^3.3.1" + "@formatjs/intl-utils" "^3.4.1" -"@formatjs/intl-utils@^3.3.1": - version "3.3.1" - resolved "https://registry.yarnpkg.com/@formatjs/intl-utils/-/intl-utils-3.3.1.tgz#7ceadbb7e251318729d9bf693731e1a5dcdfa15a" - integrity sha512-7AAicg2wqCJQ+gFEw5Nxp+ttavajBrPAD1HDmzA4jzvUCrF5a2NCJm/c5qON3VBubWWF2cu8HglEouj2h/l7KQ== +"@formatjs/intl-relativetimeformat@^5.2.10": + version "5.2.10" + resolved "https://registry.yarnpkg.com/@formatjs/intl-relativetimeformat/-/intl-relativetimeformat-5.2.10.tgz#abb29304d0f3a55e7d351a5fa07b3a18cbaf0638" + integrity sha512-ipNDOpczSdJEwNSIQfA7AT/5vF3VTOSMgBQWBG165lPp+hU3V9QbT1lWGeYfzyiUKTEqEtcY7HBy9GTDuITvjw== dependencies: - emojis-list "^3.0.0" + "@formatjs/intl-utils" "^3.4.1" -"@formatjs/intl-utils@^3.4.0": - version "3.4.0" - resolved "https://registry.yarnpkg.com/@formatjs/intl-utils/-/intl-utils-3.4.0.tgz#91fcaffcf3925feab888b4a9bad08a51bd0365be" - integrity sha512-rP79Y0e6tWXYO+DBddfIi3TFBh0/wE4x+XCDf43nDcnXD5OUTwLBDX521+e0wwDByq6rc/9Bu/W5llwaBsy6bQ== +"@formatjs/intl-utils@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@formatjs/intl-utils/-/intl-utils-3.4.1.tgz#705646e3be11e5851c33c44448dc3d828997ac41" + integrity sha512-4rdSTl+ki74ncP0GsdqoKczVWHZQKAemW9YRkhbvpcJrAFDLSEMIagQ+YPy+25plyLfgE/iOYManLdpdUF2IcA== dependencies: emojis-list "^3.0.0" @@ -1230,6 +1231,11 @@ dependencies: debug "^4.1.1" +"@kwsites/promise-deferred@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@kwsites/promise-deferred/-/promise-deferred-1.0.1.tgz#63b170e0d02b85a1fa6ad6bdea1f2f14f6f6adc2" + integrity sha512-+D6vnc8qMjU2s8DP7khMWA3/+ONsGYu8bTqRhC2mhYdG3mUEC7OGHX7x71V7VPADDcoR6/hMbuafdoGOthekMw== + "@nodelib/fs.scandir@2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" @@ -1551,10 +1557,10 @@ resolved "https://registry.yarnpkg.com/@types/invariant/-/invariant-2.2.31.tgz#4444c03004f215289dbca3856538434317dd28b2" integrity sha512-jMlgg9pIURvy9jgBHCjQp/CyBjYHUwj91etVcDdXkFl2CwTFiQlB+8tcsMeXpXf2PFE5X2pjk4Gm43hQSMHAdA== -"@types/jasmine@3.5.10": - version "3.5.10" - resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-3.5.10.tgz#a1a41012012b5da9d4b205ba9eba58f6cce2ab7b" - integrity sha512-3F8qpwBAiVc5+HPJeXJpbrl+XjawGmciN5LgiO7Gv1pl1RHtjoMNqZpqEksaPJW05ViKe8snYInRs6xB25Xdew== +"@types/jasmine@3.5.11": + version "3.5.11" + resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-3.5.11.tgz#ba8e80639dffbe277f49c708b45373a320d158e2" + integrity sha512-fg1rOd/DehQTIJTifGqGVY6q92lDgnLfs7C6t1ccSwQrMyoTGSoH6wWzhJDZb6ezhsdwAX4EIBLe8w5fXWmEng== "@types/jquery@3.3.14": version "3.3.14" @@ -1706,18 +1712,18 @@ "@types/react" "*" "@types/react-router" "*" -"@types/react-router@*", "@types/react-router@5.1.7": - version "5.1.7" - resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.7.tgz#e9d12ed7dcfc79187e4d36667745b69a5aa11556" - integrity sha512-2ouP76VQafKjtuc0ShpwUebhHwJo0G6rhahW9Pb8au3tQTjYXd2jta4wv6U2tGLR/I42yuG00+UXjNYY0dTzbg== +"@types/react-router@*", "@types/react-router@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.8.tgz#4614e5ba7559657438e17766bb95ef6ed6acc3fa" + integrity sha512-HzOyJb+wFmyEhyfp4D4NYrumi+LQgQL/68HvJO+q6XtuHSDvw6Aqov7sCAhjbNq3bUPgPqbdvjXC5HeB2oEAPg== dependencies: "@types/history" "*" "@types/react" "*" -"@types/react@*", "@types/react@16.9.38": - version "16.9.38" - resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.38.tgz#868405dace93a4095d3e054f4c4a1de7a1ac0680" - integrity sha512-pHAeZbjjNRa/hxyNuLrvbxhhnKyKNiLC6I5fRF2Zr/t/S6zS41MiyzH4+c+1I9vVfvuRt1VS2Lodjr4ZWnxrdA== +"@types/react@*", "@types/react@16.9.41": + version "16.9.41" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.41.tgz#925137ee4d2ff406a0ecf29e8e9237390844002e" + integrity sha512-6cFei7F7L4wwuM+IND/Q2cV1koQUvJ8iSV+Gwn0c3kvABZ691g7sp3hfEQHOUBJtccl1gPi+EyNjMIl9nGA0ug== dependencies: "@types/prop-types" "*" csstype "^2.2.0" @@ -1793,24 +1799,25 @@ resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.15.2.tgz#927997342bb9f4a5185a86e6579a0a18afc33b0a" integrity sha512-67ZgZpAlhIICIdfQrB5fnDvaKFcDxpKibxznfYRVAT4mQE41Dido/3Ty+E3xGBmTogc5+0Qb8tWhna+5B8z1iQ== -"@typescript-eslint/eslint-plugin@3.3.0": - version "3.3.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.3.0.tgz#89518e5c5209a349bde161c3489b0ec187ae5d37" - integrity sha512-Ybx/wU75Tazz6nU2d7nN6ll0B98odoiYLXwcuwS5WSttGzK46t0n7TPRQ4ozwcTv82UY6TQoIvI+sJfTzqK9dQ== +"@typescript-eslint/eslint-plugin@3.4.0": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.4.0.tgz#8378062e6be8a1d049259bdbcf27ce5dfbeee62b" + integrity sha512-wfkpiqaEVhZIuQRmudDszc01jC/YR7gMSxa6ulhggAe/Hs0KVIuo9wzvFiDbG3JD5pRFQoqnf4m7REDsUvBnMQ== dependencies: - "@typescript-eslint/experimental-utils" "3.3.0" + "@typescript-eslint/experimental-utils" "3.4.0" + debug "^4.1.1" functional-red-black-tree "^1.0.1" regexpp "^3.0.0" semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/experimental-utils@3.3.0": - version "3.3.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.3.0.tgz#d72a946e056a83d4edf97f3411cceb639b0b8c87" - integrity sha512-d4pGIAbu/tYsrPrdHCQ5xfadJGvlkUxbeBB56nO/VGmEDi/sKmfa5fGty5t5veL1OyJBrUmSiRn1R1qfVDydrg== +"@typescript-eslint/experimental-utils@3.4.0": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.4.0.tgz#8a44dfc6fb7f1d071937b390fe27608ebda122b8" + integrity sha512-rHPOjL43lOH1Opte4+dhC0a/+ks+8gOBwxXnyrZ/K4OTAChpSjP76fbI8Cglj7V5GouwVAGaK+xVwzqTyE/TPw== dependencies: "@types/json-schema" "^7.0.3" - "@typescript-eslint/typescript-estree" "3.3.0" + "@typescript-eslint/typescript-estree" "3.4.0" eslint-scope "^5.0.0" eslint-utils "^2.0.0" @@ -1824,14 +1831,14 @@ eslint-scope "^5.0.0" eslint-utils "^2.0.0" -"@typescript-eslint/parser@3.3.0": - version "3.3.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-3.3.0.tgz#fcae40012ded822aa8b2739a1a03a4e3c5bbb7bb" - integrity sha512-a7S0Sqn/+RpOOWTcaLw6RD4obsharzxmgMfdK24l364VxuBODXjuJM7ImCkSXEN7oz52aiZbXSbc76+2EsE91w== +"@typescript-eslint/parser@3.4.0": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-3.4.0.tgz#fe52b68c5cb3bba3f5d875bd17adb70420d49d8d" + integrity sha512-ZUGI/de44L5x87uX5zM14UYcbn79HSXUR+kzcqU42gH0AgpdB/TjuJy3m4ezI7Q/jk3wTQd755mxSDLhQP79KA== dependencies: "@types/eslint-visitor-keys" "^1.0.0" - "@typescript-eslint/experimental-utils" "3.3.0" - "@typescript-eslint/typescript-estree" "3.3.0" + "@typescript-eslint/experimental-utils" "3.4.0" + "@typescript-eslint/typescript-estree" "3.4.0" eslint-visitor-keys "^1.1.0" "@typescript-eslint/typescript-estree@2.32.0": @@ -1847,10 +1854,10 @@ semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/typescript-estree@3.3.0": - version "3.3.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.3.0.tgz#841ffed25c29b0049ebffb4c2071268a34558a2a" - integrity sha512-3SqxylENltEvJsjjMSDCUx/edZNSC7wAqifUU1Ywp//0OWEZwMZJfecJud9XxJ/40rAKEbJMKBOQzeOjrLJFzQ== +"@typescript-eslint/typescript-estree@3.4.0": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.4.0.tgz#6a787eb70b48969e4cd1ea67b057083f96dfee29" + integrity sha512-zKwLiybtt4uJb4mkG5q2t6+W7BuYx2IISiDNV+IY68VfoGwErDx/RfVI7SWL4gnZ2t1A1ytQQwZ+YOJbHHJ2rw== dependencies: debug "^4.1.1" eslint-visitor-keys "^1.1.0" @@ -2297,10 +2304,10 @@ acorn@^7.1.0, acorn@^7.2.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.2.0.tgz#17ea7e40d7c8640ff54a694c889c26f31704effe" integrity sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ== -adm-zip@0.4.14: - version "0.4.14" - resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.14.tgz#2cf312bcc9f8875df835b0f6040bd89be0a727a9" - integrity sha512-/9aQCnQHF+0IiCl0qhXoK7qs//SwYE7zX8lsr/DNk1BRAHYxeLZPL4pguwK29gUEqasYQjqPtEpDRSWEkdHn9g== +adm-zip@0.4.16: + version "0.4.16" + resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.16.tgz#cf4c508fdffab02c269cbc7f471a875f05570365" + integrity sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg== after@0.8.2: version "0.8.2" @@ -2725,14 +2732,14 @@ atob@^2.1.1: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -autoprefixer@9.8.1, autoprefixer@^9.8.0: - version "9.8.1" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.1.tgz#09ebdf209ddeb6900b310c71219f367138950ddd" - integrity sha512-zDw9+mkCdWZHloBIGrOgMq1tTUed4qy6ZgNAe2Ze2xERZA7CyTgW5Bw3XZbwSeJe8lfDHZIkw8Hwd/6hI3p0NQ== +autoprefixer@9.8.4, autoprefixer@^9.8.0: + version "9.8.4" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.4.tgz#736f1012673a70fa3464671d78d41abd54512863" + integrity sha512-84aYfXlpUe45lvmS+HoAWKCkirI/sw4JK0/bTeeqgHYco3dcsOn0NqdejISjptsYwNji/21dnkDri9PsYKk89A== dependencies: browserslist "^4.12.0" - caniuse-lite "^1.0.30001084" - kleur "^4.0.1" + caniuse-lite "^1.0.30001087" + colorette "^1.2.0" normalize-range "^0.1.2" num2fraction "^1.2.2" postcss "^7.0.32" @@ -2867,10 +2874,10 @@ babel-plugin-macros@^2.0.0: cosmiconfig "^5.2.0" resolve "^1.10.0" -babel-plugin-react-intl@7.5.21: - version "7.5.21" - resolved "https://registry.yarnpkg.com/babel-plugin-react-intl/-/babel-plugin-react-intl-7.5.21.tgz#03a2ccd0b283a7a10aaf06924f83edbe15bcda8b" - integrity sha512-JfMEVlHQ7jorh4hi7bq2db075vaUtbRrPf6+msAUw22E9xqG7PlGbenoAss9EioSt4zhJIotzhHefeWe6VcT7Q== +babel-plugin-react-intl@7.5.24: + version "7.5.24" + resolved "https://registry.yarnpkg.com/babel-plugin-react-intl/-/babel-plugin-react-intl-7.5.24.tgz#23bb9719adc66030131e285ec45b2e3ce49bd2ea" + integrity sha512-U/zhokfHp+XRvZkqfpqucDkAZAtb+N1YqChTGQwIgK8Te/Zghh7bcXGvOBq1TXp/xQsDR4OP7+GKUOZ8qSvNng== dependencies: "@babel/core" "^7.9.0" "@babel/helper-plugin-utils" "^7.8.3" @@ -2879,7 +2886,7 @@ babel-plugin-react-intl@7.5.21: "@types/fs-extra" "^8.1.0" "@types/schema-utils" "^2.4.0" fs-extra "^9.0.0" - intl-messageformat-parser "^5.1.4" + intl-messageformat-parser "^5.2.0" schema-utils "^2.6.6" babel-plugin-syntax-jsx@^6.18.0: @@ -3447,10 +3454,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000792, caniuse-lite@^1.0.30000805, caniuse-lite@^1.0.30001043, caniuse-lite@^1.0.30001084: - version "1.0.30001084" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001084.tgz#00e471931eaefbeef54f46aa2203914d3c165669" - integrity sha512-ftdc5oGmhEbLUuMZ/Qp3mOpzfZLCxPYKcvGv6v2dJJ+8EdqcvZRbAGOiLmkM/PV1QGta/uwBs8/nCl6sokDW6w== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000792, caniuse-lite@^1.0.30000805, caniuse-lite@^1.0.30001043, caniuse-lite@^1.0.30001087: + version "1.0.30001090" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001090.tgz#ff7766332f60e80fea4903f30d360622e5551850" + integrity sha512-QzPRKDCyp7RhjczTPZaqK3CjPA5Ht2UnXhZhCI4f7QiB5JK6KEuZBxIzyWnB3wO4hgAj4GMRxAhuiacfw0Psjg== caseless@~0.12.0: version "0.12.0" @@ -3605,6 +3612,11 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +cldr-core@36.0.0: + version "36.0.0" + resolved "https://registry.yarnpkg.com/cldr-core/-/cldr-core-36.0.0.tgz#1d2148ed6802411845baeeb21432d7bbfde7d4f7" + integrity sha512-QLnAjt20rZe38c8h8OJ9jPND+O4o5O8Nw0TK/P3KpNn1cmOhMu0rk6Kc3ap96c5OStQ9gAngs9+Be2sum26NOw== + clean-stack@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" @@ -3802,6 +3814,11 @@ color@^2.0.1: color-convert "^1.9.1" color-string "^1.5.2" +colorette@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.0.tgz#45306add826d196e8c87236ac05d797f25982e63" + integrity sha512-soRSroY+OF/8OdA3PTQXwaDJeMc7TfknKKrxeSCencL2a4+Tx5zhxmmv7hdpCjhKBjehzp8+bwe/T68K0hpIjw== + colors@^1.1.2, colors@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" @@ -5412,10 +5429,10 @@ eslint-plugin-babel@5.3.0: dependencies: eslint-rule-composer "^0.3.0" -eslint-plugin-import@2.21.2: - version "2.21.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.21.2.tgz#8fef77475cc5510801bedc95f84b932f7f334a7c" - integrity sha512-FEmxeGI6yaz+SnEB6YgNHlQK1Bs2DKLM+YF+vuTk5H8J9CLbJLtlPvRFgZZ2+sXiKAlN5dpdlrWOjK8ZoZJpQA== +eslint-plugin-import@2.22.0: + version "2.22.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.22.0.tgz#92f7736fe1fde3e2de77623c838dd992ff5ffb7e" + integrity sha512-66Fpf1Ln6aIS5Gr/55ts19eUuoDhAbZgnr6UxK5hbDx6l/QgQgx61AePq+BV4PP2uXQFClgMVzep5zZ94qqsxg== dependencies: array-includes "^3.1.1" array.prototype.flat "^1.2.3" @@ -5431,10 +5448,10 @@ eslint-plugin-import@2.21.2: resolve "^1.17.0" tsconfig-paths "^3.9.0" -eslint-plugin-jsdoc@28.0.0: - version "28.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-28.0.0.tgz#e726a79b4a0e16e8602022d55e0e705e91dc0f50" - integrity sha512-Etne7B8AQcgXrnDPXdfV4x+szHVEP+JVZ2cYNfZGn+HoaZigIOzxxJGU+QUhymz6vuz0fpzFM6fTt64XOvw69w== +eslint-plugin-jsdoc@28.5.1: + version "28.5.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-28.5.1.tgz#5a95ee8705af389ba2062a1036be6077b5e62f3f" + integrity sha512-1XSWu8UnGwqO8mX3XKGofffL83VRt00ptq0m5OrTLFDN3At4x+/pJ8YHJONKhGC35TtjskcS9/RR6F9pjQ8c+w== dependencies: comment-parser "^0.7.5" debug "^4.1.1" @@ -5527,10 +5544,10 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.2 resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.2.0.tgz#74415ac884874495f78ec2a97349525344c981fa" integrity sha512-WFb4ihckKil6hu3Dp798xdzSfddwKKU3+nGniKF6HfeW6OLd2OUDEPP7TcHtB5+QXOKg2s6B2DaMPE1Nn/kxKQ== -eslint@7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.3.0.tgz#f9f1fc3dc1227985d0db88769f2bbac7b4b875d7" - integrity sha512-dJMVXwfU5PT1cj2Nv2VPPrKahKTGdX+5Dh0Q3YuKt+Y2UhdL2YbzsVaBMyG9HC0tBismlv/r1+eZqs6SMIV38Q== +eslint@7.3.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.3.1.tgz#76392bd7e44468d046149ba128d1566c59acbe19" + integrity sha512-cQC/xj9bhWUcyi/RuMbRtC3I0eW8MH0jhRELSvpKYkWep3C6YZ2OkvcvJVUeO6gcunABmzptbXBuDoXsjHmfTA== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.10.0" @@ -7207,25 +7224,25 @@ interpret@~1.1.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" integrity sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ= -intl-format-cache@^4.2.38: - version "4.2.38" - resolved "https://registry.yarnpkg.com/intl-format-cache/-/intl-format-cache-4.2.38.tgz#36de38f45d6881d6566e7a1c45f971ad39ab1c56" - integrity sha512-2jezJUaVUcNfgdllfjnZIkIrweLpMwouT4rTSyUk2Ig/6+O7PjZQPIIwkywSjnwVpTAXBj5VEkig+4z+c4trjg== +intl-format-cache@^4.2.42: + version "4.2.42" + resolved "https://registry.yarnpkg.com/intl-format-cache/-/intl-format-cache-4.2.42.tgz#8fc1de0fe72764d05b339a71b7ee0517c5ef0757" + integrity sha512-NJldCapugigFv1yAyqsY8jDdHFIJU427Ko47xf4yg2qLj4TtBA0d9lwqFnP5s9WOLJoNP/4ddu85B3ix0c5R7Q== -intl-messageformat-parser@^5.1.3, intl-messageformat-parser@^5.1.4: - version "5.1.4" - resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-5.1.4.tgz#53b8a2bbe2b615c5d3d643ad8beba024d8bb1554" - integrity sha512-q0SRG8eSbQ1ET1heE9DjyvzFjMALrAN84G5Xx02R7ArpSeRpXn5347++akxCJL7tgpF1csrlYlqiizHzjGIX0Q== +intl-messageformat-parser@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-5.2.0.tgz#c9b0cb60dbd327c4ed93f24db7d1806cd45f4769" + integrity sha512-SNEyrrDkkSVUfnt+b+RCwn2rq5cMz7hZIJvn76ot0CcoRMIm8i9rU4Rpy6xUM8oayJyD1ayQYVjjeC1+Qea6Aw== dependencies: - "@formatjs/intl-numberformat" "^4.2.7" + "@formatjs/intl-numberformat" "^4.2.10" -intl-messageformat@^8.3.23: - version "8.3.23" - resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-8.3.23.tgz#139c79db5e58dd5bd28c963eae1d05ad23fe940b" - integrity sha512-km3/LXz/fggXSbY/Ew6IKsL47v3gBrDDd0QYtesTaxK1zeRLrBwJksXmk4R4dJua9P8zGLT+wBsao4UvViKkVA== +intl-messageformat@^8.4.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-8.4.0.tgz#e41466135330b168b3df7cc1e8dd5c616d97faa3" + integrity sha512-1W1lLNuf11qCg8pRHwINvvCHu1sa8vS9ZbIKP0qv5E/wfx1NvIPx4e4FPa/LCfsT4cz/Ifh1MeMW6Sb3HJgOhg== dependencies: - intl-format-cache "^4.2.38" - intl-messageformat-parser "^5.1.3" + intl-format-cache "^4.2.42" + intl-messageformat-parser "^5.2.0" invariant@^2.2.2, invariant@^2.2.4: version "2.2.4" @@ -8112,11 +8129,6 @@ kind-of@^6.0.3: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== -kleur@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.0.1.tgz#3d4948534b666e2578f93b6fafb62108e64f05ef" - integrity sha512-Qs6SqCLm63rd0kNVh+wO4XsWLU6kgfwwaPYsLiClWf0Tewkzsa6MvB21bespb8cz+ANS+2t3So1ge3gintzhlw== - knockout@3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/knockout/-/knockout-3.5.1.tgz#62c81e81843bea2008fd23c575edd9ca978e75cf" @@ -10941,22 +10953,23 @@ react-intl-po@2.2.2: po2json "^0.4.5" ramda "^0.25.0" -react-intl@4.6.9: - version "4.6.9" - resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-4.6.9.tgz#1a8bd689f9610b5bef41d24b9cd4e3997767e2a9" - integrity sha512-2LNXxCVWFm1dz9C+gsOkbS1mIVeANUXA9Qc7vFOOZVEOHOtpSMfPI2FXHINBOSi4Vk4UTlmfgSzfTik6EMtb+Q== - dependencies: - "@formatjs/intl-displaynames" "^2.2.6" - "@formatjs/intl-listformat" "^2.2.6" - "@formatjs/intl-numberformat" "^4.2.6" - "@formatjs/intl-relativetimeformat" "^5.2.6" - "@formatjs/intl-utils" "^3.3.1" +react-intl@4.7.5: + version "4.7.5" + resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-4.7.5.tgz#f8b70db030270289904d19c724668ef69a4641ed" + integrity sha512-JaLV4cPo4eo/oVNJI0cfeCGn15RLFjS6ImpnCr1MKWBXxFHJhCNs00OGikI9/M01u8oBEYebQkqE7PkN+1NjZg== + dependencies: + "@formatjs/intl-datetimeformat" "^1.3.2" + "@formatjs/intl-displaynames" "^2.2.8" + "@formatjs/intl-listformat" "^2.2.8" + "@formatjs/intl-numberformat" "^4.2.10" + "@formatjs/intl-relativetimeformat" "^5.2.10" + "@formatjs/intl-utils" "^3.4.1" "@types/hoist-non-react-statics" "^3.3.1" "@types/invariant" "^2.2.31" hoist-non-react-statics "^3.3.2" - intl-format-cache "^4.2.38" - intl-messageformat "^8.3.23" - intl-messageformat-parser "^5.1.3" + intl-format-cache "^4.2.42" + intl-messageformat "^8.4.0" + intl-messageformat-parser "^5.2.0" shallow-equal "^1.2.1" react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.6, react-is@^16.9.0: @@ -11982,12 +11995,13 @@ simple-get@^3.0.3: once "^1.3.1" simple-concat "^1.0.0" -simple-git@2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-2.9.0.tgz#060f87e2d81235f01200d4596b3397a458d76fbe" - integrity sha512-rDnsMqvvk2pF7+ID8v7GtzdaXlCJfz1qFIuiQ8fcmCaqm7MITXoOx294ymSzMP0D7IC27kA5WLskkl4ZpauYNQ== +simple-git@2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-2.11.0.tgz#5bd99fe3465dcbcb82f0eb23ab3c1615cb947374" + integrity sha512-wFePCEQYY6BzVOg/BuUVEhr3jZPF/cPG/BN2UXgax6NHc3bJ9UrDc5AME281gs2C7J1UZ6BGRJYT64khx9T+ng== dependencies: "@kwsites/file-exists" "^1.1.1" + "@kwsites/promise-deferred" "^1.0.1" debug "^4.1.1" simple-html-tokenizer@^0.1.1: @@ -12002,10 +12016,10 @@ simple-swizzle@^0.2.2: dependencies: is-arrayish "^0.3.1" -simplebar@5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/simplebar/-/simplebar-5.2.0.tgz#032e6e435032a0a6f26146f190bdd1095d5a9d2f" - integrity sha512-CpVSINCQ/XAYABUdUAnVWHyjkBYoFu+s12IUrZgVNfXzILNXP0MP+5OaIBjylzjYxIE/rsuC1K50/xJldPGGpQ== +simplebar@5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/simplebar/-/simplebar-5.2.1.tgz#b373841d10df1827562481306a51dae9062734d6" + integrity sha512-nfOsptB/tb1kzSOaDIJFcrm8EXj5J0pZBPLGetJR8SE6v+97cbedtlNH/L81okgjsFlF11kDndmZ0mscaGAILw== dependencies: can-use-dom "^0.1.0" core-js "^3.0.1"