Compare commits

..

1 Commits

Author SHA1 Message Date
Vladimir D
b72a23cf0d MAS implementation 2025-04-25 14:25:20 +04:00
11 changed files with 559 additions and 501 deletions

View File

@@ -1393,100 +1393,3 @@
* Add background job to clear unreferenced state groups. (#18254) * Add background job to clear unreferenced state groups. (#18254)
* Hashes of media files are now tracked by Synapse. Media quarantines will now apply to all files with the same hash. (#18277, #18302, #18296) * Hashes of media files are now tracked by Synapse. Media quarantines will now apply to all files with the same hash. (#18277, #18302, #18296)
[1.110.0]
* Update synapse to 1.129.0
* [Full Changelog](https://github.com/element-hq/synapse/releases/tag/v1.129.0)
[1.111.0]
* Update synapse to 1.130.0
* [Full Changelog](https://github.com/element-hq/synapse/releases/tag/v1.130.0)
* Fix startup being blocked on creating a new index that was introduced in v1.130.0rc1. ([#​18439](https://github.com/element-hq/synapse/issues/18439))
* Fix the ordering of local messages in rooms that were affected by [GHSA-v56r-hwv5-mxg6](https://github.com/advisories/GHSA-v56r-hwv5-mxg6). ([#​18447](https://github.com/element-hq/synapse/issues/18447))
[1.112.0]
* Update synapse to 1.131.0
* [Full Changelog](https://github.com/element-hq/synapse/releases/tag/v1.131.0)
[1.113.0]
* Update synapse to 1.132.0
* [Full Changelog](https://github.com/element-hq/synapse/releases/tag/v1.132.0)
[1.114.0]
* Update synapse to 1.133.0
* [Full Changelog](https://github.com/element-hq/synapse/releases/tag/v1.133.0)
* Pre-built wheels are now built using the manylinux\_2\_28 base, which is expected to be compatible with distros using glibc 2.28 or later, including:
* Previously, wheels were built using the manylinux2014 base, which was expected to be compatible with distros using glibc 2.17 or later.
* Bump `cibuildwheel` to 3.0.0 to fix the `manylinux` wheel builds. ([#​18615](https://github.com/element-hq/synapse/issues/18615))
[1.115.0]
* Update synapse to 1.134.0
* [Full Changelog](https://github.com/element-hq/synapse/releases/tag/v1.134.0)
[1.116.0]
* Update synapse to 1.135.0
* [Full Changelog](https://github.com/element-hq/synapse/releases/tag/v1.135.0)
[1.116.1]
* Update synapse to 1.135.2
* [Full Changelog](https://github.com/element-hq/synapse/releases/tag/v1.135.2)
* Fix invalidation of storage cache that was broken in 1.135.0. ([#​18786](https://github.com/element-hq/synapse/issues/18786))
* Add a parameter to `upgrade_rooms(..)` to allow auto join local users. ([#​82](https://github.com/element-hq/synapse/issues/82))
* Speed up upgrading a room with large numbers of banned users. ([#​18574](https://github.com/element-hq/synapse/issues/18574))
[1.117.0]
* Update synapse to 1.136.0
* [Full Changelog](https://github.com/element-hq/synapse/releases/tag/v1.136.0)
* Fix bug introduced in 1.135.2 and 1.136.0rc2 where the [Make Room Admin API](https://element-hq.github.io/synapse/latest/admin_api/rooms.html#make-room-admin-api) would not treat a room v12's creator power level as the highest in room. ([#​18805](https://github.com/element-hq/synapse/issues/18805))
[1.118.0]
* Update synapse to 1.137.0
* [Full Changelog](https://github.com/element-hq/synapse/releases/tag/v1.137.0)
* Fix a bug which could corrupt auth chains making it impossible to perform state resolution. (#18746)
* Fix error message in register_new_matrix_user utility script for empty registration_shared_secret. (#18780)
* Allow enabling MSC4108 when the stable Matrix Authentication Service integration is enabled. (#18832)
* Include IPv6 networks in denied-peer-ips of coturn setup. Contributed by @litetex. (#18781)
[1.119.0]
* Update synapse to 1.138.0
* [Full Changelog](https://github.com/element-hq/synapse/releases/tag/v1.138.0)
* Support for the stable endpoint and scopes of [MSC3861](https://github.com/matrix-org/matrix-spec-proposals/pull/3861) & co. ([\#18549](https://github.com/element-hq/synapse/issues/18549))
* Improve database performance of [MSC4293](https://github.com/matrix-org/matrix-spec-proposals/pull/4293) - Redact on Kick/Ban. ([\#18851](https://github.com/element-hq/synapse/issues/18851))
* Do not throw an error when fetching a rejected delayed state event on startup. ([\#18858](https://github.com/element-hq/synapse/issues/18858))
* Fix worker documentation incorrectly indicating all room Admin API requests were capable of being handled by workers. ([\#18853](https://github.com/element-hq/synapse/issues/18853))
* Instrument `_ByteProducer` with tracing to measure potential dead time while writing bytes to the request. ([\#18804](https://github.com/element-hq/synapse/issues/18804))
* Switch to OpenTracing's `ContextVarsScopeManager` instead of our own custom `LogContextScopeManager`. ([\#18849](https://github.com/element-hq/synapse/issues/18849))
* Trace how much work is being done while "recursively fetching redactions". ([\#18854](https://github.com/element-hq/synapse/issues/18854))
* Link [upstream Twisted bug](https://github.com/twisted/twisted/issues/12498) tracking the problem that explains why we have to use a `Producer` to write bytes to the request. ([\#18855](https://github.com/element-hq/synapse/issues/18855))
* Introduce `EventPersistencePair` type. ([\#18857](https://github.com/element-hq/synapse/issues/18857))
[1.119.1]
* Update synapse to 1.138.2
* [Full Changelog](https://github.com/element-hq/synapse/releases/tag/v1.138.2)
* Drop support for Ubuntu 24.10 Oracular Oriole, and add support for Ubuntu 25.04 Plucky Puffin. This change was applied on top of 1.138.1. ([#​18962](https://github.com/element-hq/synapse/issues/18962))
[1.120.0]
* Update synapse to 1.139.0
* [Full Changelog](https://github.com/element-hq/synapse/releases/tag/v1.139.0)
* /register requests from old application service implementations may break when using MAS
[1.120.1]
* Update synapse to 1.139.1
* [Full Changelog](https://github.com/element-hq/synapse/releases/tag/v1.139.1)
* Fix [CVE-2025-61672](https://www.cve.org/CVERecord?id=CVE-2025-61672) / [GHSA-fh66-fcv5-jjfr](https://github.com/element-hq/synapse/security/advisories/GHSA-fh66-fcv5-jjfr). Lack of validation for device keys in Synapse before 1.139.1 allows an attacker registered on the victim homeserver to degrade federation functionality, unpredictably breaking outbound federation to other homeservers. ([#17097](https://github.com/element-hq/synapse/issues/17097))
* Drop support for unstable field names from the long-accepted [MSC2732](https://github.com/matrix-org/matrix-spec-proposals/pull/2732) (Olm fallback keys) proposal. This change allows unit tests to pass following the security patch above. ([#18996](https://github.com/element-hq/synapse/issues/18996))
[1.120.2]
* Update synapse to 1.139.2
[1.120.3]
* Update synapse-s3-storage-provider to 1.6.0
[1.121.0]
* Update synapse to 1.140.0
* [Full Changelog](https://github.com/element-hq/synapse/releases/tag/v1.140.0)
* Add a new Media Query by ID Admin API that allows server admins to query and investigate the metadata of local or cached remote media via the origin/media_id identifier found in a Matrix Content URI. (#18911)
* Add a new Fetch Event Admin API to fetch an event by ID. (#18963)
* Update MSC4284: Policy Servers implementation to support signatures when available. (#18934)
* Add experimental implementation of the GET /_matrix/client/v1/rtc/transports endpoint for the latest draft of MSC4143: MatrixRTC. (#18967)
* Expose a defer_to_threadpool function in the Synapse Module API that allows modules to run a function on a separate thread in a custom threadpool. (#19032)

View File

@@ -5,15 +5,23 @@
"description": "file://DESCRIPTION.md", "description": "file://DESCRIPTION.md",
"changelog": "file://CHANGELOG.md", "changelog": "file://CHANGELOG.md",
"tagline": "Secure & decentralized communication", "tagline": "Secure & decentralized communication",
"version": "1.121.0", "version": "1.109.0",
"upstreamVersion": "1.140.0", "upstreamVersion": "1.128.0",
"healthCheckPath": "/", "healthCheckPath": "/",
"httpPort": 8008, "httpPort": 8008,
"httpPorts": {
"MAS_DOMAIN": {
"title": "Matrix Authentication Service Domain",
"description": "Matrix Authentication Service domain",
"containerPort": 8080,
"defaultValue": "auth"
}
},
"memoryLimit": 536870912, "memoryLimit": 536870912,
"addons": { "addons": {
"localstorage": {}, "localstorage": {},
"oidc": { "oidc": {
"loginRedirectUri": "/_synapse/client/oidc/callback" "loginRedirectUri": "/_synapse/client/oidc/callback, /upstream/callback/000000000000000000C10WDR0N"
}, },
"postgresql": {}, "postgresql": {},
"sendmail": { "sendmail": {
@@ -44,18 +52,9 @@
"https://screenshots.cloudron.io/org.matrix.synapse/2.png", "https://screenshots.cloudron.io/org.matrix.synapse/2.png",
"https://screenshots.cloudron.io/org.matrix.synapse/3.png" "https://screenshots.cloudron.io/org.matrix.synapse/3.png"
], ],
"checklist": {
"configure-federation": {
"message": "For federation to work, the delegation URI `https://$CLOUDRON-APP-DOMAIN/.well-known/matrix/server` must be configured. See the [docs](https://docs.cloudron.io/apps/synapse/#post-installation) on how to do this."
},
"registration-enabled-without-verification": {
"message": "Registration is enabled but verification is disabled. See [docs](https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html?highlight=registration_require#enable_registration) for more information",
"sso": false
}
},
"postInstallMessage": "file://POSTINSTALL.md", "postInstallMessage": "file://POSTINSTALL.md",
"minBoxVersion": "8.2.0", "minBoxVersion": "7.5.1",
"forumUrl": "https://forum.cloudron.io/category/50/matrix-synapse-riot", "forumUrl": "https://forum.cloudron.io/category/50/matrix-synapse-riot",
"documentationUrl": "https://docs.cloudron.io/packages/synapse/", "documentationUrl": "https://docs.cloudron.io/apps/synapse/",
"optionalSso": true "optionalSso": true
} }

View File

@@ -8,10 +8,13 @@ WORKDIR /app/code
RUN python3 -m venv /app/code/env RUN python3 -m venv /app/code/env
# renovate: datasource=github-releases depName=element-hq/synapse versioning=semver extractVersion=^v(?<version>.+)$ # renovate: datasource=github-releases depName=element-hq/synapse versioning=semver extractVersion=^v(?<version>.+)$
ARG SYNAPSE_VERSION=1.140.0 ARG SYNAPSE_VERSION=1.128.0
# renovate: datasource=github-releases depName=matrix-org/synapse-s3-storage-provider versioning=semver extractVersion=^v(?<version>.+)$ # renovate: datasource=github-releases depName=matrix-org/synapse-s3-storage-provider versioning=semver extractVersion=^v(?<version>.+)$
ARG S3PROVIDER_VERSION=1.6.0 ARG S3PROVIDER_VERSION=1.5.0
# renovate: datasource=github-releases depName=element-hq/matrix-authentication-service versioning=semver extractVersion=^v(?<version>.+)$
ARG MAS_VERSION=0.15.0
# Synapse (https://github.com/matrix-org/synapse/blob/master/INSTALL.md) # Synapse (https://github.com/matrix-org/synapse/blob/master/INSTALL.md)
# lxml - required for previews # lxml - required for previews
@@ -21,8 +24,19 @@ RUN source /app/code/env/bin/activate && \
# Updated suffix list # Updated suffix list
RUN curl -L https://publicsuffix.org/list/public_suffix_list.dat -o /app/code/env/lib/python3.12/site-packages/publicsuffix2/public_suffix_list.dat RUN curl -L https://publicsuffix.org/list/public_suffix_list.dat -o /app/code/env/lib/python3.12/site-packages/publicsuffix2/public_suffix_list.dat
# matrix-authentication-service
RUN mkdir -p /app/code/mas && \
curl -L https://github.com/element-hq/matrix-authentication-service/releases/download/v${MAS_VERSION}/mas-cli-x86_64-linux.tar.gz | tar zxf - --strip-components 1 -C /app/code/mas
ENV PATH=$PATH:/app/code/mas
RUN ln -sf /app/data/index.html /app/code/env/lib/python3.12/site-packages/synapse/static/index.html RUN ln -sf /app/data/index.html /app/code/env/lib/python3.12/site-packages/synapse/static/index.html
# Add supervisor configs
COPY supervisor/* /etc/supervisor/conf.d/
RUN ln -sf /run/synapse/supervisord.log /var/log/supervisor/supervisord.log
RUN chown -R cloudron:cloudron /app/code
ADD index.html homeserver.yaml.template start.sh /app/pkg/ ADD index.html homeserver.yaml.template start.sh /app/pkg/
CMD [ "/app/pkg/start.sh" ] CMD [ "/app/pkg/start.sh" ]

View File

@@ -1,2 +1,6 @@
Account ids are created with the username and the second level domain under which the Account ids are created with the username and the second level domain under which the
app is installed e.g. `@$CLOUDRON-USERNAME:$CLOUDRON-APP-DOMAIN`. app is installed e.g. `@$CLOUDRON-USERNAME:$CLOUDRON-APP-DOMAIN`.
For federation to work, the delegation URI `https://$CLOUDRON-APP-DOMAIN/.well-known/matrix/server`
must be configured. See the [docs](https://docs.cloudron.io/apps/synapse/#post-installation) on how to do this.

View File

@@ -1,4 +1,4 @@
# https://github.com/element-hq/synapse/blob/master/docs/sample_config.yaml # https://github.com/matrix-org/synapse/blob/master/docs/sample_config.yaml
# if you change this, change the auto_join_rooms below as well # if you change this, change the auto_join_rooms below as well
server_name: "example.com" server_name: "example.com"
@@ -13,6 +13,7 @@ listeners:
type: http type: http
x_forwarded: true x_forwarded: true
bind_addresses: ['0.0.0.0'] bind_addresses: ['0.0.0.0']
resources: resources:
- names: [client,federation] - names: [client,federation]
compress: false compress: false
@@ -20,6 +21,7 @@ listeners:
database: database:
name: "psycopg2" name: "psycopg2"
args: args:
# Path to the database
user: ${POSTGRESQL_USERNAME} user: ${POSTGRESQL_USERNAME}
password: ${POSTGRESQL_PASSWORD} password: ${POSTGRESQL_PASSWORD}
database: ${POSTGRESQL_DATABASE} database: ${POSTGRESQL_DATABASE}
@@ -27,17 +29,6 @@ database:
cp_min: 5 cp_min: 5
cp_max: 10 cp_max: 10
log_config: "/app/data/configs/log.config"
media_store_path: "/app/data/data/media_store"
registration_shared_secret: "some_shared_secret"
report_stats: false
macaroon_secret_key: "some_macaroon_secret"
form_secret: "some_form_secret"
signing_key_path: "/app/data/configs/signing.key"
trusted_key_servers:
- server_name: "matrix.org"
## Cloudron packaging
email: email:
smtp_host: mail.server smtp_host: mail.server
smtp_port: 587 smtp_port: 587
@@ -49,37 +40,74 @@ email:
enable_notifs: true enable_notifs: true
notif_for_new_users: true notif_for_new_users: true
password_providers:
- module: "synapse.util.ldap_auth_provider.LdapAuthProvider"
config:
enabled: true
uri: "ldap://ldap.example.com:389"
start_tls: true
base: "ou=users,dc=example,dc=com"
attributes:
uid: "username"
mail: "mail"
name: "username"
bind_dn: "ou=users,dc=cloudron"
bind_password: "password"
filter: "(objectClass=posixAccount)"
# turn # turn
turn_uris: [] turn_uris: []
turn_shared_secret: "sharedsecret" turn_shared_secret: "sharedsecret"
turn_allow_guests: true turn_allow_guests: true
# sso (https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#single-sign-on-integration) federation_ip_range_blacklist:
enable_registration: false - '127.0.0.0/8'
# without this, registration requires one of email/captcha/token verification - '10.0.0.0/8'
enable_registration_without_verification: true - '172.16.0.0/12'
- '192.168.0.0/16'
- '100.64.0.0/10'
- '169.254.0.0/16'
- '::1/128'
- 'fe80::/64'
- 'fc00::/7'
oidc_providers: enable_registration: false
- idp_id: cloudron enable_registration_without_verification: true
idp_name: "CLOUDRON_OIDC_PROVIDER_NAME" registration_shared_secret: "somesecret"
issuer: "CLOUDRON_OIDC_ISSUER" allow_guest_access: false
client_id: "CLOUDRON_OIDC_CLIENT_ID"
client_secret: "CLOUDRON_OIDC_CLIENT_SECRET" enable_group_creation: true
scopes: ["openid", "profile", "email"]
authorization_endpoint: "CLOUDRON_OIDC_AUTH_ENDPOINT" report_stats: False
token_endpoint: "CLOUDRON_OIDC_TOKEN_ENDPOINT"
userinfo_endpoint: "CLOUDRON_OIDC_AUTH_ENDPOINT" signing_key_path: "/app/data/configs/signing.key"
allow_existing_users: true
enable_registration: true url_preview_enabled: true
backchannel_logout_enabled: false url_preview_ip_range_blacklist:
user_mapping_provider: - '127.0.0.0/8'
config: - '10.0.0.0/8'
localpart_template: "{{ user.sub }}" - '172.16.0.0/12'
display_name_template: "{{ user.name }}" - '192.168.0.0/16'
email_template: "{{ user.email }}" - '100.64.0.0/10'
- '169.254.0.0/16'
- '::1/128'
- 'fe80::/64'
- 'fc00::/7'
media_store_path: "/app/data/data/media_store"
max_upload_size: 200M
max_image_pixels: "32M"
dynamic_thumbnails: false
autocreate_auto_join_rooms: true
auto_join_rooms:
- "#discuss:example.com"
trusted_key_servers:
- server_name: "matrix.org"
suppress_key_server_warning: true
password_config: password_config:
enabled: false enabled: true
localdb_enabled: false localdb_enabled: false
pepper: "some_pepper_secret"

152
start.sh
View File

@@ -2,10 +2,96 @@
set -eu set -eu
mkdir -p /app/data/data /app/data/configs /run/synapse mkdir -p /app/data/data /app/data/configs/policies /run/synapse
source /app/code/env/bin/activate source /app/code/env/bin/activate
mas_client_id="0000000000000000000SYNAPSE"
cloudron_client_id="000000000000000000C10WDR0N" # a valid ULID excludes I, L, O, and U
mas_client_secret=$(openssl rand -hex 32)
matrix_secret=$(openssl rand -hex 32)
function mas_config() {
export MAS_CONFIG=/run/synapse/mas-config.yaml
echo "MAS configuration"
if [[ ! -f /app/data/configs/mas.yaml ]]; then
mas-cli config generate > /app/data/configs/mas.yaml
yq eval -i ".email.from=\"${CLOUDRON_MAIL_FROM_DISPLAY_NAME:-Matrix} <${CLOUDRON_MAIL_FROM}>\"" /app/data/configs/mas.yaml
yq eval -i ".email.reply_to=\"${CLOUDRON_MAIL_FROM_DISPLAY_NAME:-Matrix} <${CLOUDRON_MAIL_FROM}>\"" /app/data/configs/mas.yaml
fi
cat /app/data/configs/mas.yaml > ${MAS_CONFIG}
# http
yq eval -i ".http.public_base=\"https://${MAS_DOMAIN}\"" ${MAS_CONFIG}
# database
yq eval -i ".database.uri=\"${CLOUDRON_POSTGRESQL_URL}\"" ${MAS_CONFIG}
# yq eval -i ".database.user=\"${CLOUDRON_POSTGRESQL_USERNAME}\"" ${MAS_CONFIG}
# yq eval -i ".database.password=\"${CLOUDRON_POSTGRESQL_PASSWORD}\"" ${MAS_CONFIG}
# yq eval -i ".database.database=\"${CLOUDRON_POSTGRESQL_DATABASE}\"" ${MAS_CONFIG}
# yq eval -i ".database.host=\"${CLOUDRON_POSTGRESQL_HOST}\"" ${MAS_CONFIG}
# yq eval -i ".database.port=${CLOUDRON_POSTGRESQL_PORT}" ${MAS_CONFIG}
# email
yq eval -i ".email.transport=\"smtp\"" ${MAS_CONFIG}
yq eval -i ".email.mode=\"plain\"" ${MAS_CONFIG}
yq eval -i ".email.hostname=\"${CLOUDRON_MAIL_SMTP_SERVER}\"" ${MAS_CONFIG}
yq eval -i ".email.port=${CLOUDRON_MAIL_SMTP_PORT}" ${MAS_CONFIG}
yq eval -i ".email.username=\"${CLOUDRON_MAIL_SMTP_USERNAME}\"" ${MAS_CONFIG}
yq eval -i ".email.password=\"${CLOUDRON_MAIL_SMTP_PASSWORD}\"" ${MAS_CONFIG}
# provision client for the homeserver
yq eval -i ".clients[0].client_id=\"${mas_client_id}\"" ${MAS_CONFIG}
yq eval -i ".clients[0].client_auth_method=\"client_secret_basic\"" ${MAS_CONFIG}
yq eval -i ".clients[0].client_secret=\"${mas_client_secret}\"" ${MAS_CONFIG}
# connection to the homeserver
yq eval -i ".matrix.homeserver=\"localhost:8008\"" ${MAS_CONFIG}
yq eval -i ".matrix.secret=\"${matrix_secret}\"" ${MAS_CONFIG}
yq eval -i ".matrix.endpoint=\"http://localhost:8008\"" ${MAS_CONFIG}
# setup cloudron OIDC as upstrem SSO provider
if [[ -n "${CLOUDRON_OIDC_ISSUER:-}" ]]; then
yq eval -i ".upstream_oauth2.providers[0].id=\"${cloudron_client_id}\"" ${MAS_CONFIG}
yq eval -i ".upstream_oauth2.providers[0].human_name=\"${CLOUDRON_OIDC_PROVIDER_NAME:-Cloudron}\"" ${MAS_CONFIG}
yq eval -i ".upstream_oauth2.providers[0].issuer=\"${CLOUDRON_OIDC_ISSUER}\"" ${MAS_CONFIG}
yq eval -i ".upstream_oauth2.providers[0].client_id=\"${CLOUDRON_OIDC_CLIENT_ID}\"" ${MAS_CONFIG}
yq eval -i ".upstream_oauth2.providers[0].client_secret=\"${CLOUDRON_OIDC_CLIENT_SECRET}\"" ${MAS_CONFIG}
yq eval -i ".upstream_oauth2.providers[0].scope=\"openid, email, profile\"" ${MAS_CONFIG}
# How the provider configuration and endpoints should be discovered
# Possible values are:
# - `oidc`: discover the provider through OIDC discovery,
# with strict metadata validation (default)
# - `insecure`: discover through OIDC discovery, but skip metadata validation
# - `disabled`: don't discover the provider and use the endpoints below
yq eval -i ".upstream_oauth2.providers[0].discovery_mode=\"oidc\"" ${MAS_CONFIG}
yq eval -i ".upstream_oauth2.providers[0].authorization_endpoint=\"${CLOUDRON_OIDC_AUTH_ENDPOINT}\"" ${MAS_CONFIG}
yq eval -i ".upstream_oauth2.providers[0].token_endpoint=\"${CLOUDRON_OIDC_TOKEN_ENDPOINT}\"" ${MAS_CONFIG}
yq eval -i ".upstream_oauth2.providers[0].userinfo_endpoint=\"${CLOUDRON_OIDC_PROFILE_ENDPOINT}\"" ${MAS_CONFIG}
yq eval -i ".upstream_oauth2.providers[0].jwks_uri=\"${CLOUDRON_OIDC_KEYS_ENDPOINT}\"" ${MAS_CONFIG}
yq eval -i ".upstream_oauth2.providers[0].token_endpoint_auth_method=\"client_secret_post\"" ${MAS_CONFIG}
yq eval -i ".upstream_oauth2.providers[0].response_mode=\"query\"" ${MAS_CONFIG}
yq eval -i ".claims_imports.subject.template=\"{{ user.sub }}\"" ${MAS_CONFIG}
yq eval -i ".claims_imports.localpart.action=\"force\"" ${MAS_CONFIG}
yq eval -i ".claims_imports.localpart.template=\"{{ user.preferred_username }}\"" ${MAS_CONFIG}
yq eval -i ".claims_imports.displayname.action=\"suggest\"" ${MAS_CONFIG}
yq eval -i ".claims_imports.displayname.template=\"{{ user.name }}\"" ${MAS_CONFIG}
yq eval -i ".claims_imports.email.action=\"suggest\"" ${MAS_CONFIG}
yq eval -i ".claims_imports.email.template=\"{{ user.email }}\"" ${MAS_CONFIG}
yq eval -i ".claims_imports.set_email_verification=\"import\"" ${MAS_CONFIG}
yq eval -i ".claims_imports.account_name.template=\"@{{ user.preferred_username }}\"" ${MAS_CONFIG}
fi
mas-cli -c ${MAS_CONFIG} database migrate
}
if [[ ! -f /app/data/configs/homeserver.yaml ]]; then if [[ ! -f /app/data/configs/homeserver.yaml ]]; then
echo "==> Detected first run" echo "==> Detected first run"
@@ -33,18 +119,19 @@ if [[ ! -f /app/data/configs/homeserver.yaml ]]; then
yq eval -i ".server_name=\"${server_name}\"" /app/data/configs/homeserver.yaml yq eval -i ".server_name=\"${server_name}\"" /app/data/configs/homeserver.yaml
yq eval -i ".registration_shared_secret=\"$(pwgen -1s 64)\"" /app/data/configs/homeserver.yaml yq eval -i ".registration_shared_secret=\"$(pwgen -1s 64)\"" /app/data/configs/homeserver.yaml
yq eval -i ".macaroon_secret_key=\"$(pwgen -1s 64)\"" /app/data/configs/homeserver.yaml
yq eval -i ".form_secret=\"$(pwgen -1s 64)\"" /app/data/configs/homeserver.yaml yq eval -i ".auto_join_rooms=[]" /app/data/configs/homeserver.yaml
yq eval -i ".auto_join_rooms[0]=\"#discuss:${server_name}\"" /app/data/configs/homeserver.yaml
if [[ -z "${CLOUDRON_OIDC_ISSUER:-}" ]]; then if [[ -z "${CLOUDRON_OIDC_ISSUER:-}" ]]; then
yq eval -i ".enable_registration=true" /app/data/configs/homeserver.yaml yq eval -i ".enable_registration=true" /app/data/configs/homeserver.yaml
yq eval -i ".password_config.enabled=true" /app/data/configs/homeserver.yaml # just setting enabled to false is not enough. see https://github.com/matrix-org/matrix-synapse-ldap3/issues/123
yq eval -i ".password_config.localdb_enabled=true" /app/data/configs/homeserver.yaml yq eval -i "del(.password_providers)" /app/data/configs/homeserver.yaml
yq eval -i "del(.oidc_providers)" /app/data/configs/homeserver.yaml
fi fi
yq eval -i ".password_config.pepper=\"$(pwgen -1s 12)\"" /app/data/configs/homeserver.yaml # always set this so that users can enable password login if needed yq eval -i ".password_config.pepper=\"$(pwgen -1s 12)\"" /app/data/configs/homeserver.yaml # always set this so that users can enable password login if needed
fi fi
echo "==> Ensure we log to console" echo "==> Ensure we log to console"
yq eval -i ".root.handlers=[\"console\"]" /app/data/configs/log.config yq eval -i ".root.handlers=[\"console\"]" /app/data/configs/log.config
yq eval -i ".loggers.twisted.handlers=[\"console\"]" /app/data/configs/log.config yq eval -i ".loggers.twisted.handlers=[\"console\"]" /app/data/configs/log.config
@@ -69,25 +156,28 @@ yq eval -i ".email.notif_from=\"${CLOUDRON_MAIL_FROM_DISPLAY_NAME:-Matrix} <${CL
# oidc # oidc
if [[ -n "${CLOUDRON_OIDC_ISSUER:-}" ]]; then if [[ -n "${CLOUDRON_OIDC_ISSUER:-}" ]]; then
echo " ==> Configuring OIDC auth" yq eval -i "del(.password_providers)" /app/data/configs/homeserver.yaml # remove old ldap config
yq eval -i ".oidc_providers[0].idp_id=\"cloudron\"" /app/data/configs/homeserver.yaml yq eval -i "del(.oidc_providers[0])" /app/data/configs/homeserver.yaml # remove old oidc config
yq eval -i ".oidc_providers[0].idp_name=\"${CLOUDRON_OIDC_PROVIDER_NAME:-Cloudron}\"" /app/data/configs/homeserver.yaml # echo " ==> Configuring OIDC auth"
yq eval -i ".oidc_providers[0].issuer=\"${CLOUDRON_OIDC_ISSUER}\"" /app/data/configs/homeserver.yaml # yq eval -i ".oidc_providers[0].idp_id=\"cloudron\"" /app/data/configs/homeserver.yaml
yq eval -i ".oidc_providers[0].client_id=\"${CLOUDRON_OIDC_CLIENT_ID}\"" /app/data/configs/homeserver.yaml # yq eval -i ".oidc_providers[0].idp_name=\"${CLOUDRON_OIDC_PROVIDER_NAME:-Cloudron}\"" /app/data/configs/homeserver.yaml
yq eval -i ".oidc_providers[0].client_secret=\"${CLOUDRON_OIDC_CLIENT_SECRET}\"" /app/data/configs/homeserver.yaml # yq eval -i ".oidc_providers[0].issuer=\"${CLOUDRON_OIDC_ISSUER}\"" /app/data/configs/homeserver.yaml
# yq eval -i ".oidc_providers[0].client_id=\"${CLOUDRON_OIDC_CLIENT_ID}\"" /app/data/configs/homeserver.yaml
yq eval -i ".oidc_providers[0].scopes=[\"openid\", \"email\", \"profile\"]" /app/data/configs/homeserver.yaml # yq eval -i ".oidc_providers[0].client_secret=\"${CLOUDRON_OIDC_CLIENT_SECRET}\"" /app/data/configs/homeserver.yaml
yq eval -i ".oidc_providers[0].authorization_endpoint=\"${CLOUDRON_OIDC_AUTH_ENDPOINT}\"" /app/data/configs/homeserver.yaml #
yq eval -i ".oidc_providers[0].token_endpoint=\"${CLOUDRON_OIDC_TOKEN_ENDPOINT}\"" /app/data/configs/homeserver.yaml # yq eval -i ".oidc_providers[0].scopes=[\"openid\", \"email\", \"profile\"]" /app/data/configs/homeserver.yaml
yq eval -i ".oidc_providers[0].userinfo_endpoint=\"${CLOUDRON_OIDC_PROFILE_ENDPOINT}\"" /app/data/configs/homeserver.yaml # yq eval -i ".oidc_providers[0].authorization_endpoint=\"${CLOUDRON_OIDC_AUTH_ENDPOINT}\"" /app/data/configs/homeserver.yaml
# https://s3lph.me/ldap-to-oidc-migration-3-matrix.html # yq eval -i ".oidc_providers[0].token_endpoint=\"${CLOUDRON_OIDC_TOKEN_ENDPOINT}\"" /app/data/configs/homeserver.yaml
yq eval -i ".oidc_providers[0].allow_existing_users=true" /app/data/configs/homeserver.yaml # yq eval -i ".oidc_providers[0].userinfo_endpoint=\"${CLOUDRON_OIDC_PROFILE_ENDPOINT}\"" /app/data/configs/homeserver.yaml
yq eval -i ".oidc_providers[0].skip_verification=true" /app/data/configs/homeserver.yaml # # https://s3lph.me/ldap-to-oidc-migration-3-matrix.html
yq eval -i ".oidc_providers[0].user_mapping_provider.config.localpart_template=\"{{ user.sub }}\"" /app/data/configs/homeserver.yaml # yq eval -i ".oidc_providers[0].allow_existing_users=true" /app/data/configs/homeserver.yaml
yq eval -i ".oidc_providers[0].user_mapping_provider.config.display_name_template=\"{{ user.name }}\"" /app/data/configs/homeserver.yaml # yq eval -i ".oidc_providers[0].skip_verification=true" /app/data/configs/homeserver.yaml
yq eval -i ".oidc_providers[0].user_mapping_provider.config.email_template=\"{{ user.email }}\"" /app/data/configs/homeserver.yaml # yq eval -i ".oidc_providers[0].user_mapping_provider.config.localpart_template=\"{{ user.sub }}\"" /app/data/configs/homeserver.yaml
# yq eval -i ".oidc_providers[0].user_mapping_provider.config.display_name_template=\"{{ user.name }}\"" /app/data/configs/homeserver.yaml
else else
yq eval -i ".password_config.localdb_enabled=true" /app/data/configs/homeserver.yaml yq eval -i ".password_config.localdb_enabled=true" /app/data/configs/homeserver.yaml
# just setting enabled to false is not enough. see https://github.com/matrix-org/matrix-synapse-ldap3/issues/123
yq eval -i "del(.password_providers)" /app/data/configs/homeserver.yaml
fi fi
# turn (https://github.com/matrix-org/synapse/blob/master/docs/turn-howto.md#synapse-setup) # turn (https://github.com/matrix-org/synapse/blob/master/docs/turn-howto.md#synapse-setup)
@@ -98,9 +188,23 @@ if [[ -n "${CLOUDRON_TURN_SERVER:-}" ]]; then
yq eval -i ".turn_shared_secret=\"${CLOUDRON_TURN_SECRET}\"" /app/data/configs/homeserver.yaml yq eval -i ".turn_shared_secret=\"${CLOUDRON_TURN_SECRET}\"" /app/data/configs/homeserver.yaml
fi fi
mas_config
# Configure the homeserver to delegate authentication to the MAS
# https://element-hq.github.io/matrix-authentication-service/setup/homeserver.html#configure-the-homeserver-to-delegate-authentication-to-the-service
yq eval -i ".experimental_features.msc3861.enabled=true" /app/data/configs/homeserver.yaml
yq eval -i ".experimental_features.msc3861.issuer=\"http://localhost:8080/\"" /app/data/configs/homeserver.yaml
yq eval -i ".experimental_features.msc3861.client_id=\"${mas_client_id}\"" /app/data/configs/homeserver.yaml
yq eval -i ".experimental_features.msc3861.client_auth_method=\"client_secret_basic\"" /app/data/configs/homeserver.yaml
# Matches the `client_secret` in the auth service config
yq eval -i ".experimental_features.msc3861.client_secret=\"${mas_client_secret}\"" /app/data/configs/homeserver.yaml
# Matches the `matrix.secret` in the auth service config
yq eval -i ".experimental_features.msc3861.admin_token=\"${matrix_secret}\"" /app/data/configs/homeserver.yaml
# fix permissions # fix permissions
echo "==> Fixing permissions" echo "==> Fixing permissions"
chown -R cloudron:cloudron /app/data /run/synapse chown -R cloudron:cloudron /app/data /run/synapse
echo "==> Starting synapse" echo "==> Starting synapse"
exec gosu cloudron:cloudron python3 -m synapse.app.homeserver --config-path /app/data/configs/homeserver.yaml -n #exec gosu cloudron:cloudron python3 -m synapse.app.homeserver --config-path /app/data/configs/homeserver.yaml -n
exec /usr/bin/supervisord --configuration /etc/supervisor/supervisord.conf --nodaemon -i Synapse

View File

@@ -0,0 +1,11 @@
[program:homeserver]
priority=10
user=cloudron
directory=/app/code
command=bash -c "source /app/code/env/bin/activate && python3 -m synapse.app.homeserver --config-path /app/data/configs/homeserver.yaml -n"
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

11
supervisor/mas.conf Normal file
View File

@@ -0,0 +1,11 @@
[program:mas]
priority=12
directory=/app/code/mas
user=cloudron
command=mas-cli -c /run/synapse/mas-config.yaml server
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

477
test/package-lock.json generated
View File

@@ -9,10 +9,10 @@
"version": "1.0.0", "version": "1.0.0",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"chromedriver": "^141.0.2", "chromedriver": "^135.0.0",
"expect.js": "^0.3.1", "expect.js": "^0.3.1",
"mocha": "^11.7.4", "mocha": "^11.1.0",
"selenium-webdriver": "^4.36.0" "selenium-webdriver": "^4.31.0"
} }
}, },
"node_modules/@bazel/runfiles": { "node_modules/@bazel/runfiles": {
@@ -89,6 +89,15 @@
"node": ">= 14" "node": ">= 14"
} }
}, },
"node_modules/ansi-colors": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
"integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/ansi-regex": { "node_modules/ansi-regex": {
"version": "6.1.0", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
@@ -116,6 +125,19 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1" "url": "https://github.com/chalk/ansi-styles?sponsor=1"
} }
}, },
"node_modules/anymatch": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
"license": "ISC",
"dependencies": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/argparse": { "node_modules/argparse": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@@ -141,13 +163,13 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/axios": { "node_modules/axios": {
"version": "1.12.2", "version": "1.7.9",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
"integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"follow-redirects": "^1.15.6", "follow-redirects": "^1.15.6",
"form-data": "^4.0.4", "form-data": "^4.0.0",
"proxy-from-env": "^1.1.0" "proxy-from-env": "^1.1.0"
} }
}, },
@@ -166,6 +188,18 @@
"node": ">=10.0.0" "node": ">=10.0.0"
} }
}, },
"node_modules/binary-extensions": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
"license": "MIT",
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/brace-expansion": { "node_modules/brace-expansion": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
@@ -175,6 +209,18 @@
"balanced-match": "^1.0.0" "balanced-match": "^1.0.0"
} }
}, },
"node_modules/braces": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"license": "MIT",
"dependencies": {
"fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/browser-stdout": { "node_modules/browser-stdout": {
"version": "1.3.1", "version": "1.3.1",
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
@@ -190,19 +236,6 @@
"node": "*" "node": "*"
} }
}, },
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/camelcase": { "node_modules/camelcase": {
"version": "6.3.0", "version": "6.3.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
@@ -244,29 +277,38 @@
} }
}, },
"node_modules/chokidar": { "node_modules/chokidar": {
"version": "4.0.3", "version": "3.6.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"readdirp": "^4.0.1" "anymatch": "~3.1.2",
"braces": "~3.0.2",
"glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.6.0"
}, },
"engines": { "engines": {
"node": ">= 14.16.0" "node": ">= 8.10.0"
}, },
"funding": { "funding": {
"url": "https://paulmillr.com/funding/" "url": "https://paulmillr.com/funding/"
},
"optionalDependencies": {
"fsevents": "~2.3.2"
} }
}, },
"node_modules/chromedriver": { "node_modules/chromedriver": {
"version": "141.0.2", "version": "135.0.0",
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-141.0.2.tgz", "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-135.0.0.tgz",
"integrity": "sha512-MNtgzm5SjTtbHDXlpuXkQ7brxkOYTK+qDbnmr7UrurfuhqJfIkL+nnKo7hev/hR6sFL8mV8r5+1Kn51Mo9zsDg==", "integrity": "sha512-ilE3cIrIieiRU/a6MNpt0CL0UZs2tu0lQAes+el5SV03MB1zYIEXy+dDeueid/g8AmT1loy7TB2fjWwcHLY8lg==",
"hasInstallScript": true, "hasInstallScript": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@testim/chrome-version": "^1.1.4", "@testim/chrome-version": "^1.1.4",
"axios": "^1.12.0", "axios": "^1.7.4",
"compare-versions": "^6.1.0", "compare-versions": "^6.1.0",
"extract-zip": "^2.0.1", "extract-zip": "^2.0.1",
"proxy-agent": "^6.4.0", "proxy-agent": "^6.4.0",
@@ -277,7 +319,7 @@
"chromedriver": "bin/chromedriver" "chromedriver": "bin/chromedriver"
}, },
"engines": { "engines": {
"node": ">=20" "node": ">=18"
} }
}, },
"node_modules/cliui": { "node_modules/cliui": {
@@ -476,28 +518,14 @@
} }
}, },
"node_modules/diff": { "node_modules/diff": {
"version": "7.0.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
"integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"engines": { "engines": {
"node": ">=0.3.1" "node": ">=0.3.1"
} }
}, },
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/eastasianwidth": { "node_modules/eastasianwidth": {
"version": "0.2.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
@@ -519,51 +547,6 @@
"once": "^1.4.0" "once": "^1.4.0"
} }
}, },
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-set-tostringtag": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.6",
"has-tostringtag": "^1.0.2",
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/escalade": { "node_modules/escalade": {
"version": "3.2.0", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
@@ -671,6 +654,18 @@
"pend": "~1.2.0" "pend": "~1.2.0"
} }
}, },
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"license": "MIT",
"dependencies": {
"to-regex-range": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/find-up": { "node_modules/find-up": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
@@ -697,9 +692,9 @@
} }
}, },
"node_modules/follow-redirects": { "node_modules/follow-redirects": {
"version": "1.15.11", "version": "1.15.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
"funding": [ "funding": [
{ {
"type": "individual", "type": "individual",
@@ -733,28 +728,31 @@
} }
}, },
"node_modules/form-data": { "node_modules/form-data": {
"version": "4.0.4", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"asynckit": "^0.4.0", "asynckit": "^0.4.0",
"combined-stream": "^1.0.8", "combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.2",
"mime-types": "^2.1.12" "mime-types": "^2.1.12"
}, },
"engines": { "engines": {
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/function-bind": { "node_modules/fsevents": {
"version": "1.1.2", "version": "2.3.3",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"hasInstallScript": true,
"license": "MIT", "license": "MIT",
"funding": { "optional": true,
"url": "https://github.com/sponsors/ljharb" "os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
} }
}, },
"node_modules/get-caller-file": { "node_modules/get-caller-file": {
@@ -766,43 +764,6 @@
"node": "6.* || 8.* || >= 10.*" "node": "6.* || 8.* || >= 10.*"
} }
}, },
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/get-stream": { "node_modules/get-stream": {
"version": "5.2.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
@@ -852,16 +813,31 @@
"url": "https://github.com/sponsors/isaacs" "url": "https://github.com/sponsors/isaacs"
} }
}, },
"node_modules/gopd": { "node_modules/glob-parent": {
"version": "1.2.0", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"license": "MIT", "license": "ISC",
"dependencies": {
"is-glob": "^4.0.1"
},
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 6"
}
},
"node_modules/glob/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
}, },
"funding": { "funding": {
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/isaacs"
} }
}, },
"node_modules/has-flag": { "node_modules/has-flag": {
@@ -873,45 +849,6 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-tostringtag": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/he": { "node_modules/he": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
@@ -981,6 +918,27 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"license": "MIT",
"dependencies": {
"binary-extensions": "^2.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-fullwidth-code-point": { "node_modules/is-fullwidth-code-point": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
@@ -990,13 +948,25 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/is-path-inside": { "node_modules/is-glob": {
"version": "3.0.3", "version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"license": "MIT",
"dependencies": {
"is-extglob": "^2.1.1"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=8" "node": ">=0.12.0"
} }
}, },
"node_modules/is-plain-obj": { "node_modules/is-plain-obj": {
@@ -1143,15 +1113,6 @@
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"license": "ISC" "license": "ISC"
}, },
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/mime-db": { "node_modules/mime-db": {
"version": "1.52.0", "version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
@@ -1174,18 +1135,15 @@
} }
}, },
"node_modules/minimatch": { "node_modules/minimatch": {
"version": "9.0.5", "version": "5.1.6",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"brace-expansion": "^2.0.1" "brace-expansion": "^2.0.1"
}, },
"engines": { "engines": {
"node": ">=16 || 14 >=14.17" "node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
} }
}, },
"node_modules/minipass": { "node_modules/minipass": {
@@ -1198,29 +1156,28 @@
} }
}, },
"node_modules/mocha": { "node_modules/mocha": {
"version": "11.7.4", "version": "11.1.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.4.tgz", "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.1.0.tgz",
"integrity": "sha512-1jYAaY8x0kAZ0XszLWu14pzsf4KV740Gld4HXkhNTXwcHx4AUEDkPzgEHg9CM5dVcW+zv036tjpsEbLraPJj4w==", "integrity": "sha512-8uJR5RTC2NgpY3GrYcgpZrsEd9zKbPDpob1RezyR2upGHRQtHWofmzTMzTMSV6dru3tj5Ukt0+Vnq1qhFEEwAg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"ansi-colors": "^4.1.3",
"browser-stdout": "^1.3.1", "browser-stdout": "^1.3.1",
"chokidar": "^4.0.1", "chokidar": "^3.5.3",
"debug": "^4.3.5", "debug": "^4.3.5",
"diff": "^7.0.0", "diff": "^5.2.0",
"escape-string-regexp": "^4.0.0", "escape-string-regexp": "^4.0.0",
"find-up": "^5.0.0", "find-up": "^5.0.0",
"glob": "^10.4.5", "glob": "^10.4.5",
"he": "^1.2.0", "he": "^1.2.0",
"is-path-inside": "^3.0.3",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"log-symbols": "^4.1.0", "log-symbols": "^4.1.0",
"minimatch": "^9.0.5", "minimatch": "^5.1.6",
"ms": "^2.1.3", "ms": "^2.1.3",
"picocolors": "^1.1.1",
"serialize-javascript": "^6.0.2", "serialize-javascript": "^6.0.2",
"strip-json-comments": "^3.1.1", "strip-json-comments": "^3.1.1",
"supports-color": "^8.1.1", "supports-color": "^8.1.1",
"workerpool": "^9.2.0", "workerpool": "^6.5.1",
"yargs": "^17.7.2", "yargs": "^17.7.2",
"yargs-parser": "^21.1.1", "yargs-parser": "^21.1.1",
"yargs-unparser": "^2.0.0" "yargs-unparser": "^2.0.0"
@@ -1248,6 +1205,15 @@
"node": ">= 0.4.0" "node": ">= 0.4.0"
} }
}, },
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/once": { "node_modules/once": {
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -1371,11 +1337,17 @@
"integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/picocolors": { "node_modules/picomatch": {
"version": "1.1.1", "version": "2.3.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"license": "ISC" "license": "MIT",
"engines": {
"node": ">=8.6"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
}, },
"node_modules/process-nextick-args": { "node_modules/process-nextick-args": {
"version": "2.0.1", "version": "2.0.1",
@@ -1452,16 +1424,15 @@
} }
}, },
"node_modules/readdirp": { "node_modules/readdirp": {
"version": "4.1.2", "version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"license": "MIT", "license": "MIT",
"engines": { "dependencies": {
"node": ">= 14.18.0" "picomatch": "^2.2.1"
}, },
"funding": { "engines": {
"type": "individual", "node": ">=8.10.0"
"url": "https://paulmillr.com/funding/"
} }
}, },
"node_modules/require-directory": { "node_modules/require-directory": {
@@ -1480,9 +1451,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/selenium-webdriver": { "node_modules/selenium-webdriver": {
"version": "4.36.0", "version": "4.31.0",
"resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.36.0.tgz", "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.31.0.tgz",
"integrity": "sha512-rZGqjXiqNVL6QNqKNEk5DPaIMPbvApcmAS9QsXyt5wT3sfTSHGCh4AX/YKeDTOwei1BOZDlPOKBd82WCosUt9w==", "integrity": "sha512-0MWEwypM0+c1NnZ87UEMxZdwphKoaK2UJ2qXzKWrJiM0gazFjgNVimxlHTOO90G2cOhphZqwpqSCJy62NTEzyA==",
"funding": [ "funding": [
{ {
"type": "github", "type": "github",
@@ -1497,11 +1468,11 @@
"dependencies": { "dependencies": {
"@bazel/runfiles": "^6.3.1", "@bazel/runfiles": "^6.3.1",
"jszip": "^3.10.1", "jszip": "^3.10.1",
"tmp": "^0.2.5", "tmp": "^0.2.3",
"ws": "^8.18.3" "ws": "^8.18.0"
}, },
"engines": { "engines": {
"node": ">= 20.0.0" "node": ">= 18.20.5"
} }
}, },
"node_modules/serialize-javascript": { "node_modules/serialize-javascript": {
@@ -1772,14 +1743,26 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/tmp": { "node_modules/tmp": {
"version": "0.2.5", "version": "0.2.3",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz",
"integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=14.14" "node": ">=14.14"
} }
}, },
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"license": "MIT",
"dependencies": {
"is-number": "^7.0.0"
},
"engines": {
"node": ">=8.0"
}
},
"node_modules/tslib": { "node_modules/tslib": {
"version": "2.8.1", "version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
@@ -1815,9 +1798,9 @@
} }
}, },
"node_modules/workerpool": { "node_modules/workerpool": {
"version": "9.3.2", "version": "6.5.1",
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.2.tgz", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz",
"integrity": "sha512-Xz4Nm9c+LiBHhDR5bDLnNzmj6+5F+cyEAWPMkbs2awq/dYazR/efelZzUAjB/y3kNHL+uzkHvxVVpaOfGCPV7A==", "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==",
"license": "Apache-2.0" "license": "Apache-2.0"
}, },
"node_modules/wrap-ansi": { "node_modules/wrap-ansi": {
@@ -1915,9 +1898,9 @@
"license": "ISC" "license": "ISC"
}, },
"node_modules/ws": { "node_modules/ws": {
"version": "8.18.3", "version": "8.18.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=10.0.0" "node": ">=10.0.0"

View File

@@ -9,9 +9,9 @@
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"chromedriver": "^141.0.2", "chromedriver": "^135.0.0",
"expect.js": "^0.3.1", "expect.js": "^0.3.1",
"mocha": "^11.7.4", "mocha": "^11.1.0",
"selenium-webdriver": "^4.36.0" "selenium-webdriver": "^4.31.0"
} }
} }

View File

@@ -119,7 +119,8 @@ describe('Application life cycle test', function () {
await waitForElement(By.xpath(`//h1[contains(., "Welcome")]`)); await waitForElement(By.xpath(`//h1[contains(., "Welcome")]`));
} }
async function loginOIDCOld(username, password, alreadyAuthenticated, proceedWithReset) { async function loginOIDC(username, password, alreadyAuthenticated, proceedWithReset) {
browser.manage().deleteAllCookies();
await browser.get(`https://${elementApp.fqdn}/#/login`); await browser.get(`https://${elementApp.fqdn}/#/login`);
await browser.sleep(2000); await browser.sleep(2000);
@@ -132,9 +133,9 @@ describe('Application life cycle test', function () {
await waitForElement(By.xpath('//div[@role="button" and contains(., "Continue with")]')); await waitForElement(By.xpath('//div[@role="button" and contains(., "Continue with")]'));
await browser.findElement(By.xpath('//div[@role="button" and contains(., "Continue with")]')).click(); await browser.findElement(By.xpath('//div[@role="button" and contains(., "Continue with")]')).click();
if (!alreadyAuthenticated) { if (!alreadyAuthenticated) {
await waitForElement(By.id('inputUsername')); await waitForElement(By.xpath('//input[@name="username"]'));
await browser.findElement(By.id('inputUsername')).sendKeys(username); await browser.findElement(By.xpath('//input[@name="username"]')).sendKeys(username);
await browser.findElement(By.id('inputPassword')).sendKeys(password); await browser.findElement(By.xpath('//input[@name="password"]')).sendKeys(password);
await browser.findElement(By.id('loginSubmitButton')).click(); await browser.findElement(By.id('loginSubmitButton')).click();
} }
@@ -151,11 +152,14 @@ describe('Application life cycle test', function () {
await waitForElement(By.xpath('//div[text()="Proceed with reset"]')); await waitForElement(By.xpath('//div[text()="Proceed with reset"]'));
await browser.findElement(By.xpath('//div[text()="Proceed with reset"]')).click(); await browser.findElement(By.xpath('//div[text()="Proceed with reset"]')).click();
await waitForElement(By.xpath('//button[@class="mx_Dialog_primary" and text()="Continue"] | //div[@class="mx_EncryptionCard_buttons"]/button[@data-kind="primary"]')); await waitForElement(By.xpath('//button[@class="mx_Dialog_primary" and text()="Continue"]'));
await browser.findElement(By.xpath('//button[@class="mx_Dialog_primary" and text()="Continue"] | //div[@class="mx_EncryptionCard_buttons"]/button[@data-kind="primary"]')).click(); await browser.findElement(By.xpath('//button[@class="mx_Dialog_primary" and text()="Continue"]')).click();
await waitForElement(By.xpath('//button[@class="mx_Dialog_primary" and text()="Continue"] | //div[@class="mx_EncryptionCard_buttons"]/button[@data-kind="primary"]')); await waitForElement(By.xpath('//div[text()="Copy"]'));
await browser.findElement(By.xpath('//button[@class="mx_Dialog_primary" and text()="Continue"] | //div[@class="mx_EncryptionCard_buttons"]/button[@data-kind="primary"]')).click(); await browser.findElement(By.xpath('//div[text()="Copy"]')).click();
await waitForElement(By.xpath('//button[@class="mx_Dialog_primary" and text()="Continue"]'));
await browser.findElement(By.xpath('//button[@class="mx_Dialog_primary" and text()="Continue"]')).click();
await waitForElement(By.xpath('//button[text()="Done"] | //div[text()="Single Sign On"]')); await waitForElement(By.xpath('//button[text()="Done"] | //div[text()="Single Sign On"]'));
if (await browser.findElements(By.xpath('//div[text()="Single Sign On"]')).then(found => !!found.length)) { if (await browser.findElements(By.xpath('//div[text()="Single Sign On"]')).then(found => !!found.length)) {
@@ -181,71 +185,8 @@ describe('Application life cycle test', function () {
await browser.findElement(By.xpath('//div[text()="Confirm"]')).click(); await browser.findElement(By.xpath('//div[text()="Confirm"]')).click();
} }
await waitForElement(By.xpath('//div[text()="Cancel"] | //h1[contains(., "Welcome")]')); await waitForElement(By.xpath('//button[text()="Done"]'));
if (await browser.findElements(By.xpath('//div[text()="Cancel"]')).then(found => !!found.length)) { await browser.findElement(By.xpath('//button[text()="Done"]')).click();
await browser.findElement(By.xpath('//div[text()="Cancel"]')).click();
}
}
await browser.sleep(3000);
await waitForElement(By.xpath(`//h1[contains(., "Welcome")]`));
}
async function loginOIDC(username, password, alreadyAuthenticated, proceedWithReset) {
await browser.get(`https://${elementApp.fqdn}/#/login`);
await browser.sleep(2000);
await waitForElement(By.css('.mx_Dropdown_arrow'));
await browser.findElement(By.css('.mx_Dropdown_arrow')).click();
await waitForElement(By.id('mx_LanguageDropdown__en'));
await browser.findElement(By.id('mx_LanguageDropdown__en')).click();
await browser.sleep(3000);
await waitForElement(By.xpath('//div[@role="button" and contains(., "Continue with")]'));
await browser.findElement(By.xpath('//div[@role="button" and contains(., "Continue with")]')).click();
if (!alreadyAuthenticated) {
await waitForElement(By.id('inputUsername'));
await browser.findElement(By.id('inputUsername')).sendKeys(username);
await browser.findElement(By.id('inputPassword')).sendKeys(password);
await browser.findElement(By.id('loginSubmitButton')).click();
}
await waitForElement(By.xpath('//p[@class="confirm-trust" and contains(., "Continuing will grant ")]'));
await browser.findElement(By.xpath('//a[contains(., "Continue")]')).click();
if (proceedWithReset) {
await waitForElement(By.xpath('//h2[text()="Confirm your identity"]'));
await waitForElement(By.xpath('//button[text()="Can\'t confirm?"]'));
await browser.findElement(By.xpath('//button[text()="Can\'t confirm?"]')).click();
await waitForElement(By.xpath('//button[text()="Continue"]'));
await browser.findElement(By.xpath('//button[text()="Continue"]')).click();
await waitForElement(By.xpath('//button[text()="Done"] | //div[text()="Single Sign On"]'));
if (await browser.findElements(By.xpath('//div[text()="Single Sign On"]')).then(found => !!found.length)) {
await browser.findElement(By.xpath('//div[text()="Single Sign On"]')).click();
const originalWindowHandle = await browser.getWindowHandle();
await browser.wait(async () => (await browser.getAllWindowHandles()).length === 2, 10000);
//Loop through until we find a new window handle
const windows = await browser.getAllWindowHandles();
windows.forEach(async handle => {
if (handle !== originalWindowHandle) {
await browser.switchTo().window(handle);
}
});
await waitForElement(By.xpath('//a[contains(., "Continue with")]'));
await browser.findElement(By.xpath('//a[contains(., "Continue with")]')).click();
// switch back to the main window
await browser.switchTo().window(originalWindowHandle);
await waitForElement(By.xpath('//div[text()="Confirm"]'));
await browser.findElement(By.xpath('//div[text()="Confirm"]')).click();
}
await waitForElement(By.xpath('//div[text()="Cancel"] | //h1[contains(., "Welcome")]')); await waitForElement(By.xpath('//div[text()="Cancel"] | //h1[contains(., "Welcome")]'));
if (await browser.findElements(By.xpath('//div[text()="Cancel"]')).then(found => !!found.length)) { if (await browser.findElements(By.xpath('//div[text()="Cancel"]')).then(found => !!found.length)) {
@@ -265,7 +206,7 @@ describe('Application life cycle test', function () {
await browser.findElement(By.xpath('//input[@value="Sign in"]')).click(); await browser.findElement(By.xpath('//input[@value="Sign in"]')).click();
await browser.sleep(5000); await browser.sleep(5000);
await skipVerification(); await skipVerification();
await browser.wait(until.elementLocated(By.xpath('//h1[contains(., "Welcome")] | //span[text()="Rooms"]')), TEST_TIMEOUT); await browser.wait(until.elementLocated(By.xpath('//span[text()="Rooms"]')), TEST_TIMEOUT);
} }
async function skipVerification() { async function skipVerification() {
@@ -299,7 +240,51 @@ describe('Application life cycle test', function () {
async function isLoggedIn() { async function isLoggedIn() {
await browser.get(`https://${elementApp.fqdn}/#/home`); await browser.get(`https://${elementApp.fqdn}/#/home`);
await browser.wait(until.elementLocated(By.xpath('//h1[contains(., "Welcome")] | //span[text()="Rooms"]')), TEST_TIMEOUT); await browser.wait(until.elementLocated(By.xpath('//span[text()="Rooms"]')), TEST_TIMEOUT);
}
async function createRoom() {
await browser.get(`https://${elementApp.fqdn}/#/home`);
await browser.sleep(2000);
await waitForElement(By.xpath('//div[@role="button" and @aria-label="Add room"]'));
await browser.findElement(By.xpath('//div[@role="button" and @aria-label="Add room"]')).click();
await browser.sleep(1000);
await waitForElement(By.xpath('//li[@role="menuitem" and @aria-label="New room"]'));
await browser.findElement(By.xpath('//li[@role="menuitem" and @aria-label="New room"]')).click();
await browser.sleep(1000);
await waitForElement(By.xpath('//input[@label="Name"]'));
await browser.findElement(By.xpath('//input[@label="Name"]')).sendKeys(ROOM_NAME);
await browser.sleep(1000);
await waitForElement(By.xpath('//button[text()="Create room"]'));
await browser.findElement(By.xpath('//button[text()="Create room"]')).click();
await browser.sleep(1000);
await waitForElement(By.xpath('//div[@role="button" and @aria-label="Add room"]'));
await waitForElement(By.xpath('//div[@class="mx_RoomTile_titleContainer"]/div[@title="' + ROOM_NAME + '"]'));
}
async function checkRoom() {
await browser.get(`https://${elementApp.fqdn}/#/home`);
await browser.sleep(4000);
await waitForElement(By.xpath('//div[@role="treeitem" and @aria-label="' + ROOM_NAME + '"]'));
await browser.findElement(By.xpath('//div[@role="treeitem" and @aria-label="' + ROOM_NAME + '"]')).click();
await browser.sleep(2000);
await waitForElement(By.xpath('//h2[text()="' + ROOM_NAME + '"]'));
}
async function sendMessage() {
await checkRoom();
await browser.findElement(By.xpath('//div[contains(@class, "mx_BasicMessageComposer_input")]')).sendKeys(getMessage());
await browser.sleep(2000);
await browser.findElement(By.xpath('//div[@role="button" and @aria-label="Send message"]')).click();
await browser.sleep(2000);
} }
xit('build app', function () { execSync('cloudron build', EXEC_ARGS); }); xit('build app', function () { execSync('cloudron build', EXEC_ARGS); });
@@ -314,9 +299,13 @@ describe('Application life cycle test', function () {
it('can get Element app info', getElementAppInfo); it('can get Element app info', getElementAppInfo);
it('can register new user', registerUser); it('can register new user', registerUser);
it('create room', createRoom);
it('can send message', sendMessage);
it('can logout', logout); // from auto-login it('can logout', logout); // from auto-login
it('can login', login); it('can login', login);
it('check room', checkRoom);
it('can logout', logout); it('can logout', logout);
it('uninstall element-web app', async function () { it('uninstall element-web app', async function () {
@@ -334,6 +323,8 @@ describe('Application life cycle test', function () {
it('update element-app config', updateSynapseConfig); it('update element-app config', updateSynapseConfig);
it('can login via OIDC', loginOIDC.bind(null, USERNAME, PASSWORD, false, false)); it('can login via OIDC', loginOIDC.bind(null, USERNAME, PASSWORD, false, false));
it('create room', createRoom);
it('can send message', sendMessage);
it('can get app info', getAppInfo); it('can get app info', getAppInfo);
it('can restart app', function () { execSync(`cloudron restart --app ${app.id}`); }); it('can restart app', function () { execSync(`cloudron restart --app ${app.id}`); });
@@ -341,6 +332,7 @@ describe('Application life cycle test', function () {
it('backup app', function () { execSync(`cloudron backup create --app ${app.id}`, EXEC_ARGS); }); it('backup app', function () { execSync(`cloudron backup create --app ${app.id}`, EXEC_ARGS); });
it('is logged in', isLoggedIn); it('is logged in', isLoggedIn);
it('check room', checkRoom);
it('restore app', async function () { it('restore app', async function () {
const backups = JSON.parse(execSync(`cloudron backup list --raw --app ${app.id}`)); const backups = JSON.parse(execSync(`cloudron backup list --raw --app ${app.id}`));
@@ -355,6 +347,8 @@ describe('Application life cycle test', function () {
}); });
it('is logged in', isLoggedIn); it('is logged in', isLoggedIn);
it('check room', checkRoom);
it('can send message', sendMessage);
it('can logout', logout); it('can logout', logout);
it('can get app info', getAppInfo); it('can get app info', getAppInfo);
@@ -370,6 +364,8 @@ describe('Application life cycle test', function () {
xit('update element-app config', updateSynapseConfig); xit('update element-app config', updateSynapseConfig);
xit('can get Element app info', getElementAppInfo); xit('can get Element app info', getElementAppInfo);
xit('can login via OIDC', loginOIDC.bind(null, USERNAME, PASSWORD, true, true)); xit('can login via OIDC', loginOIDC.bind(null, USERNAME, PASSWORD, true, true));
xit('check room', checkRoom);
xit('can send message', sendMessage);
it('uninstall app', async function () { it('uninstall app', async function () {
await browser.get('about:blank'); await browser.get('about:blank');
@@ -389,9 +385,10 @@ describe('Application life cycle test', function () {
it('can get Element app info', getElementAppInfo); it('can get Element app info', getElementAppInfo);
it('update element-app config', updateSynapseConfig); it('update element-app config', updateSynapseConfig);
it('can login via OIDC', loginOIDCOld.bind(null, USERNAME, PASSWORD, false, false)); it('can login via OIDC', loginOIDC.bind(null, USERNAME, PASSWORD, false, false));
it('is logged in', isLoggedIn); it('is logged in', isLoggedIn);
it('create room', createRoom);
it('can send message', sendMessage);
it('can logout', logout); it('can logout', logout);
it('clear cache', clearCache); it('clear cache', clearCache);
@@ -405,6 +402,10 @@ describe('Application life cycle test', function () {
it('can login via OIDC', loginOIDC.bind(null, USERNAME, PASSWORD, false, true)); it('can login via OIDC', loginOIDC.bind(null, USERNAME, PASSWORD, false, true));
it('is logged in', isLoggedIn); it('is logged in', isLoggedIn);
it('check room', checkRoom);
it('can send message', sendMessage);
it('can get app info', getAppInfo);
it('uninstall app', async function () { it('uninstall app', async function () {
await browser.get('about:blank'); await browser.get('about:blank');