From f246792965d2366d325bf1b555cddea4d942b9a7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 14 Apr 2026 12:03:04 +0000 Subject: [PATCH 1/6] Translations updates --- frontend/.storybook/locales.ts | 78 +++++++++++++++++----------------- frontend/locales/fi.json | 20 ++++----- frontend/locales/fr.json | 2 +- frontend/locales/hu.json | 4 +- 4 files changed, 52 insertions(+), 52 deletions(-) diff --git a/frontend/.storybook/locales.ts b/frontend/.storybook/locales.ts index f71735058..ffcc627ed 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.15", + projectUrl: "https://localazy.com/p/matrix-authentication-service", baseLocale: "en", languages: [ { @@ -208,25 +208,25 @@ const localazyMetadata: LocalazyMetadata = { file: "frontend.json", path: "", cdnFiles: { - "cs": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/cs/frontend.json", - "da": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/da/frontend.json", - "de": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/de/frontend.json", - "en": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/en/frontend.json", - "et": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/et/frontend.json", - "fi": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/fi/frontend.json", - "fr": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/fr/frontend.json", - "hu": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/hu/frontend.json", - "nb_NO": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/nb-NO/frontend.json", - "nl": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/nl/frontend.json", - "pl": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pl/frontend.json", - "pt": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pt/frontend.json", - "pt_BR": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/pt-BR/frontend.json", - "ru": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/ru/frontend.json", - "sk": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/sk/frontend.json", - "sv": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/sv/frontend.json", - "uk": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/uk/frontend.json", - "uz": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/7c203a8ac8bd48c3c4609a8effcd0fbac430f9b2/uz/frontend.json", - "zh#Hans": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_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", + "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 +234,25 @@ const localazyMetadata: LocalazyMetadata = { file: "file.json", path: "", cdnFiles: { - "cs": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/cs/file.json", - "da": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/da/file.json", - "de": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/de/file.json", - "en": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/en/file.json", - "et": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/et/file.json", - "fi": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/fi/file.json", - "fr": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/fr/file.json", - "hu": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/hu/file.json", - "nb_NO": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/nb-NO/file.json", - "nl": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/nl/file.json", - "pl": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pl/file.json", - "pt": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pt/file.json", - "pt_BR": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/pt-BR/file.json", - "ru": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/ru/file.json", - "sk": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/sk/file.json", - "sv": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/sv/file.json", - "uk": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/uk/file.json", - "uz": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_e0/5b69b0350dccfd47c245a5d41c1b9fdf6912cc6e/uz/file.json", - "zh#Hans": "https://delivery.localazy.com/_a6577655471040064500233bbe56/_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", + "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/fi.json b/frontend/locales/fi.json index ed3574a94..4283fd13f 100644 --- a/frontend/locales/fi.json +++ b/frontend/locales/fi.json @@ -258,10 +258,10 @@ "button": "Nollaa identiteetti", "cancelled": { "description_1": "Voit sulkea tämän ikkunan ja palata sovellukseen jatkaaksesi.", - "description_2": "Jos olet kirjautunut ulos kaikkialta etkä muista palautuskoodiasi, sinun on silti nollattava identiteettisi.", - "heading": "Identiteetin nollaus peruutettu." + "description_2": "Jos sinulla ei ole muita vahvistettuja laitteita eikä palautuskoodiasi käytettävissä, sinun on nollattava digitaalinen identiteettisi, jotta voit jatkaa sovelluksen käyttöä.", + "heading": "Digitaalisen identiteetin nollaus peruutettu." }, - "description": "Jos et ole kirjautunut muihin laitteisiin ja olet kadottanut palautusavaimesi, sinun on nollattava identiteettisi, jotta voit jatkaa sovelluksen käyttöä.", + "description": "Jos sinulla ei ole muita vahvistettuja laitteita eikä palautuskoodiasi käytettävissä, sinun on nollattava digitaalinen identiteettisi, jotta voit jatkaa sovelluksen käyttöä.", "effect_list": { "negative_1": "Menetät nykyisen viestihistoriasi", "negative_2": "Sinun on vahvistettava kaikki olemassa olevat laitteesi ja yhteystietosi uudelleen", @@ -271,18 +271,18 @@ }, "failure": { "description": "Tämä saattaa olla väliaikainen ongelma, joten yritä myöhemmin uudelleen. Jos ongelma jatkuu, ota yhteyttä palvelimen ylläpitäjään.", - "heading": "Kryptografisen identiteetin nollauksen salliminen epäonnistui", - "title": "Kryptografisen identiteetin nollauksen salliminen epäonnistui" + "heading": "Digitaalisen identiteetin nollauksen salliminen epäonnistui", + "title": "Digitaalisen identiteetin nollauksen salliminen epäonnistui" }, "finish_reset": "Viimeistele nollaus", - "heading": "Nollaa identiteettisi, jos et voi vahvistaa muulla tavalla", + "heading": "Nollaa digitaalinen identiteettisi, jos et voi vahvistaa muulla tavalla", "start_reset": "Aloita nollaus", "success": { - "description": "Identiteetin nollaus on hyväksytty seuraavaksi {{minutes}} minuutiksi. Voit sulkea tämän ikkunan ja palata sovellukseen jatkaaksesi.", - "heading": "Identiteetin nollaus onnistui. Palaa takaisin sovellukseen viimeistelläksesi prosessin.", - "title": "Kryptografisen identiteetin nollaus tilapäisesti sallittu" + "description": "Digitaalisen identiteetin nollaus on hyväksytty seuraavaksi {{minutes}} minuutiksi. Voit sulkea tämän ikkunan ja palata sovellukseen jatkaaksesi.", + "heading": "Digitaalisen identiteetin nollaus onnistui. Palaa takaisin sovellukseen viimeistelläksesi prosessin.", + "title": "Digitaalisen identiteetin nollaus tilapäisesti sallittu" }, - "warning": "Nollaa identiteettisi vain, jos et voi käyttää toista laitetta, johon olet kirjautunut, ja olet kadottanut palautusavaimesi." + "warning": "Nollaa digitaalinen identiteettisi vain, jos sinulla ei ole toista vahvistettua laitetta tai palautusavaintasi käytettävissä." }, "selectable_session": { "label": "Valitse istunto" diff --git a/frontend/locales/fr.json b/frontend/locales/fr.json index 1df554c0f..9f2ddfeb3 100644 --- a/frontend/locales/fr.json +++ b/frontend/locales/fr.json @@ -125,7 +125,7 @@ "heading": "L’adresse e-mail {{email}} est déjà utilisée." }, "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_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_title": "Êtes-vous sûr de vouloir terminer cette session ?", "text": "Supprimer l’appareil" }, diff --git a/frontend/locales/hu.json b/frontend/locales/hu.json index 010191754..73949f28d 100644 --- a/frontend/locales/hu.json +++ b/frontend/locales/hu.json @@ -125,8 +125,8 @@ "heading": "A(z) {{email}} e-mail-cím már használatban van." }, "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_title": "Biztos, hogy befejezi a munkamenetet?", + "confirmation_modal_body_text": "Győződjön meg róla, hogy mindig hozzáfér egy másik ellenőrzött eszközhöz vagy a helyreállítási kulcsához, hogy elkerülje a titkosított csevegési előzmények elvesztését.", + "confirmation_modal_title": "Biztos, hogy eltávolítja ezt az eszközt?", "text": "Eszköz eltávolítása" }, "error": { From ba306d4bcbc81120d21bc4f4692f0469b51ddb53 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 14 Apr 2026 12:23:53 +0000 Subject: [PATCH 2/6] 1.16.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 30664b95c..39a054965 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3098,7 +3098,7 @@ dependencies = [ [[package]] name = "mas-axum-utils" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "anyhow", "axum", @@ -3132,7 +3132,7 @@ dependencies = [ [[package]] name = "mas-cli" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "anyhow", "axum", @@ -3207,7 +3207,7 @@ dependencies = [ [[package]] name = "mas-config" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "anyhow", "camino", @@ -3238,7 +3238,7 @@ dependencies = [ [[package]] name = "mas-context" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "console", "opentelemetry", @@ -3254,7 +3254,7 @@ dependencies = [ [[package]] name = "mas-data-model" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "base64ct", "chrono", @@ -3275,7 +3275,7 @@ dependencies = [ [[package]] name = "mas-email" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "async-trait", "lettre", @@ -3286,7 +3286,7 @@ dependencies = [ [[package]] name = "mas-handlers" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "aide", "anyhow", @@ -3367,7 +3367,7 @@ dependencies = [ [[package]] name = "mas-http" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "futures-util", "headers", @@ -3388,7 +3388,7 @@ dependencies = [ [[package]] name = "mas-i18n" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "camino", "icu_calendar", @@ -3410,7 +3410,7 @@ dependencies = [ [[package]] name = "mas-i18n-scan" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "camino", "clap", @@ -3424,7 +3424,7 @@ dependencies = [ [[package]] name = "mas-iana" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "schemars 0.9.0", "serde", @@ -3432,7 +3432,7 @@ dependencies = [ [[package]] name = "mas-iana-codegen" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "anyhow", "async-trait", @@ -3449,7 +3449,7 @@ dependencies = [ [[package]] name = "mas-jose" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "base64ct", "chrono", @@ -3479,7 +3479,7 @@ dependencies = [ [[package]] name = "mas-keystore" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "aead", "base64ct", @@ -3507,7 +3507,7 @@ dependencies = [ [[package]] name = "mas-listener" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "anyhow", "bytes", @@ -3531,7 +3531,7 @@ dependencies = [ [[package]] name = "mas-matrix" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "anyhow", "async-trait", @@ -3541,7 +3541,7 @@ dependencies = [ [[package]] name = "mas-matrix-synapse" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "anyhow", "async-trait", @@ -3558,7 +3558,7 @@ dependencies = [ [[package]] name = "mas-oidc-client" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "assert_matches", "async-trait", @@ -3594,7 +3594,7 @@ dependencies = [ [[package]] name = "mas-policy" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "anyhow", "arc-swap", @@ -3611,7 +3611,7 @@ dependencies = [ [[package]] name = "mas-router" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "axum", "serde", @@ -3622,7 +3622,7 @@ dependencies = [ [[package]] name = "mas-spa" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "camino", "serde", @@ -3631,7 +3631,7 @@ dependencies = [ [[package]] name = "mas-storage" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "async-trait", "chrono", @@ -3653,7 +3653,7 @@ dependencies = [ [[package]] name = "mas-storage-pg" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "async-trait", "chrono", @@ -3683,7 +3683,7 @@ dependencies = [ [[package]] name = "mas-tasks" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "anyhow", "async-trait", @@ -3715,7 +3715,7 @@ dependencies = [ [[package]] name = "mas-templates" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "anyhow", "arc-swap", @@ -3747,7 +3747,7 @@ dependencies = [ [[package]] name = "mas-tower" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "http", "opentelemetry", @@ -4000,7 +4000,7 @@ dependencies = [ [[package]] name = "oauth2-types" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "assert_matches", "base64ct", @@ -6105,7 +6105,7 @@ dependencies = [ [[package]] name = "syn2mas" -version = "1.15.0" +version = "1.16.0-rc.0" dependencies = [ "anyhow", "arc-swap", diff --git a/Cargo.toml b/Cargo.toml index cb396ec4b..37b542a8e 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.15.0" +package.version = "1.16.0-rc.0" package.license = "AGPL-3.0-only OR LicenseRef-Element-Commercial" package.authors = ["Element Backend Team"] package.edition = "2024" @@ -34,35 +34,35 @@ broken_intra_doc_links = "deny" [workspace.dependencies] # Workspace crates -mas-axum-utils = { path = "./crates/axum-utils/", version = "=1.15.0" } -mas-cli = { path = "./crates/cli/", version = "=1.15.0" } -mas-config = { path = "./crates/config/", version = "=1.15.0" } -mas-context = { path = "./crates/context/", version = "=1.15.0" } -mas-data-model = { path = "./crates/data-model/", version = "=1.15.0" } -mas-email = { path = "./crates/email/", version = "=1.15.0" } -mas-graphql = { path = "./crates/graphql/", version = "=1.15.0" } -mas-handlers = { path = "./crates/handlers/", version = "=1.15.0" } -mas-http = { path = "./crates/http/", version = "=1.15.0" } -mas-i18n = { path = "./crates/i18n/", version = "=1.15.0" } -mas-i18n-scan = { path = "./crates/i18n-scan/", version = "=1.15.0" } -mas-iana = { path = "./crates/iana/", version = "=1.15.0" } -mas-iana-codegen = { path = "./crates/iana-codegen/", version = "=1.15.0" } -mas-jose = { path = "./crates/jose/", version = "=1.15.0" } -mas-keystore = { path = "./crates/keystore/", version = "=1.15.0" } -mas-listener = { path = "./crates/listener/", version = "=1.15.0" } -mas-matrix = { path = "./crates/matrix/", version = "=1.15.0" } -mas-matrix-synapse = { path = "./crates/matrix-synapse/", version = "=1.15.0" } -mas-oidc-client = { path = "./crates/oidc-client/", version = "=1.15.0" } -mas-policy = { path = "./crates/policy/", version = "=1.15.0" } -mas-router = { path = "./crates/router/", version = "=1.15.0" } -mas-spa = { path = "./crates/spa/", version = "=1.15.0" } -mas-storage = { path = "./crates/storage/", version = "=1.15.0" } -mas-storage-pg = { path = "./crates/storage-pg/", version = "=1.15.0" } -mas-tasks = { path = "./crates/tasks/", version = "=1.15.0" } -mas-templates = { path = "./crates/templates/", version = "=1.15.0" } -mas-tower = { path = "./crates/tower/", version = "=1.15.0" } -oauth2-types = { path = "./crates/oauth2-types/", version = "=1.15.0" } -syn2mas = { path = "./crates/syn2mas", version = "=1.15.0" } +mas-axum-utils = { path = "./crates/axum-utils/", version = "=1.16.0-rc.0" } +mas-cli = { path = "./crates/cli/", version = "=1.16.0-rc.0" } +mas-config = { path = "./crates/config/", version = "=1.16.0-rc.0" } +mas-context = { path = "./crates/context/", version = "=1.16.0-rc.0" } +mas-data-model = { path = "./crates/data-model/", version = "=1.16.0-rc.0" } +mas-email = { path = "./crates/email/", version = "=1.16.0-rc.0" } +mas-graphql = { path = "./crates/graphql/", version = "=1.16.0-rc.0" } +mas-handlers = { path = "./crates/handlers/", version = "=1.16.0-rc.0" } +mas-http = { path = "./crates/http/", version = "=1.16.0-rc.0" } +mas-i18n = { path = "./crates/i18n/", version = "=1.16.0-rc.0" } +mas-i18n-scan = { path = "./crates/i18n-scan/", version = "=1.16.0-rc.0" } +mas-iana = { path = "./crates/iana/", version = "=1.16.0-rc.0" } +mas-iana-codegen = { path = "./crates/iana-codegen/", version = "=1.16.0-rc.0" } +mas-jose = { path = "./crates/jose/", version = "=1.16.0-rc.0" } +mas-keystore = { path = "./crates/keystore/", version = "=1.16.0-rc.0" } +mas-listener = { path = "./crates/listener/", version = "=1.16.0-rc.0" } +mas-matrix = { path = "./crates/matrix/", version = "=1.16.0-rc.0" } +mas-matrix-synapse = { path = "./crates/matrix-synapse/", version = "=1.16.0-rc.0" } +mas-oidc-client = { path = "./crates/oidc-client/", version = "=1.16.0-rc.0" } +mas-policy = { path = "./crates/policy/", version = "=1.16.0-rc.0" } +mas-router = { path = "./crates/router/", version = "=1.16.0-rc.0" } +mas-spa = { path = "./crates/spa/", version = "=1.16.0-rc.0" } +mas-storage = { path = "./crates/storage/", version = "=1.16.0-rc.0" } +mas-storage-pg = { path = "./crates/storage-pg/", version = "=1.16.0-rc.0" } +mas-tasks = { path = "./crates/tasks/", version = "=1.16.0-rc.0" } +mas-templates = { path = "./crates/templates/", version = "=1.16.0-rc.0" } +mas-tower = { path = "./crates/tower/", version = "=1.16.0-rc.0" } +oauth2-types = { path = "./crates/oauth2-types/", version = "=1.16.0-rc.0" } +syn2mas = { path = "./crates/syn2mas", version = "=1.16.0-rc.0" } # OpenAPI schema generation and validation [workspace.dependencies.aide] From 8787fbb4596bab3602050daf9a8b5837f567b339 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 01:20:28 +0000 Subject: [PATCH 3/6] build(deps): bump rustls-webpki from 0.103.10 to 0.103.13 Bumps [rustls-webpki](https://github.com/rustls/webpki) from 0.103.10 to 0.103.13. - [Release notes](https://github.com/rustls/webpki/releases) - [Commits](https://github.com/rustls/webpki/compare/v/0.103.10...v/0.103.13) --- updated-dependencies: - dependency-name: rustls-webpki dependency-version: 0.103.13 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 39a054965..7af27529d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5198,9 +5198,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.10" +version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ "aws-lc-rs", "ring", From 29f7d986eeb8eddefeb8bd758cc2b265ed0aa85e Mon Sep 17 00:00:00 2001 From: Olivier 'reivilibre Date: Thu, 23 Apr 2026 14:16:01 +0100 Subject: [PATCH 4/6] Add characterisation test --- .../src/oauth2/authorization/callback.rs | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/crates/handlers/src/oauth2/authorization/callback.rs b/crates/handlers/src/oauth2/authorization/callback.rs index 01f59d602..33311fe39 100644 --- a/crates/handlers/src/oauth2/authorization/callback.rs +++ b/crates/handlers/src/oauth2/authorization/callback.rs @@ -164,3 +164,79 @@ impl CallbackDestination { } } } + +#[cfg(test)] +mod tests { + use hyper::{Request, StatusCode}; + use mas_router::SimpleRoute; + use oauth2_types::registration::ClientRegistrationResponse; + use sqlx::PgPool; + use url::Url; + + use crate::test_utils::{RequestBuilderExt, ResponseExt, TestState, setup}; + + /// Helper to build a GET request to the authorization endpoint with query + /// parameters. + fn authorize_get_request( + client_id: &str, + redirect_uri: &str, + state: &str, + ) -> hyper::Request { + let mut url = Url::parse("https://example.com/authorize").unwrap(); + url.query_pairs_mut() + .append_pair("response_type", "code") + .append_pair("client_id", client_id) + .append_pair("redirect_uri", redirect_uri) + .append_pair("scope", "openid") + .append_pair("state", state) + .append_pair("response_mode", "query") + .append_pair("prompt", "none"); + + let path = url.path(); + let query = url.query().unwrap_or(""); + let uri = format!("{path}?{query}"); + Request::get(uri).empty() + } + + /// Test that checks the content of the `Location` header + /// in response to an authorization request. + #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] + async fn test_query_mode_location_header(pool: PgPool) { + setup(); + let state = TestState::from_pool(pool).await.unwrap(); + + // Register an OAuth2 client + let request = + Request::post(mas_router::OAuth2RegistrationEndpoint::PATH).json(serde_json::json!({ + "client_uri": "https://example.com/", + "redirect_uris": ["https://example.com/callback"], + "token_endpoint_auth_method": "none", + "response_types": ["code"], + "grant_types": ["authorization_code"], + })); + + let response = state.request(request).await; + response.assert_status(StatusCode::CREATED); + + let registration: ClientRegistrationResponse = response.json(); + let client_id = registration.client_id; + + // Send an authorization request with response_mode=query and prompt=none. + // prompt=none always fails with login_required since there is no session, + // which exercises the CallbackDestinationMode::Query path. + let request = authorize_get_request( + &client_id, + "https://example.com/callback", + "test-state-value", + ); + let response = state.request(request).await; + + response.assert_status(StatusCode::SEE_OTHER); + + // Check the form of the Location redirect + response.assert_header_value( + hyper::header::LOCATION, + "https://example.com/callback?state=test-state-value&error=login_required&error_description=The+Authorization+Server+requires+End-User+authentication.", + ); + } +} From f50d2e53cd7cc43e7f767bc1d25d60e96ad0f1f7 Mon Sep 17 00:00:00 2001 From: Olivier 'reivilibre Date: Thu, 23 Apr 2026 14:16:57 +0100 Subject: [PATCH 5/6] Overwrite the fragment with `#` on query callback mode --- .../src/oauth2/authorization/callback.rs | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/crates/handlers/src/oauth2/authorization/callback.rs b/crates/handlers/src/oauth2/authorization/callback.rs index 33311fe39..2b08b3f78 100644 --- a/crates/handlers/src/oauth2/authorization/callback.rs +++ b/crates/handlers/src/oauth2/authorization/callback.rs @@ -133,6 +133,20 @@ impl CallbackDestination { let new_qs = serde_urlencoded::to_string(merged)?; redirect_uri.set_query(Some(&new_qs)); + if redirect_uri.fragment().is_none() { + // To avoid the browser carrying over any potential URL fragment, which may + // include sensitive data from an upstream identity provider, across the + // redirect, overwrite the fragment part by setting the + // fragment to `#`. + // + // The browser behaviour is documented as part of + // the 'location URL' algorithm at + // https://fetch.spec.whatwg.org/commit-snapshots/809904366f33a673a9489b81155ee9e3edd29c12/#concept-response-location-url + // + // We don't need to do this if the redirect URI already includes + // a fragment (as that will also overwrite the client's current value). + redirect_uri.set_fragment(Some("")); + } Ok(Redirect::to(redirect_uri.as_str()).into_response()) } @@ -200,6 +214,10 @@ mod tests { /// Test that checks the content of the `Location` header /// in response to an authorization request. + /// + /// Specifically, we expect to see an empty fragment (`#`) + /// at the end of the URL in order to overwrite any fragment + /// that the browser might otherwise preserve across the redirect. #[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")] async fn test_query_mode_location_header(pool: PgPool) { setup(); @@ -236,7 +254,7 @@ mod tests { // Check the form of the Location redirect response.assert_header_value( hyper::header::LOCATION, - "https://example.com/callback?state=test-state-value&error=login_required&error_description=The+Authorization+Server+requires+End-User+authentication.", + "https://example.com/callback?state=test-state-value&error=login_required&error_description=The+Authorization+Server+requires+End-User+authentication.#", ); } } From 76865b239afa9f3cc17328822c9ff823f36c05fb Mon Sep 17 00:00:00 2001 From: Olivier 'reivilibre Date: Fri, 24 Apr 2026 13:32:38 +0100 Subject: [PATCH 6/6] Simplify comment and test --- .../src/oauth2/authorization/callback.rs | 69 ++++++++----------- 1 file changed, 30 insertions(+), 39 deletions(-) diff --git a/crates/handlers/src/oauth2/authorization/callback.rs b/crates/handlers/src/oauth2/authorization/callback.rs index 2b08b3f78..a7d7ca4a3 100644 --- a/crates/handlers/src/oauth2/authorization/callback.rs +++ b/crates/handlers/src/oauth2/authorization/callback.rs @@ -134,17 +134,23 @@ impl CallbackDestination { redirect_uri.set_query(Some(&new_qs)); if redirect_uri.fragment().is_none() { - // To avoid the browser carrying over any potential URL fragment, which may - // include sensitive data from an upstream identity provider, across the - // redirect, overwrite the fragment part by setting the - // fragment to `#`. + // Ensure that the Location header (redirect target) + // includes a URL fragment (#) of some sort. // - // The browser behaviour is documented as part of - // the 'location URL' algorithm at - // https://fetch.spec.whatwg.org/commit-snapshots/809904366f33a673a9489b81155ee9e3edd29c12/#concept-response-location-url + // Any fragment present in the Location header URL that the server redirects to + // (e.g., via a 303 response) will overwrite the client’s existing fragment, + // otherwise the fragment will be preserved across the + // redirect (and may contain sensitive information, + // or confuse the downstream client). // - // We don't need to do this if the redirect URI already includes - // a fragment (as that will also overwrite the client's current value). + // If the redirect_uri already contains a fragment, that fragment will do the + // same job, so we leave it alone — we don't want to mangle the client's + // configured redirect URL by replacing it with a blank fragment. + // Otherwise, set a fragment of empty string (effectively appending `#` to the + // URL). + // + // Browser behaviour is documented as part of the 'location URL' algorithm at + // https://fetch.spec.whatwg.org/commit-snapshots/809904366f33a673a9489b81155ee9e3edd29c12#concept-response-location-url redirect_uri.set_fragment(Some("")); } @@ -185,33 +191,9 @@ mod tests { use mas_router::SimpleRoute; use oauth2_types::registration::ClientRegistrationResponse; use sqlx::PgPool; - use url::Url; use crate::test_utils::{RequestBuilderExt, ResponseExt, TestState, setup}; - /// Helper to build a GET request to the authorization endpoint with query - /// parameters. - fn authorize_get_request( - client_id: &str, - redirect_uri: &str, - state: &str, - ) -> hyper::Request { - let mut url = Url::parse("https://example.com/authorize").unwrap(); - url.query_pairs_mut() - .append_pair("response_type", "code") - .append_pair("client_id", client_id) - .append_pair("redirect_uri", redirect_uri) - .append_pair("scope", "openid") - .append_pair("state", state) - .append_pair("response_mode", "query") - .append_pair("prompt", "none"); - - let path = url.path(); - let query = url.query().unwrap_or(""); - let uri = format!("{path}?{query}"); - Request::get(uri).empty() - } - /// Test that checks the content of the `Location` header /// in response to an authorization request. /// @@ -242,12 +224,21 @@ mod tests { // Send an authorization request with response_mode=query and prompt=none. // prompt=none always fails with login_required since there is no session, // which exercises the CallbackDestinationMode::Query path. - let request = authorize_get_request( - &client_id, - "https://example.com/callback", - "test-state-value", - ); - let response = state.request(request).await; + + // Build /authorize query parameters + let query = url::form_urlencoded::Serializer::new(String::new()) + .append_pair("response_type", "code") + .append_pair("client_id", &client_id) + .append_pair("redirect_uri", "https://example.com/callback") + .append_pair("scope", "openid") + .append_pair("state", "test-state-value") + .append_pair("response_mode", "query") + .append_pair("prompt", "none") + .finish(); + + let response = state + .request(Request::get(format!("https://example.com/authorize?{query}")).empty()) + .await; response.assert_status(StatusCode::SEE_OTHER);