From ecc3fc54a629883d86b3296f49e4579df412cfa8 Mon Sep 17 00:00:00 2001 From: "Kai A. Hiller" Date: Thu, 6 Aug 2026 18:07:48 +0200 Subject: [PATCH 01/37] Merge error docs for existing and reserved users --- crates/handlers/src/admin/v1/users/add.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/crates/handlers/src/admin/v1/users/add.rs b/crates/handlers/src/admin/v1/users/add.rs index 976ae818f..48b357043 100644 --- a/crates/handlers/src/admin/v1/users/add.rs +++ b/crates/handlers/src/admin/v1/users/add.rs @@ -125,13 +125,9 @@ pub fn doc(operation: TransformOperation) -> TransformOperation { let response = ErrorResponse::from_error(&RouteError::UsernameNotValid); t.description("Username is not valid").example(response) }) - .response_with::<409, RouteError, _>(|t| { - let response = ErrorResponse::from_error(&RouteError::UserAlreadyExists); - t.description("User already exists").example(response) - }) .response_with::<409, RouteError, _>(|t| { let response = ErrorResponse::from_error(&RouteError::UsernameReserved); - t.description("Username is reserved by the homeserver") + t.description("User already exists or the username is reserved by the homeserver") .example(response) }) } From 5647b8a8a463347daf455895ef3945d4073fc5d3 Mon Sep 17 00:00:00 2001 From: "Kai A. Hiller" Date: Fri, 7 Aug 2026 02:08:51 +0200 Subject: [PATCH 02/37] Update schema --- docs/api/spec.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/spec.json b/docs/api/spec.json index 72c4bf0e2..8f4cbbce4 100644 --- a/docs/api/spec.json +++ b/docs/api/spec.json @@ -2310,7 +2310,7 @@ } }, "409": { - "description": "Username is reserved by the homeserver", + "description": "User already exists or the username is reserved by the homeserver", "content": { "application/json": { "schema": { From ded9de23dbe89cf80532c2bba122457ea2be2eb4 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Thu, 6 Aug 2026 17:38:58 +0200 Subject: [PATCH 03/37] Move the form_post auto-submit script to a frontend entrypoint --- frontend/src/entrypoints/form-post.ts | 10 ++++++++++ templates/form_post.html | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 frontend/src/entrypoints/form-post.ts diff --git a/frontend/src/entrypoints/form-post.ts b/frontend/src/entrypoints/form-post.ts new file mode 100644 index 000000000..fe52c04cb --- /dev/null +++ b/frontend/src/entrypoints/form-post.ts @@ -0,0 +1,10 @@ +// Copyright 2026 Element Creations Ltd. +// +// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +// Please see LICENSE files in the repository root for full details. + +// Submit the form on the next tick, so the browser can paint the +// placeholder before navigating away. +setTimeout(() => { + document.forms[0].submit(); +}, 0); diff --git a/templates/form_post.html b/templates/form_post.html index 71882c8ab..253c152d4 100644 --- a/templates/form_post.html +++ b/templates/form_post.html @@ -1,4 +1,5 @@ {# +Copyright 2025, 2026 Element Creations Ltd. Copyright 2024, 2025 New Vector Ltd. Copyright 2021-2024 The Matrix.org Foundation C.I.C. @@ -28,5 +29,5 @@ Please see LICENSE files in the repository root for full details. {# Submit the form in JavaScript on the next tick, so that if the browser wants to display the placeholder instead of a blank page, it can #} - + {{ include_asset('src/entrypoints/form-post.ts') | indent(2) | safe }} {% endblock %} From 28ffb064bf60f6f11c8183d177e0c9d72bf357b4 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Thu, 6 Aug 2026 17:39:56 +0200 Subject: [PATCH 04/37] Move the Swagger UI OAuth2 redirect script to a frontend entrypoint --- .../entrypoints/swagger-oauth2-redirect.ts | 104 ++++++++++++++++++ templates/swagger/oauth2-redirect.html | 76 +------------ translations/en.json | 4 +- 3 files changed, 109 insertions(+), 75 deletions(-) create mode 100644 frontend/src/entrypoints/swagger-oauth2-redirect.ts diff --git a/frontend/src/entrypoints/swagger-oauth2-redirect.ts b/frontend/src/entrypoints/swagger-oauth2-redirect.ts new file mode 100644 index 000000000..9eb1153d7 --- /dev/null +++ b/frontend/src/entrypoints/swagger-oauth2-redirect.ts @@ -0,0 +1,104 @@ +// Copyright 2026 Element Creations Ltd. +// +// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +// Please see LICENSE files in the repository root for full details. + +// This is taken from the swagger-ui/dist/oauth2-redirect.html file + +interface SwaggerUIRedirectOauth2 { + state?: string; + redirectUrl: string; + auth: { + name: string; + code?: string; + schema: { get(key: string): string }; + }; + errCb: (error: { + authId: string; + source: string; + level: string; + message: string; + }) => void; + callback: (result: { + auth: SwaggerUIRedirectOauth2["auth"]; + redirectUrl: string; + token?: unknown; + isValid?: boolean; + }) => void; +} + +interface RedirectOpener extends Window { + swaggerUIRedirectOauth2: SwaggerUIRedirectOauth2; +} + +const oauth2 = (window.opener as RedirectOpener).swaggerUIRedirectOauth2; +const sentState = oauth2.state; +const redirectUrl = oauth2.redirectUrl; + +let qpString: string; +if (/code|token|error/.test(window.location.hash)) { + qpString = window.location.hash.substring(1).replace("?", "&"); +} else { + qpString = location.search.substring(1); +} + +const arr = qpString.split("&"); +for (let i = 0; i < arr.length; i++) { + arr[i] = `"${arr[i].replace("=", '":"')}"`; +} +const qp: Record = qpString + ? JSON.parse(`{${arr.join()}}`, (key, value) => + key === "" ? value : decodeURIComponent(value), + ) + : {}; + +const isValid = qp.state === sentState; + +if ( + (oauth2.auth.schema.get("flow") === "accessCode" || + oauth2.auth.schema.get("flow") === "authorizationCode" || + oauth2.auth.schema.get("flow") === "authorization_code") && + !oauth2.auth.code +) { + if (!isValid) { + oauth2.errCb({ + authId: oauth2.auth.name, + source: "auth", + level: "warning", + message: + "Authorization may be unsafe, passed state was changed in server. The passed state wasn't returned from auth server.", + }); + } + + if (qp.code) { + delete oauth2.state; + oauth2.auth.code = qp.code; + oauth2.callback({ auth: oauth2.auth, redirectUrl: redirectUrl }); + } else { + let oauthErrorMsg: string | undefined; + if (qp.error) { + oauthErrorMsg = `[${qp.error}]: ${ + qp.error_description + ? `${qp.error_description}. ` + : "no accessCode received from the server. " + }${qp.error_uri ? `More info: ${qp.error_uri}` : ""}`; + } + + oauth2.errCb({ + authId: oauth2.auth.name, + source: "auth", + level: "error", + message: + oauthErrorMsg || + "[Authorization failed]: no accessCode received from the server.", + }); + } +} else { + oauth2.callback({ + auth: oauth2.auth, + token: qp, + isValid: isValid, + redirectUrl: redirectUrl, + }); +} +window.close(); diff --git a/templates/swagger/oauth2-redirect.html b/templates/swagger/oauth2-redirect.html index 831e518ec..d9a056d3a 100644 --- a/templates/swagger/oauth2-redirect.html +++ b/templates/swagger/oauth2-redirect.html @@ -1,4 +1,5 @@ {# +Copyright 2025, 2026 Element Creations Ltd. Copyright 2024, 2025 New Vector Ltd. Copyright 2024 The Matrix.org Foundation C.I.C. @@ -12,78 +13,7 @@ Please see LICENSE files in the repository root for full details. API documentation: OAuth2 Redirect + {{ include_asset('src/entrypoints/swagger-oauth2-redirect.ts') | indent(4) | safe }} - - - + diff --git a/translations/en.json b/translations/en.json index 320fed5e0..ddc348533 100644 --- a/translations/en.json +++ b/translations/en.json @@ -10,7 +10,7 @@ }, "continue": "Continue", "@continue": { - "context": "form_post.html:25:28-48, pages/consent.html:71:28-48, pages/device_link.html:42:28-48, pages/login.html:68:30-50, pages/reauth.html:32:28-48, pages/recovery/start.html:38:26-46, pages/register/password.html:77:26-46, pages/register/steps/display_name.html:43:28-48, pages/register/steps/registration_token.html:41:28-48, pages/register/steps/verify_email.html:51:26-46, pages/sso.html:52:28-48" + "context": "form_post.html:26:28-48, pages/consent.html:71:28-48, pages/device_link.html:42:28-48, pages/login.html:68:30-50, pages/reauth.html:32:28-48, pages/recovery/start.html:38:26-46, pages/register/password.html:77:26-46, pages/register/steps/display_name.html:43:28-48, pages/register/steps/registration_token.html:41:28-48, pages/register/steps/verify_email.html:51:26-46, pages/sso.html:52:28-48" }, "create_account": "Create Account", "@create_account": { @@ -83,7 +83,7 @@ }, "loading": "Loading…", "@loading": { - "context": "form_post.html:14:27-46" + "context": "form_post.html:15:27-46" }, "mxid": "Matrix ID", "@mxid": { From ac35bc7d9b7f6aefd5c7fb6437b285475b263003 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 11 Aug 2026 17:17:51 +0000 Subject: [PATCH 05/37] 1.23.0-rc.0 --- Cargo.lock | 56 +++++++++++++++++++++++++------------------------- Cargo.toml | 60 +++++++++++++++++++++++++++--------------------------- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 07924b34f..de905f86d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3198,7 +3198,7 @@ dependencies = [ [[package]] name = "mas-axum-utils" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "anyhow", "axum", @@ -3233,7 +3233,7 @@ dependencies = [ [[package]] name = "mas-cli" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "anyhow", "axum", @@ -3308,7 +3308,7 @@ dependencies = [ [[package]] name = "mas-config" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "anyhow", "camino", @@ -3339,7 +3339,7 @@ dependencies = [ [[package]] name = "mas-context" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "console", "opentelemetry", @@ -3356,7 +3356,7 @@ dependencies = [ [[package]] name = "mas-data-model" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "base64ct", "chrono", @@ -3378,7 +3378,7 @@ dependencies = [ [[package]] name = "mas-email" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "async-trait", "lettre", @@ -3389,7 +3389,7 @@ dependencies = [ [[package]] name = "mas-handlers" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "aide", "anyhow", @@ -3472,7 +3472,7 @@ dependencies = [ [[package]] name = "mas-http" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "futures-util", "headers", @@ -3492,7 +3492,7 @@ dependencies = [ [[package]] name = "mas-i18n" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "camino", "icu_datetime", @@ -3512,7 +3512,7 @@ dependencies = [ [[package]] name = "mas-i18n-scan" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "camino", "clap", @@ -3526,7 +3526,7 @@ dependencies = [ [[package]] name = "mas-iana" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "schemars 1.2.1", "serde", @@ -3534,7 +3534,7 @@ dependencies = [ [[package]] name = "mas-iana-codegen" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "anyhow", "async-trait", @@ -3551,7 +3551,7 @@ dependencies = [ [[package]] name = "mas-jose" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "base64ct", "chrono", @@ -3581,7 +3581,7 @@ dependencies = [ [[package]] name = "mas-keystore" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "aead", "base64ct", @@ -3609,7 +3609,7 @@ dependencies = [ [[package]] name = "mas-listener" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "anyhow", "bytes", @@ -3633,7 +3633,7 @@ dependencies = [ [[package]] name = "mas-matrix" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "anyhow", "async-trait", @@ -3643,7 +3643,7 @@ dependencies = [ [[package]] name = "mas-matrix-synapse" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "anyhow", "async-trait", @@ -3660,7 +3660,7 @@ dependencies = [ [[package]] name = "mas-oidc-client" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "assert_matches", "async-trait", @@ -3696,7 +3696,7 @@ dependencies = [ [[package]] name = "mas-policy" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "anyhow", "arc-swap", @@ -3713,7 +3713,7 @@ dependencies = [ [[package]] name = "mas-router" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "axum", "serde", @@ -3724,7 +3724,7 @@ dependencies = [ [[package]] name = "mas-spa" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "camino", "serde", @@ -3733,7 +3733,7 @@ dependencies = [ [[package]] name = "mas-storage" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "async-trait", "chrono", @@ -3755,7 +3755,7 @@ dependencies = [ [[package]] name = "mas-storage-pg" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "async-trait", "chrono", @@ -3787,7 +3787,7 @@ dependencies = [ [[package]] name = "mas-tasks" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "anyhow", "async-trait", @@ -3819,7 +3819,7 @@ dependencies = [ [[package]] name = "mas-templates" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "anyhow", "arc-swap", @@ -3851,7 +3851,7 @@ dependencies = [ [[package]] name = "mas-tower" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "http", "opentelemetry", @@ -4103,7 +4103,7 @@ dependencies = [ [[package]] name = "oauth2-types" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "assert_matches", "base64ct", @@ -6279,7 +6279,7 @@ dependencies = [ [[package]] name = "syn2mas" -version = "1.22.0" +version = "1.23.0-rc.0" dependencies = [ "anyhow", "arc-swap", diff --git a/Cargo.toml b/Cargo.toml index 377edbfad..39086fed6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ members = ["crates/*"] resolver = "2" # Updated in the CI with a `sed` command -package.version = "1.22.0" +package.version = "1.23.0-rc.0" package.license = "AGPL-3.0-only OR LicenseRef-Element-Commercial" package.authors = ["Element Backend Team"] package.edition = "2024" @@ -42,35 +42,35 @@ broken_intra_doc_links = "deny" [workspace.dependencies] # Workspace crates -mas-axum-utils = { path = "./crates/axum-utils/", version = "=1.22.0" } -mas-cli = { path = "./crates/cli/", version = "=1.22.0" } -mas-config = { path = "./crates/config/", version = "=1.22.0" } -mas-context = { path = "./crates/context/", version = "=1.22.0" } -mas-data-model = { path = "./crates/data-model/", version = "=1.22.0" } -mas-email = { path = "./crates/email/", version = "=1.22.0" } -mas-graphql = { path = "./crates/graphql/", version = "=1.22.0" } -mas-handlers = { path = "./crates/handlers/", version = "=1.22.0" } -mas-http = { path = "./crates/http/", version = "=1.22.0" } -mas-i18n = { path = "./crates/i18n/", version = "=1.22.0" } -mas-i18n-scan = { path = "./crates/i18n-scan/", version = "=1.22.0" } -mas-iana = { path = "./crates/iana/", version = "=1.22.0" } -mas-iana-codegen = { path = "./crates/iana-codegen/", version = "=1.22.0" } -mas-jose = { path = "./crates/jose/", version = "=1.22.0" } -mas-keystore = { path = "./crates/keystore/", version = "=1.22.0" } -mas-listener = { path = "./crates/listener/", version = "=1.22.0" } -mas-matrix = { path = "./crates/matrix/", version = "=1.22.0" } -mas-matrix-synapse = { path = "./crates/matrix-synapse/", version = "=1.22.0" } -mas-oidc-client = { path = "./crates/oidc-client/", version = "=1.22.0" } -mas-policy = { path = "./crates/policy/", version = "=1.22.0" } -mas-router = { path = "./crates/router/", version = "=1.22.0" } -mas-spa = { path = "./crates/spa/", version = "=1.22.0" } -mas-storage = { path = "./crates/storage/", version = "=1.22.0" } -mas-storage-pg = { path = "./crates/storage-pg/", version = "=1.22.0" } -mas-tasks = { path = "./crates/tasks/", version = "=1.22.0" } -mas-templates = { path = "./crates/templates/", version = "=1.22.0" } -mas-tower = { path = "./crates/tower/", version = "=1.22.0" } -oauth2-types = { path = "./crates/oauth2-types/", version = "=1.22.0" } -syn2mas = { path = "./crates/syn2mas", version = "=1.22.0" } +mas-axum-utils = { path = "./crates/axum-utils/", version = "=1.23.0-rc.0" } +mas-cli = { path = "./crates/cli/", version = "=1.23.0-rc.0" } +mas-config = { path = "./crates/config/", version = "=1.23.0-rc.0" } +mas-context = { path = "./crates/context/", version = "=1.23.0-rc.0" } +mas-data-model = { path = "./crates/data-model/", version = "=1.23.0-rc.0" } +mas-email = { path = "./crates/email/", version = "=1.23.0-rc.0" } +mas-graphql = { path = "./crates/graphql/", version = "=1.23.0-rc.0" } +mas-handlers = { path = "./crates/handlers/", version = "=1.23.0-rc.0" } +mas-http = { path = "./crates/http/", version = "=1.23.0-rc.0" } +mas-i18n = { path = "./crates/i18n/", version = "=1.23.0-rc.0" } +mas-i18n-scan = { path = "./crates/i18n-scan/", version = "=1.23.0-rc.0" } +mas-iana = { path = "./crates/iana/", version = "=1.23.0-rc.0" } +mas-iana-codegen = { path = "./crates/iana-codegen/", version = "=1.23.0-rc.0" } +mas-jose = { path = "./crates/jose/", version = "=1.23.0-rc.0" } +mas-keystore = { path = "./crates/keystore/", version = "=1.23.0-rc.0" } +mas-listener = { path = "./crates/listener/", version = "=1.23.0-rc.0" } +mas-matrix = { path = "./crates/matrix/", version = "=1.23.0-rc.0" } +mas-matrix-synapse = { path = "./crates/matrix-synapse/", version = "=1.23.0-rc.0" } +mas-oidc-client = { path = "./crates/oidc-client/", version = "=1.23.0-rc.0" } +mas-policy = { path = "./crates/policy/", version = "=1.23.0-rc.0" } +mas-router = { path = "./crates/router/", version = "=1.23.0-rc.0" } +mas-spa = { path = "./crates/spa/", version = "=1.23.0-rc.0" } +mas-storage = { path = "./crates/storage/", version = "=1.23.0-rc.0" } +mas-storage-pg = { path = "./crates/storage-pg/", version = "=1.23.0-rc.0" } +mas-tasks = { path = "./crates/tasks/", version = "=1.23.0-rc.0" } +mas-templates = { path = "./crates/templates/", version = "=1.23.0-rc.0" } +mas-tower = { path = "./crates/tower/", version = "=1.23.0-rc.0" } +oauth2-types = { path = "./crates/oauth2-types/", version = "=1.23.0-rc.0" } +syn2mas = { path = "./crates/syn2mas", version = "=1.23.0-rc.0" } # OpenAPI schema generation and validation [workspace.dependencies.aide] From 59de993b0db2649a59908db96a32c2931bd8d64e Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Fri, 14 Aug 2026 16:14:11 +0200 Subject: [PATCH 06/37] Ignore unmaintained dependencies warnings from cargo-deny on transitive dependencies --- deny.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/deny.toml b/deny.toml index e0fd70fc9..ee8a05976 100644 --- a/deny.toml +++ b/deny.toml @@ -29,6 +29,10 @@ ignore = [ "RUSTSEC-2026-0222", ] +# Only warn about unmaintained crates in direct dependencies of the workspace, +# not transitive dependencies +unmaintained = "workspace" + [licenses] version = 2 allow = [ From cf96d79af4c068fdc7e980a167519c2a96844903 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Fri, 14 Aug 2026 17:09:45 +0100 Subject: [PATCH 07/37] Fix rendering of policy violations without `code` field --- crates/templates/src/context.rs | 22 +++++++++++++++++-- .../pages/compat_login_policy_violation.html | 2 +- templates/pages/policy_violation.html | 2 +- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/crates/templates/src/context.rs b/crates/templates/src/context.rs index 98121a9ad..8b32144db 100644 --- a/crates/templates/src/context.rs +++ b/crates/templates/src/context.rs @@ -822,7 +822,12 @@ impl TemplateContext for PolicyViolationContext { let authorization_grant = PolicyViolationContext::for_authorization_grant( grant, client.clone(), - Vec::new(), + vec![Violation { + msg: "scope 'foo' not allowed".to_owned(), + redirect_uri: None, + field: None, + variant: None, + }], ); let device_code_grant = PolicyViolationContext::for_device_code_grant( DeviceCodeGrant { @@ -839,7 +844,12 @@ impl TemplateContext for PolicyViolationContext { locale: None, }, client, - Vec::new(), + vec![Violation { + msg: "user has too many active sessions".to_owned(), + redirect_uri: None, + field: None, + variant: Some(ViolationVariant::TooManySessions { need_to_remove: 1 }), + }], ); [authorization_grant, device_code_grant] @@ -902,6 +912,14 @@ impl TemplateContext for CompatLoginPolicyViolationContext { { sample_list(vec![ CompatLoginPolicyViolationContext { violations: vec![] }, + CompatLoginPolicyViolationContext { + violations: vec![Violation { + msg: "scope 'foo' not allowed".to_owned(), + redirect_uri: None, + field: None, + variant: None, + }], + }, CompatLoginPolicyViolationContext { violations: vec![Violation { msg: "user has too many active sessions".to_owned(), diff --git a/templates/pages/compat_login_policy_violation.html b/templates/pages/compat_login_policy_violation.html index 2c1a12847..d6b7372dc 100644 --- a/templates/pages/compat_login_policy_violation.html +++ b/templates/pages/compat_login_policy_violation.html @@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details. {% extends "base.html" %} -{% set is_too_many_sessions = violations | length == 1 and violations[0].code == "too-many-sessions" %} +{% set is_too_many_sessions = violations | length == 1 and violations[0].code | default("") == "too-many-sessions" %} {% set num_sessions_need_to_remove = violations[0].need_to_remove if is_too_many_sessions else none %} {% block content %} diff --git a/templates/pages/policy_violation.html b/templates/pages/policy_violation.html index 2b97a8bc4..d44593c85 100644 --- a/templates/pages/policy_violation.html +++ b/templates/pages/policy_violation.html @@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details. {% extends "base.html" %} -{% set is_too_many_sessions = violations | length == 1 and violations[0].code == "too-many-sessions" %} +{% set is_too_many_sessions = violations | length == 1 and violations[0].code | default("") == "too-many-sessions" %} {% set num_sessions_need_to_remove = violations[0].need_to_remove if is_too_many_sessions else none %} {% block content %} From f94d364ddbc489b62174c38c94c7d8f8328da183 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Fri, 14 Aug 2026 17:20:03 +0100 Subject: [PATCH 08/37] Include empty tests --- crates/templates/src/context.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/crates/templates/src/context.rs b/crates/templates/src/context.rs index 8b32144db..adb5d148c 100644 --- a/crates/templates/src/context.rs +++ b/crates/templates/src/context.rs @@ -820,6 +820,12 @@ impl TemplateContext for PolicyViolationContext { grant.client_id = client.id; let authorization_grant = PolicyViolationContext::for_authorization_grant( + grant.clone(), + client.clone(), + Vec::new(), + ); + + let authorization_grant_invalid_scope = PolicyViolationContext::for_authorization_grant( grant, client.clone(), vec![Violation { @@ -830,6 +836,24 @@ impl TemplateContext for PolicyViolationContext { }], ); let device_code_grant = PolicyViolationContext::for_device_code_grant( + DeviceCodeGrant { + id: Ulid::from_datetime_with_rng(now, rng), + state: mas_data_model::DeviceCodeGrantState::Pending, + client_id: client.id, + scope: [OPENID].into_iter().collect(), + user_code: Alphanumeric.sample_string(rng, 6).to_uppercase(), + device_code: Alphanumeric.sample_string(rng, 32), + created_at: now - Duration::try_minutes(5).unwrap(), + expires_at: now + Duration::try_minutes(25).unwrap(), + ip_address: None, + user_agent: None, + locale: None, + }, + client.clone(), + Vec::new() + ); + + let device_code_grant_invalid_scope = PolicyViolationContext::for_device_code_grant( DeviceCodeGrant { id: Ulid::from_datetime_with_rng(now, rng), state: mas_data_model::DeviceCodeGrantState::Pending, @@ -852,7 +876,7 @@ impl TemplateContext for PolicyViolationContext { }], ); - [authorization_grant, device_code_grant] + [authorization_grant, authorization_grant_invalid_scope, device_code_grant, device_code_grant_invalid_scope] }) .collect(), ) From af50a1db0238d6d9d76df2a63cb8e8bbf5ccd295 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Fri, 14 Aug 2026 17:21:17 +0100 Subject: [PATCH 09/37] Format --- crates/templates/src/context.rs | 77 ++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/crates/templates/src/context.rs b/crates/templates/src/context.rs index adb5d148c..daf8ca4cf 100644 --- a/crates/templates/src/context.rs +++ b/crates/templates/src/context.rs @@ -825,16 +825,17 @@ impl TemplateContext for PolicyViolationContext { Vec::new(), ); - let authorization_grant_invalid_scope = PolicyViolationContext::for_authorization_grant( - grant, - client.clone(), - vec![Violation { - msg: "scope 'foo' not allowed".to_owned(), - redirect_uri: None, - field: None, - variant: None, - }], - ); + let authorization_grant_invalid_scope = + PolicyViolationContext::for_authorization_grant( + grant, + client.clone(), + vec![Violation { + msg: "scope 'foo' not allowed".to_owned(), + redirect_uri: None, + field: None, + variant: None, + }], + ); let device_code_grant = PolicyViolationContext::for_device_code_grant( DeviceCodeGrant { id: Ulid::from_datetime_with_rng(now, rng), @@ -850,33 +851,41 @@ impl TemplateContext for PolicyViolationContext { locale: None, }, client.clone(), - Vec::new() + Vec::new(), ); - let device_code_grant_invalid_scope = PolicyViolationContext::for_device_code_grant( - DeviceCodeGrant { - id: Ulid::from_datetime_with_rng(now, rng), - state: mas_data_model::DeviceCodeGrantState::Pending, - client_id: client.id, - scope: [OPENID].into_iter().collect(), - user_code: Alphanumeric.sample_string(rng, 6).to_uppercase(), - device_code: Alphanumeric.sample_string(rng, 32), - created_at: now - Duration::try_minutes(5).unwrap(), - expires_at: now + Duration::try_minutes(25).unwrap(), - ip_address: None, - user_agent: None, - locale: None, - }, - client, - vec![Violation { - msg: "user has too many active sessions".to_owned(), - redirect_uri: None, - field: None, - variant: Some(ViolationVariant::TooManySessions { need_to_remove: 1 }), - }], - ); + let device_code_grant_invalid_scope = + PolicyViolationContext::for_device_code_grant( + DeviceCodeGrant { + id: Ulid::from_datetime_with_rng(now, rng), + state: mas_data_model::DeviceCodeGrantState::Pending, + client_id: client.id, + scope: [OPENID].into_iter().collect(), + user_code: Alphanumeric.sample_string(rng, 6).to_uppercase(), + device_code: Alphanumeric.sample_string(rng, 32), + created_at: now - Duration::try_minutes(5).unwrap(), + expires_at: now + Duration::try_minutes(25).unwrap(), + ip_address: None, + user_agent: None, + locale: None, + }, + client, + vec![Violation { + msg: "user has too many active sessions".to_owned(), + redirect_uri: None, + field: None, + variant: Some(ViolationVariant::TooManySessions { + need_to_remove: 1, + }), + }], + ); - [authorization_grant, authorization_grant_invalid_scope, device_code_grant, device_code_grant_invalid_scope] + [ + authorization_grant, + authorization_grant_invalid_scope, + device_code_grant, + device_code_grant_invalid_scope, + ] }) .collect(), ) From 0dc893a0708e9a2ac14385c97bd5068ed99289e6 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Fri, 14 Aug 2026 17:30:16 +0100 Subject: [PATCH 10/37] Fix back_to_client template error when no state param given --- crates/templates/src/context.rs | 45 ++++++++++++++++-------- crates/templates/src/functions.rs | 8 ++++- templates/components/back_to_client.html | 4 ++- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/crates/templates/src/context.rs b/crates/templates/src/context.rs index 98121a9ad..c28362752 100644 --- a/crates/templates/src/context.rs +++ b/crates/templates/src/context.rs @@ -32,7 +32,10 @@ use mas_i18n::DataLocale; use mas_iana::jose::JsonWebSignatureAlg; use mas_policy::{Violation, ViolationVariant}; use mas_router::{Account, GraphQL, PostAuthAction, UrlBuilder}; -use oauth2_types::scope::{OPENID, Scope}; +use oauth2_types::{ + requests::ResponseMode, + scope::{OPENID, Scope}, +}; use rand::{ Rng, SeedableRng, distributions::{Alphanumeric, DistString}, @@ -750,20 +753,32 @@ impl TemplateContext for ConsentContext { sample_list( Client::samples(now, rng) .into_iter() - .map(|client| { - let mut grant = AuthorizationGrant::sample(now, rng); - let action = PostAuthAction::continue_grant(grant.id); - // XXX - grant.client_id = client.id; - Self { - grant, - client, - action, - matrix_user: MatrixUser { - mxid: "@alice:example.com".to_owned(), - display_name: Some("Alice".to_owned()), - }, - } + .flat_map(|client| { + [ + (None, ResponseMode::Query), + (None, ResponseMode::Fragment), + (None, ResponseMode::FormPost), + (Some("some-state".to_owned()), ResponseMode::Query), + (Some("some-state".to_owned()), ResponseMode::Fragment), + (Some("some-state".to_owned()), ResponseMode::FormPost), + ] + .map(|(state, response_mode)| { + let mut grant = AuthorizationGrant::sample(now, rng); + let action = PostAuthAction::continue_grant(grant.id); + // XXX + grant.client_id = client.id; + grant.state = state; + grant.response_mode = response_mode; + Self { + grant, + client: client.clone(), + action, + matrix_user: MatrixUser { + mxid: "@alice:example.com".to_owned(), + display_name: Some("Alice".to_owned()), + }, + } + }) }) .collect(), ) diff --git a/crates/templates/src/functions.rs b/crates/templates/src/functions.rs index 16515572e..05bc0f313 100644 --- a/crates/templates/src/functions.rs +++ b/crates/templates/src/functions.rs @@ -195,7 +195,13 @@ fn function_add_params_to_url( // Merge the exising and the additional parameters together // Use a BTreeMap for determinism (because it orders keys) - let params: BTreeMap<&String, &Value> = params.iter().chain(existing.iter()).collect(); + // Parameters which have no value (e.g. an absent `state`) are skipped, as they + // can't be serialized back to a query string + let params: BTreeMap<&String, &Value> = params + .iter() + .chain(existing.iter()) + .filter(|(_key, value)| !value.is_none() && !value.is_undefined()) + .collect(); // Transform them back to urlencoded let params = serde_urlencoded::to_string(params).map_err(|e| { diff --git a/templates/components/back_to_client.html b/templates/components/back_to_client.html index 67417584d..97605ed0d 100644 --- a/templates/components/back_to_client.html +++ b/templates/components/back_to_client.html @@ -25,7 +25,9 @@ Please see LICENSE files in the repository root for full details. {% if mode == "form_post" %}
{% for key, value in params|items %} - + {% if value is not none and value is defined %} + + {% endif %} {% endfor %}
From 9539e8a38eb79796579ed8a9bb0703ee31c056d0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2026 19:24:12 +0000 Subject: [PATCH 11/37] Translations updates --- frontend/.storybook/locales.ts | 78 +++++++++++++++++----------------- frontend/locales/pl.json | 8 ++-- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/frontend/.storybook/locales.ts b/frontend/.storybook/locales.ts index 396dc18c5..6a036a0fe 100644 --- a/frontend/.storybook/locales.ts +++ b/frontend/.storybook/locales.ts @@ -27,7 +27,7 @@ export type LocalazyMetadata = { }; const localazyMetadata: LocalazyMetadata = { - projectUrl: "https://localazy.com/p/matrix-authentication-service!v1.22", + projectUrl: "https://localazy.com/p/matrix-authentication-service!v1.23", baseLocale: "en", languages: [ { @@ -208,25 +208,25 @@ const localazyMetadata: LocalazyMetadata = { file: "frontend.json", path: "", cdnFiles: { - "cs": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/cs/frontend.json", - "da": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/da/frontend.json", - "de": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/de/frontend.json", - "en": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/en/frontend.json", - "et": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/et/frontend.json", - "fi": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/fi/frontend.json", - "fr": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/fr/frontend.json", - "hu": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/hu/frontend.json", - "nb_NO": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/nb-NO/frontend.json", - "nl": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/nl/frontend.json", - "pl": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pl/frontend.json", - "pt": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pt/frontend.json", - "pt_BR": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pt-BR/frontend.json", - "ru": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/ru/frontend.json", - "sk": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/sk/frontend.json", - "sv": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/sv/frontend.json", - "uk": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/uk/frontend.json", - "uz": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/uz/frontend.json", - "zh#Hans": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/zh-Hans/frontend.json" + "cs": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/cs/frontend.json", + "da": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/da/frontend.json", + "de": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/de/frontend.json", + "en": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/en/frontend.json", + "et": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/et/frontend.json", + "fi": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/fi/frontend.json", + "fr": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/fr/frontend.json", + "hu": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/hu/frontend.json", + "nb_NO": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/nb-NO/frontend.json", + "nl": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/nl/frontend.json", + "pl": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pl/frontend.json", + "pt": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pt/frontend.json", + "pt_BR": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pt-BR/frontend.json", + "ru": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/ru/frontend.json", + "sk": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/sk/frontend.json", + "sv": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/sv/frontend.json", + "uk": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/uk/frontend.json", + "uz": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/uz/frontend.json", + "zh#Hans": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/zh-Hans/frontend.json" } }, { @@ -234,25 +234,25 @@ const localazyMetadata: LocalazyMetadata = { file: "file.json", path: "", cdnFiles: { - "cs": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/cs/file.json", - "da": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/da/file.json", - "de": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/de/file.json", - "en": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/en/file.json", - "et": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/et/file.json", - "fi": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/fi/file.json", - "fr": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/fr/file.json", - "hu": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/hu/file.json", - "nb_NO": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/nb-NO/file.json", - "nl": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/nl/file.json", - "pl": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pl/file.json", - "pt": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pt/file.json", - "pt_BR": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pt-BR/file.json", - "ru": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/ru/file.json", - "sk": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/sk/file.json", - "sv": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/sv/file.json", - "uk": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/uk/file.json", - "uz": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/uz/file.json", - "zh#Hans": "https://delivery.localazy.com/_a643710470041658449213cbf79a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/zh-Hans/file.json" + "cs": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/cs/file.json", + "da": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/da/file.json", + "de": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/de/file.json", + "en": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/en/file.json", + "et": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/et/file.json", + "fi": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/fi/file.json", + "fr": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/fr/file.json", + "hu": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/hu/file.json", + "nb_NO": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/nb-NO/file.json", + "nl": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/nl/file.json", + "pl": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pl/file.json", + "pt": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pt/file.json", + "pt_BR": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pt-BR/file.json", + "ru": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/ru/file.json", + "sk": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/sk/file.json", + "sv": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/sv/file.json", + "uk": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/uk/file.json", + "uz": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/uz/file.json", + "zh#Hans": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/zh-Hans/file.json" } } ] diff --git a/frontend/locales/pl.json b/frontend/locales/pl.json index 1134698e4..801b83116 100644 --- a/frontend/locales/pl.json +++ b/frontend/locales/pl.json @@ -25,7 +25,7 @@ } }, "common": { - "e2ee": "Szyfrowanie typu end-to-end", + "e2ee": "Szyfrowanie end-to-end", "loading": "Wczytywanie…", "next": "Dalej", "password": "Hasło", @@ -35,7 +35,7 @@ }, "frontend": { "account": { - "account_password": "Hasło do konta", + "account_password": "Hasło konta", "contact_info": "Dane kontaktowe", "delete_account": { "alert_description": "To konto zostanie trwale usunięte i nie będziesz już mieć dostępu do żadnych wiadomości.", @@ -120,7 +120,7 @@ "last_active": { "active_date": "Aktywne {{relativeDate}}", "active_now": "Aktywne teraz", - "inactive_90_days": "Nieaktywny przez ponad 90 dni" + "inactive_90_days": "Nieaktywne przez ponad 90 dni" }, "nav": { "device_limit_error": "Osiągnięto limit urządzeń", @@ -233,7 +233,7 @@ "description_2": "Jeśli wylogowałeś się z dowolnego miejsca i nie pamiętasz kodu odzyskiwania, nadal musisz zresetować swoją tożsamość.", "heading": "Resetowanie tożsamości zostało anulowane." }, - "description": "Jeśli nie zalogowałeś się na żadnym innym urządzeniu i utraciłeś klucz odzyskiwania, musisz zresetować swoją tożsamość, aby móc nadal korzystać z aplikacji.", + "description": "Jeśli nie masz dostępu do innych zweryfikowanych urządzeń i nie posiadasz klucza odzyskiwania, musisz zresetować swoją tożsamość cyfrową, aby móc nadal korzystać z aplikacji.", "effect_list": { "neutral_1": "Utracisz całą historię wiadomości przechowywaną wyłącznie na serwerze", "neutral_2": "Będziesz musiał ponownie zweryfikować wszystkie swoje istniejące urządzenia i kontakty", From 46bb1044a53caebfe89dfad32f868c8241b1e9bc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2026 19:45:06 +0000 Subject: [PATCH 12/37] 1.23.0-rc.1 --- Cargo.lock | 56 +++++++++++++++++++++++++------------------------- Cargo.toml | 60 +++++++++++++++++++++++++++--------------------------- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index de905f86d..a07fe38a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3198,7 +3198,7 @@ dependencies = [ [[package]] name = "mas-axum-utils" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "anyhow", "axum", @@ -3233,7 +3233,7 @@ dependencies = [ [[package]] name = "mas-cli" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "anyhow", "axum", @@ -3308,7 +3308,7 @@ dependencies = [ [[package]] name = "mas-config" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "anyhow", "camino", @@ -3339,7 +3339,7 @@ dependencies = [ [[package]] name = "mas-context" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "console", "opentelemetry", @@ -3356,7 +3356,7 @@ dependencies = [ [[package]] name = "mas-data-model" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "base64ct", "chrono", @@ -3378,7 +3378,7 @@ dependencies = [ [[package]] name = "mas-email" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "async-trait", "lettre", @@ -3389,7 +3389,7 @@ dependencies = [ [[package]] name = "mas-handlers" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "aide", "anyhow", @@ -3472,7 +3472,7 @@ dependencies = [ [[package]] name = "mas-http" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "futures-util", "headers", @@ -3492,7 +3492,7 @@ dependencies = [ [[package]] name = "mas-i18n" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "camino", "icu_datetime", @@ -3512,7 +3512,7 @@ dependencies = [ [[package]] name = "mas-i18n-scan" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "camino", "clap", @@ -3526,7 +3526,7 @@ dependencies = [ [[package]] name = "mas-iana" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "schemars 1.2.1", "serde", @@ -3534,7 +3534,7 @@ dependencies = [ [[package]] name = "mas-iana-codegen" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "anyhow", "async-trait", @@ -3551,7 +3551,7 @@ dependencies = [ [[package]] name = "mas-jose" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "base64ct", "chrono", @@ -3581,7 +3581,7 @@ dependencies = [ [[package]] name = "mas-keystore" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "aead", "base64ct", @@ -3609,7 +3609,7 @@ dependencies = [ [[package]] name = "mas-listener" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "anyhow", "bytes", @@ -3633,7 +3633,7 @@ dependencies = [ [[package]] name = "mas-matrix" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "anyhow", "async-trait", @@ -3643,7 +3643,7 @@ dependencies = [ [[package]] name = "mas-matrix-synapse" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "anyhow", "async-trait", @@ -3660,7 +3660,7 @@ dependencies = [ [[package]] name = "mas-oidc-client" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "assert_matches", "async-trait", @@ -3696,7 +3696,7 @@ dependencies = [ [[package]] name = "mas-policy" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "anyhow", "arc-swap", @@ -3713,7 +3713,7 @@ dependencies = [ [[package]] name = "mas-router" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "axum", "serde", @@ -3724,7 +3724,7 @@ dependencies = [ [[package]] name = "mas-spa" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "camino", "serde", @@ -3733,7 +3733,7 @@ dependencies = [ [[package]] name = "mas-storage" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "async-trait", "chrono", @@ -3755,7 +3755,7 @@ dependencies = [ [[package]] name = "mas-storage-pg" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "async-trait", "chrono", @@ -3787,7 +3787,7 @@ dependencies = [ [[package]] name = "mas-tasks" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "anyhow", "async-trait", @@ -3819,7 +3819,7 @@ dependencies = [ [[package]] name = "mas-templates" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "anyhow", "arc-swap", @@ -3851,7 +3851,7 @@ dependencies = [ [[package]] name = "mas-tower" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "http", "opentelemetry", @@ -4103,7 +4103,7 @@ dependencies = [ [[package]] name = "oauth2-types" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "assert_matches", "base64ct", @@ -6279,7 +6279,7 @@ dependencies = [ [[package]] name = "syn2mas" -version = "1.23.0-rc.0" +version = "1.23.0-rc.1" dependencies = [ "anyhow", "arc-swap", diff --git a/Cargo.toml b/Cargo.toml index 39086fed6..a923dbea4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ members = ["crates/*"] resolver = "2" # Updated in the CI with a `sed` command -package.version = "1.23.0-rc.0" +package.version = "1.23.0-rc.1" package.license = "AGPL-3.0-only OR LicenseRef-Element-Commercial" package.authors = ["Element Backend Team"] package.edition = "2024" @@ -42,35 +42,35 @@ broken_intra_doc_links = "deny" [workspace.dependencies] # Workspace crates -mas-axum-utils = { path = "./crates/axum-utils/", version = "=1.23.0-rc.0" } -mas-cli = { path = "./crates/cli/", version = "=1.23.0-rc.0" } -mas-config = { path = "./crates/config/", version = "=1.23.0-rc.0" } -mas-context = { path = "./crates/context/", version = "=1.23.0-rc.0" } -mas-data-model = { path = "./crates/data-model/", version = "=1.23.0-rc.0" } -mas-email = { path = "./crates/email/", version = "=1.23.0-rc.0" } -mas-graphql = { path = "./crates/graphql/", version = "=1.23.0-rc.0" } -mas-handlers = { path = "./crates/handlers/", version = "=1.23.0-rc.0" } -mas-http = { path = "./crates/http/", version = "=1.23.0-rc.0" } -mas-i18n = { path = "./crates/i18n/", version = "=1.23.0-rc.0" } -mas-i18n-scan = { path = "./crates/i18n-scan/", version = "=1.23.0-rc.0" } -mas-iana = { path = "./crates/iana/", version = "=1.23.0-rc.0" } -mas-iana-codegen = { path = "./crates/iana-codegen/", version = "=1.23.0-rc.0" } -mas-jose = { path = "./crates/jose/", version = "=1.23.0-rc.0" } -mas-keystore = { path = "./crates/keystore/", version = "=1.23.0-rc.0" } -mas-listener = { path = "./crates/listener/", version = "=1.23.0-rc.0" } -mas-matrix = { path = "./crates/matrix/", version = "=1.23.0-rc.0" } -mas-matrix-synapse = { path = "./crates/matrix-synapse/", version = "=1.23.0-rc.0" } -mas-oidc-client = { path = "./crates/oidc-client/", version = "=1.23.0-rc.0" } -mas-policy = { path = "./crates/policy/", version = "=1.23.0-rc.0" } -mas-router = { path = "./crates/router/", version = "=1.23.0-rc.0" } -mas-spa = { path = "./crates/spa/", version = "=1.23.0-rc.0" } -mas-storage = { path = "./crates/storage/", version = "=1.23.0-rc.0" } -mas-storage-pg = { path = "./crates/storage-pg/", version = "=1.23.0-rc.0" } -mas-tasks = { path = "./crates/tasks/", version = "=1.23.0-rc.0" } -mas-templates = { path = "./crates/templates/", version = "=1.23.0-rc.0" } -mas-tower = { path = "./crates/tower/", version = "=1.23.0-rc.0" } -oauth2-types = { path = "./crates/oauth2-types/", version = "=1.23.0-rc.0" } -syn2mas = { path = "./crates/syn2mas", version = "=1.23.0-rc.0" } +mas-axum-utils = { path = "./crates/axum-utils/", version = "=1.23.0-rc.1" } +mas-cli = { path = "./crates/cli/", version = "=1.23.0-rc.1" } +mas-config = { path = "./crates/config/", version = "=1.23.0-rc.1" } +mas-context = { path = "./crates/context/", version = "=1.23.0-rc.1" } +mas-data-model = { path = "./crates/data-model/", version = "=1.23.0-rc.1" } +mas-email = { path = "./crates/email/", version = "=1.23.0-rc.1" } +mas-graphql = { path = "./crates/graphql/", version = "=1.23.0-rc.1" } +mas-handlers = { path = "./crates/handlers/", version = "=1.23.0-rc.1" } +mas-http = { path = "./crates/http/", version = "=1.23.0-rc.1" } +mas-i18n = { path = "./crates/i18n/", version = "=1.23.0-rc.1" } +mas-i18n-scan = { path = "./crates/i18n-scan/", version = "=1.23.0-rc.1" } +mas-iana = { path = "./crates/iana/", version = "=1.23.0-rc.1" } +mas-iana-codegen = { path = "./crates/iana-codegen/", version = "=1.23.0-rc.1" } +mas-jose = { path = "./crates/jose/", version = "=1.23.0-rc.1" } +mas-keystore = { path = "./crates/keystore/", version = "=1.23.0-rc.1" } +mas-listener = { path = "./crates/listener/", version = "=1.23.0-rc.1" } +mas-matrix = { path = "./crates/matrix/", version = "=1.23.0-rc.1" } +mas-matrix-synapse = { path = "./crates/matrix-synapse/", version = "=1.23.0-rc.1" } +mas-oidc-client = { path = "./crates/oidc-client/", version = "=1.23.0-rc.1" } +mas-policy = { path = "./crates/policy/", version = "=1.23.0-rc.1" } +mas-router = { path = "./crates/router/", version = "=1.23.0-rc.1" } +mas-spa = { path = "./crates/spa/", version = "=1.23.0-rc.1" } +mas-storage = { path = "./crates/storage/", version = "=1.23.0-rc.1" } +mas-storage-pg = { path = "./crates/storage-pg/", version = "=1.23.0-rc.1" } +mas-tasks = { path = "./crates/tasks/", version = "=1.23.0-rc.1" } +mas-templates = { path = "./crates/templates/", version = "=1.23.0-rc.1" } +mas-tower = { path = "./crates/tower/", version = "=1.23.0-rc.1" } +oauth2-types = { path = "./crates/oauth2-types/", version = "=1.23.0-rc.1" } +syn2mas = { path = "./crates/syn2mas", version = "=1.23.0-rc.1" } # OpenAPI schema generation and validation [workspace.dependencies.aide] From 0bd67a9f9a5aa8b133e7f438d54341c37af68ceb Mon Sep 17 00:00:00 2001 From: "Kai A. Hiller" Date: Thu, 6 Aug 2026 15:10:30 +0200 Subject: [PATCH 13/37] Add unittest for database connection via pgpass --- Cargo.lock | 1 + crates/cli/Cargo.toml | 3 +++ crates/cli/src/util.rs | 57 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index a07fe38a7..a34dda170 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3293,6 +3293,7 @@ dependencies = [ "serde_yaml", "sqlx", "syn2mas", + "tempfile", "tokio", "tokio-util", "tower", diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 5341a15f9..fae239425 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -91,6 +91,9 @@ mas-tower.workspace = true syn2mas.workspace = true +[dev-dependencies] +tempfile = "3" + [build-dependencies] anyhow.workspace = true vergen-gitcl.workspace = true diff --git a/crates/cli/src/util.rs b/crates/cli/src/util.rs index c9832ef79..5172ae1ed 100644 --- a/crates/cli/src/util.rs +++ b/crates/cli/src/util.rs @@ -627,4 +627,61 @@ mod tests { let manager = password_manager_from_config(&config).await; assert!(manager.is_err()); } + + /// RAII guard that removes an environment variable when dropped, + /// ensuring cleanup even if the test panics. + struct EnvVarGuard(&'static str); + + impl EnvVarGuard { + fn set(key: &'static str, value: impl AsRef) -> Self { + // SAFETY: single-threaded tokio test runtime; no other thread + // is reading or writing the environment concurrently. + #[expect(unsafe_code)] + unsafe { + std::env::set_var(key, value); + } + Self(key) + } + } + + impl Drop for EnvVarGuard { + fn drop(&mut self) { + // SAFETY: single-threaded tokio test runtime; no other thread + // is reading or writing the environment concurrently. + #[expect(unsafe_code)] + unsafe { + std::env::remove_var(self.0); + } + } + } + + #[tokio::test] + async fn test_database_connection_with_pgpass() { + // Write a temporary pgpass file and point PGPASSFILE at it + let pgpass_content = "*:*:*:testuser:testpassword\n"; + let pgpass_file = tempfile::NamedTempFile::new().expect("failed to create temp file"); + tokio::fs::write(pgpass_file.path(), pgpass_content) + .await + .expect("failed to write pgpass file"); + + // Set PGPASSFILE for sqlx to pick up the password from the pgpass file + let _guard = EnvVarGuard::set("PGPASSFILE", pgpass_file.path()); + + let config = serde_json::from_value(serde_json::json!({ + "uri": "postgresql://testuser@localhost/test" + })) + .unwrap(); + + let opts = DatabaseConnectOptions { + log_slow_statements: false, + }; + + let result = database_connect_options_from_config(&config, &opts).await; + assert!(result.is_ok()); + let debug = format!("{:?}", result.unwrap()); + assert!( + debug.contains("testpassword"), + "pgpass password was not resolved: {debug}" + ); + } } From 3a21f522642865943b181a5fd60d68f83e0d41ef Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 18 Aug 2026 16:32:08 +0000 Subject: [PATCH 14/37] 1.23.0 --- Cargo.lock | 56 +++++++++++++++++++++++++------------------------- Cargo.toml | 60 +++++++++++++++++++++++++++--------------------------- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a07fe38a7..3312aeeb0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3198,7 +3198,7 @@ dependencies = [ [[package]] name = "mas-axum-utils" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "anyhow", "axum", @@ -3233,7 +3233,7 @@ dependencies = [ [[package]] name = "mas-cli" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "anyhow", "axum", @@ -3308,7 +3308,7 @@ dependencies = [ [[package]] name = "mas-config" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "anyhow", "camino", @@ -3339,7 +3339,7 @@ dependencies = [ [[package]] name = "mas-context" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "console", "opentelemetry", @@ -3356,7 +3356,7 @@ dependencies = [ [[package]] name = "mas-data-model" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "base64ct", "chrono", @@ -3378,7 +3378,7 @@ dependencies = [ [[package]] name = "mas-email" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "async-trait", "lettre", @@ -3389,7 +3389,7 @@ dependencies = [ [[package]] name = "mas-handlers" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "aide", "anyhow", @@ -3472,7 +3472,7 @@ dependencies = [ [[package]] name = "mas-http" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "futures-util", "headers", @@ -3492,7 +3492,7 @@ dependencies = [ [[package]] name = "mas-i18n" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "camino", "icu_datetime", @@ -3512,7 +3512,7 @@ dependencies = [ [[package]] name = "mas-i18n-scan" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "camino", "clap", @@ -3526,7 +3526,7 @@ dependencies = [ [[package]] name = "mas-iana" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "schemars 1.2.1", "serde", @@ -3534,7 +3534,7 @@ dependencies = [ [[package]] name = "mas-iana-codegen" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "anyhow", "async-trait", @@ -3551,7 +3551,7 @@ dependencies = [ [[package]] name = "mas-jose" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "base64ct", "chrono", @@ -3581,7 +3581,7 @@ dependencies = [ [[package]] name = "mas-keystore" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "aead", "base64ct", @@ -3609,7 +3609,7 @@ dependencies = [ [[package]] name = "mas-listener" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "anyhow", "bytes", @@ -3633,7 +3633,7 @@ dependencies = [ [[package]] name = "mas-matrix" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "anyhow", "async-trait", @@ -3643,7 +3643,7 @@ dependencies = [ [[package]] name = "mas-matrix-synapse" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "anyhow", "async-trait", @@ -3660,7 +3660,7 @@ dependencies = [ [[package]] name = "mas-oidc-client" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "assert_matches", "async-trait", @@ -3696,7 +3696,7 @@ dependencies = [ [[package]] name = "mas-policy" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "anyhow", "arc-swap", @@ -3713,7 +3713,7 @@ dependencies = [ [[package]] name = "mas-router" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "axum", "serde", @@ -3724,7 +3724,7 @@ dependencies = [ [[package]] name = "mas-spa" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "camino", "serde", @@ -3733,7 +3733,7 @@ dependencies = [ [[package]] name = "mas-storage" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "async-trait", "chrono", @@ -3755,7 +3755,7 @@ dependencies = [ [[package]] name = "mas-storage-pg" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "async-trait", "chrono", @@ -3787,7 +3787,7 @@ dependencies = [ [[package]] name = "mas-tasks" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "anyhow", "async-trait", @@ -3819,7 +3819,7 @@ dependencies = [ [[package]] name = "mas-templates" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "anyhow", "arc-swap", @@ -3851,7 +3851,7 @@ dependencies = [ [[package]] name = "mas-tower" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "http", "opentelemetry", @@ -4103,7 +4103,7 @@ dependencies = [ [[package]] name = "oauth2-types" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "assert_matches", "base64ct", @@ -6279,7 +6279,7 @@ dependencies = [ [[package]] name = "syn2mas" -version = "1.23.0-rc.1" +version = "1.23.0" dependencies = [ "anyhow", "arc-swap", diff --git a/Cargo.toml b/Cargo.toml index a923dbea4..8a80b5f36 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ members = ["crates/*"] resolver = "2" # Updated in the CI with a `sed` command -package.version = "1.23.0-rc.1" +package.version = "1.23.0" package.license = "AGPL-3.0-only OR LicenseRef-Element-Commercial" package.authors = ["Element Backend Team"] package.edition = "2024" @@ -42,35 +42,35 @@ broken_intra_doc_links = "deny" [workspace.dependencies] # Workspace crates -mas-axum-utils = { path = "./crates/axum-utils/", version = "=1.23.0-rc.1" } -mas-cli = { path = "./crates/cli/", version = "=1.23.0-rc.1" } -mas-config = { path = "./crates/config/", version = "=1.23.0-rc.1" } -mas-context = { path = "./crates/context/", version = "=1.23.0-rc.1" } -mas-data-model = { path = "./crates/data-model/", version = "=1.23.0-rc.1" } -mas-email = { path = "./crates/email/", version = "=1.23.0-rc.1" } -mas-graphql = { path = "./crates/graphql/", version = "=1.23.0-rc.1" } -mas-handlers = { path = "./crates/handlers/", version = "=1.23.0-rc.1" } -mas-http = { path = "./crates/http/", version = "=1.23.0-rc.1" } -mas-i18n = { path = "./crates/i18n/", version = "=1.23.0-rc.1" } -mas-i18n-scan = { path = "./crates/i18n-scan/", version = "=1.23.0-rc.1" } -mas-iana = { path = "./crates/iana/", version = "=1.23.0-rc.1" } -mas-iana-codegen = { path = "./crates/iana-codegen/", version = "=1.23.0-rc.1" } -mas-jose = { path = "./crates/jose/", version = "=1.23.0-rc.1" } -mas-keystore = { path = "./crates/keystore/", version = "=1.23.0-rc.1" } -mas-listener = { path = "./crates/listener/", version = "=1.23.0-rc.1" } -mas-matrix = { path = "./crates/matrix/", version = "=1.23.0-rc.1" } -mas-matrix-synapse = { path = "./crates/matrix-synapse/", version = "=1.23.0-rc.1" } -mas-oidc-client = { path = "./crates/oidc-client/", version = "=1.23.0-rc.1" } -mas-policy = { path = "./crates/policy/", version = "=1.23.0-rc.1" } -mas-router = { path = "./crates/router/", version = "=1.23.0-rc.1" } -mas-spa = { path = "./crates/spa/", version = "=1.23.0-rc.1" } -mas-storage = { path = "./crates/storage/", version = "=1.23.0-rc.1" } -mas-storage-pg = { path = "./crates/storage-pg/", version = "=1.23.0-rc.1" } -mas-tasks = { path = "./crates/tasks/", version = "=1.23.0-rc.1" } -mas-templates = { path = "./crates/templates/", version = "=1.23.0-rc.1" } -mas-tower = { path = "./crates/tower/", version = "=1.23.0-rc.1" } -oauth2-types = { path = "./crates/oauth2-types/", version = "=1.23.0-rc.1" } -syn2mas = { path = "./crates/syn2mas", version = "=1.23.0-rc.1" } +mas-axum-utils = { path = "./crates/axum-utils/", version = "=1.23.0" } +mas-cli = { path = "./crates/cli/", version = "=1.23.0" } +mas-config = { path = "./crates/config/", version = "=1.23.0" } +mas-context = { path = "./crates/context/", version = "=1.23.0" } +mas-data-model = { path = "./crates/data-model/", version = "=1.23.0" } +mas-email = { path = "./crates/email/", version = "=1.23.0" } +mas-graphql = { path = "./crates/graphql/", version = "=1.23.0" } +mas-handlers = { path = "./crates/handlers/", version = "=1.23.0" } +mas-http = { path = "./crates/http/", version = "=1.23.0" } +mas-i18n = { path = "./crates/i18n/", version = "=1.23.0" } +mas-i18n-scan = { path = "./crates/i18n-scan/", version = "=1.23.0" } +mas-iana = { path = "./crates/iana/", version = "=1.23.0" } +mas-iana-codegen = { path = "./crates/iana-codegen/", version = "=1.23.0" } +mas-jose = { path = "./crates/jose/", version = "=1.23.0" } +mas-keystore = { path = "./crates/keystore/", version = "=1.23.0" } +mas-listener = { path = "./crates/listener/", version = "=1.23.0" } +mas-matrix = { path = "./crates/matrix/", version = "=1.23.0" } +mas-matrix-synapse = { path = "./crates/matrix-synapse/", version = "=1.23.0" } +mas-oidc-client = { path = "./crates/oidc-client/", version = "=1.23.0" } +mas-policy = { path = "./crates/policy/", version = "=1.23.0" } +mas-router = { path = "./crates/router/", version = "=1.23.0" } +mas-spa = { path = "./crates/spa/", version = "=1.23.0" } +mas-storage = { path = "./crates/storage/", version = "=1.23.0" } +mas-storage-pg = { path = "./crates/storage-pg/", version = "=1.23.0" } +mas-tasks = { path = "./crates/tasks/", version = "=1.23.0" } +mas-templates = { path = "./crates/templates/", version = "=1.23.0" } +mas-tower = { path = "./crates/tower/", version = "=1.23.0" } +oauth2-types = { path = "./crates/oauth2-types/", version = "=1.23.0" } +syn2mas = { path = "./crates/syn2mas", version = "=1.23.0" } # OpenAPI schema generation and validation [workspace.dependencies.aide] From a65b1e482ca4c4fbcdd0f1cb8987614bfbd03cb5 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 18 Aug 2026 14:46:27 -0500 Subject: [PATCH 15/37] `cargo update -p h2` (as the security advisory suggested) Fix https://github.com/element-hq/matrix-authentication-service/issues/5928 --- Cargo.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3312aeeb0..808440bb5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1747,7 +1747,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -2127,9 +2127,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.15" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155" +checksum = "a9f37a958b41b3b19ee2707c06439c0e9e547e847223eb791ecb0cb821c65e27" dependencies = [ "atomic-waker", "bytes", @@ -5287,7 +5287,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -5345,7 +5345,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -5958,7 +5958,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -6371,7 +6371,7 @@ dependencies = [ "getrandom 0.3.3", "once_cell", "rustix", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -7548,7 +7548,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] From 35be69bf15fdb9f64329c4de4c9ccdb66c7fa118 Mon Sep 17 00:00:00 2001 From: defaultdino Date: Wed, 19 Aug 2026 14:30:51 +0200 Subject: [PATCH 16/37] implement hard shutdown and exit for task timeout --- crates/cli/src/lifecycle.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/crates/cli/src/lifecycle.rs b/crates/cli/src/lifecycle.rs index 3da49f9d1..0f551c0bf 100644 --- a/crates/cli/src/lifecycle.rs +++ b/crates/cli/src/lifecycle.rs @@ -217,11 +217,14 @@ impl LifecycleManager { self.hard_shutdown_token().cancel(); - // TODO: we may want to have a time out on the task tracker, in case we have - // really stuck tasks on it - self.task_tracker().wait().await; - - tracing::info!("All tasks are done, exitting"); + tokio::select! { + () = self.task_tracker().wait() => { + tracing::info!("All tasks are done, exiting"); + }, + () = tokio::time::sleep(self.timeout) => { + tracing::warn!("Hard shutdown timeout reached with tasks still running, exiting anyway"); + }, + } if likely_crashed { ExitCode::FAILURE From 1a086b543df5afb68b5739d09adfdd296fce7579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20R=C3=B6ttsches?= Date: Fri, 21 Aug 2026 23:14:37 +0300 Subject: [PATCH 17/37] Format log timestamps in the local timezone Replace the UTC-only SystemTime timer in EventFormatter with chrono's ChronoLocal, which resolves the zone from TZ, then /etc/localtime, then /usr/share/zoneinfo, and falls back to UTC when none are available. The published image is distroless and ships none of them, so the default output is unchanged and operators opt in by mounting a zone file; the only difference for existing deployments is the offset suffix, Z -> +00:00. --- Cargo.lock | 1 + Cargo.toml | 2 +- crates/context/src/fmt.rs | 9 +++++++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 808440bb5..65308a147 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6804,6 +6804,7 @@ version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" dependencies = [ + "chrono", "matchers", "nu-ansi-term", "once_cell", diff --git a/Cargo.toml b/Cargo.toml index 8a80b5f36..4bab24fa5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -688,7 +688,7 @@ features = ["cors", "fs", "add-extension", "set-header"] version = "0.1.41" [workspace.dependencies.tracing-subscriber] version = "0.3.23" -features = ["env-filter"] +features = ["env-filter", "chrono"] [workspace.dependencies.tracing-appender] version = "0.2.5" diff --git a/crates/context/src/fmt.rs b/crates/context/src/fmt.rs index 0b6edb130..3be0ed3b2 100644 --- a/crates/context/src/fmt.rs +++ b/crates/context/src/fmt.rs @@ -4,6 +4,8 @@ // SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial // Please see LICENSE files in the repository root for full details. +use std::sync::LazyLock; + use console::{Color, Style}; use opentelemetry::{TraceId, trace::TraceContextExt as _}; use tracing::{Level, Subscriber}; @@ -12,13 +14,16 @@ use tracing_subscriber::{ fmt::{ FormatEvent, FormatFields, format::{DefaultFields, Writer}, - time::{FormatTime, SystemTime}, + time::{ChronoLocal, FormatTime}, }, registry::LookupSpan, }; use crate::LogContext; +static TIMER: LazyLock = + LazyLock::new(|| ChronoLocal::new("%Y-%m-%dT%H:%M:%S%.6f%:z".to_owned())); + /// An event formatter usable by the [`tracing_subscriber`] crate, which /// includes the log context and the OTEL trace ID. #[derive(Debug, Default)] @@ -98,7 +103,7 @@ where let ansi = writer.has_ansi_escapes(); let metadata = event.metadata(); - SystemTime.format_time(&mut writer)?; + TIMER.format_time(&mut writer)?; let level = FmtLevel::new(metadata.level(), ansi); write!(&mut writer, " {level} ")?; From 507893cdc46ade195143501b44877dc9a155c2bb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 25 Aug 2026 16:49:23 +0000 Subject: [PATCH 18/37] Translations updates --- frontend/.storybook/locales.ts | 89 +++++---- frontend/locales/de.json | 72 +++---- frontend/locales/fr.json | 2 +- frontend/locales/nl.json | 14 +- frontend/locales/pl.json | 16 +- frontend/locales/pt-BR.json | 14 +- frontend/locales/sk.json | 14 +- frontend/locales/sv.json | 4 +- frontend/locales/tr.json | 347 +++++++++++++++++++++++++++++++++ frontend/locales/uk.json | 6 +- frontend/locales/uz.json | 228 +++++++++++----------- frontend/locales/zh-Hans.json | 4 +- translations/de.json | 58 +++--- translations/fr.json | 4 +- translations/pl.json | 12 +- translations/tr.json | 277 ++++++++++++++++++++++++++ translations/uk.json | 6 +- translations/uz.json | 120 +++++++++++- translations/zh-Hans.json | 2 +- 19 files changed, 1014 insertions(+), 275 deletions(-) create mode 100644 frontend/locales/tr.json create mode 100644 translations/tr.json diff --git a/frontend/.storybook/locales.ts b/frontend/.storybook/locales.ts index 6a036a0fe..4b0ee9189 100644 --- a/frontend/.storybook/locales.ts +++ b/frontend/.storybook/locales.ts @@ -27,7 +27,7 @@ export type LocalazyMetadata = { }; const localazyMetadata: LocalazyMetadata = { - projectUrl: "https://localazy.com/p/matrix-authentication-service!v1.23", + projectUrl: "https://localazy.com/p/matrix-authentication-service", baseLocale: "en", languages: [ { @@ -174,6 +174,15 @@ const localazyMetadata: LocalazyMetadata = { localizedName: "Svenska", pluralType: (n) => { return (n===1) ? "one" : "other"; } }, + { + language: "tr", + region: "", + script: "", + isRtl: false, + name: "Turkish", + localizedName: "Türkçe", + pluralType: (n) => { return (n===1) ? "one" : "other"; } + }, { language: "uk", region: "", @@ -208,25 +217,26 @@ const localazyMetadata: LocalazyMetadata = { file: "frontend.json", path: "", cdnFiles: { - "cs": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/cs/frontend.json", - "da": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/da/frontend.json", - "de": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/de/frontend.json", - "en": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/en/frontend.json", - "et": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/et/frontend.json", - "fi": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/fi/frontend.json", - "fr": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/fr/frontend.json", - "hu": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/hu/frontend.json", - "nb_NO": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/nb-NO/frontend.json", - "nl": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/nl/frontend.json", - "pl": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pl/frontend.json", - "pt": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pt/frontend.json", - "pt_BR": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pt-BR/frontend.json", - "ru": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/ru/frontend.json", - "sk": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/sk/frontend.json", - "sv": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/sv/frontend.json", - "uk": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/uk/frontend.json", - "uz": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/uz/frontend.json", - "zh#Hans": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/zh-Hans/frontend.json" + "cs": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/cs/frontend.json", + "da": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/da/frontend.json", + "de": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/de/frontend.json", + "en": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/en/frontend.json", + "et": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/et/frontend.json", + "fi": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/fi/frontend.json", + "fr": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/fr/frontend.json", + "hu": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/hu/frontend.json", + "nb_NO": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/nb-NO/frontend.json", + "nl": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/nl/frontend.json", + "pl": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pl/frontend.json", + "pt": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pt/frontend.json", + "pt_BR": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pt-BR/frontend.json", + "ru": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/ru/frontend.json", + "sk": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/sk/frontend.json", + "sv": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/sv/frontend.json", + "tr": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/tr/frontend.json", + "uk": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/uk/frontend.json", + "uz": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/uz/frontend.json", + "zh#Hans": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/zh-Hans/frontend.json" } }, { @@ -234,25 +244,26 @@ const localazyMetadata: LocalazyMetadata = { file: "file.json", path: "", cdnFiles: { - "cs": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/cs/file.json", - "da": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/da/file.json", - "de": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/de/file.json", - "en": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/en/file.json", - "et": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/et/file.json", - "fi": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/fi/file.json", - "fr": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/fr/file.json", - "hu": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/hu/file.json", - "nb_NO": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/nb-NO/file.json", - "nl": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/nl/file.json", - "pl": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pl/file.json", - "pt": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pt/file.json", - "pt_BR": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pt-BR/file.json", - "ru": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/ru/file.json", - "sk": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/sk/file.json", - "sv": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/sv/file.json", - "uk": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/uk/file.json", - "uz": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/uz/file.json", - "zh#Hans": "https://delivery.localazy.com/_a64231621581342174514c92d51a/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/zh-Hans/file.json" + "cs": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/cs/file.json", + "da": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/da/file.json", + "de": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/de/file.json", + "en": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/en/file.json", + "et": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/et/file.json", + "fi": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/fi/file.json", + "fr": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/fr/file.json", + "hu": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/hu/file.json", + "nb_NO": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/nb-NO/file.json", + "nl": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/nl/file.json", + "pl": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pl/file.json", + "pt": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pt/file.json", + "pt_BR": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pt-BR/file.json", + "ru": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/ru/file.json", + "sk": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/sk/file.json", + "sv": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/sv/file.json", + "tr": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/tr/file.json", + "uk": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/uk/file.json", + "uz": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/uz/file.json", + "zh#Hans": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/zh-Hans/file.json" } } ] diff --git a/frontend/locales/de.json b/frontend/locales/de.json index b1ee48009..b89175a6b 100644 --- a/frontend/locales/de.json +++ b/frontend/locales/de.json @@ -2,9 +2,9 @@ "action": { "back": "Zurück", "cancel": "Abbrechen", - "clear": "Löschen", + "clear": "Leeren", "close": "Schließen", - "collapse": "Zusammenbruch", + "collapse": "Reduzieren", "confirm": "Bestätigen", "continue": "Weiter", "edit": "Bearbeiten", @@ -12,7 +12,7 @@ "save": "Speichern", "save_and_continue": "Speichern und fortfahren", "sign_out": "Abmelden", - "start_over": "Von vorne anfangen" + "start_over": "Neu beginnen" }, "branding": { "privacy_policy": { @@ -26,12 +26,12 @@ }, "common": { "e2ee": "Ende-zu-Ende-Verschlüsselung", - "loading": "Lade …", + "loading": "Wird geladen …", "next": "Weiter", "password": "Passwort", "previous": "Zurück", "saved": "Gespeichert", - "saving": "Speichern..." + "saving": "Wird gespeichert …" }, "frontend": { "account": { @@ -41,19 +41,19 @@ "alert_description": "Dieses Konto wird dauerhaft entfernt und du hast keinen Zugriff mehr auf deine Nachrichten.", "alert_title": "Du bist kurz davor, alle deine Daten zu verlieren.", "button": "Account löschen", - "dialog_description": "Bestätige, dass du dein Konto löschen möchtest:\n\n\nDu kannst dein Konto nicht reaktivieren\nDu kannst dich nicht mehr anmelden\nNiemand kann deinen Benutzernamen (MXID) wieder verwenden, auch du nicht.\nDu verlässt alle Gruppen und Chats\nDu wirst vom Identitätsserver entfernt und niemand kann dich mit deiner E-Mail-Adresse oder Telefonnummer finden\n\nDeine alten Nachrichten sind für die jeweiligen Empfänger weiterhin sichtbar. Möchtest du deine gesendeten Nachrichten vor zukünftigen Gruppen-Besuchern verbergen?", + "dialog_description": "Bestätige, dass du dein Konto löschen möchtest:\n\n\nDu kannst dein Konto nicht reaktivieren\nDu kannst dich nicht mehr anmelden\nNiemand kann deinen Nutzernamen (MXID) wieder verwenden, auch du nicht.\nDu verlässt alle Gruppen und Chats\nDu wirst vom Identitätsserver entfernt und niemand kann dich mit deiner E-Mail-Adresse oder Telefonnummer finden\n\nDeine alten Nachrichten sind für die jeweiligen Empfänger weiterhin sichtbar. Möchtest du deine gesendeten Nachrichten vor zukünftigen Gruppen-Besuchern verbergen?", "dialog_title": "Dieses Konto löschen?", "erase_checkbox_label": "Ja, alle meine Nachrichten vor neuen Mitgliedern verbergen", - "incorrect_password": "Falsches Passwort, versuch's nochmal", + "incorrect_password": "Falsches Passwort, bitte versuche es erneut", "mxid_label": "Bestätige deine Matrix-ID ({{ mxid }})", - "mxid_mismatch": "Dieser Wert passt nicht zu deiner Matrix-ID.", + "mxid_mismatch": "Dieser Wert passt nicht zu deiner Matrix-ID", "password_label": "Gib dein Passwort ein, um weiterzumachen" }, "edit_profile": { "display_name_help": "Dies ist der öffentliche Nutzername.", "display_name_label": "Anzeigename", "title": "Profil bearbeiten", - "username_label": "Benutzername" + "username_label": "Nutzername" }, "password": { "change": "Passwort ändern", @@ -67,12 +67,12 @@ "title": "Dein Konto" }, "add_email_form": { - "email_denied_error": "Die eingegebene E-Mail wird von der Serverrichtlinie nicht zugelassen.", + "email_denied_error": "Die eingegebene E-Mail wird von der Serverrichtlinie nicht zugelassen", "email_field_help": "Gib eine alternative E-Mail-Adresse an, mit der du auf dieses Konto zugreifen kannst.", "email_field_label": "E-Mail-Adresse hinzufügen", "email_in_use_error": "Die eingegebene E-Mail wird bereits verwendet", "email_invalid_error": "Die eingegebene E-Mail-Adresse ist ungültig", - "incorrect_password_error": "Falsches Passwort, versuch's nochmal", + "incorrect_password_error": "Falsches Passwort, bitte versuche es erneut", "password_confirmation": "Bestätige dein Passwort, um diese E-Mail-Adresse hinzuzufügen." }, "browser_session_details": { @@ -99,22 +99,22 @@ "unknown": "Unbekannter Gerätetyp" }, "email_in_use": { - "heading": "Die E-Mail-Adresse {{email}} wird bereits verwendet." + "heading": "Die E-Mail-Adresse {{email}} wird bereits verwendet" }, "end_session_button": { "confirmation_modal_body_text": "Stelle sicher, dass du immer Zugriff auf ein anderes verifiziertes Gerät oder deinen Wiederherstellungsschlüssel hast, um zu vermeiden, dass dein verschlüsselter Chatverlauf verloren geht.", - "confirmation_modal_title": "Möchten Sie dieses Gerät wirklich entfernen?", + "confirmation_modal_title": "Möchtest du dieses Gerät wirklich entfernen?", "text": "Gerät entfernen" }, "error": { "hideDetails": "Details ausblenden", "showDetails": "Details anzeigen", - "subtitle": "Ein unerwarteter Fehler ist aufgetreten, bitte versuch's nochmal.", + "subtitle": "Ein unerwarteter Fehler ist aufgetreten. Bitte versuche es erneut.", "title": "Etwas ist schief gelaufen" }, "errors": { "field_required": "Dieses Feld ist ein Pflichtfeld", - "rate_limit_exceeded": "Du hast in kurzer Zeit zu viele Anfragen gestellt. Warte bitte ein paar Minuten und versuch's nochmal." + "rate_limit_exceeded": "Du hast in kurzer Zeit zu viele Anfragen gestellt. Bitte warte ein paar Minuten und versuche es erneut." }, "last_active": { "active_date": "Aktiv {{relativeDate}}", @@ -145,15 +145,15 @@ "current_password_label": "Aktuelles Passwort", "failure": { "description": { - "account_locked": "Dein Konto ist gesperrt und kann im Moment nicht wiederhergestellt werden. Wenn du das nicht erwartet hast, wende dich bitte an deinen Server-Admin.", + "account_locked": "Dein Konto ist gesperrt und kann derzeit nicht wiederhergestellt werden. Wenn du das nicht erwartet hast, wende dich an deinen Kontoanbieter.", "expired_recovery_ticket": "Der Link zur Kontowiederherstellung ist abgelaufen. Bitte fang den Prozess noch mal von vorne an.", "invalid_new_password": "Das neue Passwort, das du gewählt hast, ist ungültig; es entspricht möglicherweise nicht den Sicherheitsrichtlinien.", "no_current_password": "Du hast kein aktuelles Passwort.", "no_such_recovery_ticket": "Der Link zum Wiederherstellen ist nicht gültig. Wenn du den Link aus der E-Mail zum Wiederherstellen kopiert hast, schau bitte nach, ob du den vollständigen Link kopiert hast.", "password_changes_disabled": "Passwortänderungen sind deaktiviert.", "recovery_ticket_already_used": "Der Wiederherstellungslink wurde bereits verwendet. Er kann nicht erneut verwendet werden.", - "unspecified": "Das könnte ein vorübergehendes Problem sein, also versuch's später nochmal. Wenn das Problem weiterhin besteht, wende dich bitte an deinen Server-Admin.", - "wrong_password": "Das Passwort, das du als dein aktuelles Passwort angegeben hast, ist falsch. Versuch's bitte nochmal." + "unspecified": "Das könnte ein vorübergehendes Problem sein. Bitte versuche es später erneut. Wenn das Problem weiterhin besteht, wende dich an deinen Kontoanbieter.", + "wrong_password": "Das Passwort, das du als aktuelles Passwort angegeben hast, ist falsch. Bitte versuche es erneut." }, "title": "Aktualisierung des Passworts fehlgeschlagen" }, @@ -170,7 +170,7 @@ }, "password_reset": { "consumed": { - "subtitle": "Um ein neues Passwort zu erstellen, fang einfach von vorne an und wähle „Passwort vergessen“.", + "subtitle": "Um ein neues Passwort zu erstellen, beginne neu und wähle „Passwort vergessen“.", "title": "Der Link zum Zurücksetzen deines Passworts wurde bereits verwendet" }, "expired": { @@ -214,11 +214,11 @@ "extended_repeat": "Wiederholte Zeichenmuster wie „abcabcabc“ sind leicht zu erraten.", "key_pattern": "Kurze Eingaben sind leicht zu erraten.", "names_by_themselves": "Einzelne Vor- oder Nachnamen sind leicht zu erraten.", - "pwned": "Dein Passwort wurde durch eine Datenpanne im Internet preisgegeben.", + "pwned": "Dieses Passwort wird zu häufig verwendet. Bitte wähle ein Passwort, das schwerer zu erraten ist.", "recent_years": "Die letzten Jahre sind leicht zu erraten.", "sequences": "Gängige Zeichenfolgen wie „abc“ sind leicht zu erraten.", "similar_to_common": "Dies ähnelt einem häufig verwendeten Passwort.", - "simple_repeat": "Sich wiederholende Zeichen wie \"aaa\" sind leicht zu erraten.", + "simple_repeat": "Sich wiederholende Zeichen wie „aaa“ sind leicht zu erraten.", "straight_row": "Gerade Reihen von Tasten auf deiner Tastatur sind leicht zu erraten.", "top_hundred": "Dies ist ein häufig verwendetes Passwort.", "top_ten": "Dies ist ein häufig verwendetes Passwort.", @@ -229,27 +229,27 @@ "reset_cross_signing": { "cancelled": { "description_1": "Du kannst dieses Fenster schließen und zur App zurückgehen, um weiterzumachen.", - "description_2": "Wenn du dich überall abgemeldet hast und deinen Wiederherstellungs-Schlüssel nicht mehr weißt, musst du deine Identität zurücksetzen.", - "heading": "Identitätszurücksetzung abgebrochen." + "description_2": "Wenn du keinen Zugriff auf ein anderes verifiziertes Gerät hast und deinen Wiederherstellungsschlüssel nicht hast, musst du deine digitale Identität zurücksetzen, um die App weiter nutzen zu können.", + "heading": "Zurücksetzen der digitalen Identität abgebrochen" }, - "description": "Wenn du auf keinem anderen Gerät angemeldet bist und deinen Wiederherstellungs-Schlüssel verloren hast, musst du deine Identität zurücksetzen, um die App weiter nutzen zu können.", + "description": "Wenn du keinen Zugriff auf ein anderes verifiziertes Gerät hast und deinen Wiederherstellungsschlüssel nicht hast, musst du deine digitale Identität zurücksetzen, um die App weiter nutzen zu können.", "effect_list": { - "neutral_1": "Du verlierst alle Nachrichten, die nur auf dem Server gespeichert sind.", + "neutral_1": "Du verlierst alle Nachrichten, die nur auf dem Server gespeichert sind", "neutral_2": "Du musst alle deine Geräte und Kontakte nochmal verifizieren.", - "positive_1": "Deine Kontodaten, Kontakte, Einstellungen und Chat-Liste bleiben erhalten." + "positive_1": "Deine Kontodaten, Kontakte, Einstellungen und Chat-Liste bleiben erhalten" }, "failure": { - "description": "Das könnte ein vorübergehendes Problem sein, also versuch's später nochmal. Wenn das Problem weiterhin besteht, wende dich bitte an deinen Server-Admin.", - "heading": "Zurücksetzen der Krypto-Identität konnte nicht zugelassen werden" + "description": "Das könnte ein vorübergehendes Problem sein. Bitte versuche es später erneut. Wenn das Problem weiterhin besteht, wende dich an deinen Kontoanbieter.", + "heading": "Zurücksetzen der digitalen Identität konnte nicht zugelassen werden" }, "finish_reset": "Reset beenden", - "heading": "Erstelle eine neue Identität, solltest du sie nicht auf andere Weise bestätigen können.", + "heading": "Setze deine digitale Identität zurück, falls du sie nicht anders bestätigen kannst", "start_reset": "Reset starten", "success": { - "description": "Das Zurücksetzen der Identität wurde für die nächsten {{minutes}} Minuten genehmigt. Du kannst dieses Fenster schließen und zur App zurückkehren, um fortzufahren.", - "heading": "Identität erfolgreich zurückgesetzt. Geh zurück zur App, um den Vorgang abzuschließen." + "description": "Das Zurücksetzen der digitalen Identität wurde für die nächsten {{minutes}} Minuten genehmigt. Du kannst dieses Fenster schließen und zur App zurückkehren, um fortzufahren.", + "heading": "Digitale Identität erfolgreich zurückgesetzt. Kehre zur App zurück, um den Vorgang abzuschließen." }, - "warning": "Setze deine Identität nur zurück, wenn du keinen Zugriff auf ein anderes angemeldetes Gerät hast und deinen Wiederherstellungsschlüssel verloren hast." + "warning": "Setze deine digitale Identität nur zurück, wenn du keinen Zugriff auf ein anderes verifiziertes Gerät hast und deinen Wiederherstellungsschlüssel nicht hast." }, "session": { "client_id_label": "Client-ID", @@ -283,7 +283,7 @@ "delete_button_confirmation_modal": { "action": "E-Mail löschen", "body": "Diese E-Mail löschen?", - "incorrect_password": "Falsches Passwort, versuch's nochmal", + "incorrect_password": "Falsches Passwort, bitte versuche es erneut", "password_confirmation": "Bestätige dein Passwort, um diese E-Mail-Adresse zu löschen." }, "delete_button_title": "E-Mail-Adresse entfernen", @@ -302,8 +302,8 @@ "inactive_90_days": "Alle deine Sitzungen waren in den letzten 90 Tagen aktiv." }, "num_sessions_filtered_header": { - "header:one": "{{count}} Geräte entsprechen Ihren Suchkriterien ({{unfiltered_session_total}})", - "header:other": "{{count}} Geräte entsprechen Ihren Suchkriterien ({{unfiltered_session_total}})", + "header:one": "{{count}} Gerät entspricht deinen Suchkriterien ({{unfiltered_session_total}})", + "header:other": "{{count}} Geräte entsprechen deinen Suchkriterien ({{unfiltered_session_total}})", "unfiltered_session_total:one": "{{count}} insgesamt", "unfiltered_session_total:other": "{{count}} insgesamt" }, @@ -337,7 +337,7 @@ "scope": { "edit_profile": "Bearbeite dein Profil und deine Kontaktdaten", "manage_sessions": "Verwalte deine Geräte und Sitzungen", - "mas_admin": "Beliebige Benutzer verwalten (urn:mas:admin)", + "mas_admin": "Beliebige Nutzer verwalten (urn:mas:admin)", "send_messages": "Neue Nachrichten in deinem Namen senden", "synapse_admin": "Den Synapse-Homeserver verwalten (urn:synapse:admin:*)", "view_messages": "Zeig deine vorhandenen Nachrichten und Daten an", diff --git a/frontend/locales/fr.json b/frontend/locales/fr.json index 5fc3372e3..c6c8bc0cb 100644 --- a/frontend/locales/fr.json +++ b/frontend/locales/fr.json @@ -103,7 +103,7 @@ }, "end_session_button": { "confirmation_modal_body_text": "Assurez-vous de toujours avoir accès à un autre appareil vérifié ou à votre clé de récupération afin d'éviter de perdre l'historique de vos discussions chiffrées.", - "confirmation_modal_title": "Êtes-vous sûr de vouloir terminer cette session ?", + "confirmation_modal_title": "Êtes-vous sûr de vouloir supprimer cet appareil ?", "text": "Supprimer l’appareil" }, "error": { diff --git a/frontend/locales/nl.json b/frontend/locales/nl.json index 774601087..866fad4e5 100644 --- a/frontend/locales/nl.json +++ b/frontend/locales/nl.json @@ -39,7 +39,7 @@ "contact_info": "Contact info", "delete_account": { "alert_description": "This account will be permanently erased and you’ll no longer have access to any of your messages.", - "alert_title": "You’re about to lose all of your data", + "alert_title": "You’re about to lose all of your data.", "button": "Delete account", "dialog_description": "Confirm that you would like to delete your account:\n\n\nYou will not be able to reactivate your account\nYou will no longer be able to sign in\nNo one will be able to reuse your username (MXID), including you\nYou will leave all rooms and direct messages you are in\nYou will be removed from the identity server, and no one will be able to find you with your email or phone number\n\nYour old messages will still be visible to people who received them. Would you like to hide your sent messages from people who join rooms in the future?", "dialog_title": "Delete this account?", @@ -73,7 +73,7 @@ "email_in_use_error": "The entered email is already in use", "email_invalid_error": "Het ingevoerde e-mailadres is ongeldig", "incorrect_password_error": "Incorrect password, please try again", - "password_confirmation": "Confirm your account password to add this email address" + "password_confirmation": "Confirm your account password to add this email address." }, "browser_session_details": { "current_badge": "Huidige" @@ -99,7 +99,7 @@ "unknown": "Onbekend apparaattype" }, "email_in_use": { - "heading": "The email address {{email}} is already in use." + "heading": "The email address {{email}} is already in use" }, "end_session_button": { "confirmation_modal_body_text": "Make sure you always have access to another verified device or your recovery key to avoid losing your encrypted chat history.", @@ -145,14 +145,14 @@ "current_password_label": "Huidig wachtwoord", "failure": { "description": { - "account_locked": "Your account is locked and can not be recovered at this time. If this is not expected, please contact your server administrator.", + "account_locked": "Your account is locked and can not be recovered at this time. If this is not expected, please contact your account provider.", "expired_recovery_ticket": "The recovery link has expired. Please start the account recovery process again from the start.", "invalid_new_password": "The new password you chose is invalid; it may not meet the configured security policy.", "no_current_password": "You don't have a current password.", "no_such_recovery_ticket": "The recovery link is invalid. If you copied the link from the recovery e-mail, please check the full link was copied.", "password_changes_disabled": "Password changes are disabled.", "recovery_ticket_already_used": "The recovery link has already been used. It cannot be used again.", - "unspecified": "This might be a temporary problem, so please try again later. If the problem persists, please contact your server administrator.", + "unspecified": "This might be a temporary problem, so please try again later. If the problem persists, please contact your account provider.", "wrong_password": "The password you supplied as your current password is incorrect. Please try again." }, "title": "Failed to update password" @@ -230,7 +230,7 @@ "cancelled": { "description_1": "You can close this window and go back to the app to continue.", "description_2": "If don’t have access to any other verified devices and you don’t have your recovery key, then you’ll need to reset your digital identity to continue using the app.", - "heading": "Digital identity reset cancelled." + "heading": "Digital identity reset cancelled" }, "description": "Als u niet bent aangemeld bij andere apparaten en u bent uw herstelsleutel kwijt, moet u uw identiteit opnieuw instellen om de app te kunnen blijven gebruiken.", "effect_list": { @@ -239,7 +239,7 @@ "positive_1": "Your account details, contacts, preferences, and chat list will be kept" }, "failure": { - "description": "This might be a temporary problem, so please try again later. If the problem persists, please contact your server administrator.", + "description": "This might be a temporary problem, so please try again later. If the problem persists, please contact your account provider.", "heading": "Failed to allow digital identity reset" }, "finish_reset": "Finish reset", diff --git a/frontend/locales/pl.json b/frontend/locales/pl.json index 801b83116..852b862bd 100644 --- a/frontend/locales/pl.json +++ b/frontend/locales/pl.json @@ -146,14 +146,14 @@ "current_password_label": "Aktualne hasło", "failure": { "description": { - "account_locked": "Twoje konto jest zablokowane i nie można go obecnie odzyskać. Jeśli nie jest to oczekiwane, skontaktuj się z administratorem serwera.", + "account_locked": "Twoje konto jest zablokowane i nie można go obecnie odzyskać. Jeśli nie spodziewałeś się tej informacji, skontaktuj się z dostawcą konta.", "expired_recovery_ticket": "Link do odzyskiwania wygasł. Rozpocznij proces odzyskiwania konta od początku.", "invalid_new_password": "Wybrane nowe hasło jest nieprawidłowe i może nie spełniać skonfigurowanych zasad bezpieczeństwa.", "no_current_password": "Nie masz aktualnego hasła.", "no_such_recovery_ticket": "Link odzyskiwania jest nieprawidłowy. Jeśli skopiowałeś link z e-maila odzyskiwania, sprawdź, czy został skopiowany w całości.", "password_changes_disabled": "Możliwość zmiany hasła jest wyłączona.", "recovery_ticket_already_used": "Link odzyskiwania został już użyty. Nie można go użyć ponownie.", - "unspecified": "To może być problem tymczasowy, więc spróbuj ponownie później. Jeśli problem będzie się powtarzał, skontaktuj się z administratorem serwera.", + "unspecified": "To może być problem tymczasowy, spróbuj ponownie później. Jeśli problem będzie się powtarzał, skontaktuj się z dostawcą konta.", "wrong_password": "Podane hasło jest nieprawidłowe. Spróbuj ponownie." }, "title": "Nie udało się zaktualizować hasła" @@ -240,7 +240,7 @@ "positive_1": "Twoje dane konta, kontakty, preferencje i lista czatów zostaną zachowane" }, "failure": { - "description": "To może być problem tymczasowy, więc spróbuj ponownie później. Jeśli problem będzie się powtarzał, skontaktuj się z administratorem serwera.", + "description": "To może być problem tymczasowy, spróbuj ponownie później. Jeśli problem będzie się powtarzał, skontaktuj się z dostawcą konta.", "heading": "Nie udało się zezwolić na zresetowanie tożsamości kryptograficznej" }, "finish_reset": "Zakończ resetowanie", @@ -259,9 +259,9 @@ "finished_label": "Zakończone", "generic_browser_session": "Sesja przeglądarki", "ip_label": "Adres IP", - "last_active_label": "Ostatnio aktywny", + "last_active_label": "Ostatnio aktywne", "name_for_platform": "{{name}} dla {{platform}}", - "scopes_label": "Zakresy", + "scopes_label": "Możliwości", "set_device_name": { "help": "Ustaw nazwę, która ułatwi identyfikację tego urządzenia.", "label": "Nazwa urządzenia", @@ -345,10 +345,10 @@ "edit_profile": "Edytuj swój profil i dane kontaktowe", "manage_sessions": "Zarządzaj swoimi urządzeniami i sesjami", "mas_admin": "Zarządzaj użytkownikami (urn:mas:admin)", - "send_messages": "Wysyłaj nowe wiadomości w Twoim imieniu", + "send_messages": "Wysyłanie nowych wiadomości w Twoim imieniu", "synapse_admin": "Administrowanie serwerem (urn:synapse:admin:*)", - "view_messages": "Przegląd istniejących wiadomości i danych", - "view_profile": "Przegląd informacji o profilu i danych kontaktowych" + "view_messages": "Przeglądanie istniejących wiadomości i danych", + "view_profile": "Przeglądanie informacji profilowych i danych kontaktowych" } } } \ No newline at end of file diff --git a/frontend/locales/pt-BR.json b/frontend/locales/pt-BR.json index 73ce0149c..3193b8b25 100644 --- a/frontend/locales/pt-BR.json +++ b/frontend/locales/pt-BR.json @@ -39,7 +39,7 @@ "contact_info": "Contact info", "delete_account": { "alert_description": "This account will be permanently erased and you’ll no longer have access to any of your messages.", - "alert_title": "You’re about to lose all of your data", + "alert_title": "You’re about to lose all of your data.", "button": "Delete account", "dialog_description": "Confirm that you would like to delete your account:\n\n\nYou will not be able to reactivate your account\nYou will no longer be able to sign in\nNo one will be able to reuse your username (MXID), including you\nYou will leave all rooms and direct messages you are in\nYou will be removed from the identity server, and no one will be able to find you with your email or phone number\n\nYour old messages will still be visible to people who received them. Would you like to hide your sent messages from people who join rooms in the future?", "dialog_title": "Delete this account?", @@ -73,7 +73,7 @@ "email_in_use_error": "The entered email is already in use", "email_invalid_error": "O endereço de e-mail inserido é inválido.", "incorrect_password_error": "Incorrect password, please try again", - "password_confirmation": "Confirm your account password to add this email address" + "password_confirmation": "Confirm your account password to add this email address." }, "browser_session_details": { "current_badge": "Current" @@ -99,7 +99,7 @@ "unknown": "Unknown device type" }, "email_in_use": { - "heading": "The email address {{email}} is already in use." + "heading": "The email address {{email}} is already in use" }, "end_session_button": { "confirmation_modal_body_text": "Make sure you always have access to another verified device or your recovery key to avoid losing your encrypted chat history.", @@ -145,14 +145,14 @@ "current_password_label": "Senha atual", "failure": { "description": { - "account_locked": "Your account is locked and can not be recovered at this time. If this is not expected, please contact your server administrator.", + "account_locked": "Your account is locked and can not be recovered at this time. If this is not expected, please contact your account provider.", "expired_recovery_ticket": "The recovery link has expired. Please start the account recovery process again from the start.", "invalid_new_password": "The new password you chose is invalid; it may not meet the configured security policy.", "no_current_password": "You don't have a current password.", "no_such_recovery_ticket": "The recovery link is invalid. If you copied the link from the recovery e-mail, please check the full link was copied.", "password_changes_disabled": "Password changes are disabled.", "recovery_ticket_already_used": "The recovery link has already been used. It cannot be used again.", - "unspecified": "This might be a temporary problem, so please try again later. If the problem persists, please contact your server administrator.", + "unspecified": "This might be a temporary problem, so please try again later. If the problem persists, please contact your account provider.", "wrong_password": "The password you supplied as your current password is incorrect. Please try again." }, "title": "Failed to update password" @@ -230,7 +230,7 @@ "cancelled": { "description_1": "You can close this window and go back to the app to continue.", "description_2": "If don’t have access to any other verified devices and you don’t have your recovery key, then you’ll need to reset your digital identity to continue using the app.", - "heading": "Digital identity reset cancelled." + "heading": "Digital identity reset cancelled" }, "description": "If don’t have access to any other verified devices and you don’t have your recovery key, then you’ll need to reset your digital identity to continue using the app.", "effect_list": { @@ -239,7 +239,7 @@ "positive_1": "Your account details, contacts, preferences, and chat list will be kept" }, "failure": { - "description": "This might be a temporary problem, so please try again later. If the problem persists, please contact your server administrator.", + "description": "This might be a temporary problem, so please try again later. If the problem persists, please contact your account provider.", "heading": "Failed to allow digital identity reset" }, "finish_reset": "Finish reset", diff --git a/frontend/locales/sk.json b/frontend/locales/sk.json index c4c40df3e..804c3ce55 100644 --- a/frontend/locales/sk.json +++ b/frontend/locales/sk.json @@ -39,7 +39,7 @@ "contact_info": "Contact info", "delete_account": { "alert_description": "This account will be permanently erased and you’ll no longer have access to any of your messages.", - "alert_title": "You’re about to lose all of your data", + "alert_title": "You’re about to lose all of your data.", "button": "Delete account", "dialog_description": "Confirm that you would like to delete your account:\n\n\nYou will not be able to reactivate your account\nYou will no longer be able to sign in\nNo one will be able to reuse your username (MXID), including you\nYou will leave all rooms and direct messages you are in\nYou will be removed from the identity server, and no one will be able to find you with your email or phone number\n\nYour old messages will still be visible to people who received them. Would you like to hide your sent messages from people who join rooms in the future?", "dialog_title": "Delete this account?", @@ -73,7 +73,7 @@ "email_in_use_error": "The entered email is already in use", "email_invalid_error": "The entered email is invalid", "incorrect_password_error": "Incorrect password, please try again", - "password_confirmation": "Confirm your account password to add this email address" + "password_confirmation": "Confirm your account password to add this email address." }, "browser_session_details": { "current_badge": "Current" @@ -99,7 +99,7 @@ "unknown": "Unknown device type" }, "email_in_use": { - "heading": "The email address {{email}} is already in use." + "heading": "The email address {{email}} is already in use" }, "end_session_button": { "confirmation_modal_body_text": "Make sure you always have access to another verified device or your recovery key to avoid losing your encrypted chat history.", @@ -145,14 +145,14 @@ "current_password_label": "Súčasné heslo", "failure": { "description": { - "account_locked": "Your account is locked and can not be recovered at this time. If this is not expected, please contact your server administrator.", + "account_locked": "Your account is locked and can not be recovered at this time. If this is not expected, please contact your account provider.", "expired_recovery_ticket": "The recovery link has expired. Please start the account recovery process again from the start.", "invalid_new_password": "The new password you chose is invalid; it may not meet the configured security policy.", "no_current_password": "You don't have a current password.", "no_such_recovery_ticket": "The recovery link is invalid. If you copied the link from the recovery e-mail, please check the full link was copied.", "password_changes_disabled": "Password changes are disabled.", "recovery_ticket_already_used": "The recovery link has already been used. It cannot be used again.", - "unspecified": "This might be a temporary problem, so please try again later. If the problem persists, please contact your server administrator.", + "unspecified": "This might be a temporary problem, so please try again later. If the problem persists, please contact your account provider.", "wrong_password": "The password you supplied as your current password is incorrect. Please try again." }, "title": "Failed to update password" @@ -230,7 +230,7 @@ "cancelled": { "description_1": "You can close this window and go back to the app to continue.", "description_2": "If don’t have access to any other verified devices and you don’t have your recovery key, then you’ll need to reset your digital identity to continue using the app.", - "heading": "Digital identity reset cancelled." + "heading": "Digital identity reset cancelled" }, "description": "If don’t have access to any other verified devices and you don’t have your recovery key, then you’ll need to reset your digital identity to continue using the app.", "effect_list": { @@ -239,7 +239,7 @@ "positive_1": "Your account details, contacts, preferences, and chat list will be kept" }, "failure": { - "description": "This might be a temporary problem, so please try again later. If the problem persists, please contact your server administrator.", + "description": "This might be a temporary problem, so please try again later. If the problem persists, please contact your account provider.", "heading": "Failed to allow digital identity reset" }, "finish_reset": "Finish reset", diff --git a/frontend/locales/sv.json b/frontend/locales/sv.json index 8872c38cb..21b5b2b71 100644 --- a/frontend/locales/sv.json +++ b/frontend/locales/sv.json @@ -39,7 +39,7 @@ "contact_info": "Kontaktuppgifter", "delete_account": { "alert_description": "This account will be permanently erased and you’ll no longer have access to any of your messages.", - "alert_title": "You’re about to lose all of your data", + "alert_title": "You’re about to lose all of your data.", "button": "Delete account", "dialog_description": "Confirm that you would like to delete your account:\n\n\nYou will not be able to reactivate your account\nYou will no longer be able to sign in\nNo one will be able to reuse your username (MXID), including you\nYou will leave all rooms and direct messages you are in\nYou will be removed from the identity server, and no one will be able to find you with your email or phone number\n\nYour old messages will still be visible to people who received them. Would you like to hide your sent messages from people who join rooms in the future?", "dialog_title": "Delete this account?", @@ -73,7 +73,7 @@ "email_in_use_error": "Det angivna e-postmeddelandet används redan", "email_invalid_error": "Den angivna e-postadressen är ogiltig", "incorrect_password_error": "Incorrect password, please try again", - "password_confirmation": "Confirm your account password to add this email address" + "password_confirmation": "Confirm your account password to add this email address." }, "browser_session_details": { "current_badge": "Nuvarande" diff --git a/frontend/locales/tr.json b/frontend/locales/tr.json new file mode 100644 index 000000000..8f552a68b --- /dev/null +++ b/frontend/locales/tr.json @@ -0,0 +1,347 @@ +{ + "action": { + "back": "Geri", + "cancel": "İptal", + "clear": "Temizle", + "close": "Kapat", + "collapse": "Daralt", + "confirm": "Onayla", + "continue": "Devam Et", + "edit": "Düzenle", + "expand": "Genişlet", + "save": "Kaydet", + "save_and_continue": "Kaydet ve devam et", + "sign_out": "Çıkış Yap", + "start_over": "Baştan başla" + }, + "branding": { + "privacy_policy": { + "alt": "Hizmet gizlilik politikasına bağlantı", + "link": "Gizlilik Politikası" + }, + "terms_and_conditions": { + "alt": "Hizmet şartları ve koşullarına bağlantı", + "link": "Şartlar & Koşullar" + } + }, + "common": { + "e2ee": "Uçtan uca şifreleme", + "loading": "Yükleniyor…", + "next": "Sonraki", + "password": "Şifre", + "previous": "Önceki", + "saved": "Kaydedildi", + "saving": "Kaydediliyor…" + }, + "frontend": { + "account": { + "account_password": "Hesap parolası", + "contact_info": "İletişim bilgileri", + "delete_account": { + "alert_description": "Bu hesap kalıcı olarak silinecek ve artık mesajlarınıza erişemeyeceksiniz.", + "alert_title": "Verilerinizin tamamını kaybetmek üzeresiniz.", + "button": "Hesabı sil", + "dialog_description": " Hesabınızı silmek istediğinizi onaylayın: \n\n \n Hesabınızı yeniden etkinleştiremeyeceksiniz \n Artık oturum açamayacaksınız \n Siz de dahil olmak üzere hiç kimse kullanıcı adınızı (MXID) yeniden kullanamayacak \n Katıldığınız tüm odalardan ve doğrudan mesajlardan ayrılacaksınız \n Kimlik sunucusundan kaldırılacaksınız ve hiç kimse sizi e-posta adresiniz veya telefon numaranızla bulamayacak \n \n Eski mesajlarınız, onları alan kişiler tarafından hala görülebilir. Gelecekte odalara katılan kişilerden gönderdiğiniz mesajları gizlemek ister misiniz? ", + "dialog_title": "Bu hesabı silmek istiyor musunuz?", + "erase_checkbox_label": "Evet, yeni katılanlardan tüm mesajlarımı gizle.", + "incorrect_password": "Hatalı parola, lütfen tekrar deneyin", + "mxid_label": "Matrix Kimliğinizi ({{ mxid }}) onaylayın", + "mxid_mismatch": "Bu değer, Matrix Kimliğinizle eşleşmiyor.", + "password_label": "Devam etmek için şifrenizi girin" + }, + "edit_profile": { + "display_name_help": "Oturum açtığınız her yerde diğerler kullanıcılar bunu görecektir.", + "display_name_label": "Görünen ad", + "title": "Profili düzenle", + "username_label": "Kullanıcı Adı" + }, + "password": { + "change": "Parola değiştir", + "change_disabled": "Yönetici tarafından parola değiştirme özelliği devre dışı bırakılmıştır.", + "label": "Şifre" + }, + "sign_out": { + "button": "Hesaptan çıkış yap", + "dialog": "Bu hesaptan çıkış yapmak ister misiniz?" + }, + "title": "Hesabınız" + }, + "add_email_form": { + "email_denied_error": "Girilen e-posta adresi, sunucu politikası gereği kabul edilmiyor", + "email_field_help": "Bu hesaba erişmek için kullanabileceğiniz alternatif bir e-posta adresi ekleyin.", + "email_field_label": "E-posta ekle", + "email_in_use_error": "Girilen e-posta adresi zaten kullanımda", + "email_invalid_error": "The entered email is invalid", + "incorrect_password_error": "Hatalı parola, lütfen tekrar deneyin", + "password_confirmation": "Bu e-posta adresini eklemek için hesap şifrenizi onaylayın" + }, + "browser_session_details": { + "current_badge": "Geçerli" + }, + "browser_sessions_overview": { + "body:one": "{{count}} aktif oturum", + "body:other": "{{count}} aktif oturumlar", + "heading": "Tarayıcılar", + "no_active_sessions": { + "default": "Herhangi bir web tarayıcısına giriş yapmadınız.", + "inactive_90_days": "Son 90 gün içinde tüm oturumlarınız aktif olmuştur." + }, + "view_all_button": "Tümünü görüntüle" + }, + "compat_session_detail": { + "client_details_title": "Müşteri bilgileri", + "name": "İsim" + }, + "device_type_icon_label": { + "mobile": "Mobil", + "pc": "Bilgisayar", + "tablet": "Tablet", + "unknown": "Bilinmeyen cihaz türü" + }, + "email_in_use": { + "heading": "{{email}} e-posta adresi zaten kullanımda." + }, + "end_session_button": { + "confirmation_modal_body_text": "Şifrelenmiş sohbet geçmişinizi kaybetmemek için her zaman başka bir doğrulanmış cihaza veya kurtarma anahtarınıza erişiminizin olduğundan emin olun.", + "confirmation_modal_title": "Bu cihazı kaldırmak istediğinizden emin misiniz?", + "text": "Cihazı kaldır" + }, + "error": { + "hideDetails": "Ayrıntıları gizle", + "showDetails": "Detayları göster", + "subtitle": "Beklenmeyen bir hata oluştu. Lütfen tekrar deneyin.", + "title": "Bir şeyler ters gitti." + }, + "errors": { + "field_required": "Bu alan zorunludur", + "rate_limit_exceeded": "Kısa süre içinde çok fazla istekte bulundunuz. Lütfen birkaç dakika bekleyin ve tekrar deneyin." + }, + "last_active": { + "active_date": "Aktif {{relativeDate}}", + "active_now": "Şu anda aktif", + "inactive_90_days": "90 günden fazla süredir aktif değil" + }, + "nav": { + "device_limit_error": "Cihaz limitine ulaşıldı", + "devices": "Cihazlar", + "plan": "Plan", + "settings": "Ayarlar" + }, + "not_found_alert_title": "Bulunamadı.", + "oauth2_client_detail": { + "details_title": "Müşteri bilgileri", + "name": "İsim", + "policy": "Politika", + "terms": "Hizmet şartları" + }, + "oauth2_session_detail": { + "client_details_name": "İsim", + "client_title": "Müşteri bilgileri" + }, + "pagination_controls": { + "total": "Toplam: {{totalCount}}" + }, + "password_change": { + "current_password_label": "Mevcut parola", + "failure": { + "description": { + "account_locked": "Hesabınız kilitlendi ve şu anda kurtarılamıyor. Bu durum beklenmedik bir şeyse, lütfen sunucu yöneticinizle iletişime geçin.", + "expired_recovery_ticket": "Kurtarma bağlantısının süresi doldu. Lütfen hesap kurtarma işlemine baştan başlayın.", + "invalid_new_password": "Seçtiğiniz yeni parola geçersiz; yapılandırılmış güvenlik politikasına uymuyor olabilir.", + "no_current_password": "Şu anda geçerli bir parolanız yok.", + "no_such_recovery_ticket": "Kurtarma bağlantısı geçersiz. Kurtarma e-postasındaki bağlantıyı kopyaladıysanız, lütfen bağlantının tamamının kopyalandığından emin olun.", + "password_changes_disabled": "Parola değiştirme özelliği devre dışı bırakılmıştır.", + "recovery_ticket_already_used": "Kurtarma bağlantısı daha önce kullanıldı. Tekrar kullanılamaz.", + "unspecified": "Bu geçici bir sorun olabilir, lütfen daha sonra tekrar deneyin. Sorun devam ederse, lütfen sunucu yöneticinizle iletişime geçin.", + "wrong_password": "Girdiğiniz geçerli parola yanlış. Lütfen tekrar deneyin." + }, + "title": "Parola güncelleme başarısız oldu." + }, + "new_password_again_label": "Yeni parolayı tekrar girin.", + "new_password_label": "Yeni parola", + "passwords_match": "Parolalar eşleşiyor!", + "passwords_no_match": "Parolalar eşleşmiyor", + "subtitle": "Hesabınız için yeni bir parola belirleyin.", + "success": { + "description": "Parolanız başarıyla güncellendi.", + "title": "Parola güncellendi" + }, + "title": "Parolanızı değiştirin" + }, + "password_reset": { + "consumed": { + "subtitle": "Yeni bir parola oluşturmak için, baştan başlayın ve \"Parolamı unuttum\" seçeneğini seçin.", + "title": "Parolanızı sıfırlamak için kullanılan bağlantı daha önce kullanıldı" + }, + "expired": { + "resend_email": "Resend email", + "subtitle": "{{email}} adresine gönderilecek yeni bir e-posta isteği gönderin.", + "title": "Parolanızı sıfırlama bağlantısının süresi doldu" + }, + "subtitle": "Hesabınız için yeni bir parola belirleyin.", + "title": "Parolanızı sıfırlayın" + }, + "password_strength": { + "placeholder": "Parola gücü", + "score": { + "0": "Son derece zayıf bir parola", + "1": "Çok zayıf bir parola", + "2": "Zayıf parola", + "3": "Güçlü parola", + "4": "Çok güçlü parola" + }, + "suggestion": { + "all_uppercase": "Bazı harfleri büyük harfle yazın, ancak hepsini değil.", + "another_word": "Daha az kullanılan kelimeler ekleyin.", + "associated_years": "Sizinle ilişkilendirilen yıllardan kaçının.", + "capitalization": "İlk harften başlayarak diğer harfleri de büyük harfle yazın.", + "dates": "Sizinle ilişkilendirilen tarih ve yıllardan kaçının.", + "l33t": "'a' yerine '@' gibi tahmin edilebilir harf değişikliklerinden kaçının.", + "longer_keyboard_pattern": "Daha uzun kalıplar kullanın ve yazma yönünü birden fazla kez değiştirin.", + "no_need": "Semboller, rakamlar veya büyük harfler kullanmadan da güçlü şifreler oluşturabilirsiniz.", + "pwned": "Bu parolayı başka yerlerde kullanıyorsanız, değiştirmeniz gerekir.", + "recent_years": "Son yılları göz ardı edin.", + "repeated": "Aynı kelimeleri ve karakterleri tekrar etmekten kaçının.", + "reverse_words": "Sık kullanılan kelimelerin ters yazılışlarından kaçının.", + "sequences": "Sık kullanılan karakter dizilerinden kaçının.", + "use_words": "Birden fazla kelime kullanın, ancak yaygın ifadelerden kaçının." + }, + "too_weak": "Bu parola çok zayıf.", + "warning": { + "common": "Bu, yaygın olarak kullanılan bir paroladır.", + "common_names": "Yaygın isimler ve soyadları tahmin etmek kolaydır.", + "dates": "Tarihleri ​​tahmin etmek kolaydır.", + "extended_repeat": "\"abcabcabc\" gibi tekrarlanan karakter dizileri tahmin edilmesi kolaydır.", + "key_pattern": "Kısa metin kalıplarını tahmin etmek kolaydır.", + "names_by_themselves": "Tek isim veya soyadı tahmin etmek kolaydır.", + "pwned": "Parolanız internette yaşanan bir veri ihlali sonucu ifşa edildi.", + "recent_years": "Son yılları tahmin etmek kolaydır.", + "sequences": "\"abc\" gibi yaygın karakter dizileri tahmin edilmesi kolaydır.", + "similar_to_common": "Bu, yaygın olarak kullanılan bir parolaya benziyor.", + "simple_repeat": "\"aaa\" gibi tekrarlanan karakterler tahmin edilmesi kolaydır.", + "straight_row": "Girdiğiniz harflerin düz sıralar halinde dizilmiş olması tahmin etmeyi kolaylaştırır.", + "top_hundred": "Bu, sık kullanılan bir paroladır.", + "top_ten": "Bu, çok sık kullanılan bir parola.", + "user_inputs": "Kişisel veya sayfa ile ilgili herhangi bir veri bulunmamalıdır.", + "word_by_itself": "Tek kelimeleri tahmin etmek kolaydır." + } + }, + "reset_cross_signing": { + "cancelled": { + "description_1": "Bu pencereyi kapatıp uygulamaya geri dönerek devam edebilirsiniz.", + "description_2": "Başka doğrulanmış cihazlara erişiminiz yoksa ve kurtarma anahtarınız da yoksa, uygulamayı kullanmaya devam etmek için dijital kimliğinizi sıfırlamanız gerekecektir.", + "heading": "Dijital kimlik sıfırlama işlemi iptal edildi." + }, + "description": "Başka doğrulanmış cihazlara erişiminiz yoksa ve kurtarma anahtarınız da yoksa, uygulamayı kullanmaya devam etmek için dijital kimliğinizi sıfırlamanız gerekecektir.", + "effect_list": { + "neutral_1": "Yalnızca sunucuda saklanan tüm mesaj geçmişinizi kaybedeceksiniz", + "neutral_2": "You will need to verify all your existing devices and contacts again", + "positive_1": "Hesap bilgileriniz, kişileriniz, tercihleriniz ve sohbet listeniz saklanacaktır" + }, + "failure": { + "description": "Bu geçici bir sorun olabilir, lütfen daha sonra tekrar deneyin. Sorun devam ederse, lütfen sunucu yöneticinizle iletişime geçin.", + "heading": "Dijital kimlik sıfırlama işlemi başarısız oldu" + }, + "finish_reset": "Sıfırlamayı tamamla", + "heading": "Başka bir şekilde doğrulama yapamıyorsanız dijital kimliğinizi sıfırlayın", + "start_reset": "Sıfırlamayı başlat", + "success": { + "description": "Dijital kimlik sıfırlama işlemi {{minutes}} dakika boyunca onaylanmıştır. Bu pencereyi kapatıp uygulamaya geri dönerek devam edebilirsiniz.", + "heading": "Dijital kimlik sıfırlama işlemi başarıyla oluşturuldu. İşlemi tamamlamak için uygulamaya geri dönün." + }, + "warning": "Kimliğinizi yalnızca oturum açtığınız başka bir cihaza erişiminiz yoksa ve kurtarma anahtarınızı kaybettiyseniz sıfırlayın." + }, + "session": { + "client_id_label": "Client ID", + "current": "Geçerli", + "device_id_label": "Cihaz Kimliği", + "finished_label": "Tamamlandı", + "generic_browser_session": "Tarayıcı oturumu", + "ip_label": "IP Adresi", + "last_active_label": "Son Etkinlik", + "name_for_platform": "{{name}}, {{platform}} için", + "scopes_label": "Kapsamlar", + "set_device_name": { + "help": "Bu cihazı kolayca tanımanıza yardımcı olacak bir ad belirleyin.", + "label": "Cihaz adı", + "title": "Cihaz adını düzenle" + }, + "signed_in_label": "Giriş yapıldı", + "title": "Cihaz detayları", + "unknown_browser": "Bilinmeyen tarayıcı", + "unknown_device": "Bilinmeyen cihaz", + "uri_label": "Uri" + }, + "session_detail": { + "alert": { + "button": "Geri dön", + "text": "Bu oturum mevcut değil veya artık aktif değil.", + "title": "{{deviceId}} oturumu bulunamadı" + } + }, + "user_email": { + "delete_button_confirmation_modal": { + "action": "E-postayı sil", + "body": "Bu e-postayı silmek ister misiniz?", + "incorrect_password": "Hatalı parola, lütfen tekrar deneyin", + "password_confirmation": "Bu e-posta adresini silmek için hesap parolanızı onaylayın" + }, + "delete_button_title": "E-posta adresini kaldır", + "email": "E-posta" + }, + "user_sessions_overview": { + "approaching_session_limit_warning_description:one": "{{count}} cihaz sayısının {{num_sessions}}ini kullandınız. Sınırınıza ulaştığınızda, başka bir cihaz eklemek için mevcut bir cihazı kaldırmanız gerekecektir.", + "approaching_session_limit_warning_description:other": "{{num_sessions}} veya {{count}} cihaz sayısından birini kullandınız. Sınırınıza ulaştığınızda, başka bir cihaz eklemek için mevcut bir cihazı kaldırmanız gerekecektir.", + "approaching_session_limit_warning_header": "Dikkat, cihaz limitinize yaklaşıyorsunuz", + "heading": "Oturum açtığınız yer", + "hit_session_limit_warning_description:one": "{{count}} aygıt yuvasından {{num_sessions}} aygıtını kullandınız. Tekrar oturum açmayı denediğinizde, mevcut bir aygıtı kaldırmanız gerekecektir.", + "hit_session_limit_warning_description:other": "{{num_sessions}} veya {{count}} aygıt yuvalarından birini kullandınız. Tekrar oturum açmayı denediğinizde, mevcut bir aygıtı kaldırmanız gerekecektir.", + "hit_session_limit_warning_header": "Cihaz limitine ulaştınız", + "no_active_sessions": { + "default": "Şu anda hiçbir uygulamaya giriş yapmadınız.", + "inactive_90_days": "Son 90 gün içinde tüm oturumlarınız aktif olmuştur." + }, + "num_sessions_filtered_header": { + "header:one": "Filtrenize uyan {{count}} cihaz var ({{unfiltered_session_total}})", + "header:other": "Filtrenize uyan {{count}} cihaz var ({{unfiltered_session_total}})", + "unfiltered_session_total:one": "Toplam {{count}}", + "unfiltered_session_total:other": "Toplam {{count}}" + }, + "num_sessions_header:one": "{{count}} cihaz", + "num_sessions_header:other": "{{count}} cihaz", + "session_limit_info:one": "{{count}}/{{limit}} aygıt yuvalarını kullandınız.", + "session_limit_info:other": "{{count}}/{{limit}} aygıt yuvalarını kullandınız." + }, + "verify_email": { + "code_expired_alert": { + "description": "Kodun süresi doldu. Lütfen yeni bir kod talep edin.", + "title": "Kodun süresi doldu." + }, + "code_field_error": "Kod tanınmadı", + "code_field_label": "6 haneli kod", + "code_field_wrong_shape": "Kod 6 rakamdan oluşmalıdır", + "email_sent_alert": { + "description": "Yeni kodu aşağıya girin", + "title": "Yeni kod gönderildi" + }, + "enter_code_prompt": "Gönderilen 6 haneli kodu girin: {{email}}", + "heading": "E-postanızı doğrulayın", + "invalid_code_alert": { + "description": "E-postanıza gönderilen kodu kontrol edin ve devam etmek için aşağıdaki alanları güncelleyin.", + "title": "Yanlış kod girdiniz" + }, + "resend_code": "Resend code" + } + }, + "mas": { + "scope": { + "edit_profile": "Profilinizi ve iletişim bilgilerinizi düzenleyin", + "manage_sessions": "Cihazlarınızı ve oturumlarınızı yönetin", + "mas_admin": "Kullanıcıları yönet (urn:mas:admin)", + "send_messages": "Sizin adınıza mesaj gönderin", + "synapse_admin": "Sunucuyu yönetin (urn:synapse:admin:*)", + "view_messages": "Mevcut mesajları ve verilerinizi görüntüleyinmessages", + "view_profile": "Profil bilgilerinizi ve iletişim bilgilerinizi görüntüleyin" + } + } +} \ No newline at end of file diff --git a/frontend/locales/uk.json b/frontend/locales/uk.json index 0054f18f1..9ea74cfc4 100644 --- a/frontend/locales/uk.json +++ b/frontend/locales/uk.json @@ -146,14 +146,14 @@ "current_password_label": "Поточний пароль", "failure": { "description": { - "account_locked": "Ваш обліковий запис заблоковано, і зараз його неможливо відновити. Якщо цього не передбачалося, зверніться до адміністратора сервера.", + "account_locked": "Ваш обліковий запис заблоковано, і зараз його неможливо відновити. Якщо цього не передбачалося, зверніться до постачальника вашого облікового запису.", "expired_recovery_ticket": "Посилання для відновлення застаріло. Розпочніть процес відновлення облікового запису спочатку.", "invalid_new_password": "Обраний вами новий пароль неприпустимий; він може не відповідати налаштованій політиці безпеки.", "no_current_password": "У вас немає поточного пароля.", "no_such_recovery_ticket": "Посилання для відновлення недійсне. Якщо ви скопіювали посилання з електронної пошти для відновлення, перевірте, чи скопійовано повне посилання.", "password_changes_disabled": "Зміна пароля вимкнена.", "recovery_ticket_already_used": "Посилання для відновлення вже використано. Його не можна використовувати повторно.", - "unspecified": "Це може бути тимчасова проблема, тому спробуйте пізніше. Якщо проблема не зникає, зверніться до адміністратора свого сервера.", + "unspecified": "Це може бути тимчасова проблема, тому повторіть спробу пізніше. Якщо проблема не зникне, зверніться до постачальника вашого облікового запису.", "wrong_password": "Пароль, який ви вказали як свій поточний пароль, неправильний. Спробуйте ще раз." }, "title": "Не вдалося оновити пароль" @@ -240,7 +240,7 @@ "positive_1": "Ваші дані облікового запису, контакти, налаштування та список бесід будуть збережені" }, "failure": { - "description": "Це може бути тимчасова проблема, тому спробуйте пізніше. Якщо проблема не зникає, зверніться до адміністратора свого сервера.", + "description": "Це може бути тимчасова проблема, тому повторіть спробу пізніше. Якщо проблема не зникне, зверніться до постачальника вашого облікового запису.", "heading": "Не вдалося дозволити скидання криптоідентичності" }, "finish_reset": "Завершити скидання", diff --git a/frontend/locales/uz.json b/frontend/locales/uz.json index c5969cc6d..d24ddf36f 100644 --- a/frontend/locales/uz.json +++ b/frontend/locales/uz.json @@ -4,15 +4,15 @@ "cancel": "Bekor qilish", "clear": "Tozalash", "close": "Yopish", - "collapse": "Collapse", - "confirm": "Confirm", + "collapse": "Yig‘ish", + "confirm": "Tasdiqlash", "continue": "Davom etish", "edit": "Tahrirlash", - "expand": "Expand", + "expand": "Kengaytirish", "save": "Saqlash", - "save_and_continue": "Save and continue", + "save_and_continue": "Saqlash va davom ettirish", "sign_out": "Chiqish", - "start_over": "Start over" + "start_over": "Qaytadan boshlang" }, "branding": { "privacy_policy": { @@ -25,29 +25,29 @@ } }, "common": { - "e2ee": "End-to-end encryption", + "e2ee": "Abonent shifrlash ( E2EE )", "loading": "Yuklanmoqda…", "next": "Keyingisi", "password": "Parol", "previous": "Oldingi", - "saved": "Saved", - "saving": "Saving…" + "saved": "Saqlandi", + "saving": "Saqlanmoqda…" }, "frontend": { "account": { - "account_password": "Account password", - "contact_info": "Contact info", + "account_password": "Hisob paroli", + "contact_info": "Kontakt maʼlumoti", "delete_account": { - "alert_description": "This account will be permanently erased and you’ll no longer have access to any of your messages.", - "alert_title": "You’re about to lose all of your data", - "button": "Delete account", - "dialog_description": "Confirm that you would like to delete your account:\n\n\nYou will not be able to reactivate your account\nYou will no longer be able to sign in\nNo one will be able to reuse your username (MXID), including you\nYou will leave all rooms and direct messages you are in\nYou will be removed from the identity server, and no one will be able to find you with your email or phone number\n\nYour old messages will still be visible to people who received them. Would you like to hide your sent messages from people who join rooms in the future?", - "dialog_title": "Delete this account?", - "erase_checkbox_label": "Yes, hide all my messages from new joiners", - "incorrect_password": "Incorrect password, please try again", - "mxid_label": "Confirm your Matrix ID ({{ mxid }})", - "mxid_mismatch": "This value does not match your Matrix ID", - "password_label": "Enter your password to continue" + "alert_description": "Bu hisob butunlay oʻchirib tashlanadi va siz endi xabarlaringizning birortasiga ham kira olmaysiz.", + "alert_title": "Siz barcha maʻlumotlaringizni yoʻqotish arafasidasiz", + "button": "Akkauntni o‘chirish", + "dialog_description": " Hisobingizni oʻchirishni xohlayotganingizni tasdiqlang: \n\n Hisobingizni qayta faollashtira olmaysiz \n Endi tizimga kira olmaysiz \n Hech kim, shu jumladan siz ham, foydalanuvchi nomingizni (MXID) qayta ishlata olmaydi \n Siz barcha xonalarni va toʻgridan-toʻgʻri xabarlaringizni tark etasiz \n Siz identifikatsiya serveridan oʻchirilasiz va hech kim sizni elektron pochta yoki telefon raqamingiz bilan topa olmaydi \n Eski xabarlaringiz ularni olgan odamlarga koʻrinadigan boʻladi. Kelajakda xonalarga qoʻshilgan odamlardan yuborilgan xabarlaringizni yashirishni xohlaysizmi?", + "dialog_title": "Bu akkaunt oʻchirib tashlansinmi?", + "erase_checkbox_label": "Ha, barcha xabarlarimni yangi qoʻshilganlardan yashirish", + "incorrect_password": "Parol notoʻgʻri,qaytadan urining.", + "mxid_label": "Matrix identifikatoringizni tasdiqlang ({{ mxid }})", + "mxid_mismatch": "Bu qiymat sizning Matrix ID raqamingizga mos kelmaydi", + "password_label": "Davom etish uchun parolingizni kiriting" }, "edit_profile": { "display_name_help": "Siz tizimga kirgan joyingizda boshqalar buni koʻrishadi.", @@ -61,19 +61,19 @@ "label": "Parol" }, "sign_out": { - "button": "Sign out of account", - "dialog": "Sign out of this account?" + "button": "Hisobdan chiqish", + "dialog": "Bu hisobdan chiqilsinmi?" }, "title": "Sizning hisobingiz" }, "add_email_form": { - "email_denied_error": "The entered email is not allowed by the server policy", + "email_denied_error": "Kiritilgan elektron pochta manzili server siyosati tomonidan ruxsat etilmagan", "email_field_help": "Bu hisobga kirish uchun ishlatishingiz mumkin bo‘lgan muqobil email manzilini kiriting.", "email_field_label": "Email manzilini kiritish", - "email_in_use_error": "The entered email is already in use", + "email_in_use_error": "Kiritilgan elektron pochta allaqachon ishlatilmoqda", "email_invalid_error": "Kiritilgan elektron pochta manzili notogʻri", - "incorrect_password_error": "Incorrect password, please try again", - "password_confirmation": "Confirm your account password to add this email address" + "incorrect_password_error": "Parol notoʻgʻri,qaytadan urining.", + "password_confirmation": "Ushbu elektron pochta manzilini qoʻshish uchun hisobingiz parolini tasdiqlang" }, "browser_session_details": { "current_badge": "Hozirgi" @@ -83,8 +83,8 @@ "body:other": "{{count}} ta faol seans", "heading": "Brauzerlar", "no_active_sessions": { - "default": "You are not signed in to any web browsers.", - "inactive_90_days": "All your sessions have been active in the last 90 days." + "default": "Siz hech qanday veb-brauzerga kirmagansiz.", + "inactive_90_days": "Soʻnggi 90 kun ichida barcha sessiyalaringiz faol boʻldi." }, "view_all_button": "Hammasini ko‘rish" }, @@ -99,10 +99,10 @@ "unknown": "Noma’lum qurilma turi" }, "email_in_use": { - "heading": "The email address {{email}} is already in use." + "heading": "{{email}} elektron pochta manzili allaqachon ishlatilmoqda." }, "end_session_button": { - "confirmation_modal_body_text": "Make sure you always have access to another verified device or your recovery key to avoid losing your encrypted chat history.", + "confirmation_modal_body_text": "Shifrlangan chat tarixingizni yoʻqotmaslik uchun har doim boshqa tasdiqlangan qurilmaga yoki tiklash kalitingizga kirish huquqiga ega ekanligingizga ishonch hosil qiling.", "confirmation_modal_title": "Haqiqatan ham bu qurilmani olib tashlamoqchimisiz?", "text": "Qurilmani olib tashlash" }, @@ -114,7 +114,7 @@ }, "errors": { "field_required": "Ushbu qator toʻldirilishi shart", - "rate_limit_exceeded": "You've made too many requests in a short period. Please wait a few minutes and try again." + "rate_limit_exceeded": "Qisqa vaqt ichida juda koʻp soʻrov yubordingiz. Iltimos, bir necha daqiqa kuting va qayta urinib koʻring." }, "last_active": { "active_date": "Faol {{relativeDate}}", @@ -122,9 +122,9 @@ "inactive_90_days": "90+ kun davomida faol emas" }, "nav": { - "device_limit_error": "Device limit reached", + "device_limit_error": "Qurilma limitiga yetdi", "devices": "Qurilmalar", - "plan": "Plan", + "plan": "Tarif", "settings": "Sozlamalar" }, "not_found_alert_title": "Topilmadi.", @@ -145,19 +145,19 @@ "current_password_label": "Joriy parol", "failure": { "description": { - "account_locked": "Your account is locked and can not be recovered at this time. If this is not expected, please contact your server administrator.", - "expired_recovery_ticket": "The recovery link has expired. Please start the account recovery process again from the start.", + "account_locked": "Hisobingiz qulflangan va hozirda uni qayta tiklab boʻlmaydi. Agar bu kutilmasa, iltimos, server administratoringizga murojaat qiling.", + "expired_recovery_ticket": "Tiklash havolasi muddati tugagan. Hisobni tiklash jarayonini boshidan qayta boshlang.", "invalid_new_password": "Siz tanlagan yangi parol yaroqsiz; u sozlangan xavfsizlik siyosatiga mos kelmasligi mumkin.", "no_current_password": "Sizda joriy parol yo‘q.", - "no_such_recovery_ticket": "The recovery link is invalid. If you copied the link from the recovery e-mail, please check the full link was copied.", + "no_such_recovery_ticket": "Qayta tiklash havolasi yaroqsiz. Agar siz havolani tiklash elektron pochtasidan nusxa koʻchirgan boʻlsangiz, iltimos, toʻliq havola nusxalanganligini tekshiring.", "password_changes_disabled": "Parolni o‘zgartirish faolsizlantirildi.", - "recovery_ticket_already_used": "The recovery link has already been used. It cannot be used again.", + "recovery_ticket_already_used": "Qayta tiklash havolasi allaqachon ishlatilgan. Uni qayta ishlatib boʻlmaydi.", "unspecified": "Bu vaqtinchalik muammo bo‘lishi mumkin, keyinroq qayta urining. Agar muammo bartaraf etilmasa, server administratoriga murojaat qiling.", "wrong_password": "Joriy parol sifatida kiritgan parolingiz noto‘g‘ri. Iltimos, qayta urinib ko‘ring." }, "title": "Parolni yangilab bo‘lmadi." }, - "new_password_again_label": "Enter new password again", + "new_password_again_label": "Yangi parolni qayta kiriting", "new_password_label": "Yangi parol", "passwords_match": "Parollar mos keldi!", "passwords_no_match": "Parollar mos kelmadi", @@ -170,101 +170,101 @@ }, "password_reset": { "consumed": { - "subtitle": "To create a new password, start over and select ”Forgot password“.", - "title": "The link to reset your password has already been used" + "subtitle": "Yangi parol yaratish uchun boshidan boshlang va ʼʼParolni unutdingizmiʼʼ ni tanlang.", + "title": "Parolingizni tiklash havolasi allaqachon ishlatilgan" }, "expired": { "resend_email": "Elektron pochtani qayta yuborish", - "subtitle": "Request a new email that will be sent to: {{email}}", - "title": "The link to reset your password has expired" + "subtitle": "{{email}} manziliga yuboriladigan yangi elektron pochta xabarini soʻrang", + "title": "Parolingizni tiklash havolasi muddati tugagan" }, "subtitle": "Hisobingiz uchun yangi parol tanlang.", - "title": "Reset your password" + "title": "Parolingizni qayta tiklash" }, "password_strength": { - "placeholder": "Password strength", + "placeholder": "Parol kuchi", "score": { - "0": "Extremely weak password", - "1": "Very weak password", - "2": "Weak password", - "3": "Strong password", - "4": "Very strong password" + "0": "Juda zaif parol", + "1": "Juda zaif parol", + "2": "Zaif parol", + "3": "Kuchli parol", + "4": "Juda kuchli parol" }, "suggestion": { - "all_uppercase": "Capitalise some, but not all letters.", - "another_word": "Add more words that are less common.", - "associated_years": "Avoid years that are associated with you.", - "capitalization": "Capitalise more than the first letter.", - "dates": "Avoid dates and years that are associated with you.", - "l33t": "Avoid predictable letter substitutions like '@' for 'a'.", - "longer_keyboard_pattern": "Use longer keyboard patterns and change typing direction multiple times.", - "no_need": "You can create strong passwords without using symbols, numbers, or uppercase letters.", - "pwned": "If you use this password elsewhere, you should change it.", - "recent_years": "Avoid recent years.", - "repeated": "Avoid repeated words and characters.", - "reverse_words": "Avoid reversed spellings of common words.", - "sequences": "Avoid common character sequences.", - "use_words": "Use multiple words, but avoid common phrases." + "all_uppercase": "Baʼzi harflarni bosh harf bilan yozing, lekin hammasini emas.", + "another_word": "Kamroq uchraydigan soʻzlarni qoʻshing.", + "associated_years": "Siz bilan bogʻliq yillardan qoching.", + "capitalization": "Birinchi harfdan koʻproq bosh harf bilan yozing.", + "dates": "Siz bilan bogʻliq sanalar va yillardan qoching.", + "l33t": "“a” harfi o‘rniga “@” kabi oldindan aytib bo‘ladigan harf almashtirishlardan saqlaning.", + "longer_keyboard_pattern": "Uzunroq klaviatura naqshlaridan foydalaning va yozish yoʻnalishini bir necha marta oʻzgartiring.", + "no_need": "Siz belgilar, raqamlar yoki katta harflardan foydalanmasdan kuchli parollar yaratishingiz mumkin.", + "pwned": "Agar siz ushbu parolni boshqa joyda ishlatsangiz, uni oʻzgartirishingiz kerak.", + "recent_years": "Soʻnggi yillardagi voqealardan qoching.", + "repeated": "Takrorlanadigan soʻzlar va belgilardan saqlaning.", + "reverse_words": "Umumiy soʻzlarning teskari yozilishidan saqlaning.", + "sequences": "Umumiy belgilar ketma-ketligidan qoching.", + "use_words": "Bir nechta soʻzlardan foydalaning, lekin umumiy iboralardan qoching." }, - "too_weak": "This password is too weak", + "too_weak": "Bu parol juda zaif", "warning": { - "common": "This is a commonly used password.", - "common_names": "Common names and surnames are easy to guess.", - "dates": "Dates are easy to guess.", - "extended_repeat": "Repeated character patterns like \"abcabcabc\" are easy to guess.", - "key_pattern": "Short keyboard patterns are easy to guess.", - "names_by_themselves": "Single names or surnames are easy to guess.", - "pwned": "Your password was exposed by a data breach on the Internet.", - "recent_years": "Recent years are easy to guess.", - "sequences": "Common character sequences like \"abc\" are easy to guess.", - "similar_to_common": "This is similar to a commonly used password.", - "simple_repeat": "Repeated characters like \"aaa\" are easy to guess.", - "straight_row": "Straight rows of keys on your keyboard are easy to guess.", - "top_hundred": "This is a frequently used password.", - "top_ten": "This is a heavily used password.", - "user_inputs": "There should not be any personal or page related data.", - "word_by_itself": "Single words are easy to guess." + "common": "Bu tez-tez ishlatiladigan parol.", + "common_names": "Umumiy ismlar va familiyalarni taxmin qilish oson.", + "dates": "Sanalar taxmin qilish oson.", + "extended_repeat": "\"abcabcabc\" kabi takroriy belgi naqshlarini taxmin qilish oson.", + "key_pattern": "Qisqa klaviatura birikmalarini topish oson.", + "names_by_themselves": "Bitta ism yoki familiyani taxmin qilish oson.", + "pwned": "Parolingiz internetda maʻlumotlarning oʻgʻirlanishi natijasida oshkor boʻldi.", + "recent_years": "Yillar oson topiladi.", + "sequences": "\"abc\" kabi keng tarqalgan belgilar ketma-ketligini taxmin qilish oson.", + "similar_to_common": "Bu keng tarqalgan parolga oʻxshaydi.", + "simple_repeat": "\"aaa\" kabi takroriy belgilarni taxmin qilish oson.", + "straight_row": "Klaviaturangizdagi tugmalarning toʻgʻri qatorlarini taxmin qilish oson.", + "top_hundred": "Bu tez-tez ishlatiladigan parol.", + "top_ten": "Bu juda koʻp ishlatiladigan parol.", + "user_inputs": "Shaxsiy yoki sahifa bilan bogʻliq maʻlumotlar boʻlmasligi kerak.", + "word_by_itself": "Alohida soʻzlarni taxmin qilish oson." } }, "reset_cross_signing": { "cancelled": { - "description_1": "You can close this window and go back to the app to continue.", - "description_2": "If don’t have access to any other verified devices and you don’t have your recovery key, then you’ll need to reset your digital identity to continue using the app.", - "heading": "Digital identity reset cancelled." + "description_1": "Davom etish uchun ushbu oynani yopib, ilovaga qaytishingiz mumkin.", + "description_2": "Agar boshqa tasdiqlangan qurilmalarga kirish imkoningiz boʻlmasa va sizda tiklash kaliti boʻlmasa, ilovadan foydalanishda davom etish uchun raqamli identifikatsiyangizni tiklashingiz kerak boʻladi.", + "heading": "Raqamli identifikatsiyani tiklash bekor qilindi." }, "description": "Agar boshqa tasdiqlangan qurilmalarga kirish imkoningiz boʻlmasa va sizda tiklash kaliti boʻlmasa, ilovadan foydalanishda davom etish uchun raqamli identifikatsiyangizni tiklashingiz kerak boʻladi.", "effect_list": { - "neutral_1": "You will lose any message history that's stored only on the server", + "neutral_1": "Faqat serverda saqlangan har qanday xabarlar tarixi oʻchib ketadi", "neutral_2": "You will need to verify all your existing devices and contacts again", - "positive_1": "Your account details, contacts, preferences, and chat list will be kept" + "positive_1": "Hisob maʼlumotlaringiz, kontaktlaringiz, sozlamalaringiz va suhbatlar roʻyxatingiz saqlanib qoladi" }, "failure": { "description": "Bu vaqtinchalik muammo bo‘lishi mumkin, keyinroq qayta urining. Agar muammo bartaraf etilmasa, server administratoriga murojaat qiling.", - "heading": "Failed to allow digital identity reset" + "heading": "Raqamli identifikatsiyani qayta tiklashga ruxsat berilmadi" }, - "finish_reset": "Finish reset", + "finish_reset": "Qayta tiklashni tugatish", "heading": "Boshqa usulda tasdiqlay olmasangiz, raqamli identifikatoringizni asliga qaytaring", - "start_reset": "Start reset", + "start_reset": "Qayta tiklashni boshlang", "success": { "description": "Raqamli identifikatorni tiklash keyingi {{minutes}} daqiqa uchun tasdiqlandi. Bu oynani yopib, davom etish uchun ilovaga qaytishingiz mumkin.", - "heading": "Digital identity reset successfully. Go back to the app to finish the process." + "heading": "Raqamli identifikatsiya muvaffaqiyatli tiklandi. Jarayonni yakunlash uchun ilovaga qayting." }, - "warning": "Only reset your digital identity if you don't have access to another verified device and you don't have your recovery key." + "warning": "Agar boshqa tasdiqlangan qurilmaga kira olmasangiz va zaxira kalitingiz bo‘lmasa, raqamli identifikatoringizni asliga qaytaring." }, "session": { "client_id_label": "Mijoz ID raqami", "current": "Hozirgi", "device_id_label": "Qurilma ID", "finished_label": "Tugadi", - "generic_browser_session": "Browser session", + "generic_browser_session": "Brauzer sessiyasi", "ip_label": "IP-manzil", "last_active_label": "Oxirgi faollik", "name_for_platform": "{{platform}} uchun {{name}}", "scopes_label": "Ko‘lamlar", "set_device_name": { - "help": "Set a name that will help you identify this device.", - "label": "Device name", - "title": "Edit device name" + "help": "Ushbu qurilmani aniqlashga yordam beradigan nom oʻrnating.", + "label": "Qurilma nomi", + "title": "Qurilma nomini tahrirlash" }, "signed_in_label": "Kirish", "title": "Qurilma tafsilotlari", @@ -283,39 +283,39 @@ "delete_button_confirmation_modal": { "action": "Elektron pochtani oʻchirish", "body": "Bu email o‘chirib tashlansinmi?", - "incorrect_password": "Incorrect password, please try again", - "password_confirmation": "Confirm your account password to delete this email address" + "incorrect_password": "Parol notoʻgʻri,qaytadan urining.", + "password_confirmation": "Ushbu elektron pochta manzilini oʻchirish uchun hisobingiz parolini tasdiqlang" }, "delete_button_title": "Elektron pochta manzilini olib tashlash", "email": "Elektron pochta" }, "user_sessions_overview": { - "approaching_session_limit_warning_description:one": "You've used {{num_sessions}} of {{count}} device slot. Once you reach your limit, you'll need to remove an existing device to add another.", - "approaching_session_limit_warning_description:other": "You've used {{num_sessions}} of {{count}} device slots. Once you reach your limit, you'll need to remove an existing device to add another.", - "approaching_session_limit_warning_header": "Heads up, you're close to your device limit", + "approaching_session_limit_warning_description:one": "Siz {{count}} qurilma uyasidan {{num_sessions}} dan foydalandingiz. Cheklovga yetganingizdan soʻng, yangi qurilma qoʻshish uchun mavjud qurilmadan birini olib tashlashingiz kerak boʻladi.", + "approaching_session_limit_warning_description:other": "Siz {{count}} qurilma uyalaridan {{num_sessions}} dan foydalangansiz. Cheklovga yetganingizdan soʻng, boshqa qurilma qoʻshish uchun mavjud qurilmadan birini olib tashlashingiz kerak boʻladi.", + "approaching_session_limit_warning_header": "Diqqat! Qurilmangiz limitiga yaqinlashdingiz", "heading": "Qayerda tizimga kirgansiz", - "hit_session_limit_warning_description:one": "You've used {{num_sessions}} of {{count}} device slot. When you try to sign-in again, you'll need to remove an existing device.", - "hit_session_limit_warning_description:other": "You've used {{num_sessions}} of {{count}} device slots. When you try to sign-in again, you'll need to remove an existing device.", - "hit_session_limit_warning_header": "You've hit the device limit", + "hit_session_limit_warning_description:one": "Siz {{count}} qurilma uyasidan {{num_sessions}} dan foydalandingiz. Qayta kirishga urinayotganingizda, mavjud qurilmani olib tashlashingiz kerak boʻladi.", + "hit_session_limit_warning_description:other": "Siz {{count}} qurilma uyalaridan {{num_sessions}} dan foydalangansiz. Qayta kirishga urinayotganingizda, mavjud qurilmani olib tashlashingiz kerak boʻladi.", + "hit_session_limit_warning_header": "Qurilmalar soni limitiga yetdingiz", "no_active_sessions": { - "default": "You are not signed in to any application.", - "inactive_90_days": "All your sessions have been active in the last 90 days." + "default": "Siz hech qanday ilovaga kirmagansiz.", + "inactive_90_days": "Soʻnggi 90 kun ichida barcha sessiyalaringiz faol boʻldi." }, "num_sessions_filtered_header": { - "header:one": "{{count}} device matches your filter ({{unfiltered_session_total}})", - "header:other": "{{count}} devices match your filter ({{unfiltered_session_total}})", - "unfiltered_session_total:one": "{{count}} total", - "unfiltered_session_total:other": "{{count}} total" + "header:one": "{{count}} qurilmasi sizning filtringizga mos keladi ({{unfiltered_session_total}})", + "header:other": "{{count}} qurilmalari sizning filtringizga mos keladi ({{unfiltered_session_total}})", + "unfiltered_session_total:one": "Jami {{count}}", + "unfiltered_session_total:other": "Jami {{count}}" }, - "num_sessions_header:one": "{{count}} device", - "num_sessions_header:other": "{{count}} devices", - "session_limit_info:one": "You've used {{count}}/{{limit}} device slots", - "session_limit_info:other": "You've used {{count}}/{{limit}} device slots" + "num_sessions_header:one": "{{count}} qurilmasi", + "num_sessions_header:other": "{{count}} qurilmalari", + "session_limit_info:one": "Siz {{count}}/{{limit}} qurilma uyalaridan foydalangansiz", + "session_limit_info:other": "Siz {{count}}/{{limit}} qurilma uyalaridan foydalangansiz" }, "verify_email": { "code_expired_alert": { - "description": "The code has expired. Please request a new code.", - "title": "Code expired" + "description": "Kodning amal qilish muddati tugagan. Iltimos, yangi kod soʻrang.", + "title": "Kod muddati tugagan" }, "code_field_error": "Kod tan olinmadi", "code_field_label": "6 xonali kod", diff --git a/frontend/locales/zh-Hans.json b/frontend/locales/zh-Hans.json index 3e6357f2d..aadf2fd63 100644 --- a/frontend/locales/zh-Hans.json +++ b/frontend/locales/zh-Hans.json @@ -116,9 +116,9 @@ "rate_limit_exceeded": "你在短时间内发出了过多请求。请于几分钟后重试。" }, "last_active": { - "active_date": "活跃 {{relativeDate}}", + "active_date": "活跃于 {{relativeDate}}", "active_now": "活跃", - "inactive_90_days": "已停用90天以上" + "inactive_90_days": "已停用 90 天以上" }, "nav": { "device_limit_error": "已达到设备数量上限", diff --git a/translations/de.json b/translations/de.json index fe1182697..29f2099dc 100644 --- a/translations/de.json +++ b/translations/de.json @@ -7,7 +7,7 @@ "sign_in": "Anmelden", "sign_out": "Abmelden", "skip": "Überspringen", - "start_over": "Von vorne anfangen" + "start_over": "Neu beginnen" }, "app": { "human_name": "Matrix Authentication Service", @@ -27,11 +27,11 @@ "common": { "display_name": "Anzeigename", "email_address": "E-Mail-Adresse", - "loading": "Lade …", + "loading": "Wird geladen …", "mxid": "Matrix-ID", "password": "Passwort", - "password_confirm": "Passwort wiederholen", - "username": "Benutzername" + "password_confirm": "Passwort bestätigen", + "username": "Nutzername" }, "error": { "unexpected": "Unerwarteter Fehler" @@ -39,11 +39,11 @@ "mas": { "account": { "deactivated": { - "description": "Dieses Konto (%(mxid)s) wurde entfernt. Wenn du dies nicht erwartet hast, wende dich an den Server Admin", + "description": "Dieses Konto (%(mxid)s) wurde entfernt. Wenn du dies nicht erwartet hast, wende dich an den Kontoanbieter.", "heading": "Konto gelöscht" }, "locked": { - "description": "Dieses Konto (%(mxid)s) wurde gesperrt. Wenn du dies nicht erwartet hast, wende dich an den Server Admin.", + "description": "Dieses Konto (%(mxid)s) wurde gesperrt. Wenn du dies nicht erwartet hast, wende dich an den Kontoanbieter.", "heading": "Konto gesperrt" }, "logged_out": { @@ -57,7 +57,7 @@ }, "change_password": { "change": "Passwort ändern", - "confirm": "Passwort wiederholen", + "confirm": "Passwort bestätigen", "current": "Aktuelles Passwort", "heading": "Mein Passwort ändern", "new": "Neues Passwort" @@ -79,8 +79,8 @@ "security_code": "Sicherheitscode" }, "device_code_link": { - "description": "Eingeben Sie den Sicherheitscode ein, der auf Ihrem anderen Gerät angezeigt wird", - "headline": "Gib den Code ein, der auf deinem Gerät angezeigt wird.", + "description": "Gib den Sicherheitscode ein, der auf deinem anderen Gerät angezeigt wird", + "headline": "Gerät zu deinem Konto hinzufügen", "verification_code": "Bestätigungscode" }, "device_consent": { @@ -113,10 +113,10 @@ "emails": { "greeting": "Hallo %(username)s,", "recovery": { - "click_button": "Klick unten, um ein neues Passwort zu erstellen:", + "click_button": "Wähle die Schaltfläche unten, um ein neues Passwort zu erstellen:", "copy_link": "Kopier den folgenden Link und füge ihn in deinen Browser ein, um ein neues Passwort zu erstellen:", "create_new_password": "Neues Passwort erstellen", - "fallback": "Funktioniert der Button bei Ihnen nicht?", + "fallback": "Funktioniert die Schaltfläche bei dir nicht?", "headline": "Du hast das Zurücksetzen des Passworts für dein Konto bei %(server_name)s angefordert.", "subject": "Setze dein Konto Passwort zurück (%(mxid)s)", "you_can_ignore": "Wenn du kein neues Passwort angefordert hast, kannst du diese E-Mail einfach ignorieren. Dein aktuelles Passwort funktioniert weiterhin." @@ -128,7 +128,7 @@ } }, "errors": { - "captcha": "Die CAPTCHA-Überprüfung hat nicht geklappt, versuch's nochmal.", + "captcha": "Die CAPTCHA-Überprüfung ist fehlgeschlagen, bitte versuche es erneut", "denied_policy": "Abgelehnt durch Richtlinie: %(policy)s", "email_banned": "E-Mail ist durch die Serverrichtlinie gesperrt", "email_domain_banned": "Die E-Mail-Domain ist durch die Serverrichtlinie gesperrt", @@ -137,14 +137,14 @@ "field_required": "Dieses Feld ist ein Pflichtfeld", "invalid_credentials": "Ungültige Anmeldeinformationen", "password_mismatch": "Die Passwortfelder stimmen nicht überein", - "rate_limit_exceeded": "Du hast in kurzer Zeit zu viele Anfragen gestellt. Warte bitte ein paar Minuten und versuch's nochmal.", - "username_all_numeric": "Der Benutzername darf nicht nur aus Zahlen bestehen", - "username_banned": "Der Benutzername ist durch die Serverrichtlinie gesperrt", + "rate_limit_exceeded": "Du hast in kurzer Zeit zu viele Anfragen gestellt. Bitte warte ein paar Minuten und versuche es erneut.", + "username_all_numeric": "Der Nutzername darf nicht nur aus Zahlen bestehen", + "username_banned": "Der Nutzername ist durch die Serverrichtlinie gesperrt", "username_invalid_chars": "Der Nutzername enthält ungültige Zeichen. Verwende nur Kleinbuchstaben, Zahlen, Bindestriche und Unterstriche.", - "username_not_allowed": "Der Benutzername ist gemäß der Serverrichtlinie nicht zulässig", - "username_taken": "Dieser Benutzername ist bereits vergeben", - "username_too_long": "Der Benutzername ist zu lang", - "username_too_short": "Der Benutzername ist zu kurz" + "username_not_allowed": "Der Nutzername ist gemäß der Serverrichtlinie nicht zulässig", + "username_taken": "Dieser Nutzername ist bereits vergeben", + "username_too_long": "Der Nutzername ist zu lang", + "username_too_short": "Der Nutzername ist zu kurz" }, "legacy_consent": { "this_will_setup": "Dadurch wird %(client_name)s mit deinem %(server_name)s Konto eingerichtet." @@ -160,7 +160,7 @@ "headline": "Melde dich zum Verbinden an" }, "no_login_methods": "Keine Anmeldemethoden verfügbar.", - "username_or_email": "Benutzername oder E-Mail-Adresse" + "username_or_email": "Nutzername oder E-Mail-Adresse" }, "navbar": { "my_account": "Mein Konto", @@ -168,13 +168,13 @@ "signed_in_as": "Angemeldet als %(username)s." }, "not_found": { - "description": "Die Seite, die du gesucht hast, gibt's nicht oder wurde verschoben.", + "description": "Die Seite, die du gesucht hast, existiert nicht oder wurde verschoben", "heading": "Seite nicht gefunden" }, "not_you": "Nicht %(username)s?", "or_separator": "Oder", "policy_violation": { - "description": "Dies kann am Client liegen, der die Anfrage erstellt hat, am aktuell angemeldeten Benutzer oder an der Anfrage selbst.", + "description": "Dies kann an der Anwendung liegen, die die Anfrage erstellt hat, am aktuell angemeldeten Nutzer oder an der Anfrage selbst.", "heading": "Die Autorisierungsanfrage wurde durch eine Richtlinie dieses Dienstes abgelehnt", "logged_as": "Eingeloggt als %(username)s", "too_many_sessions": { @@ -185,7 +185,7 @@ }, "recovery": { "consumed": { - "description": "Um ein neues Passwort zu erstellen, fang einfach von vorne an und wähle „Passwort vergessen”.", + "description": "Um ein neues Passwort zu erstellen, beginne neu und wähle „Passwort vergessen“.", "heading": "Der Link zum Zurücksetzen deines Passworts wurde bereits verwendet" }, "disabled": { @@ -205,7 +205,7 @@ "save_and_continue": "Speichern und fortfahren" }, "progress": { - "change_email": "Probier's mal mit einer anderen E-Mail-Adresse", + "change_email": "Andere E-Mail-Adresse versuchen", "description": "Eine E-Mail mit einem Link zum Zurücksetzen deines Passworts wurde versendet, wenn es ein Konto mit %(email)s gibt.", "heading": "Überprüfe deine E-Mails!", "resend_email": "E-Mail erneut senden" @@ -223,17 +223,17 @@ "description": "Wähle einen Nutzernamen, um fortzufahren.", "heading": "Konto erstellen" }, - "terms_of_service": "Ich stimme den Allgemeinen Geschäftsbedingungen zu." + "terms_of_service": "Ich stimme den Allgemeinen Geschäftsbedingungen zu" }, "registration_token": { - "description": "Gib das Registrierungstoken ein, das du vom Homeserver-Admin bekommen hast.", + "description": "Gib ein Registrierungstoken ein, das du von deinem Kontoanbieter erhalten hast.", "field": "Registrierungstoken", "headline": "Registrierungstoken" }, "scope": { "edit_profile": "Bearbeite dein Profil und deine Kontaktdaten", "manage_sessions": "Verwalte deine Geräte und Sitzungen", - "mas_admin": "Beliebige Benutzer verwalten (urn:mas:admin)", + "mas_admin": "Beliebige Nutzer verwalten (urn:mas:admin)", "send_messages": "Neue Nachrichten in deinem Namen senden", "synapse_admin": "Den Synapse-Homeserver verwalten (urn:synapse:admin:*)", "view_messages": "Zeig deine vorhandenen Nachrichten und Daten an", @@ -252,7 +252,7 @@ "enforced_by_policy": "Erzwungen durch Server-Richtlinie", "forced_display_name": "Verwendet den folgenden Anzeigenamen", "forced_email": "Verwendet die folgende E-Mail-Adresse", - "forced_localpart": "Verwendet den folgenden Benutzernamen", + "forced_localpart": "Verwendet den folgenden Nutzernamen", "import_data": { "description": "Bestätige die Informationen, die mit dem neuen %(server_name)s Konto verknüpft werden.", "heading": "Deine Daten importieren" @@ -262,7 +262,7 @@ "link_existing": "Mit einem bestehenden Konto verknüpfen", "provider_name": "%(human_name)s Konto", "signup_with_upstream": { - "heading": "Setze die Anmeldung mit %(human_name)s Konto fort." + "heading": "Setze die Anmeldung mit %(human_name)s Konto fort" }, "suggested_display_name": "Anzeigenamen importieren", "suggested_email": "E-Mail-Adresse importieren", diff --git a/translations/fr.json b/translations/fr.json index af95ed90f..281c8f7ef 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -79,8 +79,8 @@ "security_code": "Code de sécurité" }, "device_code_link": { - "description": "Associer un appareil", - "headline": "Entrez le code affiché sur votre appareil", + "description": "Saisissez le code de sécurité affiché sur votre autre appareil", + "headline": "Associer un nouvel appareil à votre compte", "verification_code": "Code de vérification" }, "device_consent": { diff --git a/translations/pl.json b/translations/pl.json index 4964b924b..f46a12dc7 100644 --- a/translations/pl.json +++ b/translations/pl.json @@ -39,11 +39,11 @@ "mas": { "account": { "deactivated": { - "description": "To konto (%(mxid)s) zostało usunięte. Jeśli jest to nieoczekiwane, skontaktuj się z administratorem serwera.", + "description": "To konto (%(mxid)s) zostało usunięte. Jeśli jest to nieoczekiwane, skontaktuj się z dostawcą konta.", "heading": "Konto usunięte" }, "locked": { - "description": "To konto (%(mxid)s) zostało zablokowane. Jeśli jest to nieoczekiwane, skontaktuj się z administratorem serwera.", + "description": "To konto (%(mxid)s) zostało zablokowane. Jeśli jest to nieoczekiwane, skontaktuj się z dostawcą konta.", "heading": "Konto zablokowane" }, "logged_out": { @@ -226,7 +226,7 @@ "terms_of_service": "Wyrażam zgodę na warunki korzystania z serwisu" }, "registration_token": { - "description": "Wprowadź token rejestracyjny dostarczony przez administratora serwera domowego.", + "description": "Wprowadź token rejestracyjny dostarczony przez dostawcę Twojego konta.", "field": "Token rejestracyjny", "headline": "Token rejestracyjny" }, @@ -234,10 +234,10 @@ "edit_profile": "Edytuj swój profil i dane kontaktowe", "manage_sessions": "Zarządzaj swoimi urządzeniami i sesjami", "mas_admin": "Zarządzaj użytkownikami (urn:mas:admin)", - "send_messages": "Wysyłaj nowe wiadomości w Twoim imieniu", + "send_messages": "Wysyłanie nowych wiadomości w Twoim imieniu", "synapse_admin": "Administrowanie serwerem (urn:synapse:admin:*)", - "view_messages": "Przegląd istniejących wiadomości i danych", - "view_profile": "Przegląd informacji o profilu i danych kontaktowych" + "view_messages": "Przeglądanie istniejących wiadomości i danych", + "view_profile": "Przeglądanie informacji profilowych i danych kontaktowych" }, "upstream_oauth2": { "link_mismatch": { diff --git a/translations/tr.json b/translations/tr.json new file mode 100644 index 000000000..02e1ef9b3 --- /dev/null +++ b/translations/tr.json @@ -0,0 +1,277 @@ +{ + "action": { + "back": "Geri", + "cancel": "İptal", + "continue": "Devam Et", + "create_account": "Hesap Oluştur", + "sign_in": "Giriş Yap", + "sign_out": "Çıkış Yap", + "skip": "Atla", + "start_over": "Baştan başla" + }, + "app": { + "human_name": "Matrix Authentication Service", + "name": "matrix-authentication-service", + "technical_description": "OpenID Connect keşif belgesi: %(discovery_url)s" + }, + "branding": { + "privacy_policy": { + "alt": "Hizmet gizlilik politikasına bağlantı", + "link": "Gizlilik Politikası" + }, + "terms_and_conditions": { + "alt": "Hizmet şartları ve koşullarına bağlantı", + "link": "Şartlar & Koşullar" + } + }, + "common": { + "email_address": "E-posta Adresi", + "loading": "Yükleniyor…", + "mxid": "Matrix Kimliği", + "password": "Şifre", + "password_confirm": "Şifreyi onayla", + "username": "Kullanıcı Adı" + }, + "error": { + "unexpected": "Beklenmeyen hata" + }, + "mas": { + "account": { + "deactivated": { + "description": "Bu hesap (%(mxid)s) silindi. Beklenmedik bir durumsa, sunucu yöneticinizle iletişime geçin.", + "heading": "Hesap silindi" + }, + "locked": { + "description": "Bu hesap (%(mxid)s) kilitlendi. Bu beklenmedik bir durumsa, sunucu yöneticinizle iletişime geçin.", + "heading": "Hesap kilitlendi" + }, + "logged_out": { + "description": "Bu oturum sonlandırılmıştır. Tekrar giriş yapabilmek için lütfen oturumu kapatın.", + "heading": "Oturum sonlandırıldı" + } + }, + "back_to_homepage": "Ana sayfaya geri dön", + "captcha": { + "noscript": "Bu form bir CAPTCHA ile korunmaktadır ve gönderilebilmesi için JavaScript'in etkinleştirilmesi gerekmektedir. Lütfen tarayıcınızda JavaScript'i etkinleştirin ve bu sayfayı yeniden yükleyin." + }, + "change_password": { + "change": "Parola değiştir", + "confirm": "Şifreyi onayla", + "current": "Mevcut parola", + "heading": "Parolamı değiştir", + "new": "Yeni parola" + }, + "choose_display_name": { + "description": "Bu, diğer kişilerin göreceği isimdir. Bunu istediğiniz zaman değiştirebilirsiniz.", + "headline": "Görüntülenecek adınızı seçin" + }, + "consent": { + "continue_to": "%(client_name)s devam edilsin mi?", + "scope_list_preface": "Devam ederek, %(client_name)s'in şunları yapmasına izin vermiş oluyorsunuz:", + "this_will_setup": "Bu işlem, %(client_name)s (%(client_uri)s) cihazını %(server_name)s hesabınızla eşleştirecektir.", + "use_another_account": "Başka bir hesap kullanın" + }, + "device_card": { + "access_requested": "Erişim talebi", + "generic_device": "Cihaz", + "ip_address": "IP Adresi", + "security_code": "Güvenlik kodu" + }, + "device_code_link": { + "description": "Diğer cihazınızda gösterilen güvenlik kodunu girin", + "headline": "Hesabınıza yeni bir cihaz bağlayın", + "verification_code": "Doğrulama kodu" + }, + "device_consent": { + "confirm_device": "Evet, bunun benim cihazım olduğunu ve oturum açmak istediğimi onaylıyorum.", + "denied": { + "description": "%(client_name)s'e erişimi reddettiniz. Bu pencereyi kapatabilirsiniz.", + "heading": "Erişim engellendi" + }, + "description": " Başka bir cihaz olan , %(client_name)s (, %(client_uri)s, ) cihazını , %(server_name)s, hesabınızla bağlantı istiyor. Bu cihazı tanıdığınızdan emin olun.", + "grant_access": "Erişim izni ver", + "granted": { + "description": "%(client_name)s kullanıcısına erişim izni verdiniz. Bu pencereyi kapatabilirsiniz.", + "heading": "Erişim izni verildi" + }, + "title": "Hesabınıza erişim izni verecek misiniz?", + "warning": { + "description": "Bu cihazın gerçekten sizin cihazınız olduğundan emin misiniz? Yöneticiler veya BT destek ekibi sizden bunu kabul etmenizi asla istemez.", + "title": "Hesabınıza uzaktan erişim sağlayan bir cihaza erişim izni vermek üzeresiniz" + } + }, + "device_display_name": { + "client_on_device": "%(client_name)s, %(device_name)s üzerinde", + "name_for_platform": "%(name)s / %(platform)s", + "unknown_device": "Bilinmeyen cihaz" + }, + "email_in_use": { + "description": "Hesap bilgilerinizi unuttuysanız, hesabınızı kurtarabilirsiniz. Ayrıca sıfırdan başlayıp farklı bir e-posta adresi de kullanabilirsiniz.", + "title": "%(email)s e-posta adresi zaten kullanımda." + }, + "emails": { + "greeting": "Merhaba %(username)s,", + "recovery": { + "click_button": "Yeni bir parola oluşturmak için aşağıdaki düğmeye tıklayın:", + "copy_link": "Yeni bir parola oluşturmak için aşağıdaki bağlantıyı kopyalayıp tarayıcınıza yapıştırın:", + "create_new_password": "Yeni parola oluştur", + "fallback": "Buton sizde çalışmıyor mu?", + "headline": "%(server_name)s hesabınız için parola sıfırlama talebinde bulundunuz.", + "subject": "Hesap parolanızı sıfırlayın (%(mxid)s)", + "you_can_ignore": "Yeni bir parola talep etmediyseniz, bu e-postayı dikkate almayın. Mevcut parolanız çalışmaya devam edecektir." + }, + "verify": { + "body_html": "Bu e-posta adresini doğrulamak için gereken doğrulama kodunuz: %(code)s", + "body_text": "Bu e-posta adresini doğrulamak için gereken doğrulama kodunuz: %(code)s", + "subject": "E-posta doğrulama kodunuz: %(code)s" + } + }, + "errors": { + "captcha": "CAPTCHA doğrulaması başarısız oldu, lütfen tekrar deneyin", + "denied_policy": "Politika gereği reddedildi: %(policy)s", + "email_banned": "Sunucu politikası gereği e-posta kullanımı yasaktır.", + "email_domain_banned": "E-posta etki alanı, sunucu politikası tarafından yasaklandı", + "email_domain_not_allowed": "E-posta alan adı sunucu politikası tarafından izin verilmiyor", + "email_not_allowed": "Sunucu politikası gereği e-posta gönderimine izin verilmiyor", + "field_required": "Bu alan zorunludur", + "invalid_credentials": "Geçersiz kimlik bilgileri", + "password_mismatch": "Parola alanları birbiriyle uyuşmuyor", + "rate_limit_exceeded": "Kısa süre içinde çok fazla istekte bulundunuz. Lütfen birkaç dakika bekleyin ve tekrar deneyin.", + "username_all_numeric": "Kullanıcı adı yalnızca rakamlardan oluşamaz", + "username_banned": "Kullanıcı adı sunucu politikası gereği yasaklanmıştır", + "username_invalid_chars": "Kullanıcı adı geçersiz karakterler içeriyor. Yalnızca küçük harfler, rakamlar, tire ve alt çizgi kullanın.", + "username_not_allowed": "Kullanıcı adı sunucu politikası gereği izin verilmiyor", + "username_taken": "Bu kullanıcı adı zaten alınmış", + "username_too_long": "Kullanıcı adı çok uzun", + "username_too_short": "Kullanıcı adı çok kısa" + }, + "legacy_consent": { + "this_will_setup": "Bu işlem, %(client_name)s cihazını %(server_name)s hesabınızla eşleştirecektir." + }, + "login": { + "call_to_register": "Henüz hesabınız yok mu?", + "continue_with_provider": "%(provider)s ile devam edin", + "description": "Devam etmek için lütfen giriş yapın:", + "forgot_password": "Parolanızı mı unuttunuz?", + "headline": "Giriş Yap", + "link": { + "description": "%(provider)s hesabınızı bağlama", + "headline": "Bağlantıya erişmek için giriş yapın" + }, + "no_login_methods": "Kullanılabilir giriş yöntemi yok.", + "username_or_email": "Kullanıcı adı veya E-posta" + }, + "navbar": { + "my_account": "Hesabım", + "register": "Hesap oluştur", + "signed_in_as": "%(username)s olarak giriş yapıldı." + }, + "not_found": { + "description": "Aradığınız sayfa mevcut değil veya taşınmış", + "heading": "Sayfa bulunamadı" + }, + "not_you": "%(username)s değil mi?", + "policy_violation": { + "description": "Bu durum, isteği oluşturan istemci, şu anda oturum açmış olan kullanıcı veya isteğin kendisinden kaynaklanıyor olabilir.", + "heading": "Yetkilendirme isteği, bu hizmet tarafından uygulanan politika nedeniyle reddedildi", + "logged_as": "%(username)s olarak kaydedildi.", + "too_many_sessions": { + "description": "Hesabınız maksimum sayıda cihazda oturum açmış durumda. Devam etmek için, mevcut cihazlarınızdan %(num_devices_to_remove)s kaldırın ve tekrar oturum açın.", + "heading": "Cihaz limitine ulaşıldı", + "manage_devices": "Cihazları yönetin" + } + }, + "recovery": { + "consumed": { + "description": "Yeni bir parola oluşturmak için baştan başlayın ve \"Parolamı unuttum\" seçeneğini seçin.", + "heading": "Parolanızı sıfırlamak için kullanılan bağlantı daha önce kullanıldı" + }, + "disabled": { + "description": "Giriş bilgilerinizi kaybettiyseniz, hesabınızı kurtarmak için lütfen yöneticiyle iletişime geçin.", + "heading": "Hesap kurtarma devre dışı bırakıldı." + }, + "expired": { + "description": "Aşağıdaki adreslere gönderilecek yeni bir e-posta isteği gönderin: %(email)s.", + "heading": "Parolanızı sıfırlama bağlantısının süresi doldu" + }, + "finish": { + "confirm": "Yeni parolayı tekrar girin.", + "description": "Hesabınız için yeni bir parola belirleyin.", + "heading": "Parolanızı sıfırlayın", + "new": "Yeni parola", + "save_and_continue": "Kaydet ve devam et" + }, + "progress": { + "change_email": "Farklı bir e-posta adresi deneyin", + "description": "%(email)s kullanan bir hesabınız varsa, parolanızı sıfırlamak için bağlantı içeren bir e-posta gönderdik.", + "heading": "E-postalarınızı kontrol edin" + }, + "start": { + "description": "Parolanızı sıfırlamak için bağlantı içeren bir e-posta gönderilecektir.", + "heading": "Devam etmek için e-postanızı girin." + } + }, + "register": { + "call_to_login": "Zaten hesabınız var mı?", + "continue_with_email": "E-posta adresiyle devam edin", + "continue_with_password": "Parolayla devam et", + "create_account": { + "description": "Devam etmek için bir kullanıcı adı seçin.", + "heading": "Hesap oluştur" + }, + "terms_of_service": " Şartları ve Koşulları kabul ediyorum" + }, + "registration_token": { + "description": "Ana sunucu yöneticisi tarafından sağlanan bir kayıt belirteci girin.", + "field": "Kayıt anahtarı", + "headline": "Kayıt anahtarı" + }, + "scope": { + "edit_profile": "Profilinizi ve iletişim bilgilerinizi düzenleyin", + "manage_sessions": "Cihazlarınızı ve oturumlarınızı yönetin", + "mas_admin": "Kullanıcıları yönet (urn:mas:admin)", + "send_messages": "Sizin adınıza mesaj gönderin", + "synapse_admin": "Sunucuyu yönetin (urn:synapse:admin:*)", + "view_messages": "Mevcut mesajları ve verilerinizi görüntüleyinmessages", + "view_profile": "Profil bilgilerinizi ve iletişim bilgilerinizi görüntüleyin" + }, + "upstream_oauth2": { + "link_mismatch": { + "heading": "Bu üst hesap zaten başka bir hesaba bağlı." + }, + "register": { + "choose_username": { + "description": "Bu daha sonra değiştirilemez." + }, + "create_account": "Yeni hesap oluşturun", + "enforced_by_policy": "Sunucu politikası tarafından uygulanır", + "forced_display_name": "Aşağıdaki görünen adı kullanacağız", + "forced_email": "Aşağıdaki e-posta adresini kullanacağım", + "forced_localpart": "Aşağıdaki kullanıcı adını kullanacağım", + "import_data": { + "description": "Yeni %(server_name)s hesabınızla ilişkilendirilecek bilgileri onaylayın.", + "heading": "Verilerinizi içe aktarın" + }, + "imported_from_upstream": "Ana hesabınızdan içe aktarıldı", + "imported_from_upstream_with_name": "%(human_name)s hesabınızdan içe aktarıldı", + "link_existing": "Mevcut bir hesaba bağlantı", + "provider_name": "%(human_name)s hesabı", + "signup_with_upstream": { + "heading": "%(human_name)s hesabınızla kaydolmaya devam edin" + }, + "suggested_display_name": "İçe aktarılan görünen ad", + "suggested_email": "E-posta adresini içe aktar", + "use": "Kullan" + }, + "suggest_link": { + "action": "Bağlantı", + "heading": "Mevcut hesabınıza bağlanın" + } + }, + "verify_email": { + "6_digit_code": "6 haneli kod", + "description": "Gönderilen 6 haneli kodu girin: %(email)s", + "headline": "E-postanızı doğrulayın" + } + } +} \ No newline at end of file diff --git a/translations/uk.json b/translations/uk.json index d347b16e1..aba940519 100644 --- a/translations/uk.json +++ b/translations/uk.json @@ -39,11 +39,11 @@ "mas": { "account": { "deactivated": { - "description": "Цей обліковий запис (%(mxid)s) видалено. Якщо цього не передбачалося, зверніться до адміністратора сервера.", + "description": "Цей обліковий запис (%(mxid)s) видалено. Якщо цього не передбачалося, зверніться до постачальника вашого облікового запису.", "heading": "Обліковий запис видалено" }, "locked": { - "description": "Цей обліковий запис (%(mxid)s) заблоковано. Якщо цього не передбачалося, зверніться до адміністратора сервера.", + "description": "Цей обліковий запис (%(mxid)s) заблоковано. Якщо цього не передбачалося, зверніться до постачальника вашого облікового запису.", "heading": "Обліковий запис заблоковано" }, "logged_out": { @@ -226,7 +226,7 @@ "terms_of_service": "Я погоджуюся з Умовами та положеннями" }, "registration_token": { - "description": "Введіть реєстраційний токен, наданий адміністратором домашнього сервера.", + "description": "Введіть реєстраційний токен, наданий постачальником вашого облікового запису.", "field": "Токен реєстрації", "headline": "Токен реєстрації" }, diff --git a/translations/uz.json b/translations/uz.json index e18523f0a..2cf006025 100644 --- a/translations/uz.json +++ b/translations/uz.json @@ -5,7 +5,9 @@ "continue": "Davom etish", "create_account": "Ro'yxatdan o'tish", "sign_in": "Kirish", - "sign_out": "Chiqish" + "sign_out": "Chiqish", + "skip": "Oʻtkazib yuborish", + "start_over": "Qaytadan boshlang" }, "app": { "human_name": "Matrix Authentication Service", @@ -35,6 +37,20 @@ "unexpected": "Kutilmagan xato" }, "mas": { + "account": { + "deactivated": { + "description": "Ushbu hisob (%(mxid)s) oʻchirildi. Agar bu kutilmasa, server administratoringiz bilan bogʻlaning.", + "heading": "Hisob oʻchirildi" + }, + "locked": { + "description": "Ushbu hisob (%(mxid)s) qulflangan. Agar bu kutilmasa, server administratoringizga murojaat qiling.", + "heading": "Hisob qulflangan" + }, + "logged_out": { + "description": "Bu sessiya tugatildi. Qayta kirish uchun tizimdan chiqing", + "heading": "Sessiya tugadi" + } + }, "back_to_homepage": "Bosh sahifaga qaytish", "captcha": { "noscript": "Bu shakl CAPTCHA bilan himoyalangan va uni yuborish uchun JavaScript yoqilishi kerak. Brauzeringizda JavaScript’ni yoqing va bu sahifani qayta yuklang." @@ -46,30 +62,65 @@ "heading": "Parolni o‘zgartirish", "new": "Yangi parol" }, + "choose_display_name": { + "description": "Bu boshqa odamlar koʻradigan nom. Buni istalgan vaqtda oʻzgartirishingiz mumkin.", + "headline": "Koʻrsatiladigan nomingizni tanlang" + }, + "consent": { + "continue_to": "%(client_name)s ga oʻtishni xohlaysizmi?", + "scope_list_preface": "Davom etish orqali siz %(client_name)s ga quyidagilarga ruxsat berasiz:", + "this_will_setup": "Bu sizning %(server_name)s hisobingiz bilan %(client_name)s (%(client_uri)s) ni oʻrnatadi.", + "use_another_account": "Boshqa hisobdan foydalaning" + }, "device_card": { "access_requested": "Ruxsat so‘raldi", "generic_device": "Qurilma", - "ip_address": "IP manzili" + "ip_address": "IP manzili", + "security_code": "Xavfsizlik kodi" }, "device_code_link": { - "description": "Qurilmani ulang", - "headline": "Qurilmangizda chiqqan kodni kiriting" + "description": "Boshqa qurilmangizda koʻrsatilgan xavfsizlik kodini kiriting", + "headline": "Qurilmangizda chiqqan kodni kiriting", + "verification_code": "Tasdiqlash kodi" }, "device_consent": { + "confirm_device": "Ha, men bu mening qurilmam ekanligini tasdiqlayman va unga kirishni xohlayman.", "denied": { "description": "Siz %(client_name)s uchun ruxsatni rad etdingiz. Bu oynani yopishingiz mumkin.", "heading": "Ruxsat berilmadi" }, + "description": "Boshqa qurilma %(client_name)s (%(client_uri)s) ni sizning %(server_name)s hisobingiz bilan bogʻlamoqchi. Ushbu qurilmani tanib olganingizga ishonch hosil qiling.", + "grant_access": "Kirishga ruxsat berish", "granted": { "description": "Siz %(client_name)s uchun ruxsat berdingiz. Bu oynani yopishingiz mumkin.", "heading": "Ruxsat berildi" + }, + "title": "Hisobingizga kirish huquqi berilsinmi?", + "warning": { + "description": "Bu sizning qurilmangiz ekanligiga aminmisiz? Administratorlar yoki IT qoʻllab-quvvatlash xizmati sizdan buni qabul qilishingizni hech qachon soʻramaydi.", + "title": "Siz hisobingizga masofaviy qurilmaga kirish huquqini bermoqchisiz" } }, "device_display_name": { + "client_on_device": "%(client_name)s ustida %(device_name)s", + "name_for_platform": "%(platform)s uchun %(name)s", "unknown_device": "Noma’lum qurilma." }, + "email_in_use": { + "description": "Agar hisob qaydnomangiz maʻlumotlarini unutgan boʻlsangiz, hisobingizni tiklashingiz mumkin. Shuningdek, qayta boshlashingiz va boshqa elektron pochta manzilidan foydalanishingiz mumkin.", + "title": "%(email)s elektron pochta manzili allaqachon ishlatilmoqda" + }, "emails": { "greeting": "Salom %(username)s ,", + "recovery": { + "click_button": "Yangi parol yaratish uchun quyidagi tugmani bosing:", + "copy_link": "Yangi parol yaratish uchun quyidagi havolani nusxalang va brauzerga joylashtiring:", + "create_new_password": "Yangi parol yarating", + "fallback": "Tugma siz uchun ishlamayaptimi?", + "headline": "Siz %(server_name)s hisobingiz uchun parolni qayta tiklashni soʻradingiz.", + "subject": "Hisob parolingizni qayta oʻrnating (%(mxid)s)", + "you_can_ignore": "Agar siz yangi parol soʻramagan boʻlsangiz, ushbu elektron pochta xabarini eʻtiborsiz qoldirishingiz mumkin. Joriy parolingiz ishlashda davom etadi." + }, "verify": { "body_html": "Ushbu elektron pochta manzilini tasdiqlash uchun tasdiqlash kodingiz: %(code)s", "body_text": "Ushbu elektron pochta manzilini tasdiqlash uchun tasdiqlash kodingiz: %(code)s", @@ -79,21 +130,37 @@ "errors": { "captcha": "CAPTCHA tekshiruvi amalga oshmadi, qayta urining", "denied_policy": "Siyosat tomonidan rad etilgan: %(policy)s", + "email_banned": "Elektron pochta server siyosati tomonidan taqiqlangan", + "email_domain_banned": "Elektron pochta domeni server siyosati tomonidan taqiqlangan", + "email_domain_not_allowed": "Elektron pochta domeni server siyosati tomonidan ruxsat etilmagan", + "email_not_allowed": "Server siyosati elektron pochtaga ruxsat bermagan", "field_required": "Ushbu qator toʻldirilishi shart", "invalid_credentials": "Hisob ma’lumotlari yaroqsiz", "password_mismatch": "Parol maydonlari mos kelmayapti", - "username_taken": "Bu foydalanuvchi nomi allaqachon band" + "rate_limit_exceeded": "Qisqa vaqt ichida juda koʻp soʻrov yubordingiz. Iltimos, bir necha daqiqa kuting va qayta urinib koʻring.", + "username_all_numeric": "Foydalanuvchi nomi faqat raqamlardan iborat boʻlmasligi kerak", + "username_banned": "Foydalanuvchi nomi server siyosati tomonidan taqiqlangan", + "username_invalid_chars": "Foydalanuvchi nomida yaroqsiz belgilar mavjud. Faqat kichik harflar, raqamlar, tire va pastki chiziqlardan foydalaning.", + "username_not_allowed": "Foydalanuvchi nomi server siyosati tomonidan ruxsat etilmagan", + "username_taken": "Bu foydalanuvchi nomi allaqachon band", + "username_too_long": "Foydalanuvchi nomi juda uzun", + "username_too_short": "Foydalanuvchi nomi juda qisqa" + }, + "legacy_consent": { + "this_will_setup": "Bu sizning %(server_name)s hisobingiz bilan %(client_name)s ni oʻrnatadi." }, "login": { "call_to_register": "Hali hisobingiz yo‘qmi?", "continue_with_provider": "%(provider)s bilan davom etish", "description": "Davom etish uchun tizimga kiring:", + "forgot_password": "Parolni unutdingizmi?", "headline": "Kirish", "link": { "description": "%(provider)s hisobingiz ulanmoqda", "headline": "Havola uchun tizimga kiring" }, - "no_login_methods": "Kirish usullari mavjud emas." + "no_login_methods": "Kirish usullari mavjud emas.", + "username_or_email": "Foydalanuvchi nomi yoki elektron pochta manzili" }, "navbar": { "my_account": "Mening hisobim", @@ -109,28 +176,60 @@ "policy_violation": { "description": "Bu so‘rovni yaratgan mijoz, hozirda tizimga kirgan foydalanuvchi yoki so‘rovning o‘zi bilan bog‘liq bo‘lishi mumkin.", "heading": "Avtorizatsiya so‘rovi ushbu xizmatda amalda bo‘lgan siyosat tufayli rad etildi.", - "logged_as": "%(username)s sifatida kirildi" + "logged_as": "%(username)s sifatida kirildi", + "too_many_sessions": { + "description": "Hisobingiz allaqachon maksimal miqdordagi qurilmalarda tizimga kirgan. Davom etish uchun mavjud qurilmalaringizdan %(num_devices_to_remove)s ni olib tashlang va qaytadan kiring.", + "heading": "Qurilma limitiga yetdi", + "manage_devices": "Qurilmalarni boshqarish" + } }, "recovery": { + "consumed": { + "description": "Yangi parol yaratish uchun boshidan boshlang va ʼʼParolni unutdingizmi“ ni tanlang.", + "heading": "Parolingizni tiklash havolasi allaqachon ishlatilgan" + }, + "disabled": { + "description": "Agar hisob maʻlumotlaringizni yoʻqotib qoʻysangiz, hisobingizni tiklash uchun administrator bilan bogʻlaning.", + "heading": "Hisobni tiklash oʻchirib qoʻyilgan" + }, "expired": { + "description": "Quyidagi manzilga yuboriladigan yangi elektron pochta xabarini soʻrang: %(email)s.", + "heading": "Parolingizni tiklash havolasi muddati tugagan", "resend_email": "Elektron pochtani qayta yuborish" }, "finish": { + "confirm": "Yangi parolni qayta kiriting", "description": "Hisobingiz uchun yangi parol tanlang.", - "new": "Yangi parol" + "heading": "Parolingizni qayta tiklash", + "new": "Yangi parol", + "save_and_continue": "Saqlash va davom ettirish" }, "progress": { + "change_email": "Boshqa elektron pochta manzilini sinab koʻring", + "description": "Agar %(email)s dan foydalanadigan hisob mavjud boʻlsa, parolingizni tiklash uchun havola bilan elektron pochta xabarini yubordik.", + "heading": "Elektron pochtangizni tekshiring", "resend_email": "Elektron pochtani qayta yuborish" + }, + "start": { + "description": "Parolingizni tiklash uchun havola bilan elektron pochta xabari yuboriladi.", + "heading": "Davom etish uchun elektron pochta manzilingizni kiriting" } }, "register": { "call_to_login": "Hisobingiz allaqachon bormi?", + "continue_with_email": "Elektron pochta manzili bilan davom eting", + "continue_with_password": "Parol bilan davom eting", "create_account": { "description": "Davom etish uchun foydalanuvchi nomini tanlang.", "heading": "Hisob yaratish" }, "terms_of_service": "Men roziman Foydalanish shartlari" }, + "registration_token": { + "description": "Homeserver administratori tomonidan taqdim etilgan roʻyxatdan oʻtish tokenini kiriting.", + "field": "Roʻyxatdan oʻtish tokeni", + "headline": "Roʻyxatdan oʻtish tokeni" + }, "scope": { "edit_profile": "Profilingiz va aloqa maʼlumotlaringizni tahrirlang", "manage_sessions": "Qurilmalaringiz va sessiyalaringizni boshqaring", @@ -159,7 +258,12 @@ "heading": "Ma’lumotlaringizni import qiling" }, "imported_from_upstream": "Yuqori darajadagi hisobingizdan import qilindi", + "imported_from_upstream_with_name": "%(human_name)s hisobingizdan import qilindi", "link_existing": "Mavjud hisobga havola", + "provider_name": "%(human_name)s hisobi", + "signup_with_upstream": { + "heading": "%(human_name)s hisobingiz bilan roʻyxatdan oʻtishda davom eting" + }, "suggested_display_name": "Ko‘rsatish nomini import qilish", "suggested_email": "Elektron pochta manzilini import qilish", "use": "Foydalanish" diff --git a/translations/zh-Hans.json b/translations/zh-Hans.json index c5b34bd3d..4f68ea2b4 100644 --- a/translations/zh-Hans.json +++ b/translations/zh-Hans.json @@ -79,7 +79,7 @@ "security_code": "安全代码" }, "device_code_link": { - "description": "关联设备", + "description": "输入你另一设备上显示的安全代码", "headline": "关联新设备到账户", "verification_code": "验证码" }, From 04f92810ee347bb3e09e4f6f4d188175950215c1 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 25 Aug 2026 14:11:43 -0500 Subject: [PATCH 19/37] Remove outdated translations See https://github.com/element-hq/matrix-authentication-service/pull/5933#discussion_r3856142806 Removed as that is what https://github.com/element-hq/matrix-authentication-service/pull/5602 did for other languages. --- translations/tr.json | 3 +-- translations/uz.json | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/translations/tr.json b/translations/tr.json index 02e1ef9b3..93603957e 100644 --- a/translations/tr.json +++ b/translations/tr.json @@ -88,7 +88,6 @@ "description": "%(client_name)s'e erişimi reddettiniz. Bu pencereyi kapatabilirsiniz.", "heading": "Erişim engellendi" }, - "description": " Başka bir cihaz olan , %(client_name)s (, %(client_uri)s, ) cihazını , %(server_name)s, hesabınızla bağlantı istiyor. Bu cihazı tanıdığınızdan emin olun.", "grant_access": "Erişim izni ver", "granted": { "description": "%(client_name)s kullanıcısına erişim izni verdiniz. Bu pencereyi kapatabilirsiniz.", @@ -274,4 +273,4 @@ "headline": "E-postanızı doğrulayın" } } -} \ No newline at end of file +} diff --git a/translations/uz.json b/translations/uz.json index 2cf006025..47522d04c 100644 --- a/translations/uz.json +++ b/translations/uz.json @@ -89,7 +89,6 @@ "description": "Siz %(client_name)s uchun ruxsatni rad etdingiz. Bu oynani yopishingiz mumkin.", "heading": "Ruxsat berilmadi" }, - "description": "Boshqa qurilma %(client_name)s (%(client_uri)s) ni sizning %(server_name)s hisobingiz bilan bogʻlamoqchi. Ushbu qurilmani tanib olganingizga ishonch hosil qiling.", "grant_access": "Kirishga ruxsat berish", "granted": { "description": "Siz %(client_name)s uchun ruxsat berdingiz. Bu oynani yopishingiz mumkin.", @@ -279,4 +278,4 @@ "headline": "Elektron pochtangizni tasdiqlang" } } -} \ No newline at end of file +} From d0e299918f6402e6b394f3185569eaf2c804bb42 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 25 Aug 2026 19:35:11 +0000 Subject: [PATCH 20/37] 1.24.0-rc.0 --- Cargo.lock | 56 +++++++++++++++++++++++++------------------------- Cargo.toml | 60 +++++++++++++++++++++++++++--------------------------- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 808440bb5..d56735998 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3198,7 +3198,7 @@ dependencies = [ [[package]] name = "mas-axum-utils" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "anyhow", "axum", @@ -3233,7 +3233,7 @@ dependencies = [ [[package]] name = "mas-cli" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "anyhow", "axum", @@ -3308,7 +3308,7 @@ dependencies = [ [[package]] name = "mas-config" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "anyhow", "camino", @@ -3339,7 +3339,7 @@ dependencies = [ [[package]] name = "mas-context" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "console", "opentelemetry", @@ -3356,7 +3356,7 @@ dependencies = [ [[package]] name = "mas-data-model" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "base64ct", "chrono", @@ -3378,7 +3378,7 @@ dependencies = [ [[package]] name = "mas-email" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "async-trait", "lettre", @@ -3389,7 +3389,7 @@ dependencies = [ [[package]] name = "mas-handlers" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "aide", "anyhow", @@ -3472,7 +3472,7 @@ dependencies = [ [[package]] name = "mas-http" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "futures-util", "headers", @@ -3492,7 +3492,7 @@ dependencies = [ [[package]] name = "mas-i18n" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "camino", "icu_datetime", @@ -3512,7 +3512,7 @@ dependencies = [ [[package]] name = "mas-i18n-scan" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "camino", "clap", @@ -3526,7 +3526,7 @@ dependencies = [ [[package]] name = "mas-iana" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "schemars 1.2.1", "serde", @@ -3534,7 +3534,7 @@ dependencies = [ [[package]] name = "mas-iana-codegen" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "anyhow", "async-trait", @@ -3551,7 +3551,7 @@ dependencies = [ [[package]] name = "mas-jose" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "base64ct", "chrono", @@ -3581,7 +3581,7 @@ dependencies = [ [[package]] name = "mas-keystore" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "aead", "base64ct", @@ -3609,7 +3609,7 @@ dependencies = [ [[package]] name = "mas-listener" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "anyhow", "bytes", @@ -3633,7 +3633,7 @@ dependencies = [ [[package]] name = "mas-matrix" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "anyhow", "async-trait", @@ -3643,7 +3643,7 @@ dependencies = [ [[package]] name = "mas-matrix-synapse" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "anyhow", "async-trait", @@ -3660,7 +3660,7 @@ dependencies = [ [[package]] name = "mas-oidc-client" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "assert_matches", "async-trait", @@ -3696,7 +3696,7 @@ dependencies = [ [[package]] name = "mas-policy" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "anyhow", "arc-swap", @@ -3713,7 +3713,7 @@ dependencies = [ [[package]] name = "mas-router" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "axum", "serde", @@ -3724,7 +3724,7 @@ dependencies = [ [[package]] name = "mas-spa" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "camino", "serde", @@ -3733,7 +3733,7 @@ dependencies = [ [[package]] name = "mas-storage" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "async-trait", "chrono", @@ -3755,7 +3755,7 @@ dependencies = [ [[package]] name = "mas-storage-pg" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "async-trait", "chrono", @@ -3787,7 +3787,7 @@ dependencies = [ [[package]] name = "mas-tasks" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "anyhow", "async-trait", @@ -3819,7 +3819,7 @@ dependencies = [ [[package]] name = "mas-templates" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "anyhow", "arc-swap", @@ -3851,7 +3851,7 @@ dependencies = [ [[package]] name = "mas-tower" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "http", "opentelemetry", @@ -4103,7 +4103,7 @@ dependencies = [ [[package]] name = "oauth2-types" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "assert_matches", "base64ct", @@ -6279,7 +6279,7 @@ dependencies = [ [[package]] name = "syn2mas" -version = "1.23.0" +version = "1.24.0-rc.0" dependencies = [ "anyhow", "arc-swap", diff --git a/Cargo.toml b/Cargo.toml index 8a80b5f36..5f85aed87 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ members = ["crates/*"] resolver = "2" # Updated in the CI with a `sed` command -package.version = "1.23.0" +package.version = "1.24.0-rc.0" package.license = "AGPL-3.0-only OR LicenseRef-Element-Commercial" package.authors = ["Element Backend Team"] package.edition = "2024" @@ -42,35 +42,35 @@ broken_intra_doc_links = "deny" [workspace.dependencies] # Workspace crates -mas-axum-utils = { path = "./crates/axum-utils/", version = "=1.23.0" } -mas-cli = { path = "./crates/cli/", version = "=1.23.0" } -mas-config = { path = "./crates/config/", version = "=1.23.0" } -mas-context = { path = "./crates/context/", version = "=1.23.0" } -mas-data-model = { path = "./crates/data-model/", version = "=1.23.0" } -mas-email = { path = "./crates/email/", version = "=1.23.0" } -mas-graphql = { path = "./crates/graphql/", version = "=1.23.0" } -mas-handlers = { path = "./crates/handlers/", version = "=1.23.0" } -mas-http = { path = "./crates/http/", version = "=1.23.0" } -mas-i18n = { path = "./crates/i18n/", version = "=1.23.0" } -mas-i18n-scan = { path = "./crates/i18n-scan/", version = "=1.23.0" } -mas-iana = { path = "./crates/iana/", version = "=1.23.0" } -mas-iana-codegen = { path = "./crates/iana-codegen/", version = "=1.23.0" } -mas-jose = { path = "./crates/jose/", version = "=1.23.0" } -mas-keystore = { path = "./crates/keystore/", version = "=1.23.0" } -mas-listener = { path = "./crates/listener/", version = "=1.23.0" } -mas-matrix = { path = "./crates/matrix/", version = "=1.23.0" } -mas-matrix-synapse = { path = "./crates/matrix-synapse/", version = "=1.23.0" } -mas-oidc-client = { path = "./crates/oidc-client/", version = "=1.23.0" } -mas-policy = { path = "./crates/policy/", version = "=1.23.0" } -mas-router = { path = "./crates/router/", version = "=1.23.0" } -mas-spa = { path = "./crates/spa/", version = "=1.23.0" } -mas-storage = { path = "./crates/storage/", version = "=1.23.0" } -mas-storage-pg = { path = "./crates/storage-pg/", version = "=1.23.0" } -mas-tasks = { path = "./crates/tasks/", version = "=1.23.0" } -mas-templates = { path = "./crates/templates/", version = "=1.23.0" } -mas-tower = { path = "./crates/tower/", version = "=1.23.0" } -oauth2-types = { path = "./crates/oauth2-types/", version = "=1.23.0" } -syn2mas = { path = "./crates/syn2mas", version = "=1.23.0" } +mas-axum-utils = { path = "./crates/axum-utils/", version = "=1.24.0-rc.0" } +mas-cli = { path = "./crates/cli/", version = "=1.24.0-rc.0" } +mas-config = { path = "./crates/config/", version = "=1.24.0-rc.0" } +mas-context = { path = "./crates/context/", version = "=1.24.0-rc.0" } +mas-data-model = { path = "./crates/data-model/", version = "=1.24.0-rc.0" } +mas-email = { path = "./crates/email/", version = "=1.24.0-rc.0" } +mas-graphql = { path = "./crates/graphql/", version = "=1.24.0-rc.0" } +mas-handlers = { path = "./crates/handlers/", version = "=1.24.0-rc.0" } +mas-http = { path = "./crates/http/", version = "=1.24.0-rc.0" } +mas-i18n = { path = "./crates/i18n/", version = "=1.24.0-rc.0" } +mas-i18n-scan = { path = "./crates/i18n-scan/", version = "=1.24.0-rc.0" } +mas-iana = { path = "./crates/iana/", version = "=1.24.0-rc.0" } +mas-iana-codegen = { path = "./crates/iana-codegen/", version = "=1.24.0-rc.0" } +mas-jose = { path = "./crates/jose/", version = "=1.24.0-rc.0" } +mas-keystore = { path = "./crates/keystore/", version = "=1.24.0-rc.0" } +mas-listener = { path = "./crates/listener/", version = "=1.24.0-rc.0" } +mas-matrix = { path = "./crates/matrix/", version = "=1.24.0-rc.0" } +mas-matrix-synapse = { path = "./crates/matrix-synapse/", version = "=1.24.0-rc.0" } +mas-oidc-client = { path = "./crates/oidc-client/", version = "=1.24.0-rc.0" } +mas-policy = { path = "./crates/policy/", version = "=1.24.0-rc.0" } +mas-router = { path = "./crates/router/", version = "=1.24.0-rc.0" } +mas-spa = { path = "./crates/spa/", version = "=1.24.0-rc.0" } +mas-storage = { path = "./crates/storage/", version = "=1.24.0-rc.0" } +mas-storage-pg = { path = "./crates/storage-pg/", version = "=1.24.0-rc.0" } +mas-tasks = { path = "./crates/tasks/", version = "=1.24.0-rc.0" } +mas-templates = { path = "./crates/templates/", version = "=1.24.0-rc.0" } +mas-tower = { path = "./crates/tower/", version = "=1.24.0-rc.0" } +oauth2-types = { path = "./crates/oauth2-types/", version = "=1.24.0-rc.0" } +syn2mas = { path = "./crates/syn2mas", version = "=1.24.0-rc.0" } # OpenAPI schema generation and validation [workspace.dependencies.aide] From 0fed77c818b3095a0542d405ff863b722b8c3dd6 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 25 Aug 2026 16:59:29 -0500 Subject: [PATCH 21/37] Update `taiki-e/install-action` so it knows about newer `cargo-zigbuild` --- .github/workflows/build.yaml | 2 +- .github/workflows/ci.yaml | 6 +++--- .github/workflows/coverage.yaml | 2 +- .github/workflows/docs.yaml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index d2e412bc7..99414a5e7 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -137,7 +137,7 @@ jobs: version: 0.13.0 - name: Install cargo-zigbuild - uses: taiki-e/install-action@b8cecb83565409bcc297b2df6e77f030b2a468d5 # v2 + uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2 with: tool: cargo-zigbuild diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 0640b7fb9..b71a656ef 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -274,7 +274,7 @@ jobs: run: rustup toolchain install stable --profile minimal - name: Install nextest - uses: taiki-e/install-action@b8cecb83565409bcc297b2df6e77f030b2a468d5 # v2 + uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2 with: tool: cargo-nextest @@ -330,7 +330,7 @@ jobs: run: rustup toolchain install stable --profile minimal - name: Install nextest - uses: taiki-e/install-action@b8cecb83565409bcc297b2df6e77f030b2a468d5 # v2 + uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2 with: tool: cargo-nextest @@ -410,7 +410,7 @@ jobs: - name: Upload logs if: ${{ failure() }} - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ess-helm-logs path: ess-helm-logs diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml index 8393d8e92..ee7de4d80 100644 --- a/.github/workflows/coverage.yaml +++ b/.github/workflows/coverage.yaml @@ -117,7 +117,7 @@ jobs: uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10 - name: Install grcov - uses: taiki-e/install-action@b8cecb83565409bcc297b2df6e77f030b2a468d5 # v2 + uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2 with: tool: grcov diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index e2020ef33..9fd9123bf 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -37,7 +37,7 @@ jobs: uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10 - name: Install mdbook - uses: taiki-e/install-action@b8cecb83565409bcc297b2df6e77f030b2a468d5 # v2 + uses: taiki-e/install-action@b6ff580856c41316412a0b9b60540fbc6f8c82cc # v2 with: tool: mdbook From 39220b7ae7028694db9d3c0e45d660f8ad7aac0b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 26 Aug 2026 08:30:00 +0000 Subject: [PATCH 22/37] Translations updates --- frontend/.storybook/locales.ts | 82 +++++++++++++++++----------------- frontend/locales/de.json | 8 ++-- frontend/locales/nl.json | 4 +- frontend/locales/pt-BR.json | 4 +- frontend/locales/sk.json | 4 +- frontend/locales/sv.json | 4 +- translations/tr.json | 3 +- translations/uz.json | 3 +- 8 files changed, 57 insertions(+), 55 deletions(-) diff --git a/frontend/.storybook/locales.ts b/frontend/.storybook/locales.ts index 4b0ee9189..deda65899 100644 --- a/frontend/.storybook/locales.ts +++ b/frontend/.storybook/locales.ts @@ -27,7 +27,7 @@ export type LocalazyMetadata = { }; const localazyMetadata: LocalazyMetadata = { - projectUrl: "https://localazy.com/p/matrix-authentication-service", + projectUrl: "https://localazy.com/p/matrix-authentication-service!v1.24", baseLocale: "en", languages: [ { @@ -217,26 +217,26 @@ const localazyMetadata: LocalazyMetadata = { file: "frontend.json", path: "", cdnFiles: { - "cs": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/cs/frontend.json", - "da": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/da/frontend.json", - "de": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/de/frontend.json", - "en": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/en/frontend.json", - "et": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/et/frontend.json", - "fi": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/fi/frontend.json", - "fr": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/fr/frontend.json", - "hu": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/hu/frontend.json", - "nb_NO": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/nb-NO/frontend.json", - "nl": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/nl/frontend.json", - "pl": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pl/frontend.json", - "pt": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pt/frontend.json", - "pt_BR": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pt-BR/frontend.json", - "ru": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/ru/frontend.json", - "sk": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/sk/frontend.json", - "sv": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/sv/frontend.json", - "tr": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/tr/frontend.json", - "uk": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/uk/frontend.json", - "uz": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/uz/frontend.json", - "zh#Hans": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/zh-Hans/frontend.json" + "cs": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/cs/frontend.json", + "da": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/da/frontend.json", + "de": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/de/frontend.json", + "en": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/en/frontend.json", + "et": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/et/frontend.json", + "fi": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/fi/frontend.json", + "fr": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/fr/frontend.json", + "hu": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/hu/frontend.json", + "nb_NO": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/nb-NO/frontend.json", + "nl": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/nl/frontend.json", + "pl": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pl/frontend.json", + "pt": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pt/frontend.json", + "pt_BR": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pt-BR/frontend.json", + "ru": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/ru/frontend.json", + "sk": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/sk/frontend.json", + "sv": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/sv/frontend.json", + "tr": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/tr/frontend.json", + "uk": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/uk/frontend.json", + "uz": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/uz/frontend.json", + "zh#Hans": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/zh-Hans/frontend.json" } }, { @@ -244,26 +244,26 @@ const localazyMetadata: LocalazyMetadata = { file: "file.json", path: "", cdnFiles: { - "cs": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/cs/file.json", - "da": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/da/file.json", - "de": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/de/file.json", - "en": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/en/file.json", - "et": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/et/file.json", - "fi": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/fi/file.json", - "fr": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/fr/file.json", - "hu": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/hu/file.json", - "nb_NO": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/nb-NO/file.json", - "nl": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/nl/file.json", - "pl": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pl/file.json", - "pt": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pt/file.json", - "pt_BR": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pt-BR/file.json", - "ru": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/ru/file.json", - "sk": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/sk/file.json", - "sv": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/sv/file.json", - "tr": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/tr/file.json", - "uk": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/uk/file.json", - "uz": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/uz/file.json", - "zh#Hans": "https://delivery.localazy.com/_a7686032324574572744739e0707/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/zh-Hans/file.json" + "cs": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/cs/file.json", + "da": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/da/file.json", + "de": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/de/file.json", + "en": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/en/file.json", + "et": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/et/file.json", + "fi": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/fi/file.json", + "fr": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/fr/file.json", + "hu": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/hu/file.json", + "nb_NO": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/nb-NO/file.json", + "nl": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/nl/file.json", + "pl": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pl/file.json", + "pt": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pt/file.json", + "pt_BR": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pt-BR/file.json", + "ru": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/ru/file.json", + "sk": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/sk/file.json", + "sv": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/sv/file.json", + "tr": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/tr/file.json", + "uk": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/uk/file.json", + "uz": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/uz/file.json", + "zh#Hans": "https://delivery.localazy.com/_a6406816515547716152c4539eac/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/zh-Hans/file.json" } } ] diff --git a/frontend/locales/de.json b/frontend/locales/de.json index b89175a6b..b16b69edf 100644 --- a/frontend/locales/de.json +++ b/frontend/locales/de.json @@ -39,7 +39,7 @@ "contact_info": "Kontaktinformation", "delete_account": { "alert_description": "Dieses Konto wird dauerhaft entfernt und du hast keinen Zugriff mehr auf deine Nachrichten.", - "alert_title": "Du bist kurz davor, alle deine Daten zu verlieren.", + "alert_title": "Du bist kurz davor, alle deine Daten zu verlieren", "button": "Account löschen", "dialog_description": "Bestätige, dass du dein Konto löschen möchtest:\n\n\nDu kannst dein Konto nicht reaktivieren\nDu kannst dich nicht mehr anmelden\nNiemand kann deinen Nutzernamen (MXID) wieder verwenden, auch du nicht.\nDu verlässt alle Gruppen und Chats\nDu wirst vom Identitätsserver entfernt und niemand kann dich mit deiner E-Mail-Adresse oder Telefonnummer finden\n\nDeine alten Nachrichten sind für die jeweiligen Empfänger weiterhin sichtbar. Möchtest du deine gesendeten Nachrichten vor zukünftigen Gruppen-Besuchern verbergen?", "dialog_title": "Dieses Konto löschen?", @@ -73,7 +73,7 @@ "email_in_use_error": "Die eingegebene E-Mail wird bereits verwendet", "email_invalid_error": "Die eingegebene E-Mail-Adresse ist ungültig", "incorrect_password_error": "Falsches Passwort, bitte versuche es erneut", - "password_confirmation": "Bestätige dein Passwort, um diese E-Mail-Adresse hinzuzufügen." + "password_confirmation": "Bestätige dein Passwort, um diese E-Mail-Adresse hinzuzufügen" }, "browser_session_details": { "current_badge": "Aktuell" @@ -284,7 +284,7 @@ "action": "E-Mail löschen", "body": "Diese E-Mail löschen?", "incorrect_password": "Falsches Passwort, bitte versuche es erneut", - "password_confirmation": "Bestätige dein Passwort, um diese E-Mail-Adresse zu löschen." + "password_confirmation": "Bestätige dein Passwort, um diese E-Mail-Adresse zu löschen" }, "delete_button_title": "E-Mail-Adresse entfernen", "email": "E-Mail" @@ -328,7 +328,7 @@ "heading": "Bestätige deine E-Mail", "invalid_code_alert": { "description": "Überprüfe den Code, der an deine E-Mail-Adresse gesendet wurde, und aktualisiere die folgenden Felder, um fortzufahren.", - "title": "Du hast den falschen Code eingegeben." + "title": "Du hast den falschen Code eingegeben" }, "resend_code": "Code erneut senden" } diff --git a/frontend/locales/nl.json b/frontend/locales/nl.json index 866fad4e5..0c30ef5fb 100644 --- a/frontend/locales/nl.json +++ b/frontend/locales/nl.json @@ -39,7 +39,7 @@ "contact_info": "Contact info", "delete_account": { "alert_description": "This account will be permanently erased and you’ll no longer have access to any of your messages.", - "alert_title": "You’re about to lose all of your data.", + "alert_title": "You’re about to lose all of your data", "button": "Delete account", "dialog_description": "Confirm that you would like to delete your account:\n\n\nYou will not be able to reactivate your account\nYou will no longer be able to sign in\nNo one will be able to reuse your username (MXID), including you\nYou will leave all rooms and direct messages you are in\nYou will be removed from the identity server, and no one will be able to find you with your email or phone number\n\nYour old messages will still be visible to people who received them. Would you like to hide your sent messages from people who join rooms in the future?", "dialog_title": "Delete this account?", @@ -73,7 +73,7 @@ "email_in_use_error": "The entered email is already in use", "email_invalid_error": "Het ingevoerde e-mailadres is ongeldig", "incorrect_password_error": "Incorrect password, please try again", - "password_confirmation": "Confirm your account password to add this email address." + "password_confirmation": "Confirm your account password to add this email address" }, "browser_session_details": { "current_badge": "Huidige" diff --git a/frontend/locales/pt-BR.json b/frontend/locales/pt-BR.json index 3193b8b25..24cbc1cde 100644 --- a/frontend/locales/pt-BR.json +++ b/frontend/locales/pt-BR.json @@ -39,7 +39,7 @@ "contact_info": "Contact info", "delete_account": { "alert_description": "This account will be permanently erased and you’ll no longer have access to any of your messages.", - "alert_title": "You’re about to lose all of your data.", + "alert_title": "You’re about to lose all of your data", "button": "Delete account", "dialog_description": "Confirm that you would like to delete your account:\n\n\nYou will not be able to reactivate your account\nYou will no longer be able to sign in\nNo one will be able to reuse your username (MXID), including you\nYou will leave all rooms and direct messages you are in\nYou will be removed from the identity server, and no one will be able to find you with your email or phone number\n\nYour old messages will still be visible to people who received them. Would you like to hide your sent messages from people who join rooms in the future?", "dialog_title": "Delete this account?", @@ -73,7 +73,7 @@ "email_in_use_error": "The entered email is already in use", "email_invalid_error": "O endereço de e-mail inserido é inválido.", "incorrect_password_error": "Incorrect password, please try again", - "password_confirmation": "Confirm your account password to add this email address." + "password_confirmation": "Confirm your account password to add this email address" }, "browser_session_details": { "current_badge": "Current" diff --git a/frontend/locales/sk.json b/frontend/locales/sk.json index 804c3ce55..2a6cdfe68 100644 --- a/frontend/locales/sk.json +++ b/frontend/locales/sk.json @@ -39,7 +39,7 @@ "contact_info": "Contact info", "delete_account": { "alert_description": "This account will be permanently erased and you’ll no longer have access to any of your messages.", - "alert_title": "You’re about to lose all of your data.", + "alert_title": "You’re about to lose all of your data", "button": "Delete account", "dialog_description": "Confirm that you would like to delete your account:\n\n\nYou will not be able to reactivate your account\nYou will no longer be able to sign in\nNo one will be able to reuse your username (MXID), including you\nYou will leave all rooms and direct messages you are in\nYou will be removed from the identity server, and no one will be able to find you with your email or phone number\n\nYour old messages will still be visible to people who received them. Would you like to hide your sent messages from people who join rooms in the future?", "dialog_title": "Delete this account?", @@ -73,7 +73,7 @@ "email_in_use_error": "The entered email is already in use", "email_invalid_error": "The entered email is invalid", "incorrect_password_error": "Incorrect password, please try again", - "password_confirmation": "Confirm your account password to add this email address." + "password_confirmation": "Confirm your account password to add this email address" }, "browser_session_details": { "current_badge": "Current" diff --git a/frontend/locales/sv.json b/frontend/locales/sv.json index 21b5b2b71..8872c38cb 100644 --- a/frontend/locales/sv.json +++ b/frontend/locales/sv.json @@ -39,7 +39,7 @@ "contact_info": "Kontaktuppgifter", "delete_account": { "alert_description": "This account will be permanently erased and you’ll no longer have access to any of your messages.", - "alert_title": "You’re about to lose all of your data.", + "alert_title": "You’re about to lose all of your data", "button": "Delete account", "dialog_description": "Confirm that you would like to delete your account:\n\n\nYou will not be able to reactivate your account\nYou will no longer be able to sign in\nNo one will be able to reuse your username (MXID), including you\nYou will leave all rooms and direct messages you are in\nYou will be removed from the identity server, and no one will be able to find you with your email or phone number\n\nYour old messages will still be visible to people who received them. Would you like to hide your sent messages from people who join rooms in the future?", "dialog_title": "Delete this account?", @@ -73,7 +73,7 @@ "email_in_use_error": "Det angivna e-postmeddelandet används redan", "email_invalid_error": "Den angivna e-postadressen är ogiltig", "incorrect_password_error": "Incorrect password, please try again", - "password_confirmation": "Confirm your account password to add this email address." + "password_confirmation": "Confirm your account password to add this email address" }, "browser_session_details": { "current_badge": "Nuvarande" diff --git a/translations/tr.json b/translations/tr.json index 93603957e..67e75e028 100644 --- a/translations/tr.json +++ b/translations/tr.json @@ -88,6 +88,7 @@ "description": "%(client_name)s'e erişimi reddettiniz. Bu pencereyi kapatabilirsiniz.", "heading": "Erişim engellendi" }, + "description": " Başka bir cihaz olan , %(client_name)s cihazını , %(server_name)s, hesabınızla bağlantı istiyor. Bu cihazı tanıdığınızdan emin olun.", "grant_access": "Erişim izni ver", "granted": { "description": "%(client_name)s kullanıcısına erişim izni verdiniz. Bu pencereyi kapatabilirsiniz.", @@ -273,4 +274,4 @@ "headline": "E-postanızı doğrulayın" } } -} +} \ No newline at end of file diff --git a/translations/uz.json b/translations/uz.json index 47522d04c..a8afc9534 100644 --- a/translations/uz.json +++ b/translations/uz.json @@ -89,6 +89,7 @@ "description": "Siz %(client_name)s uchun ruxsatni rad etdingiz. Bu oynani yopishingiz mumkin.", "heading": "Ruxsat berilmadi" }, + "description": "Boshqa qurilma %(client_name)s ni sizning %(server_name)s hisobingiz bilan bogʻlamoqchi. Ushbu qurilmani tanib olganingizga ishonch hosil qiling.", "grant_access": "Kirishga ruxsat berish", "granted": { "description": "Siz %(client_name)s uchun ruxsat berdingiz. Bu oynani yopishingiz mumkin.", @@ -278,4 +279,4 @@ "headline": "Elektron pochtangizni tasdiqlang" } } -} +} \ No newline at end of file From f000510f2f3cb7587a3dd817908fde8092752dc5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 26 Aug 2026 09:03:53 +0000 Subject: [PATCH 23/37] 1.24.0-rc.1 --- Cargo.lock | 56 +++++++++++++++++++++++++------------------------- Cargo.toml | 60 +++++++++++++++++++++++++++--------------------------- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d56735998..eed116643 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3198,7 +3198,7 @@ dependencies = [ [[package]] name = "mas-axum-utils" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "anyhow", "axum", @@ -3233,7 +3233,7 @@ dependencies = [ [[package]] name = "mas-cli" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "anyhow", "axum", @@ -3308,7 +3308,7 @@ dependencies = [ [[package]] name = "mas-config" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "anyhow", "camino", @@ -3339,7 +3339,7 @@ dependencies = [ [[package]] name = "mas-context" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "console", "opentelemetry", @@ -3356,7 +3356,7 @@ dependencies = [ [[package]] name = "mas-data-model" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "base64ct", "chrono", @@ -3378,7 +3378,7 @@ dependencies = [ [[package]] name = "mas-email" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "async-trait", "lettre", @@ -3389,7 +3389,7 @@ dependencies = [ [[package]] name = "mas-handlers" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "aide", "anyhow", @@ -3472,7 +3472,7 @@ dependencies = [ [[package]] name = "mas-http" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "futures-util", "headers", @@ -3492,7 +3492,7 @@ dependencies = [ [[package]] name = "mas-i18n" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "camino", "icu_datetime", @@ -3512,7 +3512,7 @@ dependencies = [ [[package]] name = "mas-i18n-scan" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "camino", "clap", @@ -3526,7 +3526,7 @@ dependencies = [ [[package]] name = "mas-iana" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "schemars 1.2.1", "serde", @@ -3534,7 +3534,7 @@ dependencies = [ [[package]] name = "mas-iana-codegen" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "anyhow", "async-trait", @@ -3551,7 +3551,7 @@ dependencies = [ [[package]] name = "mas-jose" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "base64ct", "chrono", @@ -3581,7 +3581,7 @@ dependencies = [ [[package]] name = "mas-keystore" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "aead", "base64ct", @@ -3609,7 +3609,7 @@ dependencies = [ [[package]] name = "mas-listener" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "anyhow", "bytes", @@ -3633,7 +3633,7 @@ dependencies = [ [[package]] name = "mas-matrix" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "anyhow", "async-trait", @@ -3643,7 +3643,7 @@ dependencies = [ [[package]] name = "mas-matrix-synapse" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "anyhow", "async-trait", @@ -3660,7 +3660,7 @@ dependencies = [ [[package]] name = "mas-oidc-client" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "assert_matches", "async-trait", @@ -3696,7 +3696,7 @@ dependencies = [ [[package]] name = "mas-policy" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "anyhow", "arc-swap", @@ -3713,7 +3713,7 @@ dependencies = [ [[package]] name = "mas-router" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "axum", "serde", @@ -3724,7 +3724,7 @@ dependencies = [ [[package]] name = "mas-spa" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "camino", "serde", @@ -3733,7 +3733,7 @@ dependencies = [ [[package]] name = "mas-storage" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "async-trait", "chrono", @@ -3755,7 +3755,7 @@ dependencies = [ [[package]] name = "mas-storage-pg" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "async-trait", "chrono", @@ -3787,7 +3787,7 @@ dependencies = [ [[package]] name = "mas-tasks" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "anyhow", "async-trait", @@ -3819,7 +3819,7 @@ dependencies = [ [[package]] name = "mas-templates" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "anyhow", "arc-swap", @@ -3851,7 +3851,7 @@ dependencies = [ [[package]] name = "mas-tower" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "http", "opentelemetry", @@ -4103,7 +4103,7 @@ dependencies = [ [[package]] name = "oauth2-types" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "assert_matches", "base64ct", @@ -6279,7 +6279,7 @@ dependencies = [ [[package]] name = "syn2mas" -version = "1.24.0-rc.0" +version = "1.24.0-rc.1" dependencies = [ "anyhow", "arc-swap", diff --git a/Cargo.toml b/Cargo.toml index 5f85aed87..e354805e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ members = ["crates/*"] resolver = "2" # Updated in the CI with a `sed` command -package.version = "1.24.0-rc.0" +package.version = "1.24.0-rc.1" package.license = "AGPL-3.0-only OR LicenseRef-Element-Commercial" package.authors = ["Element Backend Team"] package.edition = "2024" @@ -42,35 +42,35 @@ broken_intra_doc_links = "deny" [workspace.dependencies] # Workspace crates -mas-axum-utils = { path = "./crates/axum-utils/", version = "=1.24.0-rc.0" } -mas-cli = { path = "./crates/cli/", version = "=1.24.0-rc.0" } -mas-config = { path = "./crates/config/", version = "=1.24.0-rc.0" } -mas-context = { path = "./crates/context/", version = "=1.24.0-rc.0" } -mas-data-model = { path = "./crates/data-model/", version = "=1.24.0-rc.0" } -mas-email = { path = "./crates/email/", version = "=1.24.0-rc.0" } -mas-graphql = { path = "./crates/graphql/", version = "=1.24.0-rc.0" } -mas-handlers = { path = "./crates/handlers/", version = "=1.24.0-rc.0" } -mas-http = { path = "./crates/http/", version = "=1.24.0-rc.0" } -mas-i18n = { path = "./crates/i18n/", version = "=1.24.0-rc.0" } -mas-i18n-scan = { path = "./crates/i18n-scan/", version = "=1.24.0-rc.0" } -mas-iana = { path = "./crates/iana/", version = "=1.24.0-rc.0" } -mas-iana-codegen = { path = "./crates/iana-codegen/", version = "=1.24.0-rc.0" } -mas-jose = { path = "./crates/jose/", version = "=1.24.0-rc.0" } -mas-keystore = { path = "./crates/keystore/", version = "=1.24.0-rc.0" } -mas-listener = { path = "./crates/listener/", version = "=1.24.0-rc.0" } -mas-matrix = { path = "./crates/matrix/", version = "=1.24.0-rc.0" } -mas-matrix-synapse = { path = "./crates/matrix-synapse/", version = "=1.24.0-rc.0" } -mas-oidc-client = { path = "./crates/oidc-client/", version = "=1.24.0-rc.0" } -mas-policy = { path = "./crates/policy/", version = "=1.24.0-rc.0" } -mas-router = { path = "./crates/router/", version = "=1.24.0-rc.0" } -mas-spa = { path = "./crates/spa/", version = "=1.24.0-rc.0" } -mas-storage = { path = "./crates/storage/", version = "=1.24.0-rc.0" } -mas-storage-pg = { path = "./crates/storage-pg/", version = "=1.24.0-rc.0" } -mas-tasks = { path = "./crates/tasks/", version = "=1.24.0-rc.0" } -mas-templates = { path = "./crates/templates/", version = "=1.24.0-rc.0" } -mas-tower = { path = "./crates/tower/", version = "=1.24.0-rc.0" } -oauth2-types = { path = "./crates/oauth2-types/", version = "=1.24.0-rc.0" } -syn2mas = { path = "./crates/syn2mas", version = "=1.24.0-rc.0" } +mas-axum-utils = { path = "./crates/axum-utils/", version = "=1.24.0-rc.1" } +mas-cli = { path = "./crates/cli/", version = "=1.24.0-rc.1" } +mas-config = { path = "./crates/config/", version = "=1.24.0-rc.1" } +mas-context = { path = "./crates/context/", version = "=1.24.0-rc.1" } +mas-data-model = { path = "./crates/data-model/", version = "=1.24.0-rc.1" } +mas-email = { path = "./crates/email/", version = "=1.24.0-rc.1" } +mas-graphql = { path = "./crates/graphql/", version = "=1.24.0-rc.1" } +mas-handlers = { path = "./crates/handlers/", version = "=1.24.0-rc.1" } +mas-http = { path = "./crates/http/", version = "=1.24.0-rc.1" } +mas-i18n = { path = "./crates/i18n/", version = "=1.24.0-rc.1" } +mas-i18n-scan = { path = "./crates/i18n-scan/", version = "=1.24.0-rc.1" } +mas-iana = { path = "./crates/iana/", version = "=1.24.0-rc.1" } +mas-iana-codegen = { path = "./crates/iana-codegen/", version = "=1.24.0-rc.1" } +mas-jose = { path = "./crates/jose/", version = "=1.24.0-rc.1" } +mas-keystore = { path = "./crates/keystore/", version = "=1.24.0-rc.1" } +mas-listener = { path = "./crates/listener/", version = "=1.24.0-rc.1" } +mas-matrix = { path = "./crates/matrix/", version = "=1.24.0-rc.1" } +mas-matrix-synapse = { path = "./crates/matrix-synapse/", version = "=1.24.0-rc.1" } +mas-oidc-client = { path = "./crates/oidc-client/", version = "=1.24.0-rc.1" } +mas-policy = { path = "./crates/policy/", version = "=1.24.0-rc.1" } +mas-router = { path = "./crates/router/", version = "=1.24.0-rc.1" } +mas-spa = { path = "./crates/spa/", version = "=1.24.0-rc.1" } +mas-storage = { path = "./crates/storage/", version = "=1.24.0-rc.1" } +mas-storage-pg = { path = "./crates/storage-pg/", version = "=1.24.0-rc.1" } +mas-tasks = { path = "./crates/tasks/", version = "=1.24.0-rc.1" } +mas-templates = { path = "./crates/templates/", version = "=1.24.0-rc.1" } +mas-tower = { path = "./crates/tower/", version = "=1.24.0-rc.1" } +oauth2-types = { path = "./crates/oauth2-types/", version = "=1.24.0-rc.1" } +syn2mas = { path = "./crates/syn2mas", version = "=1.24.0-rc.1" } # OpenAPI schema generation and validation [workspace.dependencies.aide] From 66e73f9910a1b5e9b52b7d1dddaf572f9e39afc6 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Wed, 26 Aug 2026 11:23:44 +0200 Subject: [PATCH 24/37] Pin the Rust toolchain with a `rust-toolchain.toml` Until now only the clippy CI job and the Dockerfile named a Rust version (kept in sync by hand), while every other CI job, the release binaries and the docs build ran on whatever `stable` happened to be that day. Rust 1.98.0 landing on 2026-08-20 broke `build-binaries` overnight because of that (#5935). `rust-toolchain.toml` pins 1.96.0 with the `minimal` profile plus clippy, and every `rustup toolchain install stable ...` in CI becomes a bare `rustup toolchain install`, which reads the file. Starting at 1.96.0 (the version clippy is already clean against) keeps this change free of lint churn; catching up to 1.98.0 is a follow-up. rustfmt stays on nightly because `.rustfmt.toml` uses nightly-only options, so that job now invokes `cargo +nightly fmt` explicitly instead of setting a rustup directory override, which would silently take precedence over the toolchain file. The file does not list the linux cross-compilation targets on purpose: that would make every developer and CI job download `rust-std` they never use. The two consumers that cross-compile add the targets themselves. --- .github/workflows/build.yaml | 4 ++-- .github/workflows/ci.yaml | 27 ++++++++------------------- .github/workflows/coverage.yaml | 7 ++++--- .github/workflows/docs.yaml | 4 ++-- .github/workflows/release-branch.yaml | 4 ++-- .github/workflows/release-bump.yaml | 4 ++-- .github/workflows/tag.yaml | 4 ++-- docs/development/contributing.md | 4 ++-- docs/setup/installation.md | 2 +- misc/build-docs.sh | 5 +++-- rust-toolchain.toml | 11 +++++++++++ 11 files changed, 39 insertions(+), 37 deletions(-) create mode 100644 rust-toolchain.toml diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index d2e412bc7..54a35fa4f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -1,3 +1,4 @@ +# Copyright 2025, 2026 Element Creations Ltd. # Copyright 2025 New Vector Ltd. # # SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial @@ -123,9 +124,8 @@ jobs: persist-credentials: false - name: Install Rust toolchain - # Install the minimal toolchain, which includes rustc, rustdoc, and cargo. run: | - rustup toolchain install stable --profile minimal + rustup toolchain install rustup target add ${{ matrix.target }} - name: Setup sccache diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 0640b7fb9..026a9a785 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -153,15 +153,12 @@ jobs: persist-credentials: false - name: Install Rust toolchain - # Install the minimal toolchain, which includes rustc, rustdoc, and cargo. - # Then install rustfmt for `cargo fmt`. - # - # --override sets this as the default rust toolchain version in this directory. + # rustfmt runs on nightly because .rustfmt.toml uses nightly-only options. run: | - rustup toolchain install nightly --profile minimal --component rustfmt --override + rustup toolchain install nightly --profile minimal --component rustfmt - name: Check style - run: cargo fmt --all -- --check + run: cargo +nightly fmt --all -- --check cargo-deny: name: Run `cargo deny` checks @@ -182,8 +179,6 @@ jobs: - name: Run `cargo-deny` uses: EmbarkStudios/cargo-deny-action@3c6349835b2b7b196a839186cb8b78e02f7b5f25 # v2.1.1 - with: - rust-version: stable check-schema: name: Check schema @@ -200,7 +195,7 @@ jobs: - name: Install Rust toolchain run: | - rustup toolchain install stable + rustup toolchain install - name: Setup sccache uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10 @@ -241,11 +236,7 @@ jobs: persist-credentials: false - name: Install Rust toolchain - # Install the minimal toolchain with clippy, pinned to a version kept in - # sync with Dockerfile. - # - # --override sets this as the default rust toolchain version in this directory. - run: rustup toolchain install 1.96.0 --profile minimal --component clippy --override + run: rustup toolchain install - uses: ./.github/actions/build-policies @@ -270,8 +261,7 @@ jobs: persist-credentials: false - name: Install Rust toolchain - # Install the minimal toolchain, which includes rustc, rustdoc, and cargo. - run: rustup toolchain install stable --profile minimal + run: rustup toolchain install - name: Install nextest uses: taiki-e/install-action@b8cecb83565409bcc297b2df6e77f030b2a468d5 # v2 @@ -293,7 +283,7 @@ jobs: path: nextest-archive.tar.zst test: - name: Run test suite with Rust stable + name: Run test suite needs: [rustfmt, opa-lint, compile-test-artifacts] runs-on: ubuntu-24.04 @@ -326,8 +316,7 @@ jobs: persist-credentials: false - name: Install Rust toolchain - # Install the minimal toolchain, which includes rustc, rustdoc, and cargo. - run: rustup toolchain install stable --profile minimal + run: rustup toolchain install - name: Install nextest uses: taiki-e/install-action@b8cecb83565409bcc297b2df6e77f030b2a468d5 # v2 diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml index 8393d8e92..bbe9989b5 100644 --- a/.github/workflows/coverage.yaml +++ b/.github/workflows/coverage.yaml @@ -1,3 +1,4 @@ +# Copyright 2025, 2026 Element Creations Ltd. # Copyright 2025 New Vector Ltd. # # SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial @@ -107,11 +108,11 @@ jobs: persist-credentials: false - name: Install Rust toolchain - # Install the minimal toolchain, which includes rustc, rustdoc, and cargo. - # # llvm-tools-preview installs some llvm tools, which are needed for `grcov` below. # See https://github.com/rust-lang/rust/issues/85658 for stability tracking issue. - run: rustup toolchain install stable --profile minimal --component llvm-tools-preview + run: | + rustup toolchain install + rustup component add llvm-tools-preview - name: Setup sccache uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10 diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index e2020ef33..74b9ee99b 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -1,3 +1,4 @@ +# Copyright 2025, 2026 Element Creations Ltd. # Copyright 2025 New Vector Ltd. # # SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial @@ -30,8 +31,7 @@ jobs: persist-credentials: false - name: Install Rust toolchain - # Install the minimal toolchain, which includes rustc, rustdoc, and cargo - run: rustup toolchain install stable --profile minimal + run: rustup toolchain install - name: Setup sccache uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10 diff --git a/.github/workflows/release-branch.yaml b/.github/workflows/release-branch.yaml index 68788d1bb..637acc053 100644 --- a/.github/workflows/release-branch.yaml +++ b/.github/workflows/release-branch.yaml @@ -1,3 +1,4 @@ +# Copyright 2025, 2026 Element Creations Ltd. # Copyright 2025 New Vector Ltd. # # SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial @@ -39,8 +40,7 @@ jobs: persist-credentials: false - name: Install Rust toolchain - # Only the minimal profile is required here to run `cargo metadata` - run: rustup toolchain install stable --profile minimal + run: rustup toolchain install - name: Install pnpm uses: pnpm/action-setup@v6.0.9 diff --git a/.github/workflows/release-bump.yaml b/.github/workflows/release-bump.yaml index d5467d5d8..ae095b1c5 100644 --- a/.github/workflows/release-bump.yaml +++ b/.github/workflows/release-bump.yaml @@ -1,3 +1,4 @@ +# Copyright 2025, 2026 Element Creations Ltd. # Copyright 2025 New Vector Ltd. # # SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial @@ -38,8 +39,7 @@ jobs: persist-credentials: false - name: Install Rust toolchain - # Only the minimal profile is required here to run `cargo` - run: rustup toolchain install stable --profile minimal + run: rustup toolchain install - name: Install pnpm uses: pnpm/action-setup@v6.0.9 diff --git a/.github/workflows/tag.yaml b/.github/workflows/tag.yaml index fba71867d..c52fa107d 100644 --- a/.github/workflows/tag.yaml +++ b/.github/workflows/tag.yaml @@ -1,3 +1,4 @@ +# Copyright 2025, 2026 Element Creations Ltd. # Copyright 2025 New Vector Ltd. # # SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial @@ -35,8 +36,7 @@ jobs: persist-credentials: false - name: Install Rust toolchain - # Only the minimal profile is required here to run `cargo metadata` - run: rustup toolchain install stable --profile minimal + run: rustup toolchain install - name: Set the crates version env: diff --git a/docs/development/contributing.md b/docs/development/contributing.md index e0c962f83..e8a32ccbf 100644 --- a/docs/development/contributing.md +++ b/docs/development/contributing.md @@ -19,7 +19,7 @@ There are two main ways to contribute to MAS: To get MAS running locally from source you will need to: -- [Install Rust and Cargo](https://www.rust-lang.org/learn/get-started). We recommend using the latest stable version of Rust. +- [Install Rust and Cargo](https://www.rust-lang.org/learn/get-started). The exact version is pinned in `rust-toolchain.toml`; rustup installs it automatically when you run cargo in the repo. - [Install Node.js](https://nodejs.org/). We recommend using the latest LTS version of Node.js. The frontend uses pnpm, which is installed automatically via corepack — see below. - [Install Open Policy Agent](https://www.openpolicyagent.org/docs#1-download-opa) @@ -79,7 +79,7 @@ Most of them can be updated by running `sh misc/update.sh` at the root of the pr Make sure your code adheres to our Rust and TypeScript code style by running: - - `cargo +nightly fmt` (with the nightly toolchain installed) + - `cargo +nightly fmt` (`.rustfmt.toml` uses nightly-only options, so this needs the nightly toolchain installed) - `pnpm run format` in the `frontend` directory - `make fmt` in the `policies` directory (if changed) diff --git a/docs/setup/installation.md b/docs/setup/installation.md index f444f1bdf..bcdb7fbd4 100644 --- a/docs/setup/installation.md +++ b/docs/setup/installation.md @@ -63,7 +63,7 @@ The image can also be built from the source: Building from the source requires: -- The latest stable [Rust toolchain](https://www.rust-lang.org/learn/get-started) +- The [Rust toolchain](https://www.rust-lang.org/learn/get-started) pinned by `rust-toolchain.toml` (installed automatically by rustup) - [Node.js (24 and later)](https://nodejs.org/en/), with [corepack](https://nodejs.org/api/corepack.html) enabled so pnpm@11 is provisioned automatically - the [Open Policy Agent](https://www.openpolicyagent.org/docs/latest/#running-opa) binary (or alternatively, Docker) diff --git a/misc/build-docs.sh b/misc/build-docs.sh index 390c1376f..da0bed402 100644 --- a/misc/build-docs.sh +++ b/misc/build-docs.sh @@ -1,5 +1,6 @@ #!/bin/sh +# Copyright 2025, 2026 Element Creations Ltd. # Copyright 2025 New Vector Ltd. # # SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial @@ -22,8 +23,8 @@ if [ "${CF_PAGES:-""}" = "1" ]; then # Source the environment variables to add cargo to the path . "$HOME/.cargo/env" - # Install the minimal toolchain, which includes rustc, rustdoc, and cargo - rustup toolchain install stable --profile minimal + # Install the toolchain pinned in rust-toolchain.toml + rustup toolchain install # Install mdbook MDBOOK_URL="https://github.com/rust-lang/mdBook/releases/download/v${MDBOOK_VERSION}/mdbook-v${MDBOOK_VERSION}-$(uname -m)-unknown-linux-gnu.tar.gz" diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 000000000..c0b6afb91 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,11 @@ +# Copyright 2026 Element Creations Ltd. +# +# SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +# Please see LICENSE files in the repository root for full details. + +[toolchain] +channel = "1.96.0" +profile = "minimal" +# No rustfmt: .rustfmt.toml uses nightly-only options, so formatting runs as `cargo +nightly fmt`. +# No cross-compilation targets: the Dockerfile and build.yaml add the ones they need. +components = ["clippy"] From 507d49829430c1e05087d82e78245d10d4859c4c Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Wed, 26 Aug 2026 11:23:44 +0200 Subject: [PATCH 25/37] Install the Rust toolchain in the Dockerfile from `rust-toolchain.toml` The builder stage starts from `buildpack-deps` (what the `rust:` image is built on anyway), installs a pinned `rustup-init` with `--default-toolchain none`, copies only `rust-toolchain.toml` and lets rustup install the toolchain it names. The Rust version is now written in exactly one place, shared with CI, so a toolchain bump needs no Dockerfile edit. The toolchain layer is cached on the content of `rust-toolchain.toml` and the base image, and it is the same bytes we pulled as `rust:` image layers before, so build times are unchanged. The registry cache mount also moves to `/usr/local/cargo/registry`: the `rust:` image already set `CARGO_HOME=/usr/local/cargo`, so the previous `/root/.cargo/registry` mount never held anything. --- Dockerfile | 52 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/Dockerfile b/Dockerfile index b7e3b2bd2..899ef0710 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,8 +13,7 @@ # The Debian version and version name must be in sync ARG DEBIAN_VERSION=13 ARG DEBIAN_VERSION_NAME=trixie -# Keep in sync with .github/workflows/ci.yaml -ARG RUSTC_VERSION=1.96.0 +ARG RUSTUP_VERSION=1.29.0 # Keep in sync with .node-version ARG NODEJS_VERSION=24.15.0 # Keep in sync with .github/actions/build-policies/action.yml and policies/Makefile @@ -76,10 +75,42 @@ RUN --network=none \ ######################################## ## Build stage that builds the binary ## ######################################## -FROM --platform=${BUILDPLATFORM} docker.io/library/rust:${RUSTC_VERSION}-${DEBIAN_VERSION_NAME} AS builder +FROM --platform=${BUILDPLATFORM} docker.io/library/buildpack-deps:${DEBIAN_VERSION_NAME} AS builder +ARG BUILDARCH ARG CARGO_AUDITABLE_VERSION -ARG RUSTC_VERSION +ARG RUSTUP_VERSION + +ENV RUSTUP_HOME=/usr/local/rustup \ + CARGO_HOME=/usr/local/cargo \ + PATH=/usr/local/cargo/bin:$PATH + +# Checksums come from https://static.rust-lang.org/rustup/archive///rustup-init.sha256 +# Network access: to download rustup +RUN --network=default \ + case "${BUILDARCH}" in \ + amd64) RUSTUP_TRIPLE="x86_64-unknown-linux-gnu"; RUSTUP_SHA256="4acc9acc76d5079515b46346a485974457b5a79893cfb01112423c89aeb5aa10" ;; \ + arm64) RUSTUP_TRIPLE="aarch64-unknown-linux-gnu"; RUSTUP_SHA256="9732d6c5e2a098d3521fca8145d826ae0aaa067ef2385ead08e6feac88fa5792" ;; \ + *) echo "unsupported architecture: ${BUILDARCH}" >&2; exit 1 ;; \ + esac && \ + curl -fsSLo rustup-init "https://static.rust-lang.org/rustup/archive/${RUSTUP_VERSION}/${RUSTUP_TRIPLE}/rustup-init" && \ + echo "${RUSTUP_SHA256} *rustup-init" | sha256sum -c - && \ + chmod +x rustup-init && \ + ./rustup-init -y --no-modify-path --default-toolchain none && \ + rm rustup-init + +# Set the working directory +WORKDIR /app + +# Copied on its own so the toolchain layer is cached independently of the source tree +COPY rust-toolchain.toml ./ + +# Network access: to download the toolchain and the cross-compilation targets +RUN --network=default \ + rustup toolchain install && \ + rustup target add \ + x86_64-unknown-linux-gnu \ + aarch64-unknown-linux-gnu # Install pinned versions of cargo-auditable # Network access: to fetch dependencies @@ -87,14 +118,6 @@ RUN --network=default \ cargo install --locked \ cargo-auditable@=${CARGO_AUDITABLE_VERSION} -# Install all cross-compilation targets -# Network access: to download the targets -RUN --network=default \ - rustup target add \ - --toolchain "${RUSTC_VERSION}" \ - x86_64-unknown-linux-gnu \ - aarch64-unknown-linux-gnu - RUN --network=none \ dpkg --add-architecture arm64 && \ dpkg --add-architecture amd64 @@ -120,9 +143,6 @@ ENV \ CC_x86_64_unknown_linux_gnu=x86_64-linux-gnu-gcc \ CXX_x86_64_unknown_linux_gnu=x86_64-linux-gnu-g++ -# Set the working directory -WORKDIR /app - # Copy the code COPY ./ /app ENV SQLX_OFFLINE=true @@ -134,7 +154,7 @@ ARG TARGETARCH # Network access: cargo auditable needs it RUN --network=default \ - --mount=type=cache,target=/root/.cargo/registry \ + --mount=type=cache,target=/usr/local/cargo/registry \ --mount=type=cache,target=/app/target \ RUST_TARGET=$(case "${TARGETARCH}" in \ amd64) echo "x86_64-unknown-linux-gnu" ;; \ From cb2a6f2df1f764742088331f93808f230bebf896 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Wed, 26 Aug 2026 11:23:44 +0200 Subject: [PATCH 26/37] Let dependabot bump the Rust toolchain The `rust-toolchain` ecosystem updates the `channel` in `rust-toolchain.toml`, which is now the only place the Rust version is written down. Weekly with the usual 14-day cooldown, so the `.1` point release has usually landed by the time the PR opens. --- .github/dependabot.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 1735e4cb9..cfc0fe5aa 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,3 +1,4 @@ +# Copyright 2025, 2026 Element Creations Ltd. # Copyright 2025 New Vector Ltd. # # SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial @@ -43,6 +44,17 @@ updates: cooldown: default-days: 14 + # Rust releases every six weeks; the cooldown lets the .1 point release land first. + - package-ecosystem: "rust-toolchain" + directory: "/" + labels: + - "A-Dependencies" + - "Z-Deps-Backend" + schedule: + interval: "weekly" + cooldown: + default-days: 14 + - package-ecosystem: "github-actions" directory: "/" labels: From 2f160c03ee901d9457e86b2c0216d2a20c6de1af Mon Sep 17 00:00:00 2001 From: Paul Chobert Date: Tue, 1 Sep 2026 11:14:55 +0200 Subject: [PATCH 27/37] Add test asserting M_APPSERVICE_LOGIN_UNSUPPORTED on appservice login Matrix 1.17 requires servers that don't support the legacy authentication API to reject `m.login.application_service` on `/login` with a 400 and the `M_APPSERVICE_LOGIN_UNSUPPORTED` error code. The test fails until the errcode is implemented. --- crates/handlers/src/compat/login.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/crates/handlers/src/compat/login.rs b/crates/handlers/src/compat/login.rs index efa8358ae..418e1a31c 100644 --- a/crates/handlers/src/compat/login.rs +++ b/crates/handlers/src/compat/login.rs @@ -1686,6 +1686,27 @@ mod tests { "###); } + /// Test the response of an `m.login.application_service` login. + #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] + async fn test_appservice_login_unsupported(pool: PgPool) { + setup(); + let state = TestState::from_pool(pool).await.unwrap(); + + let request = Request::post("/_matrix/client/v3/login").json(serde_json::json!({ + "type": "m.login.application_service", + })); + + let response = state.request(request).await; + response.assert_status(StatusCode::BAD_REQUEST); + let body: serde_json::Value = response.json(); + insta::assert_json_snapshot!(body, @r###" + { + "errcode": "M_APPSERVICE_LOGIN_UNSUPPORTED", + "error": "Application services can't log in through the legacy authentication API on this server" + } + "###); + } + /// Test `m.login.token` login flow. #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_login_token_login(pool: PgPool) { From f1e46bd6755674b1d1e77d6a921769bd1fe8aae5 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Wed, 2 Sep 2026 16:24:18 +0200 Subject: [PATCH 28/37] Ignore RUSTSEC-2026-0269 in cargo-deny as MAS isn't affected by it --- deny.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/deny.toml b/deny.toml index ee8a05976..7d6a0cf7f 100644 --- a/deny.toml +++ b/deny.toml @@ -27,6 +27,9 @@ ignore = [ # Engine/Store, and as the advisory says explicitly: # > This bug is not triggerable by guest WebAssembly programs. "RUSTSEC-2026-0222", + # A bug in wasmtime, but we are not affected as we're not using the WASI + # capabilities and filesystem APIs + "RUSTSEC-2026-0269", ] # Only warn about unmaintained crates in direct dependencies of the workspace, From b0c53acf07ad226e0abd10fcb375ba2369e580a6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 2 Sep 2026 21:24:07 +0000 Subject: [PATCH 29/37] Translations updates --- frontend/locales/et.json | 6 +++--- frontend/locales/pl.json | 4 ++-- translations/et.json | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/frontend/locales/et.json b/frontend/locales/et.json index 0d986c0dc..5514e0e75 100644 --- a/frontend/locales/et.json +++ b/frontend/locales/et.json @@ -145,14 +145,14 @@ "current_password_label": "Senine salasõna", "failure": { "description": { - "account_locked": "Sinu kasutajakonto on lukustatud ning salasõna taastamist ei ole hetkel võimalik teha. Kui antud olukord tundub sulle kahtlane, siis palun teavita sellest sinu serveri haldajat.", + "account_locked": "Sinu kasutajakonto on lukustatud ning salasõna taastamist ei ole hetkel võimalik teha. Kui antud olukord tundub sulle kahtlane, siis palun teavita sellest sinu teenusepakkujat.", "expired_recovery_ticket": "Salasõna taastamiseks mõeldud link on aegunud. Palun alusta taastamisprotsessi algusest.", "invalid_new_password": "Sinu sisestatud uus salasõna pole korrektne, ta ilmselt ei vasta seadistatud turvareeglitele.", "no_current_password": "Sul on hetkel kehtiv salasõna määramata.", "no_such_recovery_ticket": "Salasõna taastamiseks mõeldud link on vigane. Kui sa kopeerisid ja e-kirjast, siis palun kontrolli, et kopeerisid kogu lingi ühe tervikuna.", "password_changes_disabled": "Salasõnade muutmine pole lubatud.", "recovery_ticket_already_used": "Sa oled salasõna taastamiseks mõeldud linki juba kasutanud ja seda ei saa uuesti teha.", - "unspecified": "See ilmselt on ajutine probleem, palun proovi mõne aja pärast uuesti. Kui viga ei kao, siis abi saad serveri haldajalt.", + "unspecified": "See ilmselt on ajutine probleem, palun proovi mõne aja pärast uuesti. Kui viga ei kao, siis abi saad oma teenusepakkujalt.", "wrong_password": "Sinu sisestatud salasõna ei vasta hetkel kehtivale salasõnale. Palun proovi uuesti.," }, "title": "Salasõna uuendamine ei õnnestunud" @@ -239,7 +239,7 @@ "positive_1": "Sinu kasutajakonto andmed, kontaktid, eelistused ja vestluste loendid jäävad muutmata" }, "failure": { - "description": "See ilmselt on ajutine probleem, palun proovi mõne aja pärast uuesti. Kui viga ei kao, siis abi saad serveri haldajalt.", + "description": "See ilmselt on ajutine probleem, palun proovi mõne aja pärast uuesti. Kui viga ei kao, siis abi saad oma teenusepakkujalt.", "heading": "Krüptoidentiteedi lähtestamise lubamine ei õnnestunud" }, "finish_reset": "Lõpeta lähtestamine", diff --git a/frontend/locales/pl.json b/frontend/locales/pl.json index 852b862bd..1caf5c6a7 100644 --- a/frontend/locales/pl.json +++ b/frontend/locales/pl.json @@ -76,7 +76,7 @@ "password_confirmation": "Potwierdź hasło do swojego konta, aby dodać ten adres e-mail" }, "browser_session_details": { - "current_badge": "Aktualny" + "current_badge": "Aktualne" }, "browser_sessions_overview": { "body:one": "{{count}} aktywna sesja", @@ -254,7 +254,7 @@ }, "session": { "client_id_label": "Identyfikator klienta", - "current": "Aktualny", + "current": "Aktualne", "device_id_label": "Identyfikator urządzenia", "finished_label": "Zakończone", "generic_browser_session": "Sesja przeglądarki", diff --git a/translations/et.json b/translations/et.json index 016c6cc4c..c24030796 100644 --- a/translations/et.json +++ b/translations/et.json @@ -39,11 +39,11 @@ "mas": { "account": { "deactivated": { - "description": "See kasutajakonto (%(mxid)s) on kustutatud. Kui see nii ei peaks olema, siis palun võta ühendust oma serveri haldajaga.", + "description": "See kasutajakonto (%(mxid)s) on kustutatud. Kui see nii ei peaks olema, siis palun võta ühendust oma teenusepakkujaga.", "heading": "Kasutajakonto on kustutatud" }, "locked": { - "description": "See kasutajakonto (%(mxid)s) on lukustatud. Kui see nii ei peaks olema, siis palun võta ühendust oma serveri haldajaga.", + "description": "See kasutajakonto (%(mxid)s) on lukustatud. Kui see nii ei peaks olema, siis palun võta ühendust oma teenusepakkujaga.", "heading": "Kasutajakonto on lukustatud" }, "logged_out": { @@ -226,7 +226,7 @@ "terms_of_service": "Ma nõustun teenuse kasutustingimustega" }, "registration_token": { - "description": "Palun sisesta registreerimise tunnusluba, mille serveri haldaja on sulle andnud.", + "description": "Palun sisesta registreerimise tunnusluba, mille sinu teenusepakkuja on sulle andnud.", "field": "Registreerimise tunnusluba", "headline": "Registreerimise tunnusluba" }, From c7c13a2137f03abcff2e7619f4a10611c0cd5f9a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 2 Sep 2026 21:44:13 +0000 Subject: [PATCH 30/37] 1.24.0 --- Cargo.lock | 56 +++++++++++++++++++++++++------------------------- Cargo.toml | 60 +++++++++++++++++++++++++++--------------------------- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eed116643..330f6f332 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3198,7 +3198,7 @@ dependencies = [ [[package]] name = "mas-axum-utils" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "anyhow", "axum", @@ -3233,7 +3233,7 @@ dependencies = [ [[package]] name = "mas-cli" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "anyhow", "axum", @@ -3308,7 +3308,7 @@ dependencies = [ [[package]] name = "mas-config" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "anyhow", "camino", @@ -3339,7 +3339,7 @@ dependencies = [ [[package]] name = "mas-context" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "console", "opentelemetry", @@ -3356,7 +3356,7 @@ dependencies = [ [[package]] name = "mas-data-model" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "base64ct", "chrono", @@ -3378,7 +3378,7 @@ dependencies = [ [[package]] name = "mas-email" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "async-trait", "lettre", @@ -3389,7 +3389,7 @@ dependencies = [ [[package]] name = "mas-handlers" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "aide", "anyhow", @@ -3472,7 +3472,7 @@ dependencies = [ [[package]] name = "mas-http" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "futures-util", "headers", @@ -3492,7 +3492,7 @@ dependencies = [ [[package]] name = "mas-i18n" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "camino", "icu_datetime", @@ -3512,7 +3512,7 @@ dependencies = [ [[package]] name = "mas-i18n-scan" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "camino", "clap", @@ -3526,7 +3526,7 @@ dependencies = [ [[package]] name = "mas-iana" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "schemars 1.2.1", "serde", @@ -3534,7 +3534,7 @@ dependencies = [ [[package]] name = "mas-iana-codegen" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "anyhow", "async-trait", @@ -3551,7 +3551,7 @@ dependencies = [ [[package]] name = "mas-jose" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "base64ct", "chrono", @@ -3581,7 +3581,7 @@ dependencies = [ [[package]] name = "mas-keystore" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "aead", "base64ct", @@ -3609,7 +3609,7 @@ dependencies = [ [[package]] name = "mas-listener" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "anyhow", "bytes", @@ -3633,7 +3633,7 @@ dependencies = [ [[package]] name = "mas-matrix" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "anyhow", "async-trait", @@ -3643,7 +3643,7 @@ dependencies = [ [[package]] name = "mas-matrix-synapse" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "anyhow", "async-trait", @@ -3660,7 +3660,7 @@ dependencies = [ [[package]] name = "mas-oidc-client" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "assert_matches", "async-trait", @@ -3696,7 +3696,7 @@ dependencies = [ [[package]] name = "mas-policy" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "anyhow", "arc-swap", @@ -3713,7 +3713,7 @@ dependencies = [ [[package]] name = "mas-router" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "axum", "serde", @@ -3724,7 +3724,7 @@ dependencies = [ [[package]] name = "mas-spa" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "camino", "serde", @@ -3733,7 +3733,7 @@ dependencies = [ [[package]] name = "mas-storage" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "async-trait", "chrono", @@ -3755,7 +3755,7 @@ dependencies = [ [[package]] name = "mas-storage-pg" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "async-trait", "chrono", @@ -3787,7 +3787,7 @@ dependencies = [ [[package]] name = "mas-tasks" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "anyhow", "async-trait", @@ -3819,7 +3819,7 @@ dependencies = [ [[package]] name = "mas-templates" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "anyhow", "arc-swap", @@ -3851,7 +3851,7 @@ dependencies = [ [[package]] name = "mas-tower" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "http", "opentelemetry", @@ -4103,7 +4103,7 @@ dependencies = [ [[package]] name = "oauth2-types" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "assert_matches", "base64ct", @@ -6279,7 +6279,7 @@ dependencies = [ [[package]] name = "syn2mas" -version = "1.24.0-rc.1" +version = "1.24.0" dependencies = [ "anyhow", "arc-swap", diff --git a/Cargo.toml b/Cargo.toml index e354805e5..cb65a787b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ members = ["crates/*"] resolver = "2" # Updated in the CI with a `sed` command -package.version = "1.24.0-rc.1" +package.version = "1.24.0" package.license = "AGPL-3.0-only OR LicenseRef-Element-Commercial" package.authors = ["Element Backend Team"] package.edition = "2024" @@ -42,35 +42,35 @@ broken_intra_doc_links = "deny" [workspace.dependencies] # Workspace crates -mas-axum-utils = { path = "./crates/axum-utils/", version = "=1.24.0-rc.1" } -mas-cli = { path = "./crates/cli/", version = "=1.24.0-rc.1" } -mas-config = { path = "./crates/config/", version = "=1.24.0-rc.1" } -mas-context = { path = "./crates/context/", version = "=1.24.0-rc.1" } -mas-data-model = { path = "./crates/data-model/", version = "=1.24.0-rc.1" } -mas-email = { path = "./crates/email/", version = "=1.24.0-rc.1" } -mas-graphql = { path = "./crates/graphql/", version = "=1.24.0-rc.1" } -mas-handlers = { path = "./crates/handlers/", version = "=1.24.0-rc.1" } -mas-http = { path = "./crates/http/", version = "=1.24.0-rc.1" } -mas-i18n = { path = "./crates/i18n/", version = "=1.24.0-rc.1" } -mas-i18n-scan = { path = "./crates/i18n-scan/", version = "=1.24.0-rc.1" } -mas-iana = { path = "./crates/iana/", version = "=1.24.0-rc.1" } -mas-iana-codegen = { path = "./crates/iana-codegen/", version = "=1.24.0-rc.1" } -mas-jose = { path = "./crates/jose/", version = "=1.24.0-rc.1" } -mas-keystore = { path = "./crates/keystore/", version = "=1.24.0-rc.1" } -mas-listener = { path = "./crates/listener/", version = "=1.24.0-rc.1" } -mas-matrix = { path = "./crates/matrix/", version = "=1.24.0-rc.1" } -mas-matrix-synapse = { path = "./crates/matrix-synapse/", version = "=1.24.0-rc.1" } -mas-oidc-client = { path = "./crates/oidc-client/", version = "=1.24.0-rc.1" } -mas-policy = { path = "./crates/policy/", version = "=1.24.0-rc.1" } -mas-router = { path = "./crates/router/", version = "=1.24.0-rc.1" } -mas-spa = { path = "./crates/spa/", version = "=1.24.0-rc.1" } -mas-storage = { path = "./crates/storage/", version = "=1.24.0-rc.1" } -mas-storage-pg = { path = "./crates/storage-pg/", version = "=1.24.0-rc.1" } -mas-tasks = { path = "./crates/tasks/", version = "=1.24.0-rc.1" } -mas-templates = { path = "./crates/templates/", version = "=1.24.0-rc.1" } -mas-tower = { path = "./crates/tower/", version = "=1.24.0-rc.1" } -oauth2-types = { path = "./crates/oauth2-types/", version = "=1.24.0-rc.1" } -syn2mas = { path = "./crates/syn2mas", version = "=1.24.0-rc.1" } +mas-axum-utils = { path = "./crates/axum-utils/", version = "=1.24.0" } +mas-cli = { path = "./crates/cli/", version = "=1.24.0" } +mas-config = { path = "./crates/config/", version = "=1.24.0" } +mas-context = { path = "./crates/context/", version = "=1.24.0" } +mas-data-model = { path = "./crates/data-model/", version = "=1.24.0" } +mas-email = { path = "./crates/email/", version = "=1.24.0" } +mas-graphql = { path = "./crates/graphql/", version = "=1.24.0" } +mas-handlers = { path = "./crates/handlers/", version = "=1.24.0" } +mas-http = { path = "./crates/http/", version = "=1.24.0" } +mas-i18n = { path = "./crates/i18n/", version = "=1.24.0" } +mas-i18n-scan = { path = "./crates/i18n-scan/", version = "=1.24.0" } +mas-iana = { path = "./crates/iana/", version = "=1.24.0" } +mas-iana-codegen = { path = "./crates/iana-codegen/", version = "=1.24.0" } +mas-jose = { path = "./crates/jose/", version = "=1.24.0" } +mas-keystore = { path = "./crates/keystore/", version = "=1.24.0" } +mas-listener = { path = "./crates/listener/", version = "=1.24.0" } +mas-matrix = { path = "./crates/matrix/", version = "=1.24.0" } +mas-matrix-synapse = { path = "./crates/matrix-synapse/", version = "=1.24.0" } +mas-oidc-client = { path = "./crates/oidc-client/", version = "=1.24.0" } +mas-policy = { path = "./crates/policy/", version = "=1.24.0" } +mas-router = { path = "./crates/router/", version = "=1.24.0" } +mas-spa = { path = "./crates/spa/", version = "=1.24.0" } +mas-storage = { path = "./crates/storage/", version = "=1.24.0" } +mas-storage-pg = { path = "./crates/storage-pg/", version = "=1.24.0" } +mas-tasks = { path = "./crates/tasks/", version = "=1.24.0" } +mas-templates = { path = "./crates/templates/", version = "=1.24.0" } +mas-tower = { path = "./crates/tower/", version = "=1.24.0" } +oauth2-types = { path = "./crates/oauth2-types/", version = "=1.24.0" } +syn2mas = { path = "./crates/syn2mas", version = "=1.24.0" } # OpenAPI schema generation and validation [workspace.dependencies.aide] From 765fa97ffe46116246eaf719a345114a9e6ddf27 Mon Sep 17 00:00:00 2001 From: Paul Chobert Date: Tue, 1 Sep 2026 11:17:59 +0200 Subject: [PATCH 31/37] Return M_APPSERVICE_LOGIN_UNSUPPORTED for m.login.application_service Matrix 1.17 requires servers that don't support the legacy authentication API to reject `m.login.application_service` on `/login` with a 400 and the `M_APPSERVICE_LOGIN_UNSUPPORTED` error code. Previously this login type fell through the generic unsupported credentials path and returned `M_UNKNOWN`, which appservices written against Matrix 1.17 can't distinguish from an unrelated failure. --- crates/handlers/src/compat/login.rs | 16 ++++++++++++++++ docs/as-login.md | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/crates/handlers/src/compat/login.rs b/crates/handlers/src/compat/login.rs index 418e1a31c..745fad14d 100644 --- a/crates/handlers/src/compat/login.rs +++ b/crates/handlers/src/compat/login.rs @@ -155,6 +155,9 @@ pub enum Credentials { #[serde(rename = "m.login.token")] Token { token: String }, + #[serde(rename = "m.login.application_service")] + ApplicationService, + #[serde(other)] Unsupported, } @@ -164,6 +167,7 @@ impl Credentials { match self { Self::Password { .. } => "m.login.password", Self::Token { .. } => "m.login.token", + Self::ApplicationService => "m.login.application_service", Self::Unsupported => "unsupported", } } @@ -199,6 +203,9 @@ pub enum RouteError { #[error("unsupported login method")] Unsupported, + #[error("appservice login not supported")] + AppserviceLoginUnsupported, + #[error("unsupported identifier type")] UnsupportedIdentifier, @@ -266,6 +273,11 @@ impl IntoResponse for RouteError { error: "Invalid login type", status: StatusCode::BAD_REQUEST, }, + Self::AppserviceLoginUnsupported => MatrixError { + errcode: "M_APPSERVICE_LOGIN_UNSUPPORTED", + error: "Application services can't log in through the legacy authentication API on this server", + status: StatusCode::BAD_REQUEST, + }, Self::UnsupportedIdentifier => MatrixError { errcode: "M_UNKNOWN", error: "Unsupported login identifier", @@ -394,6 +406,10 @@ pub(crate) async fn post( .await? } + (_, Credentials::ApplicationService) => { + return Err(RouteError::AppserviceLoginUnsupported); + } + _ => { return Err(RouteError::Unsupported); } diff --git a/docs/as-login.md b/docs/as-login.md index 0eed4f9e3..f3b61c257 100644 --- a/docs/as-login.md +++ b/docs/as-login.md @@ -1,7 +1,7 @@ # About Application Services login Encrypted Application Services/Bridges currently leverage the `m.login.application_service` login type to create devices for users. -This API is *not* available in the Matrix Authentication Service. +This API is *not* available in the Matrix Authentication Service: as per [Matrix 1.19](https://spec.matrix.org/v1.19/application-service-api/#registration), calling `/login` with this login type returns a 400 HTTP status code with an `M_APPSERVICE_LOGIN_UNSUPPORTED` error code. We're working on a solution to support this use case, but in the meantime, this means **encrypted bridges will not work with the Matrix Authentication Service.** A workaround is to disable E2EE support in your bridge setup. From 9e1d3b94b1ed580f3b1511cee1c220925282571b Mon Sep 17 00:00:00 2001 From: Paul Chobert Date: Thu, 3 Sep 2026 12:05:30 +0200 Subject: [PATCH 32/37] Update crates/handlers/src/compat/login.rs Co-authored-by: Quentin Gliech --- crates/handlers/src/compat/login.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/handlers/src/compat/login.rs b/crates/handlers/src/compat/login.rs index 745fad14d..f30b1bab4 100644 --- a/crates/handlers/src/compat/login.rs +++ b/crates/handlers/src/compat/login.rs @@ -1710,6 +1710,10 @@ mod tests { let request = Request::post("/_matrix/client/v3/login").json(serde_json::json!({ "type": "m.login.application_service", + "identifier": { + "type": "m.id.user", + "user": "_irc_example", + }, })); let response = state.request(request).await; From db25101de43b761ec0ba4f3b4f47fef93e4f3823 Mon Sep 17 00:00:00 2001 From: Paul Chobert Date: Thu, 3 Sep 2026 16:09:44 +0200 Subject: [PATCH 33/37] Fix flaky fail_verify_id_token_wrong_auth_time test The oidc-client integration tests read the real system clock through a `now()` helper. The ID token builder generates a fresh RSA key before stamping `iat`, while each test captured its own `now` earlier for verification. Under coverage instrumentation on a loaded CI runner, the two key generations in `fail_verify_id_token_wrong_auth_time` took more than the 5 minute `iat` leeway, so verification failed on `iat` before ever reaching the `auth_time` check the test asserts on. Make the helper return a frozen `MockClock` timestamp instead. Every token and verification in the binary now shares one instant, so setup duration can no longer affect the outcome, and the clippy opt-out for `Utc::now()` goes away. --- Cargo.lock | 1 + crates/oidc-client/Cargo.toml | 2 ++ crates/oidc-client/tests/it/main.rs | 9 +++++++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 330f6f332..58e481e25 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3673,6 +3673,7 @@ dependencies = [ "http", "http-body-util", "language-tags", + "mas-data-model", "mas-http", "mas-iana", "mas-jose", diff --git a/crates/oidc-client/Cargo.toml b/crates/oidc-client/Cargo.toml index 3fffd584c..ec1b1eb89 100644 --- a/crates/oidc-client/Cargo.toml +++ b/crates/oidc-client/Cargo.toml @@ -51,3 +51,5 @@ rand_chacha.workspace = true rustls.workspace = true tokio.workspace = true wiremock.workspace = true + +mas-data-model.workspace = true diff --git a/crates/oidc-client/tests/it/main.rs b/crates/oidc-client/tests/it/main.rs index f05340467..28960e9d5 100644 --- a/crates/oidc-client/tests/it/main.rs +++ b/crates/oidc-client/tests/it/main.rs @@ -7,6 +7,7 @@ use std::collections::HashMap; use chrono::{DateTime, Duration, Utc}; +use mas_data_model::{Clock, clock::MockClock}; use mas_iana::{jose::JsonWebSignatureAlg, oauth::OAuthClientAuthenticationMethod}; use mas_jose::{ claims::{self, hash_token}, @@ -37,9 +38,13 @@ const REFRESH_TOKEN: &str = "RefreshToken1"; const SUBJECT_IDENTIFIER: &str = "SubjectID"; const ID_TOKEN_SIGNING_ALG: JsonWebSignatureAlg = JsonWebSignatureAlg::Rs256; +/// The current time, as seen by every test in this crate. +/// +/// Tests never read the system clock: they use a [`MockClock`] frozen at a +/// fixed instant, so token timestamps and verification always agree no matter +/// how long the setup in between takes. fn now() -> DateTime { - #[expect(clippy::disallowed_methods)] - Utc::now() + MockClock::default().now() } async fn init_test() -> (reqwest::Client, MockServer, Url) { From 9c56e7f4ee3e1833866262fec1a5ddcd62acbb48 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Thu, 3 Sep 2026 19:16:19 +0200 Subject: [PATCH 34/37] Stop wrapping comments in rustfmt, drop redundant options `comment_width = 80` counts the whole line, indentation included, which wraps far more aggressively than intended; the latest nightly rustfmt (rust-lang/rustfmt#6802) started enforcing it on comments it previously left alone. Turn `wrap_comments` off rather than reformat everything. `max_width = 100`, `comment_width = 80` and `use_small_heuristics = "Default"` are rustfmt's defaults, so drop them too; only the two nightly-only import options remain. --- .rustfmt.toml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.rustfmt.toml b/.rustfmt.toml index 72a97f569..aee976484 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -1,11 +1,8 @@ +# Copyright 2025, 2026 Element Creations Ltd. # Copyright 2025 New Vector Ltd. # # SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial # Please see LICENSE files in the repository root for full details. -max_width = 100 -comment_width = 80 -wrap_comments = true imports_granularity = "Crate" -use_small_heuristics = "Default" group_imports = "StdExternalCrate" From 21aaa65b34512a584fc9cae9cae53e40cccb8132 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Sep 2026 12:48:24 +0000 Subject: [PATCH 35/37] build(deps): bump http-body-util from 0.1.3 to 0.1.5 Bumps [http-body-util](https://github.com/hyperium/http-body) from 0.1.3 to 0.1.5. - [Release notes](https://github.com/hyperium/http-body/releases) - [Commits](https://github.com/hyperium/http-body/compare/http-body-util-v0.1.3...http-body-util-v0.1.5) --- updated-dependencies: - dependency-name: http-body-util dependency-version: 0.1.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 58e481e25..ac341d0d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2304,9 +2304,9 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" dependencies = [ "bytes", "futures-core", From dbbb93915efce7edc5771aa7d26e39485fe7feb3 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Mon, 7 Sep 2026 15:50:18 +0200 Subject: [PATCH 36/37] Declare the Node.js version in `devEngines.runtime` `pnpm/setup` reads the runtime version from `package.json` and ignores `.node-version`. With `onFail: download`, pnpm records Node 24.15.0 in the lockfile and downloads it on every install unless `--no-runtime` is passed. The Dockerfile and the docs build pass it, since they already run a pinned Node. `.node-version` stays for the Cloudflare Pages build, which reads it to pick the Node that bootstraps corepack. --- Dockerfile | 6 +- docs/development/contributing.md | 2 +- docs/setup/installation.md | 2 +- misc/build-docs.sh | 7 +- package.json | 7 ++ pnpm-lock.yaml | 126 +++++++++++++++++++++++++++++++ 6 files changed, 144 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index 899ef0710..0a644d6ed 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,7 @@ ARG DEBIAN_VERSION=13 ARG DEBIAN_VERSION_NAME=trixie ARG RUSTUP_VERSION=1.29.0 -# Keep in sync with .node-version +# Keep in sync with .node-version and devEngines.runtime in package.json ARG NODEJS_VERSION=24.15.0 # Keep in sync with .github/actions/build-policies/action.yml and policies/Makefile ARG OPA_VERSION=1.13.1 @@ -38,8 +38,10 @@ COPY ./package.json ./pnpm-workspace.yaml ./pnpm-lock.yaml /app/ COPY ./frontend/package.json /app/frontend/ # Network access: to fetch dependencies +# The base image already provides the Node.js version pinned in +# `devEngines.runtime`, so skip pnpm's own runtime download. RUN --network=default \ - pnpm install --frozen-lockfile + pnpm install --frozen-lockfile --no-runtime COPY ./frontend/ /app/frontend/ COPY ./templates/ /app/templates/ diff --git a/docs/development/contributing.md b/docs/development/contributing.md index e8a32ccbf..a9079b17e 100644 --- a/docs/development/contributing.md +++ b/docs/development/contributing.md @@ -20,7 +20,7 @@ There are two main ways to contribute to MAS: To get MAS running locally from source you will need to: - [Install Rust and Cargo](https://www.rust-lang.org/learn/get-started). The exact version is pinned in `rust-toolchain.toml`; rustup installs it automatically when you run cargo in the repo. -- [Install Node.js](https://nodejs.org/). We recommend using the latest LTS version of Node.js. The frontend uses pnpm, which is installed automatically via corepack — see below. +- [Install Node.js](https://nodejs.org/). Any recent version works to bootstrap: the exact version is pinned in `devEngines.runtime` in `package.json`, and pnpm downloads it on install. The frontend uses pnpm, which is installed automatically via corepack — see below. - [Install Open Policy Agent](https://www.openpolicyagent.org/docs#1-download-opa) ## 4. Get the source diff --git a/docs/setup/installation.md b/docs/setup/installation.md index bcdb7fbd4..9d92a24ee 100644 --- a/docs/setup/installation.md +++ b/docs/setup/installation.md @@ -64,7 +64,7 @@ The image can also be built from the source: Building from the source requires: - The [Rust toolchain](https://www.rust-lang.org/learn/get-started) pinned by `rust-toolchain.toml` (installed automatically by rustup) -- [Node.js (24 and later)](https://nodejs.org/en/), with [corepack](https://nodejs.org/api/corepack.html) enabled so pnpm@11 is provisioned automatically +- [Node.js](https://nodejs.org/en/), with [corepack](https://nodejs.org/api/corepack.html) enabled so pnpm@11 is provisioned automatically; pnpm then downloads the Node.js version pinned in `package.json` - the [Open Policy Agent](https://www.openpolicyagent.org/docs/latest/#running-opa) binary (or alternatively, Docker) 1. Get the source diff --git a/misc/build-docs.sh b/misc/build-docs.sh index da0bed402..ee9c08a6f 100644 --- a/misc/build-docs.sh +++ b/misc/build-docs.sh @@ -30,7 +30,8 @@ if [ "${CF_PAGES:-""}" = "1" ]; then MDBOOK_URL="https://github.com/rust-lang/mdBook/releases/download/v${MDBOOK_VERSION}/mdbook-v${MDBOOK_VERSION}-$(uname -m)-unknown-linux-gnu.tar.gz" curl --proto '=https' --tlsv1.2 -sSfL "${MDBOOK_URL}" | tar -C "$HOME/.cargo/bin" -xzv - # Enable pnpm via corepack (Node and corepack are pre-installed on Cloudflare Pages) + # Enable pnpm via corepack (Node and corepack are pre-installed on Cloudflare + # Pages, which picks the Node version from .node-version) corepack enable fi @@ -56,5 +57,7 @@ rm -rf target/book/rustdoc mv target/doc target/book/rustdoc # Build the frontend storybook -pnpm install --frozen-lockfile +# Node is already provided by Cloudflare Pages / the CI runner, so skip pnpm's +# own runtime download. +pnpm install --frozen-lockfile --no-runtime pnpm --filter mas-frontend exec storybook build -o ../target/book/storybook diff --git a/package.json b/package.json index 563c22fa7..ef74b844d 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,13 @@ "name": "matrix-authentication-service", "private": true, "packageManager": "pnpm@11.3.0+sha512.2c403d6594527287672b1f7056343a1f7c3634036a67ffabfcc2b3d7595d843768f8787148d1b57cf7956c90606bbd192857c363af19e96d2d0ec9ec5741d215", + "devEngines": { + "runtime": { + "name": "node", + "version": "24.15.0", + "onFail": "download" + } + }, "devDependencies": { "@localazy/cli": "^2.0.11", "semver": "^7.8.5" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5f0027294..72b201e08 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ importers: '@localazy/cli': specifier: ^2.0.11 version: 2.0.11 + node: + specifier: runtime:24.15.0 + version: runtime:24.15.0 semver: specifier: ^7.8.5 version: 7.8.5 @@ -3953,6 +3956,127 @@ packages: resolution: {integrity: sha512-MRlTqhAfoMx/4mhEbPo3Hi02g9LJZaJkka69V6h67Cb1gjrAG0jsTE4CZX1eptNx+VCAwJmfpnDIF4P0Nh1A7A==} engines: {node: '>=18'} + node@runtime:24.15.0: + resolution: + type: variations + variants: + - resolution: + archive: tarball + bin: + node: bin/node + integrity: sha256-3UvHfctfTJoslkNzm7WTUAzLCUE+xCyqD47w5e8RYJU= + type: binary + url: https://nodejs.org/download/release/v24.15.0/node-v24.15.0-aix-ppc64.tar.gz + targets: + - cpu: ppc64 + os: aix + - resolution: + archive: tarball + bin: + node: bin/node + integrity: sha256-NyMxuWl3mrXRW5SYhPxur4jVr+h73ouogdZAC5EA/8Q= + type: binary + url: https://nodejs.org/download/release/v24.15.0/node-v24.15.0-darwin-arm64.tar.gz + targets: + - cpu: arm64 + os: darwin + - resolution: + archive: tarball + bin: + node: bin/node + integrity: sha256-/9XuKTRnkn8+5zGlU+uI/R9Iz3TuvC10prq+SvIoZzs= + type: binary + url: https://nodejs.org/download/release/v24.15.0/node-v24.15.0-darwin-x64.tar.gz + targets: + - cpu: x64 + os: darwin + - resolution: + archive: tarball + bin: + node: bin/node + integrity: sha256-c6/CNNVYwkkZh19RwtHqACoq2k6m+DYBo4OGn++mTu0= + type: binary + url: https://nodejs.org/download/release/v24.15.0/node-v24.15.0-linux-arm64.tar.gz + targets: + - cpu: arm64 + os: linux + - resolution: + archive: tarball + bin: + node: bin/node + integrity: sha256-sfiJAKSxY2XqulYmkwT8Edp1gdvwNVLUSV+azh/AX20= + type: binary + url: https://nodejs.org/download/release/v24.15.0/node-v24.15.0-linux-ppc64le.tar.gz + targets: + - cpu: ppc64le + os: linux + - resolution: + archive: tarball + bin: + node: bin/node + integrity: sha256-+YVFVDnVL+m43mqPbQe/7MxzbepSfofqyv5ajXUWo4A= + type: binary + url: https://nodejs.org/download/release/v24.15.0/node-v24.15.0-linux-s390x.tar.gz + targets: + - cpu: s390x + os: linux + - resolution: + archive: tarball + bin: + node: bin/node + integrity: sha256-RINoctmuxJ8ea1KpqSKHLbmisC0jWmFqVoG2qF/sjYk= + type: binary + url: https://nodejs.org/download/release/v24.15.0/node-v24.15.0-linux-x64.tar.gz + targets: + - cpu: x64 + os: linux + - resolution: + archive: zip + bin: + node: node.exe + integrity: sha256-yet0Au2ibiun5EtnJ/yFqN5WxQlbH3Hr0wYokiEaoRY= + prefix: node-v24.15.0-win-arm64 + type: binary + url: https://nodejs.org/download/release/v24.15.0/node-v24.15.0-win-arm64.zip + targets: + - cpu: arm64 + os: win32 + - resolution: + archive: zip + bin: + node: node.exe + integrity: sha256-zFFJ6r1Td5zh573FQBZDYi0MfmgAreGJKKdn6UC7DmI= + prefix: node-v24.15.0-win-x64 + type: binary + url: https://nodejs.org/download/release/v24.15.0/node-v24.15.0-win-x64.zip + targets: + - cpu: x64 + os: win32 + - resolution: + archive: tarball + bin: + node: bin/node + integrity: sha256-MemKqWCgZ9qR7f/V2TvEZle10qgClhLDWfXyrABgFSo= + type: binary + url: https://unofficial-builds.nodejs.org/download/release/v24.15.0/node-v24.15.0-linux-arm64-musl.tar.gz + targets: + - cpu: arm64 + os: linux + libc: musl + - resolution: + archive: tarball + bin: + node: bin/node + integrity: sha256-9Vr1vUicU0exE8pllMrgClSzC6V6xYdTJDEb/G9HYuM= + type: binary + url: https://unofficial-builds.nodejs.org/download/release/v24.15.0/node-v24.15.0-linux-x64-musl.tar.gz + targets: + - cpu: x64 + os: linux + libc: musl + version: 24.15.0 + hasBin: true + normalize-path@2.1.1: resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==} engines: {node: '>=0.10.0'} @@ -8387,6 +8511,8 @@ snapshots: node-releases@2.0.52: {} + node@runtime:24.15.0: {} + normalize-path@2.1.1: dependencies: remove-trailing-separator: 1.1.0 From 1826034167314a147c8ca392527d0091675f5764 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Mon, 7 Sep 2026 15:51:25 +0200 Subject: [PATCH 37/37] Replace `pnpm/action-setup` and `actions/setup-node` with `pnpm/setup` One pinned step now installs pnpm, Node.js and the dependencies. `require-lockfile: true` keeps the `--frozen-lockfile` semantics, `cache: true` keeps the pnpm store cache. --- .github/actions/build-frontend/action.yml | 18 +++------ .github/workflows/ci.yaml | 42 ++++++-------------- .github/workflows/docs.yaml | 11 ++--- .github/workflows/release-branch.yaml | 28 ++++--------- .github/workflows/release-bump.yaml | 14 ++----- .github/workflows/translations-download.yaml | 15 +++---- .github/workflows/translations-upload.yaml | 15 +++---- 7 files changed, 44 insertions(+), 99 deletions(-) diff --git a/.github/actions/build-frontend/action.yml b/.github/actions/build-frontend/action.yml index dd8a30703..3118e4f22 100644 --- a/.github/actions/build-frontend/action.yml +++ b/.github/actions/build-frontend/action.yml @@ -1,26 +1,20 @@ +# Copyright 2025, 2026 Element Creations Ltd. # Copyright 2025 New Vector Ltd. # # SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial # Please see LICENSE files in the repository root for full details. name: Build the frontend assets -description: Installs Node.js and builds the frontend assets from the frontend directory +description: Installs pnpm, Node.js and the dependencies, then builds the frontend assets runs: using: composite steps: - - name: Install pnpm - uses: pnpm/action-setup@v6.0.5 - - - name: Install Node - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + - name: Install pnpm, Node.js and the dependencies + uses: pnpm/setup@703c52620218391530e48b9e8870d5c0082e1b9b # v2.1.0 with: - node-version-file: .node-version - cache: "pnpm" - - - name: Install dependencies - run: pnpm install --frozen-lockfile - shell: sh + cache: true + require-lockfile: true - name: Build the frontend assets run: pnpm --filter mas-frontend run build diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 7cf0db1d0..4b6eff083 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -68,17 +68,11 @@ jobs: with: persist-credentials: false - - name: Install pnpm - uses: pnpm/action-setup@v6.0.9 - - - name: Install Node - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + - name: Install pnpm, Node.js and the dependencies + uses: pnpm/setup@703c52620218391530e48b9e8870d5c0082e1b9b # v2.1.0 with: - node-version-file: .node-version - cache: "pnpm" - - - name: Install dependencies - run: pnpm install --frozen-lockfile + cache: true + require-lockfile: true - name: Lint run: pnpm --filter mas-frontend run lint @@ -96,17 +90,11 @@ jobs: with: persist-credentials: false - - name: Install pnpm - uses: pnpm/action-setup@v6.0.9 - - - name: Install Node - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + - name: Install pnpm, Node.js and the dependencies + uses: pnpm/setup@703c52620218391530e48b9e8870d5c0082e1b9b # v2.1.0 with: - node-version-file: .node-version - cache: "pnpm" - - - name: Install dependencies - run: pnpm install --frozen-lockfile + cache: true + require-lockfile: true - name: Test run: pnpm --filter mas-frontend test @@ -124,17 +112,11 @@ jobs: with: persist-credentials: false - - name: Install pnpm - uses: pnpm/action-setup@v6.0.9 - - - name: Install Node - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + - name: Install pnpm, Node.js and the dependencies + uses: pnpm/setup@703c52620218391530e48b9e8870d5c0082e1b9b # v2.1.0 with: - node-version-file: .node-version - cache: "pnpm" - - - name: Install dependencies - run: pnpm install --frozen-lockfile + cache: true + require-lockfile: true - name: Check for unused dependencies run: pnpm --filter mas-frontend run knip diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index bf01b490a..19e3d7d67 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -41,14 +41,11 @@ jobs: with: tool: mdbook - - name: Install pnpm - uses: pnpm/action-setup@v6.0.9 - - - name: Install Node - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + - name: Install pnpm, Node.js and the dependencies + uses: pnpm/setup@703c52620218391530e48b9e8870d5c0082e1b9b # v2.1.0 with: - node-version-file: .node-version - cache: "pnpm" + cache: true + require-lockfile: true - name: Build the documentation run: sh misc/build-docs.sh diff --git a/.github/workflows/release-branch.yaml b/.github/workflows/release-branch.yaml index 637acc053..108617952 100644 --- a/.github/workflows/release-branch.yaml +++ b/.github/workflows/release-branch.yaml @@ -42,17 +42,11 @@ jobs: - name: Install Rust toolchain run: rustup toolchain install - - name: Install pnpm - uses: pnpm/action-setup@v6.0.9 - - - name: Install Node - uses: actions/setup-node@v7.0.0 + - name: Install pnpm, Node.js and the dependencies + uses: pnpm/setup@703c52620218391530e48b9e8870d5c0082e1b9b # v2.1.0 with: - node-version-file: .node-version - cache: "pnpm" - - - name: Install dependencies - run: pnpm install --frozen-lockfile + cache: true + require-lockfile: true - name: Compute the new minor RC id: next @@ -80,17 +74,11 @@ jobs: with: persist-credentials: false - - name: Install pnpm - uses: pnpm/action-setup@v6.0.9 - - - name: Install Node - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + - name: Install pnpm, Node.js and the dependencies + uses: pnpm/setup@703c52620218391530e48b9e8870d5c0082e1b9b # v2.1.0 with: - node-version-file: .node-version - cache: "pnpm" - - - name: Install dependencies - run: pnpm install --frozen-lockfile + cache: true + require-lockfile: true - name: Create a new branch in Localazy run: pnpm exec localazy branch -w "$LOCALAZY_WRITE_KEY" create main "$BRANCH" diff --git a/.github/workflows/release-bump.yaml b/.github/workflows/release-bump.yaml index ae095b1c5..b1b2c4d3e 100644 --- a/.github/workflows/release-bump.yaml +++ b/.github/workflows/release-bump.yaml @@ -41,17 +41,11 @@ jobs: - name: Install Rust toolchain run: rustup toolchain install - - name: Install pnpm - uses: pnpm/action-setup@v6.0.9 - - - name: Install Node - uses: actions/setup-node@v7.0.0 + - name: Install pnpm, Node.js and the dependencies + uses: pnpm/setup@703c52620218391530e48b9e8870d5c0082e1b9b # v2.1.0 with: - node-version-file: .node-version - cache: "pnpm" - - - name: Install dependencies - run: pnpm install --frozen-lockfile + cache: true + require-lockfile: true - name: Extract the current version id: current diff --git a/.github/workflows/translations-download.yaml b/.github/workflows/translations-download.yaml index 957781591..f106b4c47 100644 --- a/.github/workflows/translations-download.yaml +++ b/.github/workflows/translations-download.yaml @@ -1,3 +1,4 @@ +# Copyright 2025, 2026 Element Creations Ltd. # Copyright 2025 New Vector Ltd. # # SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial @@ -23,17 +24,11 @@ jobs: with: persist-credentials: false - - name: Install pnpm - uses: pnpm/action-setup@v6.0.9 - - - name: Install Node - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + - name: Install pnpm, Node.js and the dependencies + uses: pnpm/setup@703c52620218391530e48b9e8870d5c0082e1b9b # v2.1.0 with: - node-version-file: .node-version - cache: "pnpm" - - - name: Install dependencies - run: pnpm install --frozen-lockfile + cache: true + require-lockfile: true - name: Compute the Localazy branch name id: branch diff --git a/.github/workflows/translations-upload.yaml b/.github/workflows/translations-upload.yaml index d81b04074..08d8d8974 100644 --- a/.github/workflows/translations-upload.yaml +++ b/.github/workflows/translations-upload.yaml @@ -1,3 +1,4 @@ +# Copyright 2025, 2026 Element Creations Ltd. # Copyright 2025 New Vector Ltd. # # SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial @@ -22,17 +23,11 @@ jobs: with: persist-credentials: false - - name: Install pnpm - uses: pnpm/action-setup@v6.0.9 - - - name: Install Node - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + - name: Install pnpm, Node.js and the dependencies + uses: pnpm/setup@703c52620218391530e48b9e8870d5c0082e1b9b # v2.1.0 with: - node-version-file: .node-version - cache: "pnpm" - - - name: Install dependencies - run: pnpm install --frozen-lockfile + cache: true + require-lockfile: true - name: Compute the Localazy branch name id: branch