diff --git a/app/authorization/client/startup.js b/app/authorization/client/startup.js index 5f26b56bbdf4e..a9cf0250f45c2 100644 --- a/app/authorization/client/startup.js +++ b/app/authorization/client/startup.js @@ -13,9 +13,10 @@ Meteor.startup(() => { CachedCollectionManager.onLogin(async () => { const { roles } = await APIClient.v1.get('roles.list'); // if a role is checked before this collection is populated, it will return undefined - for await (const role of roles) { - await Roles.upsert({ _id: role._id }, role); - } + Roles._collection._docs._map = Object.fromEntries(roles.map((record) => [record._id, record])); + Object.values(Roles._collection.queries).forEach((query) => Roles._collection._recomputeResults(query)); + + Roles.ready.set(true); }); registerAdminSidebarItem({ diff --git a/app/lib/client/lib/settings.js b/app/lib/client/lib/settings.js index 62806990bd6ad..5d909e0a2d395 100644 --- a/app/lib/client/lib/settings.js +++ b/app/lib/client/lib/settings.js @@ -1,48 +1,58 @@ import { Meteor } from 'meteor/meteor'; import { Tracker } from 'meteor/tracker'; +import toastr from 'toastr'; import { t } from '../../../utils'; -import { modal } from '../../../ui-utils'; import { settings } from '../../../settings'; import { hasRole } from '../../../authorization'; +import { Roles } from '../../../models/client'; +import { imperativeModal } from '../../../../client/lib/imperativeModal'; +import UrlChangeModal from '../../../../client/components/UrlChangeModal'; +import { isSyncReady } from '../../../../client/lib/userData'; Meteor.startup(function() { Tracker.autorun(function(c) { - const siteUrl = settings.get('Site_Url'); - if (!siteUrl || (Meteor.userId() == null)) { + if (!Meteor.userId()) { + return; + } + + if (!Roles.ready.get() || !isSyncReady.get()) { return; } + if (hasRole(Meteor.userId(), 'admin') === false) { return c.stop(); } - Meteor.setTimeout(function() { - const currentUrl = location.origin + __meteor_runtime_config__.ROOT_URL_PATH_PREFIX; - if (__meteor_runtime_config__.ROOT_URL.replace(/\/$/, '') !== currentUrl) { - modal.open({ - type: 'warning', - title: t('Warning'), - text: `${ t('The_setting_s_is_configured_to_s_and_you_are_accessing_from_s', t('Site_Url'), siteUrl, currentUrl) }

${ t('Do_you_want_to_change_to_s_question', currentUrl) }`, - showCancelButton: true, - confirmButtonText: t('Yes'), - cancelButtonText: t('Cancel'), - closeOnConfirm: false, - html: true, - }, function() { - Meteor.call('saveSetting', 'Site_Url', currentUrl, function() { - modal.open({ - title: t('Saved'), - type: 'success', - timer: 1000, - showConfirmButton: false, - }); - }); + + const siteUrl = settings.get('Site_Url'); + if (!siteUrl) { + return; + } + + const currentUrl = location.origin + __meteor_runtime_config__.ROOT_URL_PATH_PREFIX; + if (__meteor_runtime_config__.ROOT_URL.replace(/\/$/, '') !== currentUrl) { + const confirm = () => { + imperativeModal.close(); + Meteor.call('saveSetting', 'Site_Url', currentUrl, function() { + toastr.success(t('Saved')); }); - } - }, 100); + }; + imperativeModal.open({ + component: UrlChangeModal, + props: { + onConfirm: confirm, + siteUrl, + currentUrl, + onClose: imperativeModal.close, + }, + }); + } + const documentDomain = settings.get('Document_Domain'); if (documentDomain) { window.document.domain = documentDomain; } + return c.stop(); }); }); diff --git a/app/models/client/models/Roles.js b/app/models/client/models/Roles.js index b0acacdfd1842..ed4ed9fc71e61 100644 --- a/app/models/client/models/Roles.js +++ b/app/models/client/models/Roles.js @@ -1,4 +1,5 @@ import { Mongo } from 'meteor/mongo'; +import { ReactiveVar } from 'meteor/reactive-var'; import * as Models from '..'; @@ -21,6 +22,8 @@ Object.assign(Roles, { return model && model.isUserInRole && model.isUserInRole(userId, roleName, scope); }); }, + + ready: new ReactiveVar(false), }); export { Roles }; diff --git a/client/components/UrlChangeModal.tsx b/client/components/UrlChangeModal.tsx new file mode 100644 index 0000000000000..df4db6caf581b --- /dev/null +++ b/client/components/UrlChangeModal.tsx @@ -0,0 +1,49 @@ +import { Box } from '@rocket.chat/fuselage'; +import React, { ReactElement } from 'react'; + +import { useTranslation } from '../contexts/TranslationContext'; +import GenericModal from './GenericModal'; + +type UrlChangeModalProps = { + onConfirm: () => void; + siteUrl: string; + currentUrl: string; + onClose: () => void; +}; + +const UrlChangeModal = ({ + onConfirm, + siteUrl, + currentUrl, + onClose, +}: UrlChangeModalProps): ReactElement => { + const t = useTranslation(); + return ( + + +

+ + ); +}; + +export default UrlChangeModal;