masks-server 0.12.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/concerns/masks/server/scim_endpoint.rb +2 -2
- data/app/controllers/masks/server/account_exports_controller.rb +2 -2
- data/app/controllers/masks/server/addresses_controller.rb +2 -3
- data/app/controllers/masks/server/authenticator_apps_controller.rb +2 -3
- data/app/controllers/masks/server/authorize_controller.rb +2 -2
- data/app/controllers/masks/server/device_authorizations_controller.rb +2 -2
- data/app/controllers/masks/server/device_verifications_controller.rb +2 -2
- data/app/controllers/masks/server/enrollments_controller.rb +4 -4
- data/app/controllers/masks/server/forward_auth_controller.rb +2 -2
- data/app/controllers/masks/server/introspections_controller.rb +2 -2
- data/app/controllers/masks/server/logins_controller.rb +10 -12
- data/app/controllers/masks/server/manage_controller.rb +1 -0
- data/app/controllers/masks/server/organization_members_controller.rb +2 -2
- data/app/controllers/masks/server/passwords_controller.rb +2 -3
- data/app/controllers/masks/server/pushed_authorizations_controller.rb +2 -2
- data/app/controllers/masks/server/received_signals_controller.rb +2 -2
- data/app/controllers/masks/server/registrations_controller.rb +2 -2
- data/app/controllers/masks/server/revocations_controller.rb +2 -2
- data/app/controllers/masks/server/saml_controller.rb +2 -2
- data/app/controllers/masks/server/scim/metadata_controller.rb +1 -1
- data/app/controllers/masks/server/sign_in_approvals_controller.rb +2 -3
- data/app/controllers/masks/server/tokens_controller.rb +2 -2
- data/app/controllers/masks/server/verifications_controller.rb +2 -3
- data/app/graphql/masks/server/manage/types/health_check_type.rb +1 -1
- data/app/ldap/masks/server/ldap/gate.rb +14 -16
- data/app/models/masks/server/app_passwords.rb +7 -13
- data/app/models/masks/server/app_preset.rb +1 -1
- data/app/models/masks/server/client.rb +24 -0
- data/app/models/masks/server/client_metadata_document.rb +4 -8
- data/app/models/masks/server/confirmation_code.rb +2 -2
- data/app/models/masks/server/declared.rb +3 -1
- data/app/models/masks/server/event.rb +2 -2
- data/app/models/masks/server/health.rb +70 -3
- data/app/models/masks/server/saml_identity/farewells.rb +1 -0
- data/app/models/masks/server/tenant.rb +48 -4
- data/app/models/masks/server/throttle.rb +165 -0
- data/app/views/masks/server/handshakes/show.html.erb +2 -8
- data/app/views/masks/server/logins/_consent.html.erb +43 -44
- data/app/views/masks/server/logins/_enrol.html.erb +1 -1
- data/app/views/masks/server/logins/_setup_configure.html.erb +2 -6
- data/app/views/masks/server/logins/_signup.html.erb +2 -9
- data/app/views/masks/server/logins/_signup_credentials.html.erb +1 -2
- data/app/views/masks/server/logins/_signup_head.html.erb +1 -11
- data/config/locales/de/account.yml +4 -4
- data/config/locales/de/handshakes.yml +6 -6
- data/config/locales/de/logins.yml +44 -30
- data/config/locales/de/manage/health.yml +9 -2
- data/config/locales/en/account.yml +4 -4
- data/config/locales/en/handshakes.yml +6 -6
- data/config/locales/en/logins.yml +44 -30
- data/config/locales/en/manage/health.yml +9 -2
- data/config/locales/es/account.yml +4 -4
- data/config/locales/es/handshakes.yml +6 -6
- data/config/locales/es/logins.yml +42 -28
- data/config/locales/es/manage/health.yml +9 -2
- data/config/locales/fr/account.yml +4 -4
- data/config/locales/fr/handshakes.yml +6 -6
- data/config/locales/fr/logins.yml +43 -29
- data/config/locales/fr/manage/health.yml +9 -2
- data/db/migrate/20261031100000_default_key_rotation_to_ninety_days.rb +5 -0
- data/lib/generators/masks/server/install/install_generator.rb +19 -0
- data/lib/masks/server/configuration.rb +14 -8
- data/lib/masks/server/engine.rb +2 -1
- data/lib/masks/server/forwarding.rb +26 -3
- data/lib/masks/server/schema_reference.rb +1 -1
- data/lib/masks/server/tenancy/middleware.rb +4 -7
- data/lib/masks/server/tenant_isolation.rb +12 -0
- data/public/masks-assets/.vite/manifest.json +3 -3
- data/public/masks-assets/assets/app-Cfbt-A5V.css +2 -0
- data/public/masks-assets/assets/login-BDggujiZ.js +6 -0
- data/public/masks-assets/assets/login-BDggujiZ.js.map +1 -0
- data/public/masks-assets/assets/{manage-DpVxe5sv.js → manage-VgOqKj7N.js} +2 -2
- data/public/masks-assets/assets/manage-VgOqKj7N.js.map +1 -0
- data/version.txt +1 -1
- metadata +8 -6
- data/public/masks-assets/assets/app-BXOScMjL.css +0 -2
- data/public/masks-assets/assets/login-C21_jb6L.js +0 -4
- data/public/masks-assets/assets/login-C21_jb6L.js.map +0 -1
- data/public/masks-assets/assets/manage-DpVxe5sv.js.map +0 -1
|
@@ -16,7 +16,7 @@ es:
|
|
|
16
16
|
name: "Nombre"
|
|
17
17
|
phone: "Teléfono"
|
|
18
18
|
password: "Contraseña"
|
|
19
|
-
not_you: "
|
|
19
|
+
not_you: "Usar otra cuenta"
|
|
20
20
|
sign_out: "Cerrar sesión"
|
|
21
21
|
use_passkey: "Usar una llave de acceso"
|
|
22
22
|
or: "o"
|
|
@@ -40,10 +40,12 @@ es:
|
|
|
40
40
|
tab_confirmation: "Confirmación"
|
|
41
41
|
setup_cap: "¡Te damos la bienvenida!"
|
|
42
42
|
setup_title: "Configurar"
|
|
43
|
-
signup_title: "
|
|
43
|
+
signup_title: "Crea tu cuenta"
|
|
44
44
|
token: "Token de configuración"
|
|
45
|
-
token_hint: "
|
|
46
|
-
origin: "
|
|
45
|
+
token_hint: "Está impreso en el registro del servidor."
|
|
46
|
+
origin: "Este masks responde en %{origin}."
|
|
47
|
+
pick_nickname: "Elegir un apodo"
|
|
48
|
+
nickname_hint: "Otras personas lo ven. Déjalo como está para usar %{suggested}."
|
|
47
49
|
once: "Esta pantalla no volverá a aparecer."
|
|
48
50
|
docs: "Lee la documentación."
|
|
49
51
|
confirm: "Confirmar contraseña"
|
|
@@ -57,15 +59,15 @@ es:
|
|
|
57
59
|
proving: "Comprobando este navegador"
|
|
58
60
|
|
|
59
61
|
identify:
|
|
60
|
-
heading: "
|
|
62
|
+
heading: "Iniciar sesión"
|
|
61
63
|
heading_to: "Iniciar sesión en %{client}"
|
|
62
|
-
identifier: "
|
|
63
|
-
signup_hint: "¿
|
|
64
|
+
identifier: "Correo o apodo"
|
|
65
|
+
signup_hint: "¿Nuevo aquí? Escribe tu correo y masks te crea una cuenta."
|
|
64
66
|
|
|
65
67
|
first_factor:
|
|
66
68
|
title: "Escribe tu contraseña"
|
|
67
69
|
title_code: "Iniciar sesión con un código"
|
|
68
|
-
forgot: "¿
|
|
70
|
+
forgot: "¿Olvidaste tu contraseña?"
|
|
69
71
|
email_me: "Enviarme un código por correo"
|
|
70
72
|
email_only: "Enviarme un código por correo"
|
|
71
73
|
|
|
@@ -76,9 +78,9 @@ es:
|
|
|
76
78
|
sent_again: "Enviado"
|
|
77
79
|
|
|
78
80
|
second_factor:
|
|
79
|
-
title: "
|
|
80
|
-
title_passkey: "
|
|
81
|
-
trust: "
|
|
81
|
+
title: "Confirma que eres tú"
|
|
82
|
+
title_passkey: "Confirma que eres tú con tu llave de acceso"
|
|
83
|
+
trust: "Saltar esto en este dispositivo durante %{duration}"
|
|
82
84
|
use_backup_code: "Usar un código de respaldo"
|
|
83
85
|
stuck_insecure: "El segundo factor de esta cuenta es una llave de acceso, y el navegador solo ofrece llaves de acceso a páginas servidas por HTTPS. Abre esta página por HTTPS para continuar."
|
|
84
86
|
stuck_unsupported: "El segundo factor de esta cuenta es una llave de acceso, y este navegador no admite llaves de acceso. Abre esta página en un navegador que las admita para continuar."
|
|
@@ -102,15 +104,25 @@ es:
|
|
|
102
104
|
|
|
103
105
|
enrol:
|
|
104
106
|
title: "Protege tu cuenta"
|
|
105
|
-
lede: "
|
|
106
|
-
lede_optional: "
|
|
107
|
+
lede: "Elige una forma de confirmar que eres tú al iniciar sesión. Puedes añadir más después."
|
|
108
|
+
lede_optional: "Elige una forma de confirmar que eres tú al iniciar sesión, o sáltalo por ahora."
|
|
109
|
+
on_title: "Tu cuenta está protegida"
|
|
110
|
+
on_lede: "Así confirmas que eres tú al iniciar sesión."
|
|
111
|
+
on_label: "Activado"
|
|
112
|
+
passkey: "Llave de acceso"
|
|
107
113
|
otp: "Aplicación de autenticación"
|
|
114
|
+
otp_about: "Una app como Google Authenticator o 1Password muestra un código de seis dígitos."
|
|
108
115
|
otp_on: "Activada"
|
|
109
|
-
scan_hint: "
|
|
116
|
+
scan_hint: "Escanea esto con tu app de autenticación, o escribe la clave en ella:"
|
|
117
|
+
passkey_about: "Tu teléfono o computadora comprueba que eres tú con tu cara, tu huella o tu PIN."
|
|
118
|
+
codes_email_about: "Un código llega a %{to} cada vez que inicias sesión."
|
|
119
|
+
codes_sms_about: "Un código llega a %{to} por mensaje de texto cada vez que inicias sesión."
|
|
120
|
+
another_way: "Elegir otra forma"
|
|
121
|
+
add_way: "Añadir otra forma"
|
|
110
122
|
open: "Abrir en tu aplicación de autenticación"
|
|
111
123
|
turn_on: "Activarla"
|
|
112
124
|
passkeys: "Llaves de acceso"
|
|
113
|
-
passkeys_none: "Ninguna todavía.
|
|
125
|
+
passkeys_none: "Ninguna todavía."
|
|
114
126
|
passkeys_some: "%{count} añadidas"
|
|
115
127
|
add_passkey: "Añadir una llave de acceso"
|
|
116
128
|
add_another_passkey: "Añadir otra"
|
|
@@ -118,17 +130,17 @@ es:
|
|
|
118
130
|
codes_email_hint: "Un código enviado a %{to} confirma cada inicio de sesión."
|
|
119
131
|
codes_sms: "Códigos por SMS"
|
|
120
132
|
codes_sms_hint: "Un código enviado por SMS a %{to} confirma cada inicio de sesión."
|
|
121
|
-
send_code: "
|
|
133
|
+
send_code: "Enviarme un código"
|
|
122
134
|
sent_to: "Enviado a %{to}."
|
|
123
135
|
backup_codes: "Códigos de respaldo"
|
|
124
|
-
backup_codes_waiting: "Se
|
|
125
|
-
backup_codes_hint: "Cada
|
|
136
|
+
backup_codes_waiting: "Se crean cuando una forma de arriba esté activada."
|
|
137
|
+
backup_codes_hint: "Cada código te deja entrar una vez si pierdes tu otra forma de entrar. Guárdalos ahora. No se muestran otra vez."
|
|
126
138
|
backup_codes_left: "Quedan %{count}"
|
|
127
139
|
backup_codes_file: "Códigos de respaldo de %{account} en %{origin}"
|
|
128
140
|
copy: "Copiarlos"
|
|
129
141
|
copied: "Copiados"
|
|
130
142
|
download: "Descargarlos"
|
|
131
|
-
kept: "Guardé mis códigos de respaldo
|
|
143
|
+
kept: "Guardé mis códigos de respaldo"
|
|
132
144
|
done: "Continuar"
|
|
133
145
|
skip: "Omitir por ahora"
|
|
134
146
|
|
|
@@ -163,7 +175,7 @@ es:
|
|
|
163
175
|
prove_email:
|
|
164
176
|
title: "Revisa tu correo"
|
|
165
177
|
lede: "Te enviamos un código de seis dígitos a %{email}. Escríbelo para continuar."
|
|
166
|
-
no_mailer: "Este servidor
|
|
178
|
+
no_mailer: "Este servidor aún no puede enviar correo, así que no puede comprobar tu dirección. Inicia sesión con tu apodo, o pide a quien lo administra que confirme la dirección por ti."
|
|
167
179
|
|
|
168
180
|
setup_configure:
|
|
169
181
|
called: "Este servidor se llama"
|
|
@@ -202,17 +214,19 @@ es:
|
|
|
202
214
|
as: "%{organization}, como %{role}"
|
|
203
215
|
|
|
204
216
|
consent:
|
|
205
|
-
title: "
|
|
206
|
-
access: "
|
|
207
|
-
no_access: "
|
|
208
|
-
audience: "
|
|
217
|
+
title: "%{client} quiere iniciar tu sesión"
|
|
218
|
+
access: "Sabrá"
|
|
219
|
+
no_access: "Solo que tienes una cuenta aquí."
|
|
220
|
+
audience: "Puede actuar por ti en %{resources}."
|
|
209
221
|
details: "Exactamente esto"
|
|
210
222
|
returns_to: "Después vuelve a"
|
|
223
|
+
more: "Detalles"
|
|
224
|
+
scopes: "Permisos"
|
|
211
225
|
site: "Acerca de %{client}"
|
|
212
226
|
terms: "Sus condiciones"
|
|
213
227
|
privacy: "Su política de privacidad"
|
|
214
228
|
allow: "Permitir"
|
|
215
|
-
deny: "
|
|
229
|
+
deny: "Ahora no"
|
|
216
230
|
working: "Permitiendo"
|
|
217
231
|
|
|
218
232
|
settled:
|
|
@@ -221,7 +235,7 @@ es:
|
|
|
221
235
|
waiting: "Te llevamos de vuelta"
|
|
222
236
|
|
|
223
237
|
warnings:
|
|
224
|
-
invalid-credentials: "Ese apodo y
|
|
238
|
+
invalid-credentials: "Ese correo o apodo y la contraseña no coinciden."
|
|
225
239
|
invalid-code: "Ese código no es válido."
|
|
226
240
|
invalid-backup-code: "Ese código de respaldo no es válido."
|
|
227
241
|
invalid-passkey: "No se pudo usar esa llave de acceso."
|
|
@@ -233,7 +247,7 @@ es:
|
|
|
233
247
|
passkey-crowded: "Esta cuenta ya tiene tantas llaves de acceso como admite este servidor."
|
|
234
248
|
second-factor-required: "Activa al menos un segundo factor para continuar."
|
|
235
249
|
backup-codes-unkept: "Guarda tus códigos de respaldo antes de continuar."
|
|
236
|
-
missing-identifier: "Escribe tu
|
|
250
|
+
missing-identifier: "Escribe tu correo o tu apodo."
|
|
237
251
|
missing-first-factor: "Ese paso caducó. Empieza de nuevo."
|
|
238
252
|
too-many-attempts: "Demasiados intentos. Espera unos minutos."
|
|
239
253
|
too-many-attempts-for-account: "Demasiados intentos para esa cuenta."
|
|
@@ -258,7 +272,7 @@ es:
|
|
|
258
272
|
work-unsolved: "Este navegador no terminó la comprobación que frena los registros automáticos. Inténtalo de nuevo."
|
|
259
273
|
invitation-expired: "Esa invitación ya no es válida. Pide otra."
|
|
260
274
|
reset-expired: "Ese enlace de restablecimiento ya no es válido. Pide otro."
|
|
261
|
-
no-mailer: "Este servidor no puede enviar correo.
|
|
275
|
+
no-mailer: "Este servidor aún no puede enviar correo, así que no puede restablecer tu contraseña. Pide a quien lo administra un enlace para restablecerla."
|
|
262
276
|
sso-failed: "Ese inicio de sesión no se completó. Vuelve a intentarlo."
|
|
263
277
|
sso-expired: "Ese inicio de sesión tardó demasiado. Vuelve a intentarlo."
|
|
264
278
|
sso-unavailable: "Esa forma de iniciar sesión no está disponible."
|
|
@@ -65,13 +65,20 @@ es:
|
|
|
65
65
|
proven: "Cada dominio reclamado conserva su registro TXT."
|
|
66
66
|
missing: "Falta el registro TXT de %{domains}. Una reclamación se libera una semana después de que desaparezca su registro."
|
|
67
67
|
advice: "Vuelve a poner el registro TXT en el nombre que muestra la página Dominios."
|
|
68
|
+
proxy:
|
|
69
|
+
title: "Proxy inverso"
|
|
70
|
+
quiet: "Las cabeceras reenviadas llegan solo desde proxies de confianza, por HTTPS."
|
|
71
|
+
untrusted: "Llegaron cabeceras reenviadas desde %{addresses}, que no figura en MASKS_TRUSTED_PROXIES, así que se ignoraron. Todos los visitantes detrás de ese proxy comparten una dirección y un mismo límite."
|
|
72
|
+
plain: "El proxy en %{addresses} reenvía las peticiones como HTTP sin cifrar. masks marca sus cookies solo para HTTPS, así que los navegadores las descartan y el inicio de sesión se repite en bucle."
|
|
73
|
+
one: "Los %{count} eventos de la última hora llegaron todos desde %{address}, una dirección privada, que casi seguro es el propio proxy."
|
|
74
|
+
advice: "Añade el proxy a MASKS_TRUSTED_PROXIES y haz que envíe X-Forwarded-For y X-Forwarded-Proto. Busca en el registro del servidor las líneas que empiezan por proxy:."
|
|
68
75
|
keys:
|
|
69
76
|
title: "Claves de firma"
|
|
70
77
|
missing: "Este inquilino no tiene ninguna clave de firma activa, así que no se puede firmar nada."
|
|
71
|
-
manual: "Las claves se rotan a mano
|
|
78
|
+
manual: "Las claves se rotan a mano, así que nada sustituye la clave activa por sí solo. Tiene %{days} días."
|
|
72
79
|
fresh: "La clave activa tiene %{days} días y rota cada %{period} días."
|
|
73
80
|
stale: "La clave activa tiene %{days} días, más que su rotación de %{period} días."
|
|
74
|
-
advice: "
|
|
81
|
+
advice: "Elige un calendario de rotación en la página Configuración, rota la clave allí, o lee la tarea signing_keys en el registro del servidor."
|
|
75
82
|
release:
|
|
76
83
|
available: "La versión %{version} está disponible."
|
|
77
84
|
operator: "Esta versión necesita un paso de un operador. Lee sus notas antes de actualizar."
|
|
@@ -62,7 +62,7 @@ fr:
|
|
|
62
62
|
set:
|
|
63
63
|
one: "1 configurée"
|
|
64
64
|
other: "%{count} configurées"
|
|
65
|
-
explained: "Au lieu de saisir un mot de passe, votre appareil vérifie que c
|
|
65
|
+
explained: "Au lieu de saisir un mot de passe, votre appareil vérifie que c'est vous comme il se déverrouille déjà. Il compte aussi comme votre deuxième étape, donc aucun code à attendre."
|
|
66
66
|
used: "utilisée il y a %{age}"
|
|
67
67
|
never_used: "jamais utilisée"
|
|
68
68
|
remove: "Supprimer"
|
|
@@ -209,11 +209,11 @@ fr:
|
|
|
209
209
|
remembered: "%{label}, sans demander jusqu’au %{date}"
|
|
210
210
|
heading: "Applications que vous avez autorisées"
|
|
211
211
|
none_yet: "Aucune demande pour l’instant. Une application apparaît ici dès que vous vous y connectez, avec ce que vous avez accepté qu’elle voie."
|
|
212
|
-
revoke: "
|
|
212
|
+
revoke: "Retirer l'accès"
|
|
213
213
|
more:
|
|
214
214
|
one: "et une autre"
|
|
215
215
|
other: "et %{count} autres"
|
|
216
|
-
confirm_revoke: "
|
|
216
|
+
confirm_revoke: "Retirer l'accès de %{client} ? Tout ce qu'il détient cesse de fonctionner, et il devra redemander à votre prochaine connexion."
|
|
217
217
|
|
|
218
218
|
connections:
|
|
219
219
|
heading: "Comptes associés"
|
|
@@ -258,7 +258,7 @@ fr:
|
|
|
258
258
|
|
|
259
259
|
export:
|
|
260
260
|
heading: "Télécharger votre compte"
|
|
261
|
-
state: "
|
|
261
|
+
state: "Un fichier"
|
|
262
262
|
lede: "Un fichier contenant votre profil, vos modes de connexion, vos organisations, applications, comptes associés et appareils, ainsi que l’activité conservée par masks. Il ne contient aucun mot de passe, code ni clé."
|
|
263
263
|
again: "Votre connexion date d’un moment, il vous sera donc d’abord demandé de vous reconnecter."
|
|
264
264
|
submit: "Télécharger"
|
|
@@ -3,29 +3,29 @@ fr:
|
|
|
3
3
|
show:
|
|
4
4
|
page_title: "Connecter %{name}"
|
|
5
5
|
page_title_again: "Reconnecter %{name}"
|
|
6
|
-
title: "Connecter %{name}
|
|
6
|
+
title: "Connecter %{name} ?"
|
|
7
7
|
title_again: "Reconnecter %{name} ?"
|
|
8
|
-
runs_at: "
|
|
8
|
+
runs_at: "%{name} fonctionne à %{origin}."
|
|
9
9
|
lede_html: "Les gens pourront se connecter à <strong>%{name}</strong> avec leur compte %{tenant}. Pour l’instant, vous seul y avez accès, et vous choisissez plus tard qui d’autre peut entrer."
|
|
10
10
|
lede_again_html: "<strong>%{name}</strong> est déjà connectée à %{tenant}. La reconnecter la configure à nouveau. Pour l’instant, vous seul y avez accès, et vous choisissez plus tard qui d’autre peut entrer."
|
|
11
11
|
stops_working: "La connexion actuelle de %{name} cesse de fonctionner."
|
|
12
12
|
connected_by_you: "Vous avez connecté %{name} le %{date}."
|
|
13
13
|
connected_by: "%{who} a connecté %{name} le %{date}."
|
|
14
|
-
signed_in_as: "Vous
|
|
14
|
+
signed_in_as: "Vous connectez en tant que"
|
|
15
15
|
unconfirmed: "(adresse e-mail pas encore confirmée)"
|
|
16
|
-
check: "
|
|
16
|
+
check: "Avant de connecter"
|
|
17
17
|
heed:
|
|
18
18
|
offline_access: "%{name} peut garder les gens connectés sans redemander, jusqu’à ce qu’ils se déconnectent."
|
|
19
19
|
delegates_title: "Demander aux gens d’associer leurs autres comptes"
|
|
20
20
|
delegates: "Chaque personne choisit elle-même. %{name} peut ensuite utiliser ces comptes en leur absence."
|
|
21
21
|
delegate: "%{name} peut utiliser ce compte en votre absence, jusqu’à ce que vous l’arrêtiez."
|
|
22
22
|
manage: "Toute personne qui se connecte via %{name} peut modifier tous les paramètres de ce serveur."
|
|
23
|
-
sees: "%{name}
|
|
23
|
+
sees: "%{name} saura"
|
|
24
24
|
area: "Les autorisations propres à %{name}"
|
|
25
25
|
area_says_html: "%{name} reçoit son propre ensemble d’autorisations, nommé %{namespaces}. Vous décidez qui les reçoit."
|
|
26
26
|
area_yours: " Vous les recevez toutes dès maintenant."
|
|
27
27
|
also: "%{name} peut aussi"
|
|
28
|
-
details: "Détails
|
|
28
|
+
details: "Détails"
|
|
29
29
|
scopes: "Portées"
|
|
30
30
|
client: "Identifiants"
|
|
31
31
|
credentials:
|
|
@@ -16,7 +16,7 @@ fr:
|
|
|
16
16
|
name: "Nom"
|
|
17
17
|
phone: "Téléphone"
|
|
18
18
|
password: "Mot de passe"
|
|
19
|
-
not_you: "
|
|
19
|
+
not_you: "Utiliser un autre compte"
|
|
20
20
|
sign_out: "Se déconnecter"
|
|
21
21
|
use_passkey: "Utiliser une clé d’accès"
|
|
22
22
|
or: "ou"
|
|
@@ -40,10 +40,12 @@ fr:
|
|
|
40
40
|
tab_confirmation: "Confirmation"
|
|
41
41
|
setup_cap: "Bienvenue !"
|
|
42
42
|
setup_title: "Configurer"
|
|
43
|
-
signup_title: "
|
|
43
|
+
signup_title: "Créez votre compte"
|
|
44
44
|
token: "Jeton de configuration"
|
|
45
|
-
token_hint: "
|
|
46
|
-
origin: "
|
|
45
|
+
token_hint: "Il est imprimé dans le journal du serveur."
|
|
46
|
+
origin: "Ce masks répond à %{origin}."
|
|
47
|
+
pick_nickname: "Choisir un pseudo"
|
|
48
|
+
nickname_hint: "Les autres le voient. Laissez tel quel pour utiliser %{suggested}."
|
|
47
49
|
once: "Cet écran ne s’affichera plus."
|
|
48
50
|
docs: "Lire la documentation."
|
|
49
51
|
confirm: "Confirmer le mot de passe"
|
|
@@ -57,10 +59,10 @@ fr:
|
|
|
57
59
|
proving: "Vérification du navigateur"
|
|
58
60
|
|
|
59
61
|
identify:
|
|
60
|
-
heading: "
|
|
62
|
+
heading: "Se connecter"
|
|
61
63
|
heading_to: "Se connecter à %{client}"
|
|
62
|
-
identifier: "
|
|
63
|
-
signup_hint: "Nouveau ici ? Saisissez
|
|
64
|
+
identifier: "E-mail ou pseudo"
|
|
65
|
+
signup_hint: "Nouveau ici ? Saisissez votre e-mail et masks vous crée un compte."
|
|
64
66
|
|
|
65
67
|
first_factor:
|
|
66
68
|
title: "Saisissez votre mot de passe"
|
|
@@ -76,16 +78,16 @@ fr:
|
|
|
76
78
|
sent_again: "Envoyé"
|
|
77
79
|
|
|
78
80
|
second_factor:
|
|
79
|
-
title: "
|
|
80
|
-
title_passkey: "
|
|
81
|
-
trust: "
|
|
81
|
+
title: "Confirmez que c'est vous"
|
|
82
|
+
title_passkey: "Confirmez que c'est vous avec votre clé d'accès"
|
|
83
|
+
trust: "Passer cette étape sur cet appareil pendant %{duration}"
|
|
82
84
|
use_backup_code: "Utiliser un code de secours"
|
|
83
85
|
stuck_insecure: "Le second facteur de ce compte est une clé d’accès, et le navigateur ne propose les clés d’accès qu’aux pages servies en HTTPS. Ouvrez cette page en HTTPS pour continuer."
|
|
84
86
|
stuck_unsupported: "Le second facteur de ce compte est une clé d’accès, et ce navigateur ne prend pas en charge les clés d’accès. Ouvrez cette page dans un navigateur compatible pour continuer."
|
|
85
87
|
stuck_no_script: "Le second facteur de ce compte est une clé d’accès, et une clé d’accès nécessite JavaScript. Activez JavaScript pour continuer."
|
|
86
88
|
stuck_inbox: "Cette connexion a commencé depuis votre boîte de réception, donc un code envoyé à cette adresse ne peut pas la confirmer. Recommencez et connectez-vous avec votre mot de passe pour utiliser un code par e-mail."
|
|
87
89
|
stuck_nothing: "Ce compte n’a aucun second facteur utilisable pour cette connexion. Un gestionnaire peut le réinitialiser."
|
|
88
|
-
recovery_request: "Je ne peux utiliser
|
|
90
|
+
recovery_request: "Je ne peux utiliser aucun de ces moyens"
|
|
89
91
|
recovery_ask: "Demander de l’aide à un gestionnaire"
|
|
90
92
|
recovery_requested: "Un gestionnaire a été invité à réinitialiser vos seconds facteurs. Il peut vous contacter pour s’assurer qu’il s’agit bien de vous. Ensuite, reconnectez-vous pour en configurer un nouveau."
|
|
91
93
|
sent_to: "Envoyé à %{to}."
|
|
@@ -101,16 +103,26 @@ fr:
|
|
|
101
103
|
approval_checked: "Je l’ai approuvée"
|
|
102
104
|
|
|
103
105
|
enrol:
|
|
104
|
-
title: "
|
|
105
|
-
lede: "
|
|
106
|
-
lede_optional: "
|
|
106
|
+
title: "Protégez votre compte"
|
|
107
|
+
lede: "Choisissez une façon de confirmer que c'est vous à la connexion. Vous pourrez en ajouter d'autres plus tard."
|
|
108
|
+
lede_optional: "Choisissez une façon de confirmer que c'est vous à la connexion, ou passez pour l'instant."
|
|
109
|
+
on_title: "Votre compte est protégé"
|
|
110
|
+
on_lede: "Voici comment vous confirmez que c'est vous à la connexion."
|
|
111
|
+
on_label: "Activé"
|
|
112
|
+
passkey: "Clé d'accès"
|
|
107
113
|
otp: "Application d’authentification"
|
|
114
|
+
otp_about: "Une application comme Google Authenticator ou 1Password affiche un code à six chiffres."
|
|
108
115
|
otp_on: "Activée"
|
|
109
|
-
scan_hint: "Scannez
|
|
116
|
+
scan_hint: "Scannez ceci avec votre application d'authentification, ou saisissez-y la clé :"
|
|
117
|
+
passkey_about: "Votre téléphone ou ordinateur vérifie que c'est vous avec votre visage, votre empreinte ou votre code PIN."
|
|
118
|
+
codes_email_about: "Un code est envoyé à %{to} à chaque connexion."
|
|
119
|
+
codes_sms_about: "Un code est envoyé à %{to} par SMS à chaque connexion."
|
|
120
|
+
another_way: "Choisir un autre moyen"
|
|
121
|
+
add_way: "Ajouter un autre moyen"
|
|
110
122
|
open: "Ouvrir dans votre application d’authentification"
|
|
111
123
|
turn_on: "L’activer"
|
|
112
124
|
passkeys: "Clés d’accès"
|
|
113
|
-
passkeys_none: "Aucune pour l
|
|
125
|
+
passkeys_none: "Aucune pour l'instant."
|
|
114
126
|
passkeys_some: "%{count} ajoutée(s)"
|
|
115
127
|
add_passkey: "Ajouter une clé d’accès"
|
|
116
128
|
add_another_passkey: "En ajouter une autre"
|
|
@@ -118,17 +130,17 @@ fr:
|
|
|
118
130
|
codes_email_hint: "Un code envoyé à %{to} confirme chaque connexion."
|
|
119
131
|
codes_sms: "Codes par SMS"
|
|
120
132
|
codes_sms_hint: "Un code envoyé par SMS au %{to} confirme chaque connexion."
|
|
121
|
-
send_code: "
|
|
133
|
+
send_code: "M'envoyer un code"
|
|
122
134
|
sent_to: "Envoyé à %{to}."
|
|
123
135
|
backup_codes: "Codes de secours"
|
|
124
|
-
backup_codes_waiting: "
|
|
125
|
-
backup_codes_hint: "
|
|
136
|
+
backup_codes_waiting: "Créés dès qu'un moyen ci-dessus est activé."
|
|
137
|
+
backup_codes_hint: "Chaque code vous connecte une fois si vous perdez votre autre moyen. Enregistrez-les maintenant. Ils ne sont plus affichés ensuite."
|
|
126
138
|
backup_codes_left: "%{count} restant(s)"
|
|
127
139
|
backup_codes_file: "Codes de secours pour %{account} sur %{origin}"
|
|
128
140
|
copy: "Les copier"
|
|
129
141
|
copied: "Copiés"
|
|
130
142
|
download: "Les télécharger"
|
|
131
|
-
kept: "J
|
|
143
|
+
kept: "J'ai enregistré mes codes de secours"
|
|
132
144
|
done: "Continuer"
|
|
133
145
|
skip: "Ignorer pour l’instant"
|
|
134
146
|
|
|
@@ -163,7 +175,7 @@ fr:
|
|
|
163
175
|
prove_email:
|
|
164
176
|
title: "Consultez vos e-mails"
|
|
165
177
|
lede: "Un code à six chiffres est en route vers %{email}. Saisissez-le pour continuer."
|
|
166
|
-
no_mailer: "Ce serveur ne peut pas encore envoyer d
|
|
178
|
+
no_mailer: "Ce serveur ne peut pas encore envoyer d'e-mail, donc il ne peut pas vérifier votre adresse. Connectez-vous avec votre pseudo, ou demandez à la personne qui l'administre de confirmer l'adresse pour vous."
|
|
167
179
|
|
|
168
180
|
setup_configure:
|
|
169
181
|
called: "Ce serveur s’appelle"
|
|
@@ -202,17 +214,19 @@ fr:
|
|
|
202
214
|
as: "%{organization}, en tant que %{role}"
|
|
203
215
|
|
|
204
216
|
consent:
|
|
205
|
-
title: "
|
|
206
|
-
access: "
|
|
207
|
-
no_access: "
|
|
208
|
-
audience: "
|
|
217
|
+
title: "%{client} veut vous connecter"
|
|
218
|
+
access: "Il saura"
|
|
219
|
+
no_access: "Seulement que vous avez un compte ici."
|
|
220
|
+
audience: "Il peut agir pour vous sur %{resources}."
|
|
209
221
|
details: "Exactement ceci"
|
|
210
222
|
returns_to: "Puis retour à"
|
|
223
|
+
more: "Détails"
|
|
224
|
+
scopes: "Autorisations"
|
|
211
225
|
site: "À propos de %{client}"
|
|
212
226
|
terms: "Ses conditions d’utilisation"
|
|
213
227
|
privacy: "Sa politique de confidentialité"
|
|
214
228
|
allow: "Autoriser"
|
|
215
|
-
deny: "
|
|
229
|
+
deny: "Pas maintenant"
|
|
216
230
|
working: "Autorisation"
|
|
217
231
|
|
|
218
232
|
settled:
|
|
@@ -221,7 +235,7 @@ fr:
|
|
|
221
235
|
waiting: "Retour en cours"
|
|
222
236
|
|
|
223
237
|
warnings:
|
|
224
|
-
invalid-credentials: "
|
|
238
|
+
invalid-credentials: "Cet e-mail ou pseudo et ce mot de passe ne correspondent pas."
|
|
225
239
|
invalid-code: "Ce code n’est pas valide."
|
|
226
240
|
invalid-backup-code: "Ce code de secours n’est pas valide."
|
|
227
241
|
invalid-passkey: "Cette clé d’accès n’a pas pu être utilisée."
|
|
@@ -233,7 +247,7 @@ fr:
|
|
|
233
247
|
passkey-crowded: "Ce compte a déjà le nombre maximal de clés d’accès que ce serveur conserve."
|
|
234
248
|
second-factor-required: "Activez au moins un second facteur pour continuer."
|
|
235
249
|
backup-codes-unkept: "Conservez vos codes de secours avant de continuer."
|
|
236
|
-
missing-identifier: "Saisissez votre
|
|
250
|
+
missing-identifier: "Saisissez votre e-mail ou votre pseudo."
|
|
237
251
|
missing-first-factor: "Cette étape a expiré. Recommencez."
|
|
238
252
|
too-many-attempts: "Trop de tentatives. Patientez quelques minutes."
|
|
239
253
|
too-many-attempts-for-account: "Trop de tentatives pour ce compte."
|
|
@@ -258,7 +272,7 @@ fr:
|
|
|
258
272
|
work-unsolved: "Ce navigateur n'a pas terminé la vérification qui écarte les inscriptions automatisées. Réessayez."
|
|
259
273
|
invitation-expired: "Cette invitation n’est plus valide. Demandez-en une autre."
|
|
260
274
|
reset-expired: "Ce lien de réinitialisation n’est plus valide. Demandez-en un autre."
|
|
261
|
-
no-mailer: "Ce serveur ne peut pas envoyer d
|
|
275
|
+
no-mailer: "Ce serveur ne peut pas encore envoyer d'e-mail, donc il ne peut pas réinitialiser votre mot de passe. Demandez un lien de réinitialisation à la personne qui l'administre."
|
|
262
276
|
sso-failed: "Cette connexion n’a pas abouti. Réessayez."
|
|
263
277
|
sso-expired: "Cette connexion a pris trop de temps. Réessayez."
|
|
264
278
|
sso-unavailable: "Ce mode de connexion n’est pas disponible."
|
|
@@ -65,13 +65,20 @@ fr:
|
|
|
65
65
|
proven: "Chaque domaine revendiqué a toujours son enregistrement TXT."
|
|
66
66
|
missing: "L'enregistrement TXT manque pour %{domains}. Une revendication est libérée une semaine après la disparition de son enregistrement."
|
|
67
67
|
advice: "Remettez l'enregistrement TXT au nom indiqué sur la page Domaines."
|
|
68
|
+
proxy:
|
|
69
|
+
title: "Proxy inverse"
|
|
70
|
+
quiet: "Les en-têtes transmis ne viennent que de proxys de confiance, en HTTPS."
|
|
71
|
+
untrusted: "Des en-têtes transmis sont arrivés de %{addresses}, qui ne figure pas dans MASKS_TRUSTED_PROXIES, et ont donc été ignorés. Tous les visiteurs derrière ce proxy partagent une adresse et une même limite."
|
|
72
|
+
plain: "Le proxy à %{addresses} transmet les requêtes en HTTP non chiffré. masks réserve ses cookies au HTTPS, donc les navigateurs les rejettent et la connexion tourne en boucle."
|
|
73
|
+
one: "Les %{count} événements de la dernière heure viennent tous de %{address}, une adresse privée, qui est presque sûrement le proxy lui-même."
|
|
74
|
+
advice: "Ajoutez le proxy à MASKS_TRUSTED_PROXIES et faites-lui envoyer X-Forwarded-For et X-Forwarded-Proto. Cherchez dans le journal du serveur les lignes qui commencent par proxy:."
|
|
68
75
|
keys:
|
|
69
76
|
title: "Clés de signature"
|
|
70
77
|
missing: "Ce locataire n'a aucune clé de signature active, donc rien ne peut être signé."
|
|
71
|
-
manual: "Les clés tournent à la main
|
|
78
|
+
manual: "Les clés tournent à la main, donc rien ne remplace la clé active de lui-même. Elle a %{days} jours."
|
|
72
79
|
fresh: "La clé active a %{days} jours et tourne tous les %{period} jours."
|
|
73
80
|
stale: "La clé active a %{days} jours, au-delà de sa rotation de %{period} jours."
|
|
74
|
-
advice: "
|
|
81
|
+
advice: "Choisissez un calendrier de rotation sur la page Paramètres, faites tourner la clé là, ou lisez la tâche signing_keys dans le journal du serveur."
|
|
75
82
|
release:
|
|
76
83
|
available: "La version %{version} est disponible."
|
|
77
84
|
operator: "Cette version demande une étape d'un opérateur. Lisez ses notes avant de mettre à jour."
|
|
@@ -39,6 +39,7 @@ module Masks
|
|
|
39
39
|
say ""
|
|
40
40
|
|
|
41
41
|
engine? ? say_engine_database : say_server_database
|
|
42
|
+
say_cache_store if engine?
|
|
42
43
|
|
|
43
44
|
say "In production, masks keeps the address its setup screen was first opened at, and builds the"
|
|
44
45
|
say "issuer and every emailed link from it. To name the address yourself, set"
|
|
@@ -105,6 +106,24 @@ module Masks
|
|
|
105
106
|
say ""
|
|
106
107
|
end
|
|
107
108
|
|
|
109
|
+
def say_cache_store
|
|
110
|
+
say "masks holds one-time sign-in state, rate limits, and health findings in Rails.cache, so"
|
|
111
|
+
say "every process that serves it must share one cache store, such as :solid_cache_store,"
|
|
112
|
+
say ":redis_cache_store or :mem_cache_store. In production, masks refuses to boot on"
|
|
113
|
+
say ":memory_store or :null_store."
|
|
114
|
+
|
|
115
|
+
if Configuration.unshared_cache_store?(cache_store)
|
|
116
|
+
say ""
|
|
117
|
+
say "This app's cache_store is #{Array(cache_store).first.inspect}. Change it before you deploy.", :yellow
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
say ""
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def cache_store
|
|
124
|
+
::Rails.application&.config&.cache_store if defined?(::Rails.application)
|
|
125
|
+
end
|
|
126
|
+
|
|
108
127
|
def say_server_database
|
|
109
128
|
say "masks keeps its tables in the primary database. Connect as a role holding neither"
|
|
110
129
|
say "SUPERUSER nor BYPASSRLS, and set config.active_record.schema_format = :sql, since"
|
|
@@ -4,6 +4,7 @@ module Masks
|
|
|
4
4
|
module Server
|
|
5
5
|
module Configuration
|
|
6
6
|
MODES = %i[server engine].freeze
|
|
7
|
+
UNSHARED_CACHE_STORES = %i[memory_store null_store].freeze
|
|
7
8
|
|
|
8
9
|
module_function
|
|
9
10
|
|
|
@@ -12,13 +13,6 @@ module Masks
|
|
|
12
13
|
config.mode = ENV.fetch("MASKS_MODE", "server").to_sym
|
|
13
14
|
config.database = nil
|
|
14
15
|
config.secret = nil
|
|
15
|
-
config.attempt_limit = ENV.fetch("MASKS_ATTEMPT_LIMIT", 10).to_i
|
|
16
|
-
config.account_attempt_limit = ENV.fetch("MASKS_ACCOUNT_ATTEMPT_LIMIT", 5).to_i
|
|
17
|
-
config.registration_limit = ENV.fetch("MASKS_REGISTRATION_LIMIT", 10).to_i
|
|
18
|
-
config.recovery_limit = ENV.fetch("MASKS_RECOVERY_LIMIT", 5).to_i
|
|
19
|
-
config.device_code_limit = ENV.fetch("MASKS_DEVICE_CODE_LIMIT", 30).to_i
|
|
20
|
-
config.claim_limit = ENV.fetch("MASKS_CLAIM_LIMIT", 3).to_i
|
|
21
|
-
config.claim_ceiling = ENV.fetch("MASKS_CLAIM_CEILING", 30).to_i
|
|
22
16
|
config.setup_token = ENV["MASKS_SETUP_TOKEN"].presence
|
|
23
17
|
config.recover = ENV["MASKS_RECOVER"].presence
|
|
24
18
|
config.config_path = ENV["MASKS_CONFIG"].presence
|
|
@@ -88,7 +82,11 @@ module Masks
|
|
|
88
82
|
}.compact
|
|
89
83
|
end
|
|
90
84
|
|
|
91
|
-
def
|
|
85
|
+
def unshared_cache_store?(cache_store)
|
|
86
|
+
UNSHARED_CACHE_STORES.include?(Array(cache_store).first&.to_sym)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def validate!(config, local:, building:, cache_store: nil)
|
|
92
90
|
unless MODES.include?(config.mode)
|
|
93
91
|
raise "masks runs in server or engine mode, and config.masks.mode is #{config.mode.inspect}."
|
|
94
92
|
end
|
|
@@ -131,6 +129,14 @@ module Masks
|
|
|
131
129
|
raise "masks in engine mode needs a database of its own. Set config.masks.database to " \
|
|
132
130
|
"the name of a database.yml entry whose role cannot bypass row-level security."
|
|
133
131
|
end
|
|
132
|
+
|
|
133
|
+
if unshared_cache_store?(cache_store)
|
|
134
|
+
raise "config.cache_store is #{Array(cache_store).first.inspect}, which every process keeps " \
|
|
135
|
+
"to itself. masks holds one-time sign-in state, rate limits, and health findings in " \
|
|
136
|
+
"Rails.cache, so a provider's callback redeemed in one process is lost in the next. " \
|
|
137
|
+
"Use a store every process shares, such as :solid_cache_store, :redis_cache_store " \
|
|
138
|
+
"or :mem_cache_store."
|
|
139
|
+
end
|
|
134
140
|
end
|
|
135
141
|
end
|
|
136
142
|
end
|
data/lib/masks/server/engine.rb
CHANGED
|
@@ -20,7 +20,8 @@ module Masks
|
|
|
20
20
|
Configuration.validate!(
|
|
21
21
|
app.config.masks,
|
|
22
22
|
local: ::Rails.env.local?,
|
|
23
|
-
building: ENV["SECRET_KEY_BASE_DUMMY"].present
|
|
23
|
+
building: ENV["SECRET_KEY_BASE_DUMMY"].present?,
|
|
24
|
+
cache_store: app.config.cache_store
|
|
24
25
|
)
|
|
25
26
|
|
|
26
27
|
middleware.insert_before Tenancy::Middleware, Isolation if app.config.masks.mode == :engine
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
module Masks
|
|
2
2
|
module Server
|
|
3
3
|
class Forwarding
|
|
4
|
-
HEADERS = %w[
|
|
4
|
+
HEADERS = %w[
|
|
5
|
+
HTTP_X_FORWARDED_FOR HTTP_X_FORWARDED_HOST HTTP_CLIENT_IP HTTP_FORWARDED
|
|
6
|
+
HTTP_X_FORWARDED_PROTO HTTP_X_FORWARDED_SCHEME HTTP_X_FORWARDED_SSL HTTP_X_FORWARDED_PORT
|
|
7
|
+
].freeze
|
|
8
|
+
PROTO = "HTTP_X_FORWARDED_PROTO".freeze
|
|
5
9
|
|
|
6
10
|
def initialize(app, proxies)
|
|
7
11
|
@app = app
|
|
@@ -9,9 +13,20 @@ module Masks
|
|
|
9
13
|
end
|
|
10
14
|
|
|
11
15
|
def call(env)
|
|
12
|
-
|
|
16
|
+
address = env["REMOTE_ADDR"]
|
|
17
|
+
trusted = trusted?(address)
|
|
13
18
|
|
|
14
|
-
|
|
19
|
+
unless trusted
|
|
20
|
+
Health.note_proxy!("untrusted", address) if HEADERS.any? { |header| env.key?(header) }
|
|
21
|
+
HEADERS.each { |header| env.delete(header) }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
plain = trusted && plain?(env)
|
|
25
|
+
status, headers, body = @app.call(env)
|
|
26
|
+
|
|
27
|
+
Health.note_proxy!("plain", address) if plain && !sent_to_https?(status, headers)
|
|
28
|
+
|
|
29
|
+
[ status, headers, body ]
|
|
15
30
|
end
|
|
16
31
|
|
|
17
32
|
private
|
|
@@ -24,6 +39,14 @@ module Masks
|
|
|
24
39
|
rescue IPAddr::InvalidAddressError, IPAddr::AddressFamilyError
|
|
25
40
|
false
|
|
26
41
|
end
|
|
42
|
+
|
|
43
|
+
def plain?(env)
|
|
44
|
+
env[PROTO].to_s.split(",").first.to_s.strip.casecmp?("http")
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def sent_to_https?(status, headers)
|
|
48
|
+
(300..399).cover?(status) && headers["location"].to_s.downcase.start_with?("https://")
|
|
49
|
+
end
|
|
27
50
|
end
|
|
28
51
|
end
|
|
29
52
|
end
|
|
@@ -34,7 +34,7 @@ module Masks
|
|
|
34
34
|
|
|
35
35
|
Everything `/manage` can ask for and everything it can change. `/manage/graphql` accepts a
|
|
36
36
|
bearer carrying `masks:manage` or one of the narrower
|
|
37
|
-
[manage roles](/
|
|
37
|
+
[manage roles](/build/security/#manage-roles), issued for this tenant's manage resource and
|
|
38
38
|
no other. A mutation the bearer's roles do not cover answers with an error naming the scopes
|
|
39
39
|
it needs.
|
|
40
40
|
|