From 0ab30f88e628b38ea12e5d0475d2edb47a866d34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrique=20Guimar=C3=A3es=20Ribeiro?= Date: Mon, 9 Oct 2023 14:06:22 -0300 Subject: [PATCH 01/11] chore: Change Records page name to Reports (#30513) --- apps/meteor/client/views/admin/routes.tsx | 6 +++--- apps/meteor/client/views/admin/sidebarItems.ts | 4 ++-- .../meteor/client/views/admin/viewLogs/AnalyticsReports.tsx | 5 ++++- apps/meteor/client/views/admin/viewLogs/ViewLogsPage.tsx | 2 +- apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json | 6 +++--- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/apps/meteor/client/views/admin/routes.tsx b/apps/meteor/client/views/admin/routes.tsx index a25bea5affaa..bea10777d66b 100644 --- a/apps/meteor/client/views/admin/routes.tsx +++ b/apps/meteor/client/views/admin/routes.tsx @@ -70,8 +70,8 @@ declare module '@rocket.chat/ui-contexts' { pattern: '/admin/registration/:page?'; }; 'admin-view-logs': { - pathname: '/admin/records'; - pattern: '/admin/records'; + pathname: '/admin/reports'; + pattern: '/admin/reports'; }; 'federation-dashboard': { pathname: '/admin/federation'; @@ -193,7 +193,7 @@ registerAdminRoute('/registration/:page?', { component: lazy(() => import('./cloud/CloudRoute')), }); -registerAdminRoute('/records', { +registerAdminRoute('/reports', { name: 'admin-view-logs', component: lazy(() => import('./viewLogs/ViewLogsRoute')), }); diff --git a/apps/meteor/client/views/admin/sidebarItems.ts b/apps/meteor/client/views/admin/sidebarItems.ts index 50a3284b5ed1..2beee76cee02 100644 --- a/apps/meteor/client/views/admin/sidebarItems.ts +++ b/apps/meteor/client/views/admin/sidebarItems.ts @@ -112,8 +112,8 @@ export const { permissionGranted: (): boolean => hasPermission('run-import'), }, { - href: '/admin/records', - i18nLabel: 'Records', + href: '/admin/reports', + i18nLabel: 'Reports', icon: 'post', permissionGranted: (): boolean => hasPermission('view-logs'), }, diff --git a/apps/meteor/client/views/admin/viewLogs/AnalyticsReports.tsx b/apps/meteor/client/views/admin/viewLogs/AnalyticsReports.tsx index 7771298ceb73..cd300c14a481 100644 --- a/apps/meteor/client/views/admin/viewLogs/AnalyticsReports.tsx +++ b/apps/meteor/client/views/admin/viewLogs/AnalyticsReports.tsx @@ -18,7 +18,10 @@ const AnalyticsReports = () => { {t('How_and_why_we_collect_usage_data')} - {t('Analytics_page_briefing')} + + {t('Analytics_page_briefing_first_paragraph')} + + {t('Analytics_page_briefing_second_paragraph')} {isSuccess &&
{JSON.stringify(data, null, '\t')}
} diff --git a/apps/meteor/client/views/admin/viewLogs/ViewLogsPage.tsx b/apps/meteor/client/views/admin/viewLogs/ViewLogsPage.tsx index 4463fec8f5bf..2c1613f3ef74 100644 --- a/apps/meteor/client/views/admin/viewLogs/ViewLogsPage.tsx +++ b/apps/meteor/client/views/admin/viewLogs/ViewLogsPage.tsx @@ -14,7 +14,7 @@ const ViewLogsPage = (): ReactElement => { return ( - + setTab('Logs')} selected={tab === 'Logs'}> diff --git a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json index 91993ff443fb..b1ac03bd7df7 100644 --- a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json @@ -424,7 +424,8 @@ "Analytics_features_users_Description": "Tracks custom events related to actions related to users (password reset times, profile picture change, etc).", "Analytics_Google": "Google Analytics", "Analytics_Google_id": "Tracking ID", - "Analytics_page_briefing": "Rocket.Chat collects anonymous usage data to identify how many instances are deployed and to improve the product for all users. We take your privacy seriously, so the usage data is encrypted and stored securely.", + "Analytics_page_briefing_first_paragraph": "Rocket.Chat collects anonymous usage data, such as feature usage and session lengths, to improve the product for everyone.", + "Analytics_page_briefing_second_paragraph": "We protect your privacy by never collecting personal or sensitive data. This section shows what is collected, reinforcing our commitment to transparency and trust.", "Analyze_practical_usage": "Analyze practical usage statistics about users, messages and channels", "and": "and", "And_more": "And {{length}} more", @@ -2484,7 +2485,7 @@ "Hospitality_Businness": "Hospitality Business", "hours": "hours", "Hours": "Hours", - "How_and_why_we_collect_usage_data": "How and why we collect usage data", + "How_and_why_we_collect_usage_data": "How and why usage data is collected", "How_friendly_was_the_chat_agent": "How friendly was the chat agent?", "How_knowledgeable_was_the_chat_agent": "How knowledgeable was the chat agent?", "How_long_to_wait_after_agent_goes_offline": "How Long to Wait After Agent Goes Offline", @@ -4182,7 +4183,6 @@ "Receive_Login_Detection_Emails_Description": "Receive an email each time a new login is detected on your account.", "Recent_Import_History": "Recent Import History", "Record": "Record", - "Records": "Records", "recording": "recording", "Redirect_URI": "Redirect URI", "Redirect_URL_does_not_match": "Redirect URL does not match", From a58f2a707b6f0933f7ecd263745ab3d0c49d0027 Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Mon, 9 Oct 2023 11:21:09 -0600 Subject: [PATCH 02/11] regression: Undefined MAC count on startup cloud sync (#30605) --- apps/meteor/app/cloud/server/functions/buildRegistrationData.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/meteor/app/cloud/server/functions/buildRegistrationData.ts b/apps/meteor/app/cloud/server/functions/buildRegistrationData.ts index f887c9e6395c..c2bd91e82dd8 100644 --- a/apps/meteor/app/cloud/server/functions/buildRegistrationData.ts +++ b/apps/meteor/app/cloud/server/functions/buildRegistrationData.ts @@ -89,7 +89,7 @@ export async function buildWorkspaceRegistrationData Date: Mon, 9 Oct 2023 14:33:45 -0300 Subject: [PATCH 03/11] chore: Improve cache of static files (#30290) --- .changeset/wicked-humans-hang.md | 5 +++ apps/meteor/app/cors/server/cors.ts | 41 +++++++++++++++++++ .../custom-sounds/client/lib/CustomSounds.ts | 29 ++++++------- apps/meteor/app/ui-master/server/inject.ts | 24 +++++++---- apps/meteor/app/utils/client/getURL.ts | 6 +++ 5 files changed, 84 insertions(+), 21 deletions(-) create mode 100644 .changeset/wicked-humans-hang.md diff --git a/.changeset/wicked-humans-hang.md b/.changeset/wicked-humans-hang.md new file mode 100644 index 000000000000..e793bc978902 --- /dev/null +++ b/.changeset/wicked-humans-hang.md @@ -0,0 +1,5 @@ +--- +"@rocket.chat/meteor": patch +--- + +Improve cache of static files diff --git a/apps/meteor/app/cors/server/cors.ts b/apps/meteor/app/cors/server/cors.ts index 03a42e45a17b..cb6fa94273a2 100644 --- a/apps/meteor/app/cors/server/cors.ts +++ b/apps/meteor/app/cors/server/cors.ts @@ -1,4 +1,6 @@ +import { createHash } from 'crypto'; import type http from 'http'; +import type { UrlWithParsedQuery } from 'url'; import url from 'url'; import { Logger } from '@rocket.chat/logger'; @@ -77,6 +79,19 @@ WebApp.rawConnectHandlers.use((_req: http.IncomingMessage, res: http.ServerRespo }); const _staticFilesMiddleware = WebAppInternals.staticFilesMiddleware; +declare module 'meteor/webapp' { + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace WebApp { + function categorizeRequest( + req: http.IncomingMessage, + ): { arch: string; path: string; url: UrlWithParsedQuery } & Record; + } +} + +// These routes already handle cache control on their own +const cacheControlledRoutes: Array = ['/assets', '/custom-sounds', '/emoji-custom', '/avatar', '/file-upload'].map( + (route) => new RegExp(`^${route}`, 'i'), +); // @ts-expect-error - accessing internal property of webapp WebAppInternals.staticFilesMiddleware = function ( @@ -86,6 +101,32 @@ WebAppInternals.staticFilesMiddleware = function ( next: NextFunction, ) { res.setHeader('Access-Control-Allow-Origin', '*'); + const { arch, path, url } = WebApp.categorizeRequest(req); + + if (Meteor.isProduction && !cacheControlledRoutes.some((regexp) => regexp.test(path))) { + res.setHeader('Cache-Control', 'public, max-age=31536000'); + } + + // Prevent meteor_runtime_config.js to load from a different expected hash possibly causing + // a cache of the file for the wrong hash and start a client loop due to the mismatch + // of the hashes of ui versions which would be checked against a websocket response + if (path === '/meteor_runtime_config.js') { + const program = WebApp.clientPrograms[arch] as (typeof WebApp.clientPrograms)[string] & { + meteorRuntimeConfigHash?: string; + meteorRuntimeConfig: string; + }; + + if (!program?.meteorRuntimeConfigHash) { + program.meteorRuntimeConfigHash = createHash('sha1') + .update(JSON.stringify(encodeURIComponent(program.meteorRuntimeConfig))) + .digest('hex'); + } + + if (program.meteorRuntimeConfigHash !== url.query.hash) { + res.writeHead(404); + return res.end(); + } + } return _staticFilesMiddleware(staticFiles, req, res, next); }; diff --git a/apps/meteor/app/custom-sounds/client/lib/CustomSounds.ts b/apps/meteor/app/custom-sounds/client/lib/CustomSounds.ts index a4f59136a1f9..f881c15f9886 100644 --- a/apps/meteor/app/custom-sounds/client/lib/CustomSounds.ts +++ b/apps/meteor/app/custom-sounds/client/lib/CustomSounds.ts @@ -7,21 +7,22 @@ import { getURL } from '../../../utils/client'; import { sdk } from '../../../utils/client/lib/SDKClient'; const getCustomSoundId = (soundId: ICustomSound['_id']) => `custom-sound-${soundId}`; +const getAssetUrl = (asset: string, params?: Record) => getURL(asset, params, undefined, true); const defaultSounds = [ - { _id: 'chime', name: 'Chime', extension: 'mp3', src: getURL('sounds/chime.mp3') }, - { _id: 'door', name: 'Door', extension: 'mp3', src: getURL('sounds/door.mp3') }, - { _id: 'beep', name: 'Beep', extension: 'mp3', src: getURL('sounds/beep.mp3') }, - { _id: 'chelle', name: 'Chelle', extension: 'mp3', src: getURL('sounds/chelle.mp3') }, - { _id: 'ding', name: 'Ding', extension: 'mp3', src: getURL('sounds/ding.mp3') }, - { _id: 'droplet', name: 'Droplet', extension: 'mp3', src: getURL('sounds/droplet.mp3') }, - { _id: 'highbell', name: 'Highbell', extension: 'mp3', src: getURL('sounds/highbell.mp3') }, - { _id: 'seasons', name: 'Seasons', extension: 'mp3', src: getURL('sounds/seasons.mp3') }, - { _id: 'telephone', name: 'Telephone', extension: 'mp3', src: getURL('sounds/telephone.mp3') }, - { _id: 'outbound-call-ringing', name: 'Outbound Call Ringing', extension: 'mp3', src: getURL('sounds/outbound-call-ringing.mp3') }, - { _id: 'call-ended', name: 'Call Ended', extension: 'mp3', src: getURL('sounds/call-ended.mp3') }, - { _id: 'dialtone', name: 'Dialtone', extension: 'mp3', src: getURL('sounds/dialtone.mp3') }, - { _id: 'ringtone', name: 'Ringtone', extension: 'mp3', src: getURL('sounds/ringtone.mp3') }, + { _id: 'chime', name: 'Chime', extension: 'mp3', src: getAssetUrl('sounds/chime.mp3') }, + { _id: 'door', name: 'Door', extension: 'mp3', src: getAssetUrl('sounds/door.mp3') }, + { _id: 'beep', name: 'Beep', extension: 'mp3', src: getAssetUrl('sounds/beep.mp3') }, + { _id: 'chelle', name: 'Chelle', extension: 'mp3', src: getAssetUrl('sounds/chelle.mp3') }, + { _id: 'ding', name: 'Ding', extension: 'mp3', src: getAssetUrl('sounds/ding.mp3') }, + { _id: 'droplet', name: 'Droplet', extension: 'mp3', src: getAssetUrl('sounds/droplet.mp3') }, + { _id: 'highbell', name: 'Highbell', extension: 'mp3', src: getAssetUrl('sounds/highbell.mp3') }, + { _id: 'seasons', name: 'Seasons', extension: 'mp3', src: getAssetUrl('sounds/seasons.mp3') }, + { _id: 'telephone', name: 'Telephone', extension: 'mp3', src: getAssetUrl('sounds/telephone.mp3') }, + { _id: 'outbound-call-ringing', name: 'Outbound Call Ringing', extension: 'mp3', src: getAssetUrl('sounds/outbound-call-ringing.mp3') }, + { _id: 'call-ended', name: 'Call Ended', extension: 'mp3', src: getAssetUrl('sounds/call-ended.mp3') }, + { _id: 'dialtone', name: 'Dialtone', extension: 'mp3', src: getAssetUrl('sounds/dialtone.mp3') }, + { _id: 'ringtone', name: 'Ringtone', extension: 'mp3', src: getAssetUrl('sounds/ringtone.mp3') }, ]; class CustomSoundsClass { @@ -85,7 +86,7 @@ class CustomSoundsClass { } getURL(sound: ICustomSound) { - return getURL(`/custom-sounds/${sound._id}.${sound.extension}?_dc=${sound.random || 0}`); + return getAssetUrl(`/custom-sounds/${sound._id}.${sound.extension}`, { _dc: sound.random || 0 }); } getList() { diff --git a/apps/meteor/app/ui-master/server/inject.ts b/apps/meteor/app/ui-master/server/inject.ts index 78112bcee343..1e00a0e47433 100644 --- a/apps/meteor/app/ui-master/server/inject.ts +++ b/apps/meteor/app/ui-master/server/inject.ts @@ -32,7 +32,7 @@ const callback: NextHandleFunction = (req, res, next) => { return; } - const injection = headInjections.get(pathname.replace(/^\//, '')) as Injection | undefined; + const injection = headInjections.get(pathname.replace(/^\//, '').split('_')[0]) as Injection | undefined; if (!injection || typeof injection === 'string') { next(); @@ -76,27 +76,37 @@ export const injectIntoHead = (key: string, value: Injection): void => { }; export const addScript = (key: string, content: string): void => { + if (/_/.test(key)) { + throw new Error('inject.js > addScript - key cannot contain "_" (underscore)'); + } + if (!content.trim()) { - injectIntoHead(`${key}.js`, ''); + injectIntoHead(key, ''); return; } const currentHash = crypto.createHash('sha1').update(content).digest('hex'); - injectIntoHead(`${key}.js`, { + + injectIntoHead(key, { type: 'JS', - tag: ``, + tag: ``, content, }); }; export const addStyle = (key: string, content: string): void => { + if (/_/.test(key)) { + throw new Error('inject.js > addStyle - key cannot contain "_" (underscore)'); + } + if (!content.trim()) { - injectIntoHead(`${key}.css`, ''); + injectIntoHead(key, ''); return; } const currentHash = crypto.createHash('sha1').update(content).digest('hex'); - injectIntoHead(`${key}.css`, { + + injectIntoHead(key, { type: 'CSS', - tag: ``, + tag: ``, content, }); }; diff --git a/apps/meteor/app/utils/client/getURL.ts b/apps/meteor/app/utils/client/getURL.ts index 91ef0989bd19..040b6dfa9dc2 100644 --- a/apps/meteor/app/utils/client/getURL.ts +++ b/apps/meteor/app/utils/client/getURL.ts @@ -1,13 +1,19 @@ import { settings } from '../../settings/client'; import { getURLWithoutSettings } from '../lib/getURL'; +import { Info } from '../rocketchat.info'; export const getURL = function ( path: string, // eslint-disable-next-line @typescript-eslint/naming-convention params: Record = {}, cloudDeepLinkUrl?: string, + cacheKey?: boolean, ): string { const cdnPrefix = settings.get('CDN_PREFIX') || ''; const siteUrl = settings.get('Site_Url') || ''; + if (cacheKey) { + path += `${path.includes('?') ? '&' : '?'}cacheKey=${Info.version}`; + } + return getURLWithoutSettings(path, params, cdnPrefix, siteUrl, cloudDeepLinkUrl); }; From 06a8e302890c15b29c29a483d5eab8675f0447dc Mon Sep 17 00:00:00 2001 From: csuadev <72958726+csuadev@users.noreply.github.com> Date: Mon, 9 Oct 2023 13:25:57 -0500 Subject: [PATCH 04/11] chore: Change plan name Enterprise to Premium on marketplace (#30487) --- .changeset/odd-hounds-thank.md | 5 +++++ .../GenericUpsellModal/GenericUpsellModal.tsx | 2 +- .../views/marketplace/AppsPage/AppsFilters.tsx | 2 +- .../marketplace/AppsPage/AppsPageContent.tsx | 4 ++-- .../client/views/marketplace/BundleChips.tsx | 8 ++++---- .../marketplace/components/EnabledAppsCount.tsx | 2 +- .../marketplace/components/MarketplaceHeader.tsx | 2 +- .../client/views/marketplace/hooks/useAppInfo.ts | 2 +- .../views/marketplace/hooks/useAppsCountQuery.ts | 4 ++-- .../views/marketplace/hooks/useFilteredApps.ts | 4 ++-- .../client/views/marketplace/sidebarItems.tsx | 4 ++-- .../packages/rocketchat-i18n/i18n/en.i18n.json | 16 ++++++++++------ 12 files changed, 32 insertions(+), 23 deletions(-) create mode 100644 .changeset/odd-hounds-thank.md diff --git a/.changeset/odd-hounds-thank.md b/.changeset/odd-hounds-thank.md new file mode 100644 index 000000000000..aaddc5d51a38 --- /dev/null +++ b/.changeset/odd-hounds-thank.md @@ -0,0 +1,5 @@ +--- +"@rocket.chat/meteor": patch +--- + +chore: Change plan name Enterprise to Premium on marketplace diff --git a/apps/meteor/client/components/GenericUpsellModal/GenericUpsellModal.tsx b/apps/meteor/client/components/GenericUpsellModal/GenericUpsellModal.tsx index ec9f852c8a8b..513b31dd81fa 100644 --- a/apps/meteor/client/components/GenericUpsellModal/GenericUpsellModal.tsx +++ b/apps/meteor/client/components/GenericUpsellModal/GenericUpsellModal.tsx @@ -42,7 +42,7 @@ const GenericUpsellModal = ({ {icon && } - {tagline ?? t('Enterprise_capability')} + {tagline ?? t('Premium_capability')} {title} diff --git a/apps/meteor/client/views/marketplace/AppsPage/AppsFilters.tsx b/apps/meteor/client/views/marketplace/AppsPage/AppsFilters.tsx index 2fdbffda7d4d..f1332284c97f 100644 --- a/apps/meteor/client/views/marketplace/AppsPage/AppsFilters.tsx +++ b/apps/meteor/client/views/marketplace/AppsPage/AppsFilters.tsx @@ -50,7 +50,7 @@ const AppsFilters = ({ const appsSearchPlaceholders: { [key: string]: string } = { explore: t('Search_Apps'), - enterprise: t('Search_Enterprise_Apps'), + enterprise: t('Search_Premium_Apps'), installed: t('Search_Installed_Apps'), requested: t('Search_Requested_Apps'), private: t('Search_Private_apps'), diff --git a/apps/meteor/client/views/marketplace/AppsPage/AppsPageContent.tsx b/apps/meteor/client/views/marketplace/AppsPage/AppsPageContent.tsx index 5b47634bff29..1bc7642e5afc 100644 --- a/apps/meteor/client/views/marketplace/AppsPage/AppsPageContent.tsx +++ b/apps/meteor/client/views/marketplace/AppsPage/AppsPageContent.tsx @@ -40,7 +40,7 @@ const AppsPageContent = (): ReactElement => { { id: 'all', label: t('All_Prices'), checked: true }, { id: 'free', label: t('Free_Apps'), checked: false }, { id: 'paid', label: t('Paid_Apps'), checked: false }, - { id: 'enterprise', label: t('Enterprise'), checked: false }, + { id: 'premium', label: t('Premium'), checked: false }, ], }); const freePaidFilterOnSelected = useRadioToggle(setFreePaidFilterStructure); @@ -89,7 +89,7 @@ const AppsPageContent = (): ReactElement => { const getAppsData = useCallback((): appsDataType => { switch (context) { - case 'enterprise': + case 'premium': case 'explore': case 'requested': return marketplaceApps; diff --git a/apps/meteor/client/views/marketplace/BundleChips.tsx b/apps/meteor/client/views/marketplace/BundleChips.tsx index 9f988534fe14..4e2953bd8519 100644 --- a/apps/meteor/client/views/marketplace/BundleChips.tsx +++ b/apps/meteor/client/views/marketplace/BundleChips.tsx @@ -18,15 +18,15 @@ const BundleChips = ({ bundledIn }: BundleChipsProps): ReactElement => { return ( <> - {bundledIn.map((bundle) => ( + {bundledIn.map(({ bundleId, bundleName }) => ( - {bundle.bundleName} + {bundleName} ))} diff --git a/apps/meteor/client/views/marketplace/components/EnabledAppsCount.tsx b/apps/meteor/client/views/marketplace/components/EnabledAppsCount.tsx index 72cfa5474346..da135cbdedfc 100644 --- a/apps/meteor/client/views/marketplace/components/EnabledAppsCount.tsx +++ b/apps/meteor/client/views/marketplace/components/EnabledAppsCount.tsx @@ -15,7 +15,7 @@ const EnabledAppsCount = ({ percentage: number; limit: number; enabled: number; - context: 'private' | 'explore' | 'installed' | 'enterprise' | 'requested'; + context: 'private' | 'explore' | 'installed' | 'premium' | 'requested'; }): ReactElement | null => { const t = useTranslation(); diff --git a/apps/meteor/client/views/marketplace/components/MarketplaceHeader.tsx b/apps/meteor/client/views/marketplace/components/MarketplaceHeader.tsx index f93cb1fcd339..7696801c3124 100644 --- a/apps/meteor/client/views/marketplace/components/MarketplaceHeader.tsx +++ b/apps/meteor/client/views/marketplace/components/MarketplaceHeader.tsx @@ -12,7 +12,7 @@ import EnabledAppsCount from './EnabledAppsCount'; const MarketplaceHeader = ({ title }: { title: string }): ReactElement | null => { const t = useTranslation(); const isAdmin = usePermission('manage-apps'); - const context = (useRouteParameter('context') || 'explore') as 'private' | 'explore' | 'installed' | 'enterprise' | 'requested'; + const context = (useRouteParameter('context') || 'explore') as 'private' | 'explore' | 'installed' | 'premium' | 'requested'; const route = useRoute('marketplace'); const setModal = useSetModal(); const result = useAppsCountQuery(context); diff --git a/apps/meteor/client/views/marketplace/hooks/useAppInfo.ts b/apps/meteor/client/views/marketplace/hooks/useAppInfo.ts index 7e69cdeef97c..44ab240ce7b3 100644 --- a/apps/meteor/client/views/marketplace/hooks/useAppInfo.ts +++ b/apps/meteor/client/views/marketplace/hooks/useAppInfo.ts @@ -36,7 +36,7 @@ export const useAppInfo = (appId: string, context: string): AppInfo | undefined } let appResult: App | undefined; - const marketplaceAppsContexts = ['explore', 'enterprise', 'requested']; + const marketplaceAppsContexts = ['explore', 'premium', 'requested']; if (marketplaceAppsContexts.includes(context)) appResult = marketplaceApps.value?.apps.find((app) => app.id === appId); diff --git a/apps/meteor/client/views/marketplace/hooks/useAppsCountQuery.ts b/apps/meteor/client/views/marketplace/hooks/useAppsCountQuery.ts index 10689c773479..a571eac3b71f 100644 --- a/apps/meteor/client/views/marketplace/hooks/useAppsCountQuery.ts +++ b/apps/meteor/client/views/marketplace/hooks/useAppsCountQuery.ts @@ -11,10 +11,10 @@ const getProgressBarValues = (numberOfEnabledApps: number, enabledAppsLimit: num percentage: Math.round((numberOfEnabledApps / enabledAppsLimit) * 100), }); -export type MarketplaceRouteContext = 'private' | 'explore' | 'installed' | 'enterprise' | 'requested'; +export type MarketplaceRouteContext = 'private' | 'explore' | 'installed' | 'premium' | 'requested'; export function isMarketplaceRouteContext(context: string): context is MarketplaceRouteContext { - return ['private', 'explore', 'installed', 'enterprise', 'requested'].includes(context); + return ['private', 'explore', 'installed', 'premium', 'requested'].includes(context); } export const useAppsCountQuery = (context: MarketplaceRouteContext) => { diff --git a/apps/meteor/client/views/marketplace/hooks/useFilteredApps.ts b/apps/meteor/client/views/marketplace/hooks/useFilteredApps.ts index 1027aae75a8a..221990f7af2a 100644 --- a/apps/meteor/client/views/marketplace/hooks/useFilteredApps.ts +++ b/apps/meteor/client/views/marketplace/hooks/useFilteredApps.ts @@ -66,7 +66,7 @@ export const useFilteredApps = ({ const filterByPurchaseType: Record App[]> = { all: fallback, paid: (apps: App[]) => apps.filter(filterAppsByPaid), - enterprise: (apps: App[]) => apps.filter(filterAppsByEnterprise), + premium: (apps: App[]) => apps.filter(filterAppsByEnterprise), free: (apps: App[]) => apps.filter(filterAppsByFree), }; @@ -80,7 +80,7 @@ export const useFilteredApps = ({ explore: fallback, installed: fallback, private: fallback, - enterprise: (apps: App[]) => apps.filter(({ categories }) => categories.includes('Enterprise')), + premium: (apps: App[]) => apps.filter(({ categories }) => categories.includes('Enterprise')), requested: (apps: App[]) => apps.filter(({ appRequestStats, installed }) => Boolean(appRequestStats) && !installed), }; diff --git a/apps/meteor/client/views/marketplace/sidebarItems.tsx b/apps/meteor/client/views/marketplace/sidebarItems.tsx index bafcc4e62c58..f829cccf3238 100644 --- a/apps/meteor/client/views/marketplace/sidebarItems.tsx +++ b/apps/meteor/client/views/marketplace/sidebarItems.tsx @@ -17,9 +17,9 @@ export const { permissionGranted: (): boolean => hasAtLeastOnePermission(['access-marketplace', 'manage-apps']), }, { - href: '/marketplace/enterprise', + href: '/marketplace/premium', icon: 'lightning', - i18nLabel: 'Enterprise', + i18nLabel: 'Premium', permissionGranted: (): boolean => hasAtLeastOnePermission(['access-marketplace', 'manage-apps']), }, { diff --git a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json index b1ac03bd7df7..d4b28724b6e2 100644 --- a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json @@ -531,6 +531,7 @@ "Apps_context_installed": "Installed", "Apps_context_requested": "Requested", "Apps_context_private": "Private Apps", + "Apps_context_premium": "Premium", "Apps_Count_Enabled": "{{count}} app enabled", "Apps_Count_Enabled_plural": "{{count}} apps enabled", "Private_Apps_Count_Enabled": "{{count}} private app enabled", @@ -4551,6 +4552,7 @@ "Search_Installed_Apps": "Search installed apps", "Search_Private_apps": "Search private apps", "Search_Requested_Apps": "Search requested apps", + "Search_Premium_Apps": "Search Premium apps", "Search_by_file_name": "Search by file name", "Search_by_username": "Search by username", "Search_by_category": "Search by category", @@ -5946,9 +5948,9 @@ "Theme_light_description": "More accessible for individuals with visual impairments and a good choice for well-lit environments.", "Theme_dark": "Dark", "Theme_dark_description": "Reduce eye strain and fatigue in low-light conditions by minimizing the amount of light emitted by the screen.", - "Enable_of_limit_apps_currently_enabled": "**{{enabled}} of {{limit}} {{context}} apps currently enabled.** \n \nWorkspaces on Community Edition can have up to {{limit}} {{context}} apps enabled. \n \n**{{appName}} will be disabled by default.** Disable another {{context}} app or upgrade to Enterprise to enable this app.", - "Enable_of_limit_apps_currently_enabled_exceeded": "**{{enabled}} of {{limit}} {{context}} apps currently enabled.** \n \nCommunity edition app limit has been exceeded. \n \nWorkspaces on Community Edition can have up to {{limit}} {{context}} apps enabled. \n \n**{{appName}} will be disabled by default.** You will need to disable at least {{exceed}} other {{context}} apps or upgrade to Enterprise to enable this app.", - "Workspaces_on_Community_edition_install_app": "Workspaces on Community Edition can have up to {{limit}} {{context}} apps enabled. Upgrade to Enterprise to enable unlimited apps.", + "Enable_of_limit_apps_currently_enabled": "**{{enabled}} of {{limit}} {{context}} apps currently enabled.** \n \nWorkspaces on Community Edition can have up to {{limit}} {{context}} apps enabled. \n \n**{{appName}} will be disabled by default.** Disable another {{context}} app or upgrade to Premium to enable this app.", + "Enable_of_limit_apps_currently_enabled_exceeded": "**{{enabled}} of {{limit}} {{context}} apps currently enabled.** \n \nCommunity edition app limit has been exceeded. \n \nWorkspaces on Community Edition can have up to {{limit}} {{context}} apps enabled. \n \n**{{appName}} will be disabled by default.** You will need to disable at least {{exceed}} other {{context}} apps or upgrade to Premium to enable this app.", + "Workspaces_on_Community_edition_install_app": "Workspaces on Community Edition can have up to {{limit}} {{context}} apps enabled. Upgrade to Premium to enable unlimited apps.", "Apps_Currently_Enabled": "{{enabled}} of {{limit}} {{context}} apps currently enabled.", "Disable_another_app": "Disable another app or upgrade to Enterprise to enable this app.", "Upload_anyway": "Upload anyway", @@ -5971,8 +5973,8 @@ "Create_a_password": "Create a password", "Create_an_account": "Create an account", "Get_all_apps": "Get all the apps your team needs", - "Workspaces_on_community_edition_trial_on": "Workspaces on Community Edition can have up to 5 marketplace apps and 3 private apps enabled. Start a free Enterprise trial to remove these limits today!", - "Workspaces_on_community_edition_trial_off": "Workspaces on Community Edition can have up to 5 marketplace apps and 3 private apps enabled. Upgrade to Enterprise to remove limits and supercharge your workspace.", + "Workspaces_on_community_edition_trial_on": "Workspaces on Community Edition can have up to 5 marketplace apps and 3 private apps enabled. Start a free Premium trial to remove these limits today!", + "Workspaces_on_community_edition_trial_off": "Workspaces on Community Edition can have up to 5 marketplace apps and 3 private apps enabled. Upgrade to Premium to remove limits and supercharge your workspace.", "No_private_apps_installed": "No private apps installed", "Private_apps_are_side-loaded": "Private apps are side-loaded and are not available on the Marketplace.", "Chat_transcript": "Chat transcript", @@ -6074,5 +6076,7 @@ "All_visible": "All visible", "Filter_by_room": "Filter by room type", "Filter_by_visibility": "Filter by visibility", - "Theme_Appearence": "Theme Appearence" + "Theme_Appearence": "Theme Appearence", + "Premium": "Premium", + "Premium_capability": "Premium capability" } From 181441047e080fcf82e857bd798479c615bebb24 Mon Sep 17 00:00:00 2001 From: Pierre Lehnen <55164754+pierre-lehnen-rc@users.noreply.github.com> Date: Mon, 9 Oct 2023 17:56:51 -0300 Subject: [PATCH 05/11] feat: License trigger cloud sync after reach limits (#30603) Co-authored-by: Guilherme Gazzo Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- apps/meteor/ee/app/license/server/settings.ts | 49 ++--------- apps/meteor/ee/app/license/server/startup.ts | 87 +++++++++++++++++-- ee/packages/license/src/license.ts | 26 ++++-- 3 files changed, 108 insertions(+), 54 deletions(-) diff --git a/apps/meteor/ee/app/license/server/settings.ts b/apps/meteor/ee/app/license/server/settings.ts index 1bec7126ae85..ead088fd546d 100644 --- a/apps/meteor/ee/app/license/server/settings.ts +++ b/apps/meteor/ee/app/license/server/settings.ts @@ -1,8 +1,6 @@ -import { License } from '@rocket.chat/license'; -import { Settings } from '@rocket.chat/models'; import { Meteor } from 'meteor/meteor'; -import { settings, settingsRegistry } from '../../../../app/settings/server'; +import { settingsRegistry } from '../../../../app/settings/server'; Meteor.startup(async () => { await settingsRegistry.addGroup('Enterprise', async function () { @@ -11,6 +9,12 @@ Meteor.startup(async () => { type: 'string', i18nLabel: 'Enterprise_License', }); + await this.add('Enterprise_License_Data', '', { + type: 'string', + hidden: true, + blocked: true, + public: false, + }); await this.add('Enterprise_License_Status', '', { readonly: true, type: 'string', @@ -19,42 +23,3 @@ Meteor.startup(async () => { }); }); }); - -settings.watch('Enterprise_License', async (license) => { - if (!license || String(license).trim() === '') { - return; - } - - if (license === process.env.ROCKETCHAT_LICENSE) { - return; - } - - try { - if (!(await License.setLicense(license))) { - await Settings.updateValueById('Enterprise_License_Status', 'Invalid'); - return; - } - } catch (_error) { - // do nothing - } - - await Settings.updateValueById('Enterprise_License_Status', 'Valid'); -}); - -if (process.env.ROCKETCHAT_LICENSE) { - try { - await License.setLicense(process.env.ROCKETCHAT_LICENSE); - } catch (_error) { - // do nothing - } - - Meteor.startup(async () => { - if (settings.get('Enterprise_License')) { - console.warn( - 'Rocket.Chat Enterprise: The license from your environment variable was ignored, please use only the admin setting from now on.', - ); - return; - } - await Settings.updateValueById('Enterprise_License', process.env.ROCKETCHAT_LICENSE); - }); -} diff --git a/apps/meteor/ee/app/license/server/startup.ts b/apps/meteor/ee/app/license/server/startup.ts index d3523282d1e8..765a4205a1a7 100644 --- a/apps/meteor/ee/app/license/server/startup.ts +++ b/apps/meteor/ee/app/license/server/startup.ts @@ -1,6 +1,8 @@ import { License } from '@rocket.chat/license'; -import { Subscriptions, Users } from '@rocket.chat/models'; +import { Subscriptions, Users, Settings } from '@rocket.chat/models'; +import { wrapExceptions } from '@rocket.chat/tools'; +import { syncWorkspace } from '../../../../app/cloud/server/functions/syncWorkspace'; import { settings } from '../../../../app/settings/server'; import { callbacks } from '../../../../lib/callbacks'; import { getAppCount } from './lib/getAppCount'; @@ -11,12 +13,87 @@ settings.watch('Site_Url', (value) => { } }); -callbacks.add('workspaceLicenseChanged', async (updatedLicense) => { +License.onValidateLicense(async () => { + await Settings.updateValueById('Enterprise_License', License.encryptedLicense); + await Settings.updateValueById('Enterprise_License_Status', 'Valid'); +}); + +License.onInvalidateLicense(async () => { + await Settings.updateValueById('Enterprise_License_Status', 'Invalid'); +}); + +const applyLicense = async (license: string, isNewLicense: boolean): Promise => { + const enterpriseLicense = (license ?? '').trim(); + if (!enterpriseLicense) { + return false; + } + + if (enterpriseLicense === License.encryptedLicense) { + return false; + } + try { - await License.setLicense(updatedLicense); - } catch (_error) { - // Ignore + return License.setLicense(enterpriseLicense, isNewLicense); + } catch { + return false; + } +}; + +const syncByTrigger = async (context: string) => { + if (!License.encryptedLicense) { + return; } + + const existingData = wrapExceptions(() => JSON.parse(settings.get('Enterprise_License_Data'))).catch(() => ({})) ?? {}; + + const date = new Date(); + + const day = date.getDate(); + const month = date.getMonth() + 1; + const year = date.getFullYear(); + + const period = `${year}-${month}-${day}`; + + const [, , signed] = License.encryptedLicense.split('.'); + + // Check if this sync has already been done. Based on License, behavior. + if (existingData.signed === signed && existingData[context] === period) { + return; + } + + await Settings.updateValueById( + 'Enterprise_License_Data', + JSON.stringify({ + ...(existingData.signed === signed && existingData), + ...existingData, + [context]: period, + signed, + }), + ); + + await syncWorkspace(); +}; + +// When settings are loaded, apply the current license if there is one. +settings.onReady(async () => { + if (!(await applyLicense(settings.get('Enterprise_License') ?? '', false))) { + // License from the envvar is always treated as new, because it would have been saved on the setting if it was already in use. + if (process.env.ROCKETCHAT_LICENSE && !License.hasValidLicense()) { + await applyLicense(process.env.ROCKETCHAT_LICENSE, true); + } + } + + // After the current license is already loaded, watch the setting value to react to new licenses being applied. + settings.watch('Enterprise_License', async (license) => applyLicense(license, true)); + + callbacks.add('workspaceLicenseChanged', async (updatedLicense) => applyLicense(updatedLicense, true)); + + License.onBehaviorTriggered('prevent_action', (context) => syncByTrigger(`prevent_action_${context.limit}`)); + + License.onBehaviorTriggered('start_fair_policy', async (context) => syncByTrigger(`start_fair_policy_${context.limit}`)); + + License.onBehaviorTriggered('disable_modules', async (context) => syncByTrigger(`disable_modules_${context.limit}`)); + }); License.setLicenseLimitCounter('activeUsers', () => Users.getActiveLocalUserCount()); diff --git a/ee/packages/license/src/license.ts b/ee/packages/license/src/license.ts index f2d8eef362bd..8449d4136810 100644 --- a/ee/packages/license/src/license.ts +++ b/ee/packages/license/src/license.ts @@ -66,6 +66,14 @@ export class LicenseManager extends Emitter { return this._valid; } + public get encryptedLicense(): string | undefined { + if (!this.hasValidLicense()) { + return undefined; + } + + return this._lockedLicense; + } + public async setWorkspaceUrl(url: string) { this.workspaceUrl = url.replace(/\/$/, '').replace(/^https?:\/\/(.*)$/, '$1'); @@ -106,7 +114,12 @@ export class LicenseManager extends Emitter { invalidateAll.call(this); } - private async setLicenseV3(newLicense: ILicenseV3, encryptedLicense: string, originalLicense?: ILicenseV2 | ILicenseV3): Promise { + private async setLicenseV3( + newLicense: ILicenseV3, + encryptedLicense: string, + originalLicense?: ILicenseV2 | ILicenseV3, + isNewLicense?: boolean, + ): Promise { const hadValidLicense = this.hasValidLicense(); this.clearLicenseData(); @@ -114,7 +127,6 @@ export class LicenseManager extends Emitter { this._unmodifiedLicense = originalLicense || newLicense; this._license = newLicense; - const isNewLicense = encryptedLicense !== this._lockedLicense; this._lockedLicense = encryptedLicense; await this.validateLicense({ isNewLicense }); @@ -127,8 +139,8 @@ export class LicenseManager extends Emitter { } } - private async setLicenseV2(newLicense: ILicenseV2, encryptedLicense: string): Promise { - return this.setLicenseV3(convertToV3(newLicense), encryptedLicense, newLicense); + private async setLicenseV2(newLicense: ILicenseV2, encryptedLicense: string, isNewLicense?: boolean): Promise { + return this.setLicenseV3(convertToV3(newLicense), encryptedLicense, newLicense, isNewLicense); } private isLicenseDuplicated(encryptedLicense: string): boolean { @@ -180,7 +192,7 @@ export class LicenseManager extends Emitter { licenseValidated.call(this); } - public async setLicense(encryptedLicense: string): Promise { + public async setLicense(encryptedLicense: string, isNewLicense = true): Promise { if (!(await validateFormat(encryptedLicense))) { throw new InvalidLicenseError(); } @@ -209,10 +221,10 @@ export class LicenseManager extends Emitter { logger.debug({ msg: 'license', decrypted }); if (!encryptedLicense.startsWith('RCV3_')) { - await this.setLicenseV2(decrypted, encryptedLicense); + await this.setLicenseV2(decrypted, encryptedLicense, isNewLicense); return true; } - await this.setLicenseV3(decrypted, encryptedLicense); + await this.setLicenseV3(decrypted, encryptedLicense, decrypted, isNewLicense); return true; } catch (e) { From 1f2b384c624db63feb621c7e8ddc4a7237bd36aa Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Mon, 9 Oct 2023 21:05:50 -0300 Subject: [PATCH 06/11] fix: cloud alerts (#30607) --- .changeset/shiny-pillows-run.md | 5 +++++ .../server/functions/getNewUpdates.ts | 22 +++++++++---------- 2 files changed, 15 insertions(+), 12 deletions(-) create mode 100644 .changeset/shiny-pillows-run.md diff --git a/.changeset/shiny-pillows-run.md b/.changeset/shiny-pillows-run.md new file mode 100644 index 000000000000..9a85d37a2f9d --- /dev/null +++ b/.changeset/shiny-pillows-run.md @@ -0,0 +1,5 @@ +--- +"@rocket.chat/meteor": patch +--- + +fix: cloud alerts not working diff --git a/apps/meteor/app/version-check/server/functions/getNewUpdates.ts b/apps/meteor/app/version-check/server/functions/getNewUpdates.ts index ac0c0e443453..d17191a09be7 100644 --- a/apps/meteor/app/version-check/server/functions/getNewUpdates.ts +++ b/apps/meteor/app/version-check/server/functions/getNewUpdates.ts @@ -50,18 +50,16 @@ export const getNewUpdates = async () => { infoUrl: String, }), ], - alerts: [ - Match.Optional([ - Match.ObjectIncluding({ - id: String, - title: String, - text: String, - textArguments: [Match.Any], - modifiers: [String] as [StringConstructor], - infoUrl: String, - }), - ]), - ], + alerts: Match.Optional([ + Match.ObjectIncluding({ + id: String, + title: String, + text: String, + textArguments: [Match.Any], + modifiers: [String] as [StringConstructor], + infoUrl: String, + }), + ]), }), ); From ef1d37a0f497271ab37cfaf08b838482a148a74d Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Mon, 9 Oct 2023 21:08:00 -0300 Subject: [PATCH 07/11] ci: fix lint task --- apps/meteor/ee/app/license/server/startup.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/meteor/ee/app/license/server/startup.ts b/apps/meteor/ee/app/license/server/startup.ts index 765a4205a1a7..8cce4d3d1410 100644 --- a/apps/meteor/ee/app/license/server/startup.ts +++ b/apps/meteor/ee/app/license/server/startup.ts @@ -93,7 +93,6 @@ settings.onReady(async () => { License.onBehaviorTriggered('start_fair_policy', async (context) => syncByTrigger(`start_fair_policy_${context.limit}`)); License.onBehaviorTriggered('disable_modules', async (context) => syncByTrigger(`disable_modules_${context.limit}`)); - }); License.setLicenseLimitCounter('activeUsers', () => Users.getActiveLocalUserCount()); From 4344d838a95cefd3ef10442ccf2f050207c636af Mon Sep 17 00:00:00 2001 From: Murtaza Patrawala <34130764+murtaza98@users.noreply.github.com> Date: Tue, 10 Oct 2023 16:12:00 +0400 Subject: [PATCH 08/11] fix: Unable to send attachments via email as an omni-agent (#30525) --- .changeset/proud-shrimps-cheat.md | 5 +++++ .../server/features/EmailInbox/EmailInbox_Outgoing.ts | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 .changeset/proud-shrimps-cheat.md diff --git a/.changeset/proud-shrimps-cheat.md b/.changeset/proud-shrimps-cheat.md new file mode 100644 index 000000000000..cad8bc8bfa32 --- /dev/null +++ b/.changeset/proud-shrimps-cheat.md @@ -0,0 +1,5 @@ +--- +"@rocket.chat/meteor": patch +--- + +fix: Unable to send attachments via email as an omni-agent diff --git a/apps/meteor/server/features/EmailInbox/EmailInbox_Outgoing.ts b/apps/meteor/server/features/EmailInbox/EmailInbox_Outgoing.ts index 61ca75aa65d4..685c7f9e96dd 100644 --- a/apps/meteor/server/features/EmailInbox/EmailInbox_Outgoing.ts +++ b/apps/meteor/server/features/EmailInbox/EmailInbox_Outgoing.ts @@ -43,15 +43,15 @@ const sendErrorReplyMessage = async (error: string, options: any) => { return sendMessage(user, message, { _id: options.rid }); }; -const sendSuccessReplyMessage = async (options: any) => { - if (!options?.rid || !options?.msgId) { +const sendSuccessReplyMessage = async (options: { room: IOmnichannelRoom; msgId: string; sender: string }) => { + if (!options?.room?._id || !options?.msgId) { return; } const message = { groupable: false, msg: `@${options.sender} Attachment was sent successfully`, _id: String(Date.now()), - rid: options.rid, + rid: options.room._id, ts: new Date(), }; @@ -60,7 +60,7 @@ const sendSuccessReplyMessage = async (options: any) => { return; } - return sendMessage(user, message, { _id: options.rid }); + return sendMessage(user, message, options.room); }; async function sendEmail(inbox: Inbox, mail: Mail.Options, options?: any): Promise<{ messageId: string }> { @@ -174,7 +174,7 @@ slashCommands.add({ return sendSuccessReplyMessage({ msgId: message._id, sender: message.u.username, - rid: room._id, + room, }); }, options: { From b7ba7521af2cb48cce4a60266c1ec4e6130cc4d2 Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Tue, 10 Oct 2023 10:47:42 -0300 Subject: [PATCH 09/11] regression: test license from cloud (#30609) Co-authored-by: Diego Sampaio --- .../app/cloud/server/functions/getWorkspaceLicense.ts | 2 +- .../server/functions/syncWorkspace/announcementSync.ts | 2 +- .../app/cloud/server/functions/syncWorkspace/index.ts | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/meteor/app/cloud/server/functions/getWorkspaceLicense.ts b/apps/meteor/app/cloud/server/functions/getWorkspaceLicense.ts index 2ab8a4b27a62..f9f0cfadc669 100644 --- a/apps/meteor/app/cloud/server/functions/getWorkspaceLicense.ts +++ b/apps/meteor/app/cloud/server/functions/getWorkspaceLicense.ts @@ -73,7 +73,7 @@ export async function getWorkspaceLicense(): Promise<{ updated: boolean; license const payload = await fetchCloudWorkspaceLicensePayload({ token }); - if (Date.parse(payload.updatedAt) <= currentLicense._updatedAt.getTime()) { + if (currentLicense.value && Date.parse(payload.updatedAt) <= currentLicense._updatedAt.getTime()) { return fromCurrentLicense(); } diff --git a/apps/meteor/app/cloud/server/functions/syncWorkspace/announcementSync.ts b/apps/meteor/app/cloud/server/functions/syncWorkspace/announcementSync.ts index 26d98b4a7574..f3885c1e95c2 100644 --- a/apps/meteor/app/cloud/server/functions/syncWorkspace/announcementSync.ts +++ b/apps/meteor/app/cloud/server/functions/syncWorkspace/announcementSync.ts @@ -107,7 +107,7 @@ export async function announcementSync() { } catch (err) { SystemLogger.error({ msg: 'Failed to sync with Rocket.Chat Cloud', - url: '/sync', + url: '/comms/workspace', err, }); } diff --git a/apps/meteor/app/cloud/server/functions/syncWorkspace/index.ts b/apps/meteor/app/cloud/server/functions/syncWorkspace/index.ts index 3173e652afe5..bdd898b510f7 100644 --- a/apps/meteor/app/cloud/server/functions/syncWorkspace/index.ts +++ b/apps/meteor/app/cloud/server/functions/syncWorkspace/index.ts @@ -1,3 +1,4 @@ +import { SystemLogger } from '../../../../../server/lib/logger/system'; import { CloudWorkspaceAccessTokenError } from '../getWorkspaceAccessToken'; import { getCachedSupportedVersionsToken } from '../supportedVersionsToken/supportedVersionsToken'; import { announcementSync } from './announcementSync'; @@ -7,10 +8,11 @@ export async function syncWorkspace() { try { await syncCloudData(); await announcementSync(); - } catch (error) { - if (error instanceof CloudWorkspaceAccessTokenError) { + } catch (err) { + if (err instanceof CloudWorkspaceAccessTokenError) { // TODO: Remove License if there is no access token } + SystemLogger.error({ msg: 'Error during workspace sync', err }); } await getCachedSupportedVersionsToken.reset(); From 058650128d4b8c630b0767268073775263ddef9e Mon Sep 17 00:00:00 2001 From: csuadev <72958726+csuadev@users.noreply.github.com> Date: Tue, 10 Oct 2023 11:53:06 -0500 Subject: [PATCH 10/11] fix: Change plan name from Enterprise to Premium on marketplace filtering (#30616) --- .changeset/heavy-ads-carry.md | 5 +++++ .../meteor/client/views/marketplace/hooks/useFilteredApps.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/heavy-ads-carry.md diff --git a/.changeset/heavy-ads-carry.md b/.changeset/heavy-ads-carry.md new file mode 100644 index 000000000000..c04e52fb48a0 --- /dev/null +++ b/.changeset/heavy-ads-carry.md @@ -0,0 +1,5 @@ +--- +"@rocket.chat/meteor": patch +--- + +fix: Change plan name from Enterprise to Premium on marketplace filtering diff --git a/apps/meteor/client/views/marketplace/hooks/useFilteredApps.ts b/apps/meteor/client/views/marketplace/hooks/useFilteredApps.ts index 221990f7af2a..437c8d35207d 100644 --- a/apps/meteor/client/views/marketplace/hooks/useFilteredApps.ts +++ b/apps/meteor/client/views/marketplace/hooks/useFilteredApps.ts @@ -80,7 +80,7 @@ export const useFilteredApps = ({ explore: fallback, installed: fallback, private: fallback, - premium: (apps: App[]) => apps.filter(({ categories }) => categories.includes('Enterprise')), + premium: (apps: App[]) => apps.filter(({ categories }) => categories.includes('Premium')), requested: (apps: App[]) => apps.filter(({ appRequestStats, installed }) => Boolean(appRequestStats) && !installed), }; From f5c0d6b45db2828459f17e3c0f5bab238bf55b26 Mon Sep 17 00:00:00 2001 From: Heitor Tanoue <68477006+heitortanoue@users.noreply.github.com> Date: Tue, 10 Oct 2023 14:45:21 -0300 Subject: [PATCH 11/11] fix: DM room stay "read only" after the deactivate and reactivate user with "guest" role (#30459) Co-authored-by: Matheus Barbosa Silva <36537004+matheusbsilva137@users.noreply.github.com> --- .changeset/gentle-radios-relate.md | 5 +++++ apps/meteor/server/models/raw/Users.js | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 .changeset/gentle-radios-relate.md diff --git a/.changeset/gentle-radios-relate.md b/.changeset/gentle-radios-relate.md new file mode 100644 index 000000000000..8d5f12b3a286 --- /dev/null +++ b/.changeset/gentle-radios-relate.md @@ -0,0 +1,5 @@ +--- +"@rocket.chat/meteor": patch +--- + +Fixed DM room with "guest" user kept as "read only" after reactivating user diff --git a/apps/meteor/server/models/raw/Users.js b/apps/meteor/server/models/raw/Users.js index 113f18ea83da..c8cee8f2f6bf 100644 --- a/apps/meteor/server/models/raw/Users.js +++ b/apps/meteor/server/models/raw/Users.js @@ -2187,7 +2187,6 @@ export class UsersRaw extends BaseRaw { { active: true, type: { $nin: ['app'] }, - roles: { $ne: ['guest'] }, _id: { $in: ids }, }, options,