snapshot of https://github.com/RocketChat/Rocket.Chat.git (develop, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 1s
21
apps/meteor/tests/e2e/fixtures/addCustomOAuth.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { request } from '@playwright/test';
|
||||
|
||||
import { Users } from './userStates';
|
||||
import { BASE_API_URL } from '../config/constants';
|
||||
|
||||
export default async function addCustomOAuth(): Promise<void> {
|
||||
const api = await request.newContext();
|
||||
|
||||
const headers = {
|
||||
'X-Auth-Token': Users.admin.data.loginToken,
|
||||
'X-User-Id': Users.admin.data._id,
|
||||
};
|
||||
|
||||
await api.post(`${BASE_API_URL}/settings.addCustomOAuth`, { data: { name: 'Test' }, headers });
|
||||
await api.post(`${BASE_API_URL}/settings/Accounts_OAuth_Custom-Test`, { data: { value: false }, headers });
|
||||
await api.post(`${BASE_API_URL}/settings/Accounts_OAuth_Custom-Test-url`, { data: { value: 'https://rocket.chat' }, headers });
|
||||
await api.post(`${BASE_API_URL}/settings/Accounts_OAuth_Custom-Test-login_style`, { data: { value: 'redirect' }, headers });
|
||||
await api.post(`${BASE_API_URL}/settings/Accounts_OAuth_Custom-Test-id`, { data: { value: 'abc' }, headers });
|
||||
await api.post(`${BASE_API_URL}/settings/Accounts_OAuth_Custom-Test-secret`, { data: { value: 'def' }, headers });
|
||||
await api.post(`${BASE_API_URL}/settings/Accounts_OAuth_Custom-Test-authorize_path`, { data: { value: '/authorize' }, headers });
|
||||
}
|
||||
53
apps/meteor/tests/e2e/fixtures/collections/users.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import type { IUser } from '@rocket.chat/core-typings';
|
||||
|
||||
import { DEFAULT_USER_CREDENTIALS } from '../../config/constants';
|
||||
import type { IUserState } from '../userStates';
|
||||
|
||||
type UserFixture = IUser & {
|
||||
username: string;
|
||||
__rooms: string[];
|
||||
};
|
||||
|
||||
export function createUserFixture(user: IUserState): UserFixture {
|
||||
const { username, hashedToken, loginExpire, e2e } = user.data;
|
||||
|
||||
return {
|
||||
_id: `${username}`,
|
||||
type: 'user',
|
||||
active: true,
|
||||
emails: [{ address: `${username}@email.com`, verified: true }],
|
||||
roles: ['user'],
|
||||
name: username,
|
||||
lastLogin: new Date(),
|
||||
statusConnection: 'offline',
|
||||
utcOffset: -3,
|
||||
username,
|
||||
services: {
|
||||
password: { bcrypt: DEFAULT_USER_CREDENTIALS.bcrypt },
|
||||
email2fa: { enabled: true, changedAt: new Date() },
|
||||
email: {
|
||||
verificationTokens: [
|
||||
{
|
||||
token: faker.string.uuid(),
|
||||
address: `${username}@email.com`,
|
||||
when: new Date(),
|
||||
},
|
||||
],
|
||||
},
|
||||
resume: {
|
||||
loginTokens: [
|
||||
{
|
||||
when: loginExpire,
|
||||
hashedToken,
|
||||
},
|
||||
],
|
||||
},
|
||||
emailCode: { code: '', attempts: 0, expire: new Date() },
|
||||
},
|
||||
createdAt: new Date(),
|
||||
_updatedAt: new Date(),
|
||||
__rooms: ['GENERAL'],
|
||||
e2e,
|
||||
};
|
||||
}
|
||||
19
apps/meteor/tests/e2e/fixtures/createAuxContext.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import type { Browser, Page } from '@playwright/test';
|
||||
|
||||
import type { IUserState } from './userStates';
|
||||
|
||||
export const createAuxContext = async (
|
||||
browser: Browser,
|
||||
userState: IUserState,
|
||||
route = '/',
|
||||
waitForMainContent = true,
|
||||
): Promise<{ page: Page }> => {
|
||||
const page = await browser.newPage({ storageState: userState.state });
|
||||
await page.goto(route);
|
||||
|
||||
if (waitForMainContent) {
|
||||
await page.locator('#main-content').waitFor();
|
||||
}
|
||||
|
||||
return { page };
|
||||
};
|
||||
1
apps/meteor/tests/e2e/fixtures/files/another_file.txt
Normal file
@@ -0,0 +1 @@
|
||||
another_file
|
||||
1
apps/meteor/tests/e2e/fixtures/files/any_file.txt
Normal file
@@ -0,0 +1 @@
|
||||
any_file
|
||||
BIN
apps/meteor/tests/e2e/fixtures/files/csv_import.zip
Normal file
@@ -0,0 +1,4 @@
|
||||
"imported-csv-group","billy.bob","private",""
|
||||
"imported-csv-channel","billy.bob","public",""
|
||||
"imported-csv-with-members-group","billy.bob","private","billy.bob;billy.joe"
|
||||
"imported-csv-with-members-channel","billy.bob","public","billy.bob;billy.joe"
|
||||
|
@@ -0,0 +1,3 @@
|
||||
billy.bob, billy.bob@example.com, Billy Bob Jr.
|
||||
billy.joe, billy.joe@example.com, Billy Joe Jr.
|
||||
billy.billy, billy.billy@example.com, Billy Billy Jr.
|
||||
|
13
apps/meteor/tests/e2e/fixtures/files/diagram.drawio
Normal file
@@ -0,0 +1,13 @@
|
||||
<mxfile host="app.diagrams.net" modified="2024-05-21T16:10:09.295Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" etag="ZxZRCTHi-kxhlzk7b9_Z" version="24.4.4" type="device">
|
||||
<diagram name="Página-1" id="9eBILa8281JaQ4yUkDbp">
|
||||
<mxGraphModel dx="1434" dy="786" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="dopCU4gkJe7Sfp6IDYO1-1" value="<b><font style="font-size: 30px;">Rocket.Chat</font></b>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="314" y="350" width="200" height="50" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
2
apps/meteor/tests/e2e/fixtures/files/dm_messages.csv
Normal file
@@ -0,0 +1,2 @@
|
||||
"billy.joe","billy.bob","1479162481336","this is a test message"
|
||||
"billy.bob","billy.joe","1479162481654","this is another message, a test message"
|
||||
|
0
apps/meteor/tests/e2e/fixtures/files/empty_file.txt
Normal file
37
apps/meteor/tests/e2e/fixtures/files/iframe-login.html
Normal file
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Iframe Login</title>
|
||||
</head>
|
||||
<script>
|
||||
function login() {
|
||||
console.log('logging in');
|
||||
window.parent.postMessage({
|
||||
event: 'login-with-token',
|
||||
loginToken: 'REPLACE_WITH_TOKEN',
|
||||
}, '*');
|
||||
}
|
||||
|
||||
window.addEventListener('message', (event) => {
|
||||
if(event.data.event === 'login-error') {
|
||||
document.getElementById('login-error').innerText = "Login failed";
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<body>
|
||||
<h1>Iframe Authentication Login Form</h1>
|
||||
<form id="login-form">
|
||||
<label for="username">Username:</label><br/>
|
||||
<input type="text" id="username" name="username" placeholder="Enter username" /><br/><br/>
|
||||
|
||||
<label for="password">Password:</label><br/>
|
||||
<input type="password" id="password" name="password" placeholder="Enter password" /><br/><br/>
|
||||
|
||||
<button id="submit" type="button"
|
||||
|
||||
onclick="login()">Login</button>
|
||||
</form>
|
||||
<div id="login-error"></div>
|
||||
</body>
|
||||
</html>
|
||||
6
apps/meteor/tests/e2e/fixtures/files/lst-test.lst
Normal file
@@ -0,0 +1,6 @@
|
||||
# Comment
|
||||
|
||||
# Name Age
|
||||
Tom 23
|
||||
Marcus 22
|
||||
Bryan 21
|
||||
BIN
apps/meteor/tests/e2e/fixtures/files/number1.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
apps/meteor/tests/e2e/fixtures/files/number2.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
apps/meteor/tests/e2e/fixtures/files/number3.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
apps/meteor/tests/e2e/fixtures/files/number4.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
apps/meteor/tests/e2e/fixtures/files/number5.png
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
apps/meteor/tests/e2e/fixtures/files/number6.png
Normal file
|
After Width: | Height: | Size: 92 KiB |
BIN
apps/meteor/tests/e2e/fixtures/files/sample-audio.mp3
Normal file
@@ -0,0 +1,4 @@
|
||||
username,email,status,billing-active,has-2fa,has-sso,userid,fullname,displayname,expiration-timestamp
|
||||
user4.test,user4@email.com.br,Primary Owner,0,0,0,U03TVFGMHUY,user4.test,,
|
||||
user5.test,user5@email.com.br,Primary Owner,0,0,0,U0G9QF9C6,user5.test,,
|
||||
user6.test,user6@email.com.br,Primary Owner,0,0,0,U03TVFGMH,user6.test,,
|
||||
|
BIN
apps/meteor/tests/e2e/fixtures/files/test-app_0.0.1.zip
Normal file
BIN
apps/meteor/tests/e2e/fixtures/files/test-image.jpeg
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
apps/meteor/tests/e2e/fixtures/files/test_pdf_file.pdf
Normal file
84
apps/meteor/tests/e2e/fixtures/inject-initial-data.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import type { ISetting, IUser } from '@rocket.chat/core-typings';
|
||||
import { MongoClient } from 'mongodb';
|
||||
|
||||
import * as constants from '../config/constants';
|
||||
import { createUserFixture } from './collections/users';
|
||||
import { Users } from './userStates';
|
||||
|
||||
export default async function injectInitialData() {
|
||||
const connection = await MongoClient.connect(constants.URL_MONGODB);
|
||||
|
||||
const usersFixtures = [
|
||||
createUserFixture(Users.user1),
|
||||
createUserFixture(Users.user2),
|
||||
createUserFixture(Users.user3),
|
||||
createUserFixture(Users.userE2EE),
|
||||
createUserFixture(Users.userNotAllowedByApp),
|
||||
];
|
||||
|
||||
await Promise.all(
|
||||
usersFixtures.map((user) =>
|
||||
connection.db().collection('users').updateOne({ username: user.username }, { $set: user }, { upsert: true }),
|
||||
),
|
||||
);
|
||||
|
||||
await connection
|
||||
.db()
|
||||
.collection<IUser>('users')
|
||||
.updateOne(
|
||||
{ username: Users.admin.data.username },
|
||||
{ $addToSet: { 'services.resume.loginTokens': { when: Users.admin.data.loginExpire, hashedToken: Users.admin.data.hashedToken } } },
|
||||
);
|
||||
|
||||
await Promise.all(
|
||||
[
|
||||
{
|
||||
_id: 'API_Enable_Rate_Limiter_Dev',
|
||||
value: false,
|
||||
},
|
||||
{
|
||||
_id: 'Show_Setup_Wizard',
|
||||
value: 'completed',
|
||||
},
|
||||
{
|
||||
_id: 'Country',
|
||||
value: 'brazil',
|
||||
},
|
||||
{
|
||||
_id: 'Organization_Type',
|
||||
value: 'community',
|
||||
},
|
||||
{
|
||||
_id: 'Industry',
|
||||
value: 'aerospaceDefense',
|
||||
},
|
||||
{
|
||||
_id: 'Size',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
_id: 'Organization_Name',
|
||||
value: 'any_name',
|
||||
},
|
||||
{
|
||||
_id: 'API_Enable_Rate_Limiter_Dev',
|
||||
value: false,
|
||||
},
|
||||
{
|
||||
_id: 'Accounts_OAuth_Google',
|
||||
value: false,
|
||||
},
|
||||
{
|
||||
_id: 'Livechat_Require_Contact_Verification',
|
||||
value: 'never',
|
||||
},
|
||||
].map((setting) =>
|
||||
connection
|
||||
.db()
|
||||
.collection<ISetting>('rocketchat_settings')
|
||||
.updateOne({ _id: setting._id }, { $set: { value: setting.value } }),
|
||||
),
|
||||
);
|
||||
|
||||
return { usersFixtures };
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import type { Page, Response } from '@playwright/test';
|
||||
|
||||
const isMediaResponse = (response: Response) =>
|
||||
/api\/v1\/rooms\.media(?:\/|\?|$)/.test(response.url()) && response.request().method() === 'POST';
|
||||
|
||||
export const createMediaResponsePromise = (page: Page) => {
|
||||
return page.waitForResponse((response) => isMediaResponse(response));
|
||||
};
|
||||
155
apps/meteor/tests/e2e/fixtures/userStates.ts
Normal file
@@ -0,0 +1,155 @@
|
||||
import crypto from 'crypto';
|
||||
|
||||
import type { BrowserContextOptions, Page } from '@playwright/test';
|
||||
|
||||
import { BASE_URL } from '../config/constants';
|
||||
|
||||
export type IUserState = {
|
||||
data: {
|
||||
_id: string;
|
||||
username: string;
|
||||
loginToken: string;
|
||||
loginExpire: Date;
|
||||
hashedToken: string;
|
||||
e2e?: {
|
||||
private_key: string;
|
||||
public_key: string;
|
||||
};
|
||||
e2ePassword?: string;
|
||||
};
|
||||
state: Exclude<BrowserContextOptions['storageState'], string | undefined>;
|
||||
};
|
||||
|
||||
const e2eeData: Record<string, { server: IUserState['data']['e2e']; client: { private_key: string } }> = {
|
||||
userE2EE: {
|
||||
server: {
|
||||
private_key:
|
||||
'{"$binary":"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"}',
|
||||
public_key:
|
||||
'{"alg":"RSA-OAEP-256","e":"AQAB","ext":true,"key_ops":["encrypt"],"kty":"RSA","n":"qVLMv2Iwm_Hyhlnh4etNlHEiCXBzJWbqMwOZ6pz_JuZY2HiqbLmSfBtpvwBKZvcmP92BqLl-qZuLV_bJD_11UBS3gR6ykgU-RsTz1L-V8vA2QZEyULP4DqkMcRCV_7WE_sn_ScePgKszx1284gnngct_1Tv37zB6Ifz7gb1THRwAqOGcE2htea4yQEhyX8ZAl_-95DTWLbXqEAuofqDpXMcQo487VezBWIaDdfw2VX0qi6kM-pt03Gx8uMniyAjhK1G8Dro3wgAtz4PNIwOsdXEvWTSyoXLVMsIuZeO9OGdJKXnZFtVEMzXLyQTD1LjXlsM_TF09fbkN41Tz12ojmQ"}',
|
||||
},
|
||||
client: {
|
||||
private_key:
|
||||
'{"alg":"RSA-OAEP-256","d":"IpABtkEzPenNwQng105CKD5NndKj1msi_CXMibzhQk37rbg3xXi9w3KPC8th5JGnb5rl6AxxI-rZrytzUD3C8AVCjes3tSG33BdA1FkFITFSSeD6_ck2pbtxDDVAARHK431VDHjdPHz11Ui3kQZHiNGCtwKGMf9Zts1eg1WjfQnQw2ta4-38mwHpq-4Cm_F1brNTTAu5XlHMws4-TDlYhY3nFU2XvoiR2RPDbMddtvXpDZIVo9s7h3jcS4JxHeJd7mWfwcR_Wf0ArRJIhckgPQtTAAjADNpw_HAdERfJyOAJUnxtHkv4uTu_k23qDpPGEi8euFpQ_1UD8B_Z1Rxylw","dp":"OS3zu_VYJZmOXl1dRXxYGP69MR4YQ3TFJ58HFIxvebD060byGHL-mwf0R6-a1hBkHfSeUI9iPipEcjQeevasPqm5CG8eYMvGU2vhsoq1gfY79rsoKjnThCO3XiUbNeM-G9MRKMRa3ooQ8fUVHyEWKFo1ajoFbVHxZuqTAOgrYT8","dq":"yXtWRU1vM5imQJhIZBt5BO1Rfn-koHTvTM3c5QDdPLyNoGTKTyeoT3P9clN6qevJKTyJJTWiwuz8ZECSksh_m9STCY1ry2HqlF2EKdCZnTQzhoJvb6d7547Witc9eh2rBjsILSxVBadLzOFe8opkkQkdkM_gN_Rr3TtXEAo1vn8","e":"AQAB","ext":true,"key_ops":["decrypt"],"kty":"RSA","n":"qVLMv2Iwm_Hyhlnh4etNlHEiCXBzJWbqMwOZ6pz_JuZY2HiqbLmSfBtpvwBKZvcmP92BqLl-qZuLV_bJD_11UBS3gR6ykgU-RsTz1L-V8vA2QZEyULP4DqkMcRCV_7WE_sn_ScePgKszx1284gnngct_1Tv37zB6Ifz7gb1THRwAqOGcE2htea4yQEhyX8ZAl_-95DTWLbXqEAuofqDpXMcQo487VezBWIaDdfw2VX0qi6kM-pt03Gx8uMniyAjhK1G8Dro3wgAtz4PNIwOsdXEvWTSyoXLVMsIuZeO9OGdJKXnZFtVEMzXLyQTD1LjXlsM_TF09fbkN41Tz12ojmQ","p":"0GJaXeKlxgcz6pX0DdwtWG38x9vN2wfLrN3F8N_0stzyPMjMpLGXOdGq1k1V6FROYvLHZsqdCpziwJ3a1PQaGUg2lO-KeBghlbDk4xfYbzSSPhVdwvUT27dysd3-_TsBvNpVCqCLb9Wgl8f0jrrRmRTSztYSLw3ckL939OJoe0M","q":"0AOMQqdGlz0Tm81uqpzCuQcQLMj-IhmPIMuuTnIU55KCmEwmlf0mkgesj-EEBsC1h6ScC5fvznGNvSGqVQAP5ANNZxGiB73q-2YgH3FpuEeHekufl260E_9tgIuqjtCv-eT_cLUhnRNyuP2ZiqRZsBWLuaQYkTubyGRi6izoofM","qi":"FXbIXivKdh0VBgMtLe5f1OjzyrSW_IfIvz8ZM66F4tUTxnNKk5vSb_q2NPyIOVYbdonuVguX-0VO54Ct16k8VdpQSMmUxGbyQAtIck2IzEzpfbRJgn06wiAI3j8q1nRFhrzhfrpJWVyuTiXBgaeOLWBz8fBpjDU7rptmcoU3tZ4"}',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
function generateContext(username: string): IUserState {
|
||||
const date = new Date();
|
||||
date.setFullYear(date.getFullYear() + 1);
|
||||
|
||||
const token = {
|
||||
token: crypto.createHash('sha256').update(username).digest('base64'),
|
||||
when: date,
|
||||
};
|
||||
|
||||
const hashedToken = crypto.createHash('sha256').update(token.token).digest('base64');
|
||||
|
||||
return {
|
||||
data: {
|
||||
_id: username,
|
||||
username,
|
||||
loginToken: token.token,
|
||||
loginExpire: token.when,
|
||||
hashedToken,
|
||||
...(e2eeData[username] && {
|
||||
e2e: e2eeData[username]?.server,
|
||||
e2ePassword: 'minus mobile dexter forest elvis',
|
||||
}),
|
||||
},
|
||||
state: {
|
||||
cookies: [
|
||||
{
|
||||
sameSite: 'Lax',
|
||||
name: 'rc_uid',
|
||||
value: username,
|
||||
domain: 'localhost',
|
||||
path: '/',
|
||||
expires: -1,
|
||||
httpOnly: false,
|
||||
secure: false,
|
||||
},
|
||||
{
|
||||
sameSite: 'Lax',
|
||||
name: 'rc_token',
|
||||
value: token.token,
|
||||
domain: 'localhost',
|
||||
path: '/',
|
||||
expires: -1,
|
||||
httpOnly: false,
|
||||
secure: false,
|
||||
},
|
||||
],
|
||||
origins: [
|
||||
{
|
||||
origin: BASE_URL,
|
||||
localStorage: [
|
||||
{
|
||||
name: 'userLanguage',
|
||||
value: 'en-US',
|
||||
},
|
||||
{
|
||||
name: 'Meteor.loginToken',
|
||||
value: token.token,
|
||||
},
|
||||
{
|
||||
name: 'Meteor.loginTokenExpires',
|
||||
value: token.when.toISOString(),
|
||||
},
|
||||
{
|
||||
name: 'Meteor.userId',
|
||||
value: username,
|
||||
},
|
||||
...(e2eeData[username]
|
||||
? [
|
||||
{
|
||||
name: 'private_key',
|
||||
value: e2eeData[username]?.client.private_key,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export const Users = {
|
||||
user1: generateContext('user1'),
|
||||
user2: generateContext('user2'),
|
||||
user3: generateContext('user3'),
|
||||
userNotAllowedByApp: generateContext('userNotAllowedByApp'),
|
||||
userE2EE: generateContext('userE2EE'),
|
||||
samluser1: generateContext('samluser1'),
|
||||
samluser2: generateContext('samluser2'),
|
||||
samluser4: generateContext('samluser4'),
|
||||
samluser5: generateContext('samluser5'),
|
||||
samluser6: generateContext('samluser6'),
|
||||
samluser7: generateContext('samluser7'),
|
||||
samlusernoname: generateContext('custom_saml_username'),
|
||||
samlusernoname2: generateContext('custom_saml_username2'),
|
||||
userForSamlMerge: generateContext('user_for_saml_merge'),
|
||||
userForSamlMerge2: generateContext('user_for_saml_merge2'),
|
||||
admin: generateContext('rocketchat.internal.admin.test'),
|
||||
};
|
||||
|
||||
export async function storeState(page: Page, user: IUserState) {
|
||||
user.state.origins = (await page.context().storageState()).origins;
|
||||
}
|
||||
|
||||
export async function restoreState(page: Page, user: IUserState, options: { except?: string[] } = {}) {
|
||||
let ls = user.state.origins[0].localStorage;
|
||||
if (options.except?.length) {
|
||||
ls = ls.filter(({ name }) => !options.except?.includes(name));
|
||||
}
|
||||
|
||||
await page.evaluate((items) => {
|
||||
items.forEach(({ name, value }) => {
|
||||
window.localStorage.setItem(name, value);
|
||||
});
|
||||
}, ls);
|
||||
|
||||
await page.waitForTimeout(2000); // Wait for the login to be completed
|
||||
}
|
||||