Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into wip-release-3.0.x
Browse files Browse the repository at this point in the history
  • Loading branch information
rodrigok committed Nov 2, 2023
2 parents c19e356 + 4ed60c4 commit b1c6e6f
Show file tree
Hide file tree
Showing 289 changed files with 5,152 additions and 3,377 deletions.
5 changes: 5 additions & 0 deletions .changeset/brown-donuts-drive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/meteor": minor
---

Added a new admin page called `Subscription`, this page is responsible of managing the current workspace subscription and it has a overview of the usage and limits of the plan
5 changes: 5 additions & 0 deletions .changeset/ninety-carrots-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/meteor": patch
---

test: read receipts
5 changes: 5 additions & 0 deletions .changeset/quiet-countries-provide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

New permission for testing push notifications
5 changes: 5 additions & 0 deletions .changeset/sour-hotels-flash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/meteor": patch
---

Replace the old Enterprise labels to newest Premium
5 changes: 5 additions & 0 deletions .changeset/workspace-status-admin-page.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/meteor": minor
---

Added a new Admin page called `Workspace info` in place of Information page, to make it easier to check the license
2 changes: 1 addition & 1 deletion .github/workflows/ci-code-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
with:
swap-size-gb: 4

- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Setup NodeJS
uses: ./.github/actions/setup-node
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-test-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ jobs:
mongodb-version: ${{ matrix.mongodb-version }}
mongodb-replica-set: rs0

- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Setup NodeJS
uses: ./.github/actions/setup-node
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-test-unit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
name: Unit Tests

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Setup NodeJS
uses: ./.github/actions/setup-node
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ jobs:
with:
swap-size-gb: 4

- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Setup NodeJS
uses: ./.github/actions/setup-node
Expand Down Expand Up @@ -138,7 +138,7 @@ jobs:
echo "github.event_name: ${{ github.event_name }}"
cat $GITHUB_EVENT_PATH
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- uses: ./.github/actions/meteor-build
with:
Expand All @@ -162,7 +162,7 @@ jobs:
echo "github.event_name: ${{ github.event_name }}"
cat $GITHUB_EVENT_PATH
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- uses: ./.github/actions/meteor-build
with:
Expand All @@ -187,7 +187,7 @@ jobs:
platform: ['official', 'alpine']

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

# we only build and publish the actual docker images if not a PR from a fork
- uses: ./.github/actions/build-docker
Expand Down Expand Up @@ -216,7 +216,7 @@ jobs:
platform: ['official', 'alpine']

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- uses: ./.github/actions/build-docker
with:
Expand Down Expand Up @@ -415,7 +415,7 @@ jobs:
needs: [build, checks, release-versions]
if: github.event_name == 'release' || github.ref == 'refs/heads/develop'
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Restore build
uses: actions/download-artifact@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/new-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.base-ref }}
fetch-depth: 0
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.CI_PAT }}
Expand Down
11 changes: 3 additions & 8 deletions apps/meteor/app/api/server/lib/getServerInfo.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
import type { IWorkspaceInfo } from '@rocket.chat/core-typings';

import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission';
import {
getCachedSupportedVersionsToken,
wrapPromise,
} from '../../../cloud/server/functions/supportedVersionsToken/supportedVersionsToken';
import { Info, minimumClientVersions } from '../../../utils/rocketchat.info';

type ServerInfo = {
info?: typeof Info;
supportedVersions?: { signed: string };
minimumClientVersions: typeof minimumClientVersions;
version: string;
};

const removePatchInfo = (version: string): string => version.replace(/(\d+\.\d+).*/, '$1');

export async function getServerInfo(userId?: string): Promise<ServerInfo> {
export async function getServerInfo(userId?: string): Promise<IWorkspaceInfo> {
const hasPermissionToViewStatistics = userId && (await hasPermissionAsync(userId, 'view-statistics'));
const supportedVersionsToken = await wrapPromise(getCachedSupportedVersionsToken());

Expand Down
50 changes: 50 additions & 0 deletions apps/meteor/app/api/server/v1/cloud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import { check } from 'meteor/check';

import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission';
import { hasRoleAsync } from '../../../authorization/server/functions/hasRole';
import { getCheckoutUrl } from '../../../cloud/server/functions/getCheckoutUrl';
import { getConfirmationPoll } from '../../../cloud/server/functions/getConfirmationPoll';
import { registerPreIntentWorkspaceWizard } from '../../../cloud/server/functions/registerPreIntentWorkspaceWizard';
import { retrieveRegistrationStatus } from '../../../cloud/server/functions/retrieveRegistrationStatus';
import { saveRegistrationData } from '../../../cloud/server/functions/saveRegistrationData';
import { startRegisterWorkspaceSetupWizard } from '../../../cloud/server/functions/startRegisterWorkspaceSetupWizard';
import { syncWorkspace } from '../../../cloud/server/functions/syncWorkspace';
import { API } from '../api';

API.v1.addRoute(
Expand Down Expand Up @@ -126,3 +128,51 @@ API.v1.addRoute(
},
},
);

API.v1.addRoute(
'cloud.syncWorkspace',
{
authRequired: true,
permissionsRequired: ['manage-cloud'],
rateLimiterOptions: { numRequestsAllowed: 2, intervalTimeInMS: 60000 },
},
{
async post() {
try {
await syncWorkspace();

return API.v1.success({ success: true });
} catch (error) {
return API.v1.failure('Error during workspace sync');
}
},
},
);

/**
* Declaring endpoint here because we don't want this available to the sdk client
*/
declare module '@rocket.chat/rest-typings' {
// eslint-disable-next-line @typescript-eslint/naming-convention
interface Endpoints {
'/v1/cloud.checkoutUrl': {
GET: () => { url: string };
};
}
}

API.v1.addRoute(
'cloud.checkoutUrl',
{ authRequired: true, permissionsRequired: ['manage-cloud'] },
{
async get() {
const checkoutUrl = await getCheckoutUrl();

if (!checkoutUrl.url) {
return API.v1.failure();
}

return API.v1.success({ url: checkoutUrl.url });
},
},
);
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ export const permissions = [
{ _id: 'get-server-info', roles: ['admin'] },
{ _id: 'register-on-cloud', roles: ['admin'] },
{ _id: 'test-admin-options', roles: ['admin'] },
{ _id: 'test-push-notifications', roles: ['admin', 'user'] },
{ _id: 'sync-auth-services-users', roles: ['admin'] },
{ _id: 'restart-server', roles: ['admin'] },
{ _id: 'remove-slackbridge-links', roles: ['admin'] },
Expand Down
45 changes: 45 additions & 0 deletions apps/meteor/app/cloud/server/functions/getCheckoutUrl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { serverFetch as fetch } from '@rocket.chat/server-fetch';

import { SystemLogger } from '../../../../server/lib/logger/system';
import { settings } from '../../../settings/server';
import { getURL } from '../../../utils/server/getURL';
import { getWorkspaceAccessTokenOrThrow } from './getWorkspaceAccessToken';

export const getCheckoutUrl = async () => {
try {
const token = await getWorkspaceAccessTokenOrThrow(false, 'workspace:billing');

const subscriptionURL = getURL('admin/subscription', {
full: true,
});

const body = {
okCallback: `${subscriptionURL}?subscriptionSuccess=true`,
cancelCallback: subscriptionURL,
};

const billingUrl = settings.get<string>('Cloud_Billing_Url');

const response = await fetch(`${billingUrl}/api/v2/checkout`, {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
},
body,
});

if (!response.ok) {
throw new Error(await response.json());
}

return response.json();
} catch (err: any) {
SystemLogger.error({
msg: 'Failed to get Checkout URL with Rocket.Chat Billing Service',
url: '/api/v2/checkout',
err,
});

throw err;
}
};
20 changes: 12 additions & 8 deletions apps/meteor/app/cors/server/cors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,23 +88,24 @@ declare module 'meteor/webapp' {
}
}

// These routes already handle cache control on their own
const cacheControlledRoutes: Array<RegExp> = ['/assets', '/custom-sounds', '/emoji-custom', '/avatar', '/file-upload'].map(
(route) => new RegExp(`^${route}`, 'i'),
);
let cachingVersion = '';
settings.watch<string>('Troubleshoot_Force_Caching_Version', (value) => {
cachingVersion = String(value).trim();
});

// @ts-expect-error - accessing internal property of webapp
WebAppInternals.staticFilesMiddleware = function (
staticFiles: StaticFiles,
req: http.IncomingMessage,
res: http.ServerResponse,
req: http.IncomingMessage & { cookies: Record<string, string> },
res: http.ServerResponse & { cookie: (cookie: string, value: string) => void },
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');
if (cachingVersion && req.cookies.cache_version !== cachingVersion) {
res.cookie('cache_version', cachingVersion);
res.setHeader('Clear-Site-Data', '"cache"');
}

// Prevent meteor_runtime_config.js to load from a different expected hash possibly causing
Expand All @@ -126,7 +127,10 @@ WebAppInternals.staticFilesMiddleware = function (
res.writeHead(404);
return res.end();
}

res.setHeader('Cache-Control', 'public, max-age=3600');
}

return _staticFilesMiddleware(staticFiles, req, res, next);
};

Expand Down
1 change: 1 addition & 0 deletions apps/meteor/app/livechat/server/api/lib/livechat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export function findGuest(token: string): Promise<ILivechatVisitor | null> {
token: 1,
visitorEmails: 1,
department: 1,
activity: 1,
},
});
}
Expand Down
11 changes: 9 additions & 2 deletions apps/meteor/app/livechat/server/hooks/markRoomResponded.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { IOmnichannelRoom } from '@rocket.chat/core-typings';
import { isOmnichannelRoom, isEditedMessage } from '@rocket.chat/core-typings';
import { LivechatRooms, LivechatVisitors } from '@rocket.chat/models';
import { LivechatRooms, LivechatVisitors, LivechatInquiry } from '@rocket.chat/models';
import moment from 'moment';

import { callbacks } from '../../../../lib/callbacks';
Expand Down Expand Up @@ -30,11 +30,18 @@ callbacks.add(
// Return YYYY-MM from moment
const monthYear = moment().format('YYYY-MM');
const isVisitorActive = await LivechatVisitors.isVisitorActiveOnPeriod(room.v._id, monthYear);

// Case: agent answers & visitor is not active, we mark visitor as active
if (!isVisitorActive) {
await LivechatVisitors.markVisitorActiveForPeriod(room.v._id, monthYear);
}

await LivechatRooms.markVisitorActiveForPeriod(room._id, monthYear);
if (!room.v?.activity?.includes(monthYear)) {
await Promise.all([
LivechatRooms.markVisitorActiveForPeriod(room._id, monthYear),
LivechatInquiry.markInquiryActiveForPeriod(room._id, monthYear),
]);
}

if (room.responseBy) {
await LivechatRooms.setAgentLastMessageTs(room._id);
Expand Down
Loading

0 comments on commit b1c6e6f

Please sign in to comment.