From 0ef8edc9f14f7ea65b02613d4dce8a0a139764db Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sat, 1 Jan 2022 15:03:27 +0100 Subject: [PATCH] web/user: add language selection closes #2041 Signed-off-by: Jens Langhammer --- locale/en/LC_MESSAGES/django.po | 468 +++++++++--------- web/src/api/Users.ts | 13 +- web/src/common/config.ts | 24 +- web/src/interfaces/locale.ts | 48 +- web/src/locales/en.po | 24 + web/src/locales/fr_FR.po | 24 + web/src/locales/pseudo-LOCALE.po | 24 + web/src/locales/tr.po | 24 + .../user-settings/details/UserDetailsForm.ts | 145 ++++-- 9 files changed, 487 insertions(+), 307 deletions(-) diff --git a/locale/en/LC_MESSAGES/django.po b/locale/en/LC_MESSAGES/django.po index 1111fcd77..8523c4372 100644 --- a/locale/en/LC_MESSAGES/django.po +++ b/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-14 21:03+0000\n" +"POT-Creation-Date: 2022-01-01 14:02+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -51,7 +51,7 @@ msgstr "" msgid "User's display name." msgstr "" -#: authentik/core/models.py:195 authentik/providers/oauth2/models.py:314 +#: authentik/core/models.py:195 authentik/providers/oauth2/models.py:299 msgid "User" msgstr "" @@ -71,67 +71,67 @@ msgstr "" msgid "Internal application name, used in URLs." msgstr "" -#: authentik/core/models.py:288 +#: authentik/core/models.py:294 msgid "Application" msgstr "" -#: authentik/core/models.py:289 +#: authentik/core/models.py:295 msgid "Applications" msgstr "" -#: authentik/core/models.py:295 +#: authentik/core/models.py:301 msgid "Use the source-specific identifier" msgstr "" -#: authentik/core/models.py:303 +#: authentik/core/models.py:309 msgid "" "Use the user's email address, but deny enrollment when the email address " "already exists." msgstr "" -#: authentik/core/models.py:312 +#: authentik/core/models.py:318 msgid "" "Use the user's username, but deny enrollment when the username already " "exists." msgstr "" -#: authentik/core/models.py:319 +#: authentik/core/models.py:325 msgid "Source's display Name." msgstr "" -#: authentik/core/models.py:320 +#: authentik/core/models.py:326 msgid "Internal source name, used in URLs." msgstr "" -#: authentik/core/models.py:331 +#: authentik/core/models.py:337 msgid "Flow to use when authenticating existing users." msgstr "" -#: authentik/core/models.py:340 +#: authentik/core/models.py:346 msgid "Flow to use when enrolling new users." msgstr "" -#: authentik/core/models.py:470 +#: authentik/core/models.py:484 msgid "Token" msgstr "" -#: authentik/core/models.py:471 +#: authentik/core/models.py:485 msgid "Tokens" msgstr "" -#: authentik/core/models.py:514 +#: authentik/core/models.py:528 msgid "Property Mapping" msgstr "" -#: authentik/core/models.py:515 +#: authentik/core/models.py:529 msgid "Property Mappings" msgstr "" -#: authentik/core/models.py:551 +#: authentik/core/models.py:565 msgid "Authenticated Session" msgstr "" -#: authentik/core/models.py:552 +#: authentik/core/models.py:566 msgid "Authenticated Sessions" msgstr "" @@ -154,12 +154,12 @@ msgstr "" msgid "Go to home" msgstr "" -#: authentik/core/templates/if/admin.html:16 -#: authentik/core/templates/if/admin.html:22 +#: authentik/core/templates/if/admin.html:18 +#: authentik/core/templates/if/admin.html:24 #: authentik/core/templates/if/flow.html:28 #: authentik/core/templates/if/flow.html:34 -#: authentik/core/templates/if/user.html:16 -#: authentik/core/templates/if/user.html:22 +#: authentik/core/templates/if/user.html:18 +#: authentik/core/templates/if/user.html:24 msgid "Loading..." msgstr "" @@ -204,112 +204,112 @@ msgstr "" msgid "Powered by authentik" msgstr "" -#: authentik/crypto/api.py:121 +#: authentik/crypto/api.py:132 msgid "Subject-alt name" msgstr "" -#: authentik/crypto/models.py:29 +#: authentik/crypto/models.py:34 msgid "PEM-encoded Certificate data" msgstr "" -#: authentik/crypto/models.py:32 +#: authentik/crypto/models.py:37 msgid "" "Optional Private Key. If this is set, you can use this keypair for " "encryption." msgstr "" -#: authentik/crypto/models.py:93 +#: authentik/crypto/models.py:100 msgid "Certificate-Key Pair" msgstr "" -#: authentik/crypto/models.py:94 +#: authentik/crypto/models.py:101 msgid "Certificate-Key Pairs" msgstr "" -#: authentik/crypto/tasks.py:90 +#: authentik/crypto/tasks.py:93 #, python-format msgid "Successfully imported %(count)d files." msgstr "" -#: authentik/events/models.py:284 +#: authentik/events/models.py:285 msgid "Event" msgstr "" -#: authentik/events/models.py:285 +#: authentik/events/models.py:286 msgid "Events" msgstr "" -#: authentik/events/models.py:291 +#: authentik/events/models.py:292 msgid "Generic Webhook" msgstr "" -#: authentik/events/models.py:292 +#: authentik/events/models.py:293 msgid "Slack Webhook (Slack/Discord)" msgstr "" -#: authentik/events/models.py:293 +#: authentik/events/models.py:294 msgid "Email" msgstr "" -#: authentik/events/models.py:311 +#: authentik/events/models.py:312 msgid "" "Only send notification once, for example when sending a webhook into a chat " "channel." msgstr "" -#: authentik/events/models.py:356 +#: authentik/events/models.py:357 msgid "Severity" msgstr "" -#: authentik/events/models.py:361 +#: authentik/events/models.py:362 msgid "Dispatched for user" msgstr "" -#: authentik/events/models.py:438 +#: authentik/events/models.py:439 msgid "Notification Transport" msgstr "" -#: authentik/events/models.py:439 +#: authentik/events/models.py:440 msgid "Notification Transports" msgstr "" -#: authentik/events/models.py:445 +#: authentik/events/models.py:446 msgid "Notice" msgstr "" -#: authentik/events/models.py:446 +#: authentik/events/models.py:447 msgid "Warning" msgstr "" -#: authentik/events/models.py:447 +#: authentik/events/models.py:448 msgid "Alert" msgstr "" -#: authentik/events/models.py:467 +#: authentik/events/models.py:468 msgid "Notification" msgstr "" -#: authentik/events/models.py:468 +#: authentik/events/models.py:469 msgid "Notifications" msgstr "" -#: authentik/events/models.py:487 +#: authentik/events/models.py:488 msgid "Controls which severity level the created notifications will have." msgstr "" -#: authentik/events/models.py:507 +#: authentik/events/models.py:508 msgid "Notification Rule" msgstr "" -#: authentik/events/models.py:508 +#: authentik/events/models.py:509 msgid "Notification Rules" msgstr "" -#: authentik/events/models.py:529 +#: authentik/events/models.py:530 msgid "Notification Webhook Mapping" msgstr "" -#: authentik/events/models.py:530 +#: authentik/events/models.py:531 msgid "Notification Webhook Mappings" msgstr "" @@ -402,33 +402,33 @@ msgstr "" msgid "Invalid kubeconfig" msgstr "" -#: authentik/outposts/models.py:165 +#: authentik/outposts/models.py:151 msgid "Outpost Service-Connection" msgstr "" -#: authentik/outposts/models.py:166 +#: authentik/outposts/models.py:152 msgid "Outpost Service-Connections" msgstr "" -#: authentik/outposts/models.py:202 +#: authentik/outposts/models.py:188 msgid "" "Certificate/Key used for authentication. Can be left empty for no " "authentication." msgstr "" -#: authentik/outposts/models.py:244 +#: authentik/outposts/models.py:201 msgid "Docker Service-Connection" msgstr "" -#: authentik/outposts/models.py:245 +#: authentik/outposts/models.py:202 msgid "Docker Service-Connections" msgstr "" -#: authentik/outposts/models.py:291 +#: authentik/outposts/models.py:227 msgid "Kubernetes Service-Connection" msgstr "" -#: authentik/outposts/models.py:292 +#: authentik/outposts/models.py:228 msgid "Kubernetes Service-Connections" msgstr "" @@ -477,12 +477,12 @@ msgid "Expression Policies" msgstr "" #: authentik/policies/hibp/models.py:22 -#: authentik/policies/password/models.py:23 +#: authentik/policies/password/models.py:24 msgid "Field key to check, field keys defined in Prompt stages are available." msgstr "" #: authentik/policies/hibp/models.py:47 -#: authentik/policies/password/models.py:54 +#: authentik/policies/password/models.py:57 msgid "Password not set in context" msgstr "" @@ -539,11 +539,11 @@ msgstr "" msgid "Policies" msgstr "" -#: authentik/policies/password/models.py:83 +#: authentik/policies/password/models.py:89 msgid "Password Policy" msgstr "" -#: authentik/policies/password/models.py:84 +#: authentik/policies/password/models.py:90 msgid "Password Policies" msgstr "" @@ -617,177 +617,173 @@ msgstr "" msgid "LDAP Providers" msgstr "" -#: authentik/providers/oauth2/api/provider.py:26 -msgid "RS256 requires a Certificate-Key-Pair to be selected." -msgstr "" - -#: authentik/providers/oauth2/models.py:34 +#: authentik/providers/oauth2/models.py:36 msgid "Confidential" msgstr "" -#: authentik/providers/oauth2/models.py:35 +#: authentik/providers/oauth2/models.py:37 msgid "Public" msgstr "" -#: authentik/providers/oauth2/models.py:49 +#: authentik/providers/oauth2/models.py:51 msgid "Based on the Hashed User ID" msgstr "" -#: authentik/providers/oauth2/models.py:50 +#: authentik/providers/oauth2/models.py:52 msgid "Based on the username" msgstr "" -#: authentik/providers/oauth2/models.py:53 +#: authentik/providers/oauth2/models.py:55 msgid "Based on the User's Email. This is recommended over the UPN method." msgstr "" -#: authentik/providers/oauth2/models.py:69 +#: authentik/providers/oauth2/models.py:71 msgid "Same identifier is used for all providers" msgstr "" -#: authentik/providers/oauth2/models.py:71 +#: authentik/providers/oauth2/models.py:73 msgid "Each provider has a different issuer, based on the application slug." msgstr "" -#: authentik/providers/oauth2/models.py:78 +#: authentik/providers/oauth2/models.py:80 msgid "code (Authorization Code Flow)" msgstr "" -#: authentik/providers/oauth2/models.py:79 +#: authentik/providers/oauth2/models.py:81 msgid "id_token (Implicit Flow)" msgstr "" -#: authentik/providers/oauth2/models.py:80 +#: authentik/providers/oauth2/models.py:82 msgid "id_token token (Implicit Flow)" msgstr "" -#: authentik/providers/oauth2/models.py:81 +#: authentik/providers/oauth2/models.py:83 msgid "code token (Hybrid Flow)" msgstr "" -#: authentik/providers/oauth2/models.py:82 +#: authentik/providers/oauth2/models.py:84 msgid "code id_token (Hybrid Flow)" msgstr "" -#: authentik/providers/oauth2/models.py:83 +#: authentik/providers/oauth2/models.py:85 msgid "code id_token token (Hybrid Flow)" msgstr "" -#: authentik/providers/oauth2/models.py:89 +#: authentik/providers/oauth2/models.py:91 msgid "HS256 (Symmetric Encryption)" msgstr "" -#: authentik/providers/oauth2/models.py:90 +#: authentik/providers/oauth2/models.py:92 msgid "RS256 (Asymmetric Encryption)" msgstr "" -#: authentik/providers/oauth2/models.py:96 +#: authentik/providers/oauth2/models.py:93 +msgid "EC256 (Asymmetric Encryption)" +msgstr "" + +#: authentik/providers/oauth2/models.py:99 msgid "Scope used by the client" msgstr "" -#: authentik/providers/oauth2/models.py:122 +#: authentik/providers/oauth2/models.py:125 msgid "Scope Mapping" msgstr "" -#: authentik/providers/oauth2/models.py:123 +#: authentik/providers/oauth2/models.py:126 msgid "Scope Mappings" msgstr "" -#: authentik/providers/oauth2/models.py:133 +#: authentik/providers/oauth2/models.py:136 msgid "Client Type" msgstr "" -#: authentik/providers/oauth2/models.py:139 +#: authentik/providers/oauth2/models.py:142 msgid "Client ID" msgstr "" -#: authentik/providers/oauth2/models.py:145 +#: authentik/providers/oauth2/models.py:148 msgid "Client Secret" msgstr "" -#: authentik/providers/oauth2/models.py:152 -msgid "JWT Algorithm" -msgstr "" - -#: authentik/providers/oauth2/models.py:158 +#: authentik/providers/oauth2/models.py:154 msgid "Redirect URIs" msgstr "" -#: authentik/providers/oauth2/models.py:159 +#: authentik/providers/oauth2/models.py:155 msgid "Enter each URI on a new line." msgstr "" -#: authentik/providers/oauth2/models.py:164 +#: authentik/providers/oauth2/models.py:160 msgid "Include claims in id_token" msgstr "" -#: authentik/providers/oauth2/models.py:212 +#: authentik/providers/oauth2/models.py:208 msgid "RSA Key" msgstr "" -#: authentik/providers/oauth2/models.py:216 +#: authentik/providers/oauth2/models.py:212 msgid "" "Key used to sign the tokens. Only required when JWT Algorithm is set to " "RS256." msgstr "" -#: authentik/providers/oauth2/models.py:306 +#: authentik/providers/oauth2/models.py:291 msgid "OAuth2/OpenID Provider" msgstr "" -#: authentik/providers/oauth2/models.py:307 +#: authentik/providers/oauth2/models.py:292 msgid "OAuth2/OpenID Providers" msgstr "" -#: authentik/providers/oauth2/models.py:315 +#: authentik/providers/oauth2/models.py:300 msgid "Scopes" msgstr "" -#: authentik/providers/oauth2/models.py:334 +#: authentik/providers/oauth2/models.py:319 msgid "Code" msgstr "" -#: authentik/providers/oauth2/models.py:335 +#: authentik/providers/oauth2/models.py:320 msgid "Nonce" msgstr "" -#: authentik/providers/oauth2/models.py:336 +#: authentik/providers/oauth2/models.py:321 msgid "Is Authentication?" msgstr "" -#: authentik/providers/oauth2/models.py:337 +#: authentik/providers/oauth2/models.py:322 msgid "Code Challenge" msgstr "" -#: authentik/providers/oauth2/models.py:339 +#: authentik/providers/oauth2/models.py:324 msgid "Code Challenge Method" msgstr "" -#: authentik/providers/oauth2/models.py:353 +#: authentik/providers/oauth2/models.py:338 msgid "Authorization Code" msgstr "" -#: authentik/providers/oauth2/models.py:354 +#: authentik/providers/oauth2/models.py:339 msgid "Authorization Codes" msgstr "" -#: authentik/providers/oauth2/models.py:397 +#: authentik/providers/oauth2/models.py:382 msgid "Access Token" msgstr "" -#: authentik/providers/oauth2/models.py:398 +#: authentik/providers/oauth2/models.py:383 msgid "Refresh Token" msgstr "" -#: authentik/providers/oauth2/models.py:399 +#: authentik/providers/oauth2/models.py:384 msgid "ID Token" msgstr "" -#: authentik/providers/oauth2/models.py:402 +#: authentik/providers/oauth2/models.py:387 msgid "OAuth2 Token" msgstr "" -#: authentik/providers/oauth2/models.py:403 +#: authentik/providers/oauth2/models.py:388 msgid "OAuth2 Tokens" msgstr "" @@ -797,42 +793,42 @@ msgstr "" msgid "You're about to sign into %(application)s." msgstr "" -#: authentik/providers/proxy/models.py:57 +#: authentik/providers/proxy/models.py:52 msgid "Validate SSL Certificates of upstream servers" msgstr "" -#: authentik/providers/proxy/models.py:58 +#: authentik/providers/proxy/models.py:53 msgid "Internal host SSL Validation" msgstr "" -#: authentik/providers/proxy/models.py:64 +#: authentik/providers/proxy/models.py:59 msgid "" "Enable support for forwardAuth in traefik and nginx auth_request. Exclusive " "with internal_host." msgstr "" -#: authentik/providers/proxy/models.py:82 +#: authentik/providers/proxy/models.py:77 msgid "Set HTTP-Basic Authentication" msgstr "" -#: authentik/providers/proxy/models.py:84 +#: authentik/providers/proxy/models.py:79 msgid "" "Set a custom HTTP-Basic Authentication header based on values from authentik." msgstr "" -#: authentik/providers/proxy/models.py:89 +#: authentik/providers/proxy/models.py:84 msgid "HTTP-Basic Username Key" msgstr "" -#: authentik/providers/proxy/models.py:99 +#: authentik/providers/proxy/models.py:94 msgid "HTTP-Basic Password Key" msgstr "" -#: authentik/providers/proxy/models.py:155 +#: authentik/providers/proxy/models.py:149 msgid "Proxy Provider" msgstr "" -#: authentik/providers/proxy/models.py:156 +#: authentik/providers/proxy/models.py:150 msgid "Proxy Providers" msgstr "" @@ -861,39 +857,39 @@ msgstr "" msgid "NameID Property Mapping" msgstr "" -#: authentik/providers/saml/models.py:109 authentik/sources/saml/models.py:129 +#: authentik/providers/saml/models.py:109 authentik/sources/saml/models.py:128 msgid "SHA1" msgstr "" -#: authentik/providers/saml/models.py:110 authentik/sources/saml/models.py:130 +#: authentik/providers/saml/models.py:110 authentik/sources/saml/models.py:129 msgid "SHA256" msgstr "" -#: authentik/providers/saml/models.py:111 authentik/sources/saml/models.py:131 +#: authentik/providers/saml/models.py:111 authentik/sources/saml/models.py:130 msgid "SHA384" msgstr "" -#: authentik/providers/saml/models.py:112 authentik/sources/saml/models.py:132 +#: authentik/providers/saml/models.py:112 authentik/sources/saml/models.py:131 msgid "SHA512" msgstr "" -#: authentik/providers/saml/models.py:119 authentik/sources/saml/models.py:139 +#: authentik/providers/saml/models.py:119 authentik/sources/saml/models.py:138 msgid "RSA-SHA1" msgstr "" -#: authentik/providers/saml/models.py:120 authentik/sources/saml/models.py:140 +#: authentik/providers/saml/models.py:120 authentik/sources/saml/models.py:139 msgid "RSA-SHA256" msgstr "" -#: authentik/providers/saml/models.py:121 authentik/sources/saml/models.py:141 +#: authentik/providers/saml/models.py:121 authentik/sources/saml/models.py:140 msgid "RSA-SHA384" msgstr "" -#: authentik/providers/saml/models.py:122 authentik/sources/saml/models.py:142 +#: authentik/providers/saml/models.py:122 authentik/sources/saml/models.py:141 msgid "RSA-SHA512" msgstr "" -#: authentik/providers/saml/models.py:123 authentik/sources/saml/models.py:143 +#: authentik/providers/saml/models.py:123 authentik/sources/saml/models.py:142 msgid "DSA-SHA1" msgstr "" @@ -905,7 +901,7 @@ msgstr "" msgid "Keypair used to sign outgoing Responses going to the Service Provider." msgstr "" -#: authentik/providers/saml/models.py:150 authentik/sources/saml/models.py:119 +#: authentik/providers/saml/models.py:150 authentik/sources/saml/models.py:118 msgid "Signing Keypair" msgstr "" @@ -937,77 +933,77 @@ msgstr "" msgid "Used recovery-link to authenticate." msgstr "" -#: authentik/sources/ldap/models.py:33 +#: authentik/sources/ldap/models.py:32 msgid "Server URI" msgstr "" -#: authentik/sources/ldap/models.py:41 +#: authentik/sources/ldap/models.py:40 msgid "" "Optionally verify the LDAP Server's Certificate against the CA Chain in this " "keypair." msgstr "" -#: authentik/sources/ldap/models.py:46 +#: authentik/sources/ldap/models.py:45 msgid "Bind CN" msgstr "" -#: authentik/sources/ldap/models.py:48 +#: authentik/sources/ldap/models.py:47 msgid "Enable Start TLS" msgstr "" -#: authentik/sources/ldap/models.py:50 +#: authentik/sources/ldap/models.py:49 msgid "Base DN" msgstr "" -#: authentik/sources/ldap/models.py:52 +#: authentik/sources/ldap/models.py:51 msgid "Prepended to Base DN for User-queries." msgstr "" -#: authentik/sources/ldap/models.py:53 +#: authentik/sources/ldap/models.py:52 msgid "Addition User DN" msgstr "" -#: authentik/sources/ldap/models.py:57 +#: authentik/sources/ldap/models.py:56 msgid "Prepended to Base DN for Group-queries." msgstr "" -#: authentik/sources/ldap/models.py:58 +#: authentik/sources/ldap/models.py:57 msgid "Addition Group DN" msgstr "" -#: authentik/sources/ldap/models.py:64 +#: authentik/sources/ldap/models.py:63 msgid "Consider Objects matching this filter to be Users." msgstr "" -#: authentik/sources/ldap/models.py:67 +#: authentik/sources/ldap/models.py:66 msgid "Field which contains members of a group." msgstr "" -#: authentik/sources/ldap/models.py:71 +#: authentik/sources/ldap/models.py:70 msgid "Consider Objects matching this filter to be Groups." msgstr "" -#: authentik/sources/ldap/models.py:74 +#: authentik/sources/ldap/models.py:73 msgid "Field which contains a unique Identifier." msgstr "" -#: authentik/sources/ldap/models.py:81 +#: authentik/sources/ldap/models.py:80 msgid "Property mappings used for group creation/updating." msgstr "" -#: authentik/sources/ldap/models.py:146 +#: authentik/sources/ldap/models.py:145 msgid "LDAP Source" msgstr "" -#: authentik/sources/ldap/models.py:147 +#: authentik/sources/ldap/models.py:146 msgid "LDAP Sources" msgstr "" -#: authentik/sources/ldap/models.py:170 +#: authentik/sources/ldap/models.py:169 msgid "LDAP Property Mapping" msgstr "" -#: authentik/sources/ldap/models.py:171 +#: authentik/sources/ldap/models.py:170 msgid "LDAP Property Mappings" msgstr "" @@ -1048,91 +1044,91 @@ msgstr "" msgid "URL used by authentik to get user information." msgstr "" -#: authentik/sources/oauth/models.py:93 +#: authentik/sources/oauth/models.py:97 msgid "OAuth Source" msgstr "" -#: authentik/sources/oauth/models.py:94 +#: authentik/sources/oauth/models.py:98 msgid "OAuth Sources" msgstr "" -#: authentik/sources/oauth/models.py:103 +#: authentik/sources/oauth/models.py:107 msgid "GitHub OAuth Source" msgstr "" -#: authentik/sources/oauth/models.py:104 +#: authentik/sources/oauth/models.py:108 msgid "GitHub OAuth Sources" msgstr "" -#: authentik/sources/oauth/models.py:113 +#: authentik/sources/oauth/models.py:117 msgid "Twitter OAuth Source" msgstr "" -#: authentik/sources/oauth/models.py:114 +#: authentik/sources/oauth/models.py:118 msgid "Twitter OAuth Sources" msgstr "" -#: authentik/sources/oauth/models.py:123 +#: authentik/sources/oauth/models.py:127 msgid "Facebook OAuth Source" msgstr "" -#: authentik/sources/oauth/models.py:124 +#: authentik/sources/oauth/models.py:128 msgid "Facebook OAuth Sources" msgstr "" -#: authentik/sources/oauth/models.py:133 +#: authentik/sources/oauth/models.py:137 msgid "Discord OAuth Source" msgstr "" -#: authentik/sources/oauth/models.py:134 +#: authentik/sources/oauth/models.py:138 msgid "Discord OAuth Sources" msgstr "" -#: authentik/sources/oauth/models.py:143 +#: authentik/sources/oauth/models.py:147 msgid "Google OAuth Source" msgstr "" -#: authentik/sources/oauth/models.py:144 +#: authentik/sources/oauth/models.py:148 msgid "Google OAuth Sources" msgstr "" -#: authentik/sources/oauth/models.py:153 +#: authentik/sources/oauth/models.py:157 msgid "Azure AD OAuth Source" msgstr "" -#: authentik/sources/oauth/models.py:154 +#: authentik/sources/oauth/models.py:158 msgid "Azure AD OAuth Sources" msgstr "" -#: authentik/sources/oauth/models.py:163 +#: authentik/sources/oauth/models.py:167 msgid "OpenID OAuth Source" msgstr "" -#: authentik/sources/oauth/models.py:164 +#: authentik/sources/oauth/models.py:168 msgid "OpenID OAuth Sources" msgstr "" -#: authentik/sources/oauth/models.py:173 +#: authentik/sources/oauth/models.py:177 msgid "Apple OAuth Source" msgstr "" -#: authentik/sources/oauth/models.py:174 +#: authentik/sources/oauth/models.py:178 msgid "Apple OAuth Sources" msgstr "" -#: authentik/sources/oauth/models.py:183 +#: authentik/sources/oauth/models.py:187 msgid "Okta OAuth Source" msgstr "" -#: authentik/sources/oauth/models.py:184 +#: authentik/sources/oauth/models.py:188 msgid "Okta OAuth Sources" msgstr "" -#: authentik/sources/oauth/models.py:199 +#: authentik/sources/oauth/models.py:203 msgid "User OAuth Source Connection" msgstr "" -#: authentik/sources/oauth/models.py:200 +#: authentik/sources/oauth/models.py:204 msgid "User OAuth Source Connections" msgstr "" @@ -1152,88 +1148,88 @@ msgstr "" msgid "Plex token used to check friends" msgstr "" -#: authentik/sources/plex/models.py:91 +#: authentik/sources/plex/models.py:92 msgid "Plex Source" msgstr "" -#: authentik/sources/plex/models.py:92 +#: authentik/sources/plex/models.py:93 msgid "Plex Sources" msgstr "" -#: authentik/sources/plex/models.py:103 +#: authentik/sources/plex/models.py:104 msgid "User Plex Source Connection" msgstr "" -#: authentik/sources/plex/models.py:104 +#: authentik/sources/plex/models.py:105 msgid "User Plex Source Connections" msgstr "" -#: authentik/sources/saml/models.py:37 +#: authentik/sources/saml/models.py:36 msgid "Redirect Binding" msgstr "" -#: authentik/sources/saml/models.py:38 +#: authentik/sources/saml/models.py:37 msgid "POST Binding" msgstr "" -#: authentik/sources/saml/models.py:39 +#: authentik/sources/saml/models.py:38 msgid "POST Binding with auto-confirmation" msgstr "" -#: authentik/sources/saml/models.py:58 +#: authentik/sources/saml/models.py:57 msgid "Flow used before authentication." msgstr "" -#: authentik/sources/saml/models.py:65 +#: authentik/sources/saml/models.py:64 msgid "Issuer" msgstr "" -#: authentik/sources/saml/models.py:66 +#: authentik/sources/saml/models.py:65 msgid "Also known as Entity ID. Defaults the Metadata URL." msgstr "" -#: authentik/sources/saml/models.py:70 +#: authentik/sources/saml/models.py:69 msgid "SSO URL" msgstr "" -#: authentik/sources/saml/models.py:71 +#: authentik/sources/saml/models.py:70 msgid "URL that the initial Login request is sent to." msgstr "" -#: authentik/sources/saml/models.py:77 +#: authentik/sources/saml/models.py:76 msgid "SLO URL" msgstr "" -#: authentik/sources/saml/models.py:78 +#: authentik/sources/saml/models.py:77 msgid "Optional URL if your IDP supports Single-Logout." msgstr "" -#: authentik/sources/saml/models.py:84 +#: authentik/sources/saml/models.py:83 msgid "" "Allows authentication flows initiated by the IdP. This can be a security " "risk, as no validation of the request ID is done." msgstr "" -#: authentik/sources/saml/models.py:92 +#: authentik/sources/saml/models.py:91 msgid "" "NameID Policy sent to the IdP. Can be unset, in which case no Policy is sent." msgstr "" -#: authentik/sources/saml/models.py:103 +#: authentik/sources/saml/models.py:102 msgid "Delete temporary users after" msgstr "" -#: authentik/sources/saml/models.py:121 +#: authentik/sources/saml/models.py:120 msgid "" "Keypair which is used to sign outgoing requests. Leave empty to disable " "signing." msgstr "" -#: authentik/sources/saml/models.py:189 +#: authentik/sources/saml/models.py:188 msgid "SAML Source" msgstr "" -#: authentik/sources/saml/models.py:190 +#: authentik/sources/saml/models.py:189 msgid "SAML Sources" msgstr "" @@ -1298,35 +1294,35 @@ msgstr "" msgid "TOTP Authenticator Setup Stages" msgstr "" -#: authentik/stages/authenticator_validate/challenge.py:85 +#: authentik/stages/authenticator_validate/challenge.py:99 msgid "Invalid Token" msgstr "" -#: authentik/stages/authenticator_validate/models.py:18 +#: authentik/stages/authenticator_validate/models.py:17 msgid "TOTP" msgstr "" -#: authentik/stages/authenticator_validate/models.py:19 +#: authentik/stages/authenticator_validate/models.py:18 msgid "WebAuthn" msgstr "" -#: authentik/stages/authenticator_validate/models.py:20 +#: authentik/stages/authenticator_validate/models.py:19 msgid "Duo" msgstr "" -#: authentik/stages/authenticator_validate/models.py:21 +#: authentik/stages/authenticator_validate/models.py:20 msgid "SMS" msgstr "" -#: authentik/stages/authenticator_validate/models.py:59 +#: authentik/stages/authenticator_validate/models.py:58 msgid "Device classes which can be used to authenticate" msgstr "" -#: authentik/stages/authenticator_validate/models.py:81 +#: authentik/stages/authenticator_validate/models.py:80 msgid "Authenticator Validation Stage" msgstr "" -#: authentik/stages/authenticator_validate/models.py:82 +#: authentik/stages/authenticator_validate/models.py:81 msgid "Authenticator Validation Stages" msgstr "" @@ -1346,53 +1342,53 @@ msgstr "" msgid "WebAuthn Devices" msgstr "" -#: authentik/stages/captcha/models.py:16 +#: authentik/stages/captcha/models.py:15 msgid "" "Public key, acquired from https://www.google.com/recaptcha/intro/v3.html" msgstr "" -#: authentik/stages/captcha/models.py:19 +#: authentik/stages/captcha/models.py:18 msgid "" "Private key, acquired from https://www.google.com/recaptcha/intro/v3.html" msgstr "" -#: authentik/stages/captcha/models.py:40 +#: authentik/stages/captcha/models.py:39 msgid "Captcha Stage" msgstr "" -#: authentik/stages/captcha/models.py:41 +#: authentik/stages/captcha/models.py:40 msgid "Captcha Stages" msgstr "" -#: authentik/stages/consent/models.py:53 +#: authentik/stages/consent/models.py:52 msgid "Consent Stage" msgstr "" -#: authentik/stages/consent/models.py:54 +#: authentik/stages/consent/models.py:53 msgid "Consent Stages" msgstr "" -#: authentik/stages/consent/models.py:69 +#: authentik/stages/consent/models.py:68 msgid "User Consent" msgstr "" -#: authentik/stages/consent/models.py:70 +#: authentik/stages/consent/models.py:69 msgid "User Consents" msgstr "" -#: authentik/stages/deny/models.py:32 +#: authentik/stages/deny/models.py:31 msgid "Deny Stage" msgstr "" -#: authentik/stages/deny/models.py:33 +#: authentik/stages/deny/models.py:32 msgid "Deny Stages" msgstr "" -#: authentik/stages/dummy/models.py:34 +#: authentik/stages/dummy/models.py:33 msgid "Dummy Stage" msgstr "" -#: authentik/stages/dummy/models.py:35 +#: authentik/stages/dummy/models.py:34 msgid "Dummy Stages" msgstr "" @@ -1506,61 +1502,65 @@ msgid "" " " msgstr "" -#: authentik/stages/identification/models.py:43 +#: authentik/stages/identification/models.py:42 msgid "" "When set, shows a password field, instead of showing the password field as " "seaprate step." msgstr "" -#: authentik/stages/identification/models.py:49 +#: authentik/stages/identification/models.py:48 msgid "When enabled, user fields are matched regardless of their casing." msgstr "" -#: authentik/stages/identification/models.py:69 +#: authentik/stages/identification/models.py:68 msgid "Optional enrollment flow, which is linked at the bottom of the page." msgstr "" -#: authentik/stages/identification/models.py:78 +#: authentik/stages/identification/models.py:77 msgid "Optional recovery flow, which is linked at the bottom of the page." msgstr "" -#: authentik/stages/identification/models.py:82 +#: authentik/stages/identification/models.py:86 +msgid "Optional passwordless flow, which is linked at the bottom of the page." +msgstr "" + +#: authentik/stages/identification/models.py:90 msgid "Specify which sources should be shown." msgstr "" -#: authentik/stages/identification/models.py:104 +#: authentik/stages/identification/models.py:112 msgid "Identification Stage" msgstr "" -#: authentik/stages/identification/models.py:105 +#: authentik/stages/identification/models.py:113 msgid "Identification Stages" msgstr "" -#: authentik/stages/identification/stage.py:174 +#: authentik/stages/identification/stage.py:175 msgid "Log in" msgstr "" -#: authentik/stages/invitation/models.py:47 +#: authentik/stages/invitation/models.py:46 msgid "Invitation Stage" msgstr "" -#: authentik/stages/invitation/models.py:48 +#: authentik/stages/invitation/models.py:47 msgid "Invitation Stages" msgstr "" -#: authentik/stages/invitation/models.py:58 +#: authentik/stages/invitation/models.py:57 msgid "When enabled, the invitation will be deleted after usage." msgstr "" -#: authentik/stages/invitation/models.py:65 +#: authentik/stages/invitation/models.py:64 msgid "Optional fixed data to enforce on user enrollment." msgstr "" -#: authentik/stages/invitation/models.py:73 +#: authentik/stages/invitation/models.py:72 msgid "Invitation" msgstr "" -#: authentik/stages/invitation/models.py:74 +#: authentik/stages/invitation/models.py:73 msgid "Invitations" msgstr "" @@ -1640,11 +1640,11 @@ msgstr "" msgid "Passwords don't match." msgstr "" -#: authentik/stages/user_delete/models.py:33 +#: authentik/stages/user_delete/models.py:32 msgid "User Delete Stage" msgstr "" -#: authentik/stages/user_delete/models.py:34 +#: authentik/stages/user_delete/models.py:33 msgid "User Delete Stages" msgstr "" @@ -1652,17 +1652,17 @@ msgstr "" msgid "No Pending User." msgstr "" -#: authentik/stages/user_login/models.py:20 +#: authentik/stages/user_login/models.py:19 msgid "" "Determines how long a session lasts. Default of 0 means that the sessions " "lasts until the browser is closed. (Format: hours=-1;minutes=-2;seconds=-3)" msgstr "" -#: authentik/stages/user_login/models.py:44 +#: authentik/stages/user_login/models.py:43 msgid "User Login Stage" msgstr "" -#: authentik/stages/user_login/models.py:45 +#: authentik/stages/user_login/models.py:44 msgid "User Login Stages" msgstr "" @@ -1674,27 +1674,27 @@ msgstr "" msgid "Successfully logged in!" msgstr "" -#: authentik/stages/user_logout/models.py:32 +#: authentik/stages/user_logout/models.py:31 msgid "User Logout Stage" msgstr "" -#: authentik/stages/user_logout/models.py:33 +#: authentik/stages/user_logout/models.py:32 msgid "User Logout Stages" msgstr "" -#: authentik/stages/user_write/models.py:19 +#: authentik/stages/user_write/models.py:18 msgid "When set, newly created users are inactive and cannot login." msgstr "" -#: authentik/stages/user_write/models.py:27 +#: authentik/stages/user_write/models.py:26 msgid "Optionally add newly created users to this group." msgstr "" -#: authentik/stages/user_write/models.py:48 +#: authentik/stages/user_write/models.py:47 msgid "User Write Stage" msgstr "" -#: authentik/stages/user_write/models.py:49 +#: authentik/stages/user_write/models.py:48 msgid "User Write Stages" msgstr "" @@ -1702,16 +1702,16 @@ msgstr "" msgid "No Pending data." msgstr "" -#: authentik/tenants/models.py:17 +#: authentik/tenants/models.py:18 msgid "" "Domain that activates this tenant. Can be a superset, i.e. `a.b` for `aa.b` " "and `ba.b`" msgstr "" -#: authentik/tenants/models.py:61 +#: authentik/tenants/models.py:70 msgid "Tenant" msgstr "" -#: authentik/tenants/models.py:62 +#: authentik/tenants/models.py:71 msgid "Tenants" msgstr "" diff --git a/web/src/api/Users.ts b/web/src/api/Users.ts index cfe1ef9ea..d3cc0497a 100644 --- a/web/src/api/Users.ts +++ b/web/src/api/Users.ts @@ -1,10 +1,21 @@ import { CoreApi, SessionUser } from "@goauthentik/api"; +import { i18n } from "@lingui/core"; import { DEFAULT_CONFIG } from "./Config"; let globalMePromise: Promise; export function me(): Promise { if (!globalMePromise) { - globalMePromise = new CoreApi(DEFAULT_CONFIG).coreUsersMeRetrieve().catch((ex) => { + globalMePromise = new CoreApi(DEFAULT_CONFIG).coreUsersMeRetrieve().then((user) => { + if (!user.user.settings || !("locale" in user.user.settings)) { + return user; + } + const locale = user.user.settings.locale; + if (locale && locale !== "") { + console.debug(`authentik/locale: Activating user's configured locale '${locale}'`); + i18n.activate(locale); + } + return user; + }).catch((ex) => { const defaultUser: SessionUser = { user: { pk: -1, diff --git a/web/src/common/config.ts b/web/src/common/config.ts index 9ab8c8176..619fc6be7 100644 --- a/web/src/common/config.ts +++ b/web/src/common/config.ts @@ -1,3 +1,5 @@ +import { UserSelf } from "@goauthentik/api"; + import { me } from "../api/Users"; export enum UserDisplay { @@ -29,6 +31,7 @@ export interface UIConfig { pagination: { perPage: number; }; + locale: string; } export class DefaultUIConfig implements UIConfig { @@ -49,22 +52,25 @@ export class DefaultUIConfig implements UIConfig { pagination = { perPage: 20, }; + locale = ""; } let globalUiConfig: Promise; +export function getConfigForUser(user: UserSelf): UIConfig { + const settings = user.settings; + let config = new DefaultUIConfig(); + if (!settings) { + return config; + } + config = Object.assign(new DefaultUIConfig(), settings); + return config; +} + export function uiConfig(): Promise { if (!globalUiConfig) { globalUiConfig = me().then((user) => { - const settings = user.user.settings; - let config = new DefaultUIConfig(); - if (!settings) { - return config; - } - if ("userInterface" in settings) { - config = Object.assign(new DefaultUIConfig(), settings.userInterface); - } - return config; + return getConfigForUser(user.user); }); } return globalUiConfig; diff --git a/web/src/interfaces/locale.ts b/web/src/interfaces/locale.ts index 524132922..82fad3826 100644 --- a/web/src/interfaces/locale.ts +++ b/web/src/interfaces/locale.ts @@ -1,21 +1,51 @@ import { en, fr, tr } from "make-plural/plurals"; -import { i18n } from "@lingui/core"; +import { Messages, i18n } from "@lingui/core"; import { detect, fromNavigator, fromStorage, fromUrl } from "@lingui/detect-locale"; +import { t } from "@lingui/macro"; import { messages as localeEN } from "../locales/en"; import { messages as localeFR_FR } from "../locales/fr_FR"; import { messages as localeDEBUG } from "../locales/pseudo-LOCALE"; import { messages as localeTR } from "../locales/tr"; -i18n.loadLocaleData("en", { plurals: en }); -i18n.loadLocaleData("debug", { plurals: en }); -i18n.loadLocaleData("tr", { plurals: tr }); -i18n.loadLocaleData("fr_FR", { plurals: fr }); -i18n.load("en", localeEN); -i18n.load("tr", localeTR); -i18n.load("fr_FR", localeFR_FR); -i18n.load("debug", localeDEBUG); +export const LOCALES: { + code: string; + label: string; + // eslint-disable-next-line @typescript-eslint/ban-types + plurals: Function; + locale: Messages; +}[] = [ + { + code: "en", + plurals: en, + label: t`English`, + locale: localeEN, + }, + { + code: "debug", + plurals: en, + label: t`Debug`, + locale: localeDEBUG, + }, + { + code: "fr_FR", + plurals: fr, + label: t`French`, + locale: localeFR_FR, + }, + { + code: "tr", + plurals: tr, + label: t`Turkish`, + locale: localeTR, + }, +]; + +LOCALES.forEach((locale) => { + i18n.loadLocaleData(locale.code, { plurals: locale.plurals }); + i18n.load(locale.code, locale.locale); +}); const DEFAULT_FALLBACK = () => "en"; diff --git a/web/src/locales/en.po b/web/src/locales/en.po index 83dfd36d1..2762a562a 100644 --- a/web/src/locales/en.po +++ b/web/src/locales/en.po @@ -516,6 +516,10 @@ msgstr "Authorize URL" msgid "Authorized application:" msgstr "Authorized application:" +#: src/user/user-settings/details/UserDetailsForm.ts +msgid "Auto-detect (based on your browser)" +msgstr "Auto-detect (based on your browser)" + #: src/interfaces/UserInterface.ts msgid "Avatar image" msgstr "Avatar image" @@ -1317,6 +1321,10 @@ msgstr "Date Time" msgid "Deactivate" msgstr "Deactivate" +#: src/interfaces/locale.ts +msgid "Debug" +msgstr "Debug" + #: src/pages/flows/FlowForm.ts msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." msgstr "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." @@ -1715,6 +1723,10 @@ msgstr "Enabled" msgid "Enabling this toggle will create a group named after the user, with the user as member." msgstr "Enabling this toggle will create a group named after the user, with the user as member." +#: src/interfaces/locale.ts +msgid "English" +msgstr "English" + #: src/user/user-settings/mfa/MFADevicesPage.ts msgid "Enroll" msgstr "Enroll" @@ -2122,6 +2134,10 @@ msgstr "Forward auth (domain-level)" msgid "Forward auth (single application)" msgstr "Forward auth (single application)" +#: src/interfaces/locale.ts +msgid "French" +msgstr "French" + #: src/pages/property-mappings/PropertyMappingSAMLForm.ts msgid "Friendly Name" msgstr "Friendly Name" @@ -2742,6 +2758,10 @@ msgstr "Loading..." msgid "Local" msgstr "Local" +#: src/user/user-settings/details/UserDetailsForm.ts +msgid "Locale" +msgstr "Locale" + #: src/pages/stages/user_login/UserLoginStageForm.ts msgid "Log the currently pending user in." msgstr "Log the currently pending user in." @@ -5233,6 +5253,10 @@ msgstr "Transient" msgid "Transports" msgstr "Transports" +#: src/interfaces/locale.ts +msgid "Turkish" +msgstr "Turkish" + #: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts msgid "Twilio" msgstr "Twilio" diff --git a/web/src/locales/fr_FR.po b/web/src/locales/fr_FR.po index 8477ca28b..b6bbaaddf 100644 --- a/web/src/locales/fr_FR.po +++ b/web/src/locales/fr_FR.po @@ -520,6 +520,10 @@ msgstr "URL d'authorisation" msgid "Authorized application:" msgstr "Application autorisée :" +#: src/user/user-settings/details/UserDetailsForm.ts +msgid "Auto-detect (based on your browser)" +msgstr "" + #: src/interfaces/UserInterface.ts msgid "Avatar image" msgstr "Image d'avatar" @@ -1316,6 +1320,10 @@ msgstr "Date et heure" msgid "Deactivate" msgstr "Désactiver" +#: src/interfaces/locale.ts +msgid "Debug" +msgstr "" + #: src/pages/flows/FlowForm.ts msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." msgstr "Détermine l'usage de ce flux. Par exemple, un flux d'authentification est la destination d'un visiteur d'authentik non authentifié." @@ -1702,6 +1710,10 @@ msgstr "Activé" msgid "Enabling this toggle will create a group named after the user, with the user as member." msgstr "Activer cette option va créer un groupe du même nom que l'utilisateur dont il sera membre." +#: src/interfaces/locale.ts +msgid "English" +msgstr "" + #: src/user/user-settings/mfa/MFADevicesPage.ts msgid "Enroll" msgstr "" @@ -2108,6 +2120,10 @@ msgstr "" msgid "Forward auth (single application)" msgstr "Transférer l'authentification (application unique)" +#: src/interfaces/locale.ts +msgid "French" +msgstr "" + #: src/pages/property-mappings/PropertyMappingSAMLForm.ts msgid "Friendly Name" msgstr "Nom amical" @@ -2722,6 +2738,10 @@ msgstr "Chargement en cours..." msgid "Local" msgstr "Local" +#: src/user/user-settings/details/UserDetailsForm.ts +msgid "Locale" +msgstr "" + #: src/pages/stages/user_login/UserLoginStageForm.ts msgid "Log the currently pending user in." msgstr "Ouvre la session de l'utilisateur courant." @@ -5175,6 +5195,10 @@ msgstr "Transitoire" msgid "Transports" msgstr "Transports" +#: src/interfaces/locale.ts +msgid "Turkish" +msgstr "" + #: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts msgid "Twilio" msgstr "" diff --git a/web/src/locales/pseudo-LOCALE.po b/web/src/locales/pseudo-LOCALE.po index 29bad33f6..cf21cc1f7 100644 --- a/web/src/locales/pseudo-LOCALE.po +++ b/web/src/locales/pseudo-LOCALE.po @@ -512,6 +512,10 @@ msgstr "" msgid "Authorized application:" msgstr "" +#: src/user/user-settings/details/UserDetailsForm.ts +msgid "Auto-detect (based on your browser)" +msgstr "" + #: src/interfaces/UserInterface.ts msgid "Avatar image" msgstr "" @@ -1311,6 +1315,10 @@ msgstr "" msgid "Deactivate" msgstr "" +#: src/interfaces/locale.ts +msgid "Debug" +msgstr "" + #: src/pages/flows/FlowForm.ts msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." msgstr "" @@ -1707,6 +1715,10 @@ msgstr "" msgid "Enabling this toggle will create a group named after the user, with the user as member." msgstr "" +#: src/interfaces/locale.ts +msgid "English" +msgstr "" + #: src/user/user-settings/mfa/MFADevicesPage.ts msgid "Enroll" msgstr "" @@ -2114,6 +2126,10 @@ msgstr "" msgid "Forward auth (single application)" msgstr "" +#: src/interfaces/locale.ts +msgid "French" +msgstr "" + #: src/pages/property-mappings/PropertyMappingSAMLForm.ts msgid "Friendly Name" msgstr "" @@ -2732,6 +2748,10 @@ msgstr "" msgid "Local" msgstr "" +#: src/user/user-settings/details/UserDetailsForm.ts +msgid "Locale" +msgstr "" + #: src/pages/stages/user_login/UserLoginStageForm.ts msgid "Log the currently pending user in." msgstr "" @@ -5213,6 +5233,10 @@ msgstr "" msgid "Transports" msgstr "" +#: src/interfaces/locale.ts +msgid "Turkish" +msgstr "" + #: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts msgid "Twilio" msgstr "" diff --git a/web/src/locales/tr.po b/web/src/locales/tr.po index 7c4ecef38..db03b44ad 100644 --- a/web/src/locales/tr.po +++ b/web/src/locales/tr.po @@ -514,6 +514,10 @@ msgstr "URL'yi yetkilendirme" msgid "Authorized application:" msgstr "Yetkili başvuru:" +#: src/user/user-settings/details/UserDetailsForm.ts +msgid "Auto-detect (based on your browser)" +msgstr "" + #: src/interfaces/UserInterface.ts msgid "Avatar image" msgstr "Avatar resmi" @@ -1304,6 +1308,10 @@ msgstr "Tarih Saati" msgid "Deactivate" msgstr "Devre dışı bırak" +#: src/interfaces/locale.ts +msgid "Debug" +msgstr "" + #: src/pages/flows/FlowForm.ts msgid "Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik." msgstr "Bu Akış'ın ne için kullanıldığına karar verir. Örneğin, kimliği doğrulanmamış bir kullanıcı authentik ziyaret ettiğinde kimlik doğrulama akışı yönlendirir." @@ -1682,6 +1690,10 @@ msgstr "Etkin" msgid "Enabling this toggle will create a group named after the user, with the user as member." msgstr "Bu geçiş özelliğini etkinleştirmek, kullanıcının adını taşıyan ve kullanıcının üye olduğu bir grup oluşturur." +#: src/interfaces/locale.ts +msgid "English" +msgstr "" + #: src/user/user-settings/mfa/MFADevicesPage.ts msgid "Enroll" msgstr "Kaydolun" @@ -2085,6 +2097,10 @@ msgstr "İleri kimlik doğrulama (alan düzeyi)" msgid "Forward auth (single application)" msgstr "İleri kimlik doğrulaması (tek uygulama)" +#: src/interfaces/locale.ts +msgid "French" +msgstr "" + #: src/pages/property-mappings/PropertyMappingSAMLForm.ts msgid "Friendly Name" msgstr "Dostça İsim" @@ -2696,6 +2712,10 @@ msgstr "Yükleniyor..." msgid "Local" msgstr "Yerel" +#: src/user/user-settings/details/UserDetailsForm.ts +msgid "Locale" +msgstr "" + #: src/pages/stages/user_login/UserLoginStageForm.ts msgid "Log the currently pending user in." msgstr "Şu anda bekleyen kullanıcıyı oturum açın." @@ -5132,6 +5152,10 @@ msgstr "Geçici" msgid "Transports" msgstr "Taşımacılık" +#: src/interfaces/locale.ts +msgid "Turkish" +msgstr "" + #: src/pages/stages/authenticator_sms/AuthenticatorSMSStageForm.ts msgid "Twilio" msgstr "Twilio" diff --git a/web/src/user/user-settings/details/UserDetailsForm.ts b/web/src/user/user-settings/details/UserDetailsForm.ts index b27b549cc..175acb883 100644 --- a/web/src/user/user-settings/details/UserDetailsForm.ts +++ b/web/src/user/user-settings/details/UserDetailsForm.ts @@ -1,3 +1,4 @@ +import { i18n } from "@lingui/core"; import { t } from "@lingui/macro"; import { TemplateResult, html } from "lit"; @@ -9,19 +10,25 @@ import { CoreApi, UserSelf } from "@goauthentik/api"; import { DEFAULT_CONFIG, tenant } from "../../../api/Config"; import { me } from "../../../api/Users"; +import { getConfigForUser, uiConfig } from "../../../common/config"; import "../../../elements/EmptyState"; import "../../../elements/forms/Form"; import "../../../elements/forms/FormElement"; import "../../../elements/forms/HorizontalFormElement"; import { ModelForm } from "../../../elements/forms/ModelForm"; +import { LOCALES } from "../../../interfaces/locale"; @customElement("ak-user-details-form") export class UserDetailsForm extends ModelForm { + currentLocale?: string; + viewportCheck = false; // eslint-disable-next-line @typescript-eslint/no-unused-vars loadInstance(pk: number): Promise { return me().then((user) => { + const config = getConfigForUser(user.user); + this.currentLocale = config.locale; return user.user; }); } @@ -31,6 +38,13 @@ export class UserDetailsForm extends ModelForm { } send = (data: UserSelf): Promise => { + const newConfig = getConfigForUser(data); + const newLocale = LOCALES.find((locale) => locale.code === newConfig.locale); + if (newLocale) { + i18n.activate(newLocale.code); + } else { + console.debug(`authentik/user: invalid locale: '${newConfig.locale}'`); + } return new CoreApi(DEFAULT_CONFIG) .coreUsersUpdateSelfUpdate({ userSelfRequest: data, @@ -44,61 +58,84 @@ export class UserDetailsForm extends ModelForm { if (!this.instance) { return html` `; } - return html`
- - -

- ${t`Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.`} -

-
- - -

${t`User's display name.`}

-
- - - + return html`${until( + uiConfig().then((config) => { + return html` + + +

+ ${t`Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.`} +

+
+ + +

${t`User's display name.`}

+
+ + + + + + -
-
-
- - ${until( - tenant().then((tenant) => { - if (tenant.flowUnenrollment) { - return html` - ${t`Delete account`} - `; - } - return html``; - }), - )} +
+
+
+ + ${until( + tenant().then((tenant) => { + if (tenant.flowUnenrollment) { + return html` + ${t`Delete account`} + `; + } + return html``; + }), + )} +
+
-
-
- `; + `; + }), + )}`; } }