@element-hq/element-web-playwright-common 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Dockerfile +9 -0
- package/README.md +28 -0
- package/lib/element-web-test.d.ts +26 -0
- package/lib/element-web-test.d.ts.map +1 -0
- package/lib/element-web-test.js +54 -0
- package/lib/expect/axe.d.ts +11 -0
- package/lib/expect/axe.d.ts.map +1 -0
- package/lib/expect/axe.js +22 -0
- package/lib/expect/index.d.ts +6 -0
- package/lib/expect/index.d.ts.map +1 -0
- package/lib/expect/index.js +10 -0
- package/lib/expect/screenshot.d.ts +14 -0
- package/lib/expect/screenshot.d.ts.map +1 -0
- package/lib/expect/screenshot.js +48 -0
- package/lib/expect/toHaveNoViolations.d.ts +11 -0
- package/lib/expect/toHaveNoViolations.d.ts.map +1 -0
- package/lib/expect/toHaveNoViolations.js +22 -0
- package/lib/expect/toMatchScreenshot.d.ts +13 -0
- package/lib/expect/toMatchScreenshot.d.ts.map +1 -0
- package/lib/expect/toMatchScreenshot.js +44 -0
- package/lib/expect/toPassAxeCheck.d.ts +7 -0
- package/lib/expect/toPassAxeCheck.d.ts.map +1 -0
- package/lib/expect/toPassAxeCheck.js +22 -0
- package/lib/fixtures/axe.d.ts +8 -0
- package/lib/fixtures/axe.d.ts.map +1 -0
- package/lib/fixtures/axe.js +15 -0
- package/lib/fixtures/index.d.ts +10 -0
- package/lib/fixtures/index.d.ts.map +1 -0
- package/lib/fixtures/index.js +10 -0
- package/lib/fixtures/services.d.ts +57 -0
- package/lib/fixtures/services.d.ts.map +1 -0
- package/lib/fixtures/services.js +114 -0
- package/lib/fixtures/user.d.ts +31 -0
- package/lib/fixtures/user.d.ts.map +1 -0
- package/lib/fixtures/user.js +47 -0
- package/lib/index.d.ts +35 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +54 -0
- package/lib/logger.d.ts +10 -0
- package/lib/logger.d.ts.map +1 -0
- package/lib/logger.js +59 -0
- package/lib/playwright.d.ts +2 -0
- package/lib/playwright.d.ts.map +1 -0
- package/lib/playwright.js +1 -0
- package/lib/testcontainers/HomeserverContainer.d.ts +70 -0
- package/lib/testcontainers/HomeserverContainer.d.ts.map +1 -0
- package/lib/testcontainers/HomeserverContainer.js +7 -0
- package/lib/testcontainers/index.d.ts +5 -0
- package/lib/testcontainers/index.d.ts.map +1 -0
- package/lib/testcontainers/index.js +9 -0
- package/lib/testcontainers/mailpit.d.ts +33 -0
- package/lib/testcontainers/mailpit.d.ts.map +1 -0
- package/lib/testcontainers/mailpit.js +52 -0
- package/lib/testcontainers/mas.d.ts +182 -0
- package/lib/testcontainers/mas.d.ts.map +1 -0
- package/lib/testcontainers/mas.js +311 -0
- package/lib/testcontainers/synapse.d.ts +229 -0
- package/lib/testcontainers/synapse.d.ts.map +1 -0
- package/lib/testcontainers/synapse.js +383 -0
- package/lib/utils/api.d.ts +49 -0
- package/lib/utils/api.d.ts.map +1 -0
- package/lib/utils/api.js +73 -0
- package/lib/utils/logger.d.ts +25 -0
- package/lib/utils/logger.d.ts.map +1 -0
- package/lib/utils/logger.js +74 -0
- package/lib/utils/object.d.ts +8 -0
- package/lib/utils/object.d.ts.map +1 -0
- package/lib/utils/object.js +15 -0
- package/lib/utils/port.d.ts +5 -0
- package/lib/utils/port.d.ts.map +1 -0
- package/lib/utils/port.js +20 -0
- package/lib/utils/rand.d.ts +6 -0
- package/lib/utils/rand.d.ts.map +1 -0
- package/lib/utils/rand.js +15 -0
- package/package.json +30 -0
- package/playwright-screenshots.sh +53 -0
- package/src/@types/playwright-core.d.ts +12 -0
- package/src/expect/axe.ts +37 -0
- package/src/expect/index.ts +21 -0
- package/src/expect/screenshot.ts +79 -0
- package/src/fixtures/axe.ts +22 -0
- package/src/fixtures/index.ts +15 -0
- package/src/fixtures/services.ts +188 -0
- package/src/fixtures/user.ts +93 -0
- package/src/index.ts +92 -0
- package/src/testcontainers/HomeserverContainer.ts +87 -0
- package/src/testcontainers/index.ts +15 -0
- package/src/testcontainers/mailpit.ts +62 -0
- package/src/testcontainers/mas.ts +382 -0
- package/src/testcontainers/synapse.ts +493 -0
- package/src/utils/api.ts +113 -0
- package/src/utils/logger.ts +79 -0
- package/src/utils/object.ts +16 -0
- package/src/utils/port.ts +22 -0
- package/src/utils/rand.ts +17 -0
- package/tsconfig.json +10 -0
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2024-2025 New Vector Ltd.
|
|
3
|
+
|
|
4
|
+
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
|
5
|
+
Please see LICENSE files in the repository root for full details.
|
|
6
|
+
*/
|
|
7
|
+
import { AbstractStartedContainer, GenericContainer, Wait, } from "testcontainers";
|
|
8
|
+
import * as YAML from "yaml";
|
|
9
|
+
import { getFreePort } from "../utils/port.js";
|
|
10
|
+
import { deepCopy } from "../utils/object.js";
|
|
11
|
+
const DEFAULT_CONFIG = {
|
|
12
|
+
http: {
|
|
13
|
+
listeners: [
|
|
14
|
+
{
|
|
15
|
+
name: "web",
|
|
16
|
+
resources: [
|
|
17
|
+
{ name: "discovery" },
|
|
18
|
+
{ name: "human" },
|
|
19
|
+
{ name: "oauth" },
|
|
20
|
+
{ name: "compat" },
|
|
21
|
+
{
|
|
22
|
+
name: "graphql",
|
|
23
|
+
playground: true,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: "assets",
|
|
27
|
+
path: "/usr/local/share/mas-cli/assets/",
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
binds: [
|
|
31
|
+
{
|
|
32
|
+
address: "[::]:8080",
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
proxy_protocol: false,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: "internal",
|
|
39
|
+
resources: [
|
|
40
|
+
{
|
|
41
|
+
name: "health",
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
binds: [
|
|
45
|
+
{
|
|
46
|
+
address: "[::]:8081",
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
proxy_protocol: false,
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
trusted_proxies: ["192.128.0.0/16", "172.16.0.0/12", "10.0.0.0/10", "127.0.0.1/8", "fd00::/8", "::1/128"],
|
|
53
|
+
public_base: "", // Needs to be set
|
|
54
|
+
issuer: "", // Needs to be set
|
|
55
|
+
},
|
|
56
|
+
database: {
|
|
57
|
+
host: "postgres",
|
|
58
|
+
port: 5432,
|
|
59
|
+
database: "postgres",
|
|
60
|
+
username: "postgres",
|
|
61
|
+
password: "p4S5w0rD",
|
|
62
|
+
max_connections: 10,
|
|
63
|
+
min_connections: 0,
|
|
64
|
+
connect_timeout: 30,
|
|
65
|
+
idle_timeout: 600,
|
|
66
|
+
max_lifetime: 1800,
|
|
67
|
+
},
|
|
68
|
+
telemetry: {
|
|
69
|
+
tracing: {
|
|
70
|
+
exporter: "none",
|
|
71
|
+
propagators: [],
|
|
72
|
+
},
|
|
73
|
+
metrics: {
|
|
74
|
+
exporter: "none",
|
|
75
|
+
},
|
|
76
|
+
sentry: {
|
|
77
|
+
dsn: null,
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
templates: {
|
|
81
|
+
path: "/usr/local/share/mas-cli/templates/",
|
|
82
|
+
assets_manifest: "/usr/local/share/mas-cli/manifest.json",
|
|
83
|
+
translations_path: "/usr/local/share/mas-cli/translations/",
|
|
84
|
+
},
|
|
85
|
+
email: {
|
|
86
|
+
from: '"Authentication Service" <root@localhost>',
|
|
87
|
+
reply_to: '"Authentication Service" <root@localhost>',
|
|
88
|
+
transport: "smtp",
|
|
89
|
+
mode: "plain",
|
|
90
|
+
hostname: "mailpit",
|
|
91
|
+
port: 1025,
|
|
92
|
+
username: "username",
|
|
93
|
+
password: "password",
|
|
94
|
+
},
|
|
95
|
+
secrets: {
|
|
96
|
+
encryption: "984b18e207c55ad5fbb2a49b217481a722917ee87b2308d4cf314c83fed8e3b5",
|
|
97
|
+
keys: [
|
|
98
|
+
{
|
|
99
|
+
kid: "YEAhzrKipJ",
|
|
100
|
+
key: "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAuIV+AW5vx52I4CuumgSxp6yvKfIAnRdALeZZCoFkIGxUli1B\nS79NJ3ls46oLh1pSD9RrhaMp6HTNoi4K3hnP9Q9v77pD7KwdFKG3UdG1zksIB0s/\n+/Ey/DmX4LPluwBBS7r/LkQ1jk745lENA++oiDqZf2D/uP8jCHlvaSNyVKTqi1ki\nOXPd4T4xBUjzuas9ze5jQVSYtfOidgnv1EzUipbIxgvH1jNt4raRlmP8mOq7xEnW\nR+cF5x6n/g17PdSEfrwO4kz6aKGZuMP5lVlDEEnMHKabFSQDBl7+Mpok6jXutbtA\nuiBnsKEahF9eoj4na4fpbRNPdIVyoaN5eGvm5wIDAQABAoIBAApyFCYEmHNWaa83\nCdVSOrRhRDE9r+c0r79pcNT1ajOjrk4qFa4yEC4R46YntCtfY5Hd1pBkIjU0l4d8\nz8Su9WTMEOwjQUEepS7L0NLi6kXZXYT8L40VpGs+32grBvBFHW0qEtQNrHJ36gMv\nx2rXoFTF7HaXiSJx3wvVxAbRqOE9tBXLsmNHaWaAdWQG5o77V9+zvMri3cAeEg2w\nVkKokb0dza7es7xG3tqS26k69SrwGeeuKo7qCHPH2cfyWmY5Yhv8iOoA59JzzbiK\nUdxyzCHskrPSpRKVkVVwmY3RBt282TmSRG7td7e5ESSj50P2e5BI5uu1Hp/dvU4F\nvYjV7kECgYEA6WqYoUpVsgQiqhvJwJIc/8gRm0mUy8TenI36z4Iim01Nt7fibWH7\nXnsFqLGjXtYNVWvBcCrUl9doEnRbJeG2eRGbGKYAWVrOeFvwM4fYvw9GoOiJdDj4\ncgWDe7eHbHE+UTqR7Nnr/UBfipoNWDh6X68HRBuXowh0Q6tOfxsrRFECgYEAyl/V\n4b8bFp3pKZZCb+KPSYsQf793cRmrBexPcLWcDPYbMZQADEZ/VLjbrNrpTOWxUWJT\nhr8MrWswnHO+l5AFu5CNO+QgV2dHLk+2w8qpdpFRPJCfXfo2D3wZ0c4cv3VCwv1V\n5y7f6XWVjDWZYV4wj6c3shxZJjZ+9Hbhf3/twbcCgYA6fuRRR3fCbRbi2qPtBrEN\nyO3gpMgNaQEA6vP4HPzfPrhDWmn8T5nXS61XYW03zxz4U1De81zj0K/cMBzHmZFJ\nNghQXQmpWwBzWVcREvJWr1Vb7erEnaJlsMwKrSvbGWYspSj82oAxr3hCG+lMOpsw\nb4S6pM+TpAK/EqdRY1WsgQKBgQCGoMaaTRXqL9bC0bEU2XVVCWxKb8c3uEmrwQ7/\n/fD4NmjUzI5TnDps1CVfkqoNe+hAKddDFqmKXHqUOfOaxDbsFje+lf5l5tDVoDYH\nfjTKKdYPIm7CiAeauYY7qpA5Vfq52Opixy4yEwUPp0CII67OggFtPaqY3zwJyWQt\n+57hdQKBgGCXM/KKt7ceUDcNJxSGjvu0zD9D5Sv2ihYlEBT/JLaTCCJdvzREevaJ\n1d+mpUAt0Lq6A8NWOMq8HPaxAik3rMQ0WtM5iG+XgsUqvTSb7NcshArDLuWGnW3m\nMC4rM0UBYAS4QweduUSH1imrwH/1Gu5+PxbiecceRMMggWpzu0Bq\n-----END RSA PRIVATE KEY-----\n",
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
kid: "8J1AxrlNZT",
|
|
104
|
+
key: "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIF1cjfIOEdy3BXJ72x6fKpEB8WP1ddZAUJAaqqr/6CpToAoGCCqGSM49\nAwEHoUQDQgAEfHdNuI1Yeh3/uOq2PlnW2vymloOVpwBYebbw4VVsna9xhnutIdQW\ndE8hkX8Yb0pIDasrDiwllVLzSvsWJAI0Kw==\n-----END EC PRIVATE KEY-----\n",
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
kid: "3BW6un1EBi",
|
|
108
|
+
key: "-----BEGIN EC PRIVATE KEY-----\nMIGkAgEBBDA+3ZV17r8TsiMdw1cpbTSNbyEd5SMy3VS1Mk/kz6O2Ev/3QZut8GE2\nq3eGtLBoVQigBwYFK4EEACKhZANiAASs8Wxjk/uRimRKXnPr2/wDaXkN9wMDjYQK\nmZULb+0ZP1/cXmuXuri8hUGhQvIU8KWY9PkpV+LMPEdpE54mHPKSLjq5CDXoSZ/P\n9f7cdRaOZ000KQPZfIFR9ujJTtDN7Vs=\n-----END EC PRIVATE KEY-----\n",
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
kid: "pkZ0pTKK0X",
|
|
112
|
+
key: "-----BEGIN EC PRIVATE KEY-----\nMHQCAQEEIHenfsXYPc5yzjZKUfvmydDR1YRwdsfZYvwHf/2wsYxooAcGBSuBBAAK\noUQDQgAEON1x7Vlu+nA0KvC5vYSOHhDUkfLYNZwYSLPFVT02h9E13yFFMIJegIBl\nAer+6PMZpPc8ycyeH9N+U9NAyliBhQ==\n-----END EC PRIVATE KEY-----\n",
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
},
|
|
116
|
+
passwords: {
|
|
117
|
+
enabled: true,
|
|
118
|
+
schemes: [
|
|
119
|
+
{
|
|
120
|
+
version: 1,
|
|
121
|
+
algorithm: "argon2id",
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
minimum_complexity: 0,
|
|
125
|
+
},
|
|
126
|
+
policy: {
|
|
127
|
+
wasm_module: "/usr/local/share/mas-cli/policy.wasm",
|
|
128
|
+
client_registration_entrypoint: "client_registration/violation",
|
|
129
|
+
register_entrypoint: "register/violation",
|
|
130
|
+
authorization_grant_entrypoint: "authorization_grant/violation",
|
|
131
|
+
password_entrypoint: "password/violation",
|
|
132
|
+
email_entrypoint: "email/violation",
|
|
133
|
+
data: {
|
|
134
|
+
client_registration: {
|
|
135
|
+
// allow non-SSL and localhost URIs
|
|
136
|
+
allow_insecure_uris: true,
|
|
137
|
+
// EW doesn't have contacts at this time
|
|
138
|
+
allow_missing_contacts: true,
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
upstream_oauth2: {
|
|
143
|
+
providers: [],
|
|
144
|
+
},
|
|
145
|
+
branding: {
|
|
146
|
+
service_name: null,
|
|
147
|
+
policy_uri: null,
|
|
148
|
+
tos_uri: null,
|
|
149
|
+
imprint: null,
|
|
150
|
+
logo_uri: null,
|
|
151
|
+
},
|
|
152
|
+
account: {
|
|
153
|
+
password_registration_enabled: true,
|
|
154
|
+
},
|
|
155
|
+
experimental: {
|
|
156
|
+
access_token_ttl: 300,
|
|
157
|
+
compat_token_ttl: 300,
|
|
158
|
+
},
|
|
159
|
+
rate_limiting: {
|
|
160
|
+
login: {
|
|
161
|
+
burst: 10,
|
|
162
|
+
per_second: 1,
|
|
163
|
+
},
|
|
164
|
+
registration: {
|
|
165
|
+
burst: 10,
|
|
166
|
+
per_second: 1,
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* A container running the Matrix Authentication Service.
|
|
172
|
+
*
|
|
173
|
+
* Exposes the MAS API on port 8080 and the health check on port 8081.
|
|
174
|
+
* Waits for HTTP /health on port 8081 to be available.
|
|
175
|
+
*/
|
|
176
|
+
export class MatrixAuthenticationServiceContainer extends GenericContainer {
|
|
177
|
+
config;
|
|
178
|
+
args = ["-c", "/config/config.yaml"];
|
|
179
|
+
constructor(db) {
|
|
180
|
+
// We rely on `mas-cli manage add-email` which isn't in a release yet
|
|
181
|
+
// https://github.com/element-hq/matrix-authentication-service/pull/3235
|
|
182
|
+
super("ghcr.io/element-hq/matrix-authentication-service:sha-0b90c33");
|
|
183
|
+
this.config = deepCopy(DEFAULT_CONFIG);
|
|
184
|
+
this.config.database.username = db.getUsername();
|
|
185
|
+
this.config.database.password = db.getPassword();
|
|
186
|
+
this.withExposedPorts(8080, 8081)
|
|
187
|
+
.withWaitStrategy(Wait.forHttp("/health", 8081))
|
|
188
|
+
.withCommand(["server", ...this.args]);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Adds additional configuration to the MAS config.
|
|
192
|
+
* @param config - additional config fields to add
|
|
193
|
+
*/
|
|
194
|
+
withConfig(config) {
|
|
195
|
+
this.config = {
|
|
196
|
+
...this.config,
|
|
197
|
+
...config,
|
|
198
|
+
};
|
|
199
|
+
return this;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Starts the MAS container
|
|
203
|
+
*/
|
|
204
|
+
async start() {
|
|
205
|
+
// MAS config issuer needs to know what URL it'll be accessed from, so we have to map the port manually
|
|
206
|
+
const port = await getFreePort();
|
|
207
|
+
this.config.http.public_base = `http://localhost:${port}/`;
|
|
208
|
+
this.config.http.issuer = `http://localhost:${port}/`;
|
|
209
|
+
this.withExposedPorts({
|
|
210
|
+
container: 8080,
|
|
211
|
+
host: port,
|
|
212
|
+
}).withCopyContentToContainer([
|
|
213
|
+
{
|
|
214
|
+
target: "/config/config.yaml",
|
|
215
|
+
content: YAML.stringify(this.config),
|
|
216
|
+
},
|
|
217
|
+
]);
|
|
218
|
+
return new StartedMatrixAuthenticationServiceContainer(await super.start(), `http://localhost:${port}`, this.args);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* A started Matrix Authentication Service container.
|
|
223
|
+
*/
|
|
224
|
+
export class StartedMatrixAuthenticationServiceContainer extends AbstractStartedContainer {
|
|
225
|
+
baseUrl;
|
|
226
|
+
args;
|
|
227
|
+
adminTokenPromise;
|
|
228
|
+
constructor(container, baseUrl, args) {
|
|
229
|
+
super(container);
|
|
230
|
+
this.baseUrl = baseUrl;
|
|
231
|
+
this.args = args;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Retrieves a valid HS admin token
|
|
235
|
+
*/
|
|
236
|
+
async getAdminToken() {
|
|
237
|
+
if (this.adminTokenPromise === undefined) {
|
|
238
|
+
this.adminTokenPromise = this.registerUserInternal("admin", "totalyinsecureadminpassword", undefined, true).then((res) => res.accessToken);
|
|
239
|
+
}
|
|
240
|
+
return this.adminTokenPromise;
|
|
241
|
+
}
|
|
242
|
+
async manage(cmd, ...args) {
|
|
243
|
+
const result = await this.exec(["mas-cli", "manage", cmd, ...this.args, ...args]);
|
|
244
|
+
if (result.exitCode !== 0) {
|
|
245
|
+
throw new Error(`Failed mas-cli manage ${cmd}: ${result.output}`);
|
|
246
|
+
}
|
|
247
|
+
return result;
|
|
248
|
+
}
|
|
249
|
+
async manageRegisterUser(username, password, displayName, admin = false) {
|
|
250
|
+
const args = [];
|
|
251
|
+
if (admin)
|
|
252
|
+
args.push("-a");
|
|
253
|
+
const result = await this.manage("register-user", ...args, "-y", "-p", password, "-d", displayName ?? "", username);
|
|
254
|
+
const registerLines = result.output.trim().split("\n");
|
|
255
|
+
const userId = registerLines
|
|
256
|
+
.find((line) => line.includes("Matrix ID: "))
|
|
257
|
+
?.split(": ")
|
|
258
|
+
.pop();
|
|
259
|
+
if (!userId) {
|
|
260
|
+
throw new Error(`Failed to register user: ${result.output}`);
|
|
261
|
+
}
|
|
262
|
+
return userId;
|
|
263
|
+
}
|
|
264
|
+
async manageIssueCompatibilityToken(username, admin = false) {
|
|
265
|
+
const args = [];
|
|
266
|
+
if (admin)
|
|
267
|
+
args.push("--yes-i-want-to-grant-synapse-admin-privileges");
|
|
268
|
+
const result = await this.manage("issue-compatibility-token", ...args, username);
|
|
269
|
+
const parts = result.output.trim().split(/\s+/);
|
|
270
|
+
const accessToken = parts.find((part) => part.startsWith("mct_"));
|
|
271
|
+
const deviceId = parts.find((part) => part.startsWith("compat_session.device="))?.split("=")[1];
|
|
272
|
+
if (!accessToken || !deviceId) {
|
|
273
|
+
throw new Error(`Failed to issue compatibility token: ${result.output}`);
|
|
274
|
+
}
|
|
275
|
+
return { accessToken, deviceId };
|
|
276
|
+
}
|
|
277
|
+
async registerUserInternal(username, password, displayName, admin = false) {
|
|
278
|
+
const userId = await this.manageRegisterUser(username, password, displayName, admin);
|
|
279
|
+
const { deviceId, accessToken } = await this.manageIssueCompatibilityToken(username, admin);
|
|
280
|
+
return {
|
|
281
|
+
userId,
|
|
282
|
+
accessToken,
|
|
283
|
+
deviceId,
|
|
284
|
+
homeServer: userId.slice(1).split(":").slice(1).join(":"),
|
|
285
|
+
displayName,
|
|
286
|
+
username,
|
|
287
|
+
password,
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Registers a user
|
|
292
|
+
* @param username - the username of the user to register
|
|
293
|
+
* @param password - the password of the user to register
|
|
294
|
+
* @param displayName - optional display name to set on the newly registered user
|
|
295
|
+
*/
|
|
296
|
+
async registerUser(username, password, displayName) {
|
|
297
|
+
return this.registerUserInternal(username, password, displayName, false);
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Binds a 3pid
|
|
301
|
+
* @param username - the username of the user to bind the 3pid to
|
|
302
|
+
* @param medium - the medium of the 3pid to bind
|
|
303
|
+
* @param address - the address of the 3pid to bind
|
|
304
|
+
*/
|
|
305
|
+
async setThreepid(username, medium, address) {
|
|
306
|
+
if (medium !== "email") {
|
|
307
|
+
throw new Error("Only email threepids are supported by MAS");
|
|
308
|
+
}
|
|
309
|
+
await this.manage("add-email", username, address);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { AbstractStartedContainer, GenericContainer, type RestartOptions, type StartedTestContainer } from "testcontainers";
|
|
2
|
+
import { type APIRequestContext, type TestInfo } from "@playwright/test";
|
|
3
|
+
import { type HomeserverContainer, type StartedHomeserverContainer } from "./HomeserverContainer.js";
|
|
4
|
+
import { type StartedMatrixAuthenticationServiceContainer } from "./mas.js";
|
|
5
|
+
import { Api, ClientServerApi, type Credentials } from "../utils/api.js";
|
|
6
|
+
import { StartedMailpitContainer } from "./mailpit.js";
|
|
7
|
+
declare const DEFAULT_CONFIG: {
|
|
8
|
+
server_name: string;
|
|
9
|
+
public_baseurl: string;
|
|
10
|
+
pid_file: string;
|
|
11
|
+
web_client: boolean;
|
|
12
|
+
soft_file_limit: number;
|
|
13
|
+
log_config: string;
|
|
14
|
+
listeners: {
|
|
15
|
+
port: number;
|
|
16
|
+
tls: boolean;
|
|
17
|
+
bind_addresses: string[];
|
|
18
|
+
type: string;
|
|
19
|
+
x_forwarded: boolean;
|
|
20
|
+
resources: {
|
|
21
|
+
names: string[];
|
|
22
|
+
compress: boolean;
|
|
23
|
+
}[];
|
|
24
|
+
}[];
|
|
25
|
+
database: {
|
|
26
|
+
name: string;
|
|
27
|
+
args: {
|
|
28
|
+
database: string;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
rc_messages_per_second: number;
|
|
32
|
+
rc_message_burst_count: number;
|
|
33
|
+
rc_registration: {
|
|
34
|
+
per_second: number;
|
|
35
|
+
burst_count: number;
|
|
36
|
+
};
|
|
37
|
+
rc_joins: {
|
|
38
|
+
local: {
|
|
39
|
+
per_second: number;
|
|
40
|
+
burst_count: number;
|
|
41
|
+
};
|
|
42
|
+
remote: {
|
|
43
|
+
per_second: number;
|
|
44
|
+
burst_count: number;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
rc_joins_per_room: {
|
|
48
|
+
per_second: number;
|
|
49
|
+
burst_count: number;
|
|
50
|
+
};
|
|
51
|
+
rc_3pid_validation: {
|
|
52
|
+
per_second: number;
|
|
53
|
+
burst_count: number;
|
|
54
|
+
};
|
|
55
|
+
rc_invites: {
|
|
56
|
+
per_room: {
|
|
57
|
+
per_second: number;
|
|
58
|
+
burst_count: number;
|
|
59
|
+
};
|
|
60
|
+
per_user: {
|
|
61
|
+
per_second: number;
|
|
62
|
+
burst_count: number;
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
rc_login: {
|
|
66
|
+
address: {
|
|
67
|
+
per_second: number;
|
|
68
|
+
burst_count: number;
|
|
69
|
+
};
|
|
70
|
+
account: {
|
|
71
|
+
per_second: number;
|
|
72
|
+
burst_count: number;
|
|
73
|
+
};
|
|
74
|
+
failed_attempts: {
|
|
75
|
+
per_second: number;
|
|
76
|
+
burst_count: number;
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
media_store_path: string;
|
|
80
|
+
max_upload_size: string;
|
|
81
|
+
max_image_pixels: string;
|
|
82
|
+
dynamic_thumbnails: boolean;
|
|
83
|
+
enable_registration: boolean;
|
|
84
|
+
enable_registration_without_verification: boolean;
|
|
85
|
+
disable_msisdn_registration: boolean;
|
|
86
|
+
registrations_require_3pid: never[];
|
|
87
|
+
enable_metrics: boolean;
|
|
88
|
+
report_stats: boolean;
|
|
89
|
+
registration_shared_secret: string;
|
|
90
|
+
macaroon_secret_key: string;
|
|
91
|
+
form_secret: string;
|
|
92
|
+
signing_key_path: string;
|
|
93
|
+
trusted_key_servers: never[];
|
|
94
|
+
password_config: {
|
|
95
|
+
enabled: boolean;
|
|
96
|
+
};
|
|
97
|
+
ui_auth: {};
|
|
98
|
+
background_updates: {
|
|
99
|
+
min_batch_size: number;
|
|
100
|
+
sleep_duration_ms: number;
|
|
101
|
+
};
|
|
102
|
+
enable_authenticated_media: boolean;
|
|
103
|
+
email: undefined | {
|
|
104
|
+
enable_notifs: boolean;
|
|
105
|
+
smtp_host: string;
|
|
106
|
+
smtp_port: number;
|
|
107
|
+
smtp_user: string;
|
|
108
|
+
smtp_pass: string;
|
|
109
|
+
require_transport_security: false;
|
|
110
|
+
notif_from: string;
|
|
111
|
+
app_name: string;
|
|
112
|
+
notif_template_html: string;
|
|
113
|
+
notif_template_text: string;
|
|
114
|
+
notif_for_new_users: boolean;
|
|
115
|
+
client_base_url: string;
|
|
116
|
+
};
|
|
117
|
+
user_consent: undefined | {
|
|
118
|
+
template_dir: string;
|
|
119
|
+
version: string;
|
|
120
|
+
server_notice_content: Record<string, unknown>;
|
|
121
|
+
send_server_notice_to_guests: boolean;
|
|
122
|
+
block_events_error: string;
|
|
123
|
+
require_at_registration: boolean;
|
|
124
|
+
};
|
|
125
|
+
server_notices: undefined | {
|
|
126
|
+
system_mxid_localpart: string;
|
|
127
|
+
system_mxid_display_name: string;
|
|
128
|
+
system_mxid_avatar_url: string;
|
|
129
|
+
room_name: string;
|
|
130
|
+
};
|
|
131
|
+
allow_guest_access: boolean;
|
|
132
|
+
experimental_features: {};
|
|
133
|
+
oidc_providers: never[];
|
|
134
|
+
serve_server_wellknown: boolean;
|
|
135
|
+
presence: {
|
|
136
|
+
enabled: boolean;
|
|
137
|
+
include_offline_users_on_sync: boolean;
|
|
138
|
+
};
|
|
139
|
+
room_list_publication_rules: {
|
|
140
|
+
action: string;
|
|
141
|
+
}[];
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Incomplete type describing the configuration for a Synapse homeserver
|
|
145
|
+
*/
|
|
146
|
+
export type SynapseConfig = typeof DEFAULT_CONFIG;
|
|
147
|
+
/**
|
|
148
|
+
* A Synapse testcontainer
|
|
149
|
+
*
|
|
150
|
+
* Exposes port 8008.
|
|
151
|
+
* Waits for HTTP /health 8008 to 200.
|
|
152
|
+
*/
|
|
153
|
+
export declare class SynapseContainer extends GenericContainer implements HomeserverContainer<SynapseConfig> {
|
|
154
|
+
private config;
|
|
155
|
+
private mas?;
|
|
156
|
+
constructor();
|
|
157
|
+
withConfigField(key: string, value: unknown): this;
|
|
158
|
+
withConfig(config: Partial<SynapseConfig>): this;
|
|
159
|
+
withSmtpServer(mailpit: StartedMailpitContainer): this;
|
|
160
|
+
withMatrixAuthenticationService(mas?: StartedMatrixAuthenticationServiceContainer): this;
|
|
161
|
+
start(): Promise<StartedSynapseContainer>;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* A started Synapse testcontainer
|
|
165
|
+
*/
|
|
166
|
+
export declare class StartedSynapseContainer extends AbstractStartedContainer implements StartedHomeserverContainer {
|
|
167
|
+
readonly baseUrl: string;
|
|
168
|
+
private readonly registrationSharedSecret;
|
|
169
|
+
protected adminTokenPromise?: Promise<string>;
|
|
170
|
+
protected readonly adminApi: Api;
|
|
171
|
+
readonly csApi: ClientServerApi;
|
|
172
|
+
constructor(container: StartedTestContainer, baseUrl: string, registrationSharedSecret: string);
|
|
173
|
+
/**
|
|
174
|
+
* Restart the container
|
|
175
|
+
* Useful to reset the state of the homeserver between tests
|
|
176
|
+
* @param options - options to pass to the restart
|
|
177
|
+
*/
|
|
178
|
+
restart(options?: Partial<RestartOptions>): Promise<void>;
|
|
179
|
+
setRequest(request: APIRequestContext): void;
|
|
180
|
+
onTestFinished(testInfo: TestInfo): Promise<void>;
|
|
181
|
+
protected deletePublicRooms(): Promise<void>;
|
|
182
|
+
private registerUserInternal;
|
|
183
|
+
protected getAdminToken(): Promise<string>;
|
|
184
|
+
private adminRequest;
|
|
185
|
+
/**
|
|
186
|
+
* Register a user on the given Homeserver using the shared registration secret.
|
|
187
|
+
* @param username - the username of the user to register
|
|
188
|
+
* @param password - the password of the user to register
|
|
189
|
+
* @param displayName - optional display name to set on the newly registered user
|
|
190
|
+
*/
|
|
191
|
+
registerUser(username: string, password: string, displayName?: string): Promise<Credentials>;
|
|
192
|
+
/**
|
|
193
|
+
* Logs into synapse with the given username/password
|
|
194
|
+
* @param userId - login username
|
|
195
|
+
* @param password - login password
|
|
196
|
+
*/
|
|
197
|
+
loginUser(userId: string, password: string): Promise<Credentials>;
|
|
198
|
+
/**
|
|
199
|
+
* Binds a 3pid
|
|
200
|
+
* @param userId - the username of the user to bind the 3pid to
|
|
201
|
+
* @param medium - the medium of the 3pid to bind
|
|
202
|
+
* @param address - the address of the 3pid to bind
|
|
203
|
+
*/
|
|
204
|
+
setThreepid(userId: string, medium: string, address: string): Promise<void>;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* A started Synapse container when delegating auth to MAS
|
|
208
|
+
*/
|
|
209
|
+
export declare class StartedSynapseWithMasContainer extends StartedSynapseContainer {
|
|
210
|
+
private readonly mas;
|
|
211
|
+
constructor(container: StartedTestContainer, baseUrl: string, registrationSharedSecret: string, mas: StartedMatrixAuthenticationServiceContainer);
|
|
212
|
+
protected getAdminToken(): Promise<string>;
|
|
213
|
+
/**
|
|
214
|
+
* Register a user on the given Homeserver using the shared registration secret.
|
|
215
|
+
* @param username - the username of the user to register
|
|
216
|
+
* @param password - the password of the user to register
|
|
217
|
+
* @param displayName - optional display name to set on the newly registered user
|
|
218
|
+
*/
|
|
219
|
+
registerUser(username: string, password: string, displayName?: string): Promise<Credentials>;
|
|
220
|
+
/**
|
|
221
|
+
* Binds a 3pid
|
|
222
|
+
* @param userId - the username of the user to bind the 3pid to
|
|
223
|
+
* @param medium - the medium of the 3pid to bind
|
|
224
|
+
* @param address - the address of the 3pid to bind
|
|
225
|
+
*/
|
|
226
|
+
setThreepid(userId: string, medium: string, address: string): Promise<void>;
|
|
227
|
+
}
|
|
228
|
+
export {};
|
|
229
|
+
//# sourceMappingURL=synapse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"synapse.d.ts","sourceRoot":"","sources":["../../src/testcontainers/synapse.ts"],"names":[],"mappings":"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"}
|