mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-05-27 10:44:33 +00:00
Compare commits
57 Commits
debian/26.
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad1b420397 | ||
|
|
9fd7a3b3af | ||
|
|
ea48448a72 | ||
|
|
050a5366c1 | ||
|
|
bc34a50a24 | ||
|
|
ff2ac949cf | ||
|
|
941a597bc9 | ||
|
|
5f25fc56a5 | ||
|
|
fa4e6002b3 | ||
|
|
f9984ea9e4 | ||
|
|
18d6f2d5db | ||
|
|
68e28cdebc | ||
|
|
79c978e03a | ||
|
|
ce2ce04979 | ||
|
|
8e9b2a0631 | ||
|
|
60a6ac2a0d | ||
|
|
bb6729a99a | ||
|
|
81e60dff0e | ||
|
|
8cbcd39bb2 | ||
|
|
77a91fc357 | ||
|
|
ebac5e86a3 | ||
|
|
0a67183fe4 | ||
|
|
36e1dd9e74 | ||
|
|
5fe11cedb6 | ||
|
|
3d96f41053 | ||
|
|
511de5e106 | ||
|
|
9abe624265 | ||
|
|
a4b3d53141 | ||
|
|
529bbf77df | ||
|
|
e48ff1afbc | ||
|
|
f4be9039d2 | ||
|
|
0f98ed67e7 | ||
|
|
27e9b2ac0e | ||
|
|
066f22ff35 | ||
|
|
bacaa59725 | ||
|
|
2b28850b63 | ||
|
|
d0c20a74f9 | ||
|
|
5c42e04813 | ||
|
|
91296b6e81 | ||
|
|
449b78ae81 | ||
|
|
495f5f8a0d | ||
|
|
2bd33ed428 | ||
|
|
ae50ceaeb0 | ||
|
|
dc3439fd70 | ||
|
|
5cebe7ffe0 | ||
|
|
52ce78ca1e | ||
|
|
5b615a169b | ||
|
|
5b8e3b8f85 | ||
|
|
6b033b3f45 | ||
|
|
be84971c5a | ||
|
|
f9de7865ed | ||
|
|
cbb7998565 | ||
|
|
a3c4d177df | ||
|
|
abc066a92b | ||
|
|
516a8e23d0 | ||
|
|
6d7da4b43f | ||
|
|
7ff91f3e86 |
65
debian/changelog
vendored
65
debian/changelog
vendored
@ -1,3 +1,68 @@
|
||||
freedombox (26.8) unstable; urgency=medium
|
||||
|
||||
[ Pierfrancesco Passerini ]
|
||||
* Translated using Weblate (Italian)
|
||||
|
||||
[ Dietmar ]
|
||||
* Translated using Weblate (German)
|
||||
|
||||
[ Sunil Mohan Adapa ]
|
||||
* api: Drop access-info API
|
||||
|
||||
[ James Valleroy ]
|
||||
* doc: Fetch latest manual
|
||||
|
||||
-- James Valleroy <jvalleroy@mailbox.org> Mon, 11 May 2026 20:32:09 -0400
|
||||
|
||||
freedombox (26.7.1) unstable; urgency=medium
|
||||
|
||||
[ Frederico Gomes ]
|
||||
* radicale: Enable lc_username for case-insensitive auth
|
||||
|
||||
[ Sunil Mohan Adapa ]
|
||||
* radicale, bepasty: Fix issue with failed diagnostic test
|
||||
* radicale: Fix issue with parsing new configuration file
|
||||
* radicale: tests: functional: Better checking for well-known URLs
|
||||
|
||||
[ James Valleroy ]
|
||||
* locale: Update translation strings
|
||||
* doc: Fetch latest manual
|
||||
|
||||
-- James Valleroy <jvalleroy@mailbox.org> Tue, 28 Apr 2026 18:26:38 -0400
|
||||
|
||||
freedombox (26.7) unstable; urgency=medium
|
||||
|
||||
[ Burak Yavuz ]
|
||||
* Translated using Weblate (Turkish)
|
||||
|
||||
[ Besnik Bleta ]
|
||||
* Translated using Weblate (Albanian)
|
||||
|
||||
[ 大王叫我来巡山 ]
|
||||
* Translated using Weblate (Chinese (Simplified Han script))
|
||||
|
||||
[ Dietmar ]
|
||||
* Translated using Weblate (German)
|
||||
* Translated using Weblate (Italian)
|
||||
|
||||
[ Jiří Podhorecký ]
|
||||
* Translated using Weblate (Czech)
|
||||
|
||||
[ bittin1ddc447d824349b2 ]
|
||||
* Translated using Weblate (Swedish)
|
||||
|
||||
[ Coucouf ]
|
||||
* Translated using Weblate (French)
|
||||
|
||||
[ Pierfrancesco Passerini ]
|
||||
* Translated using Weblate (Italian)
|
||||
|
||||
[ James Valleroy ]
|
||||
* debian: tests: Add test to access interface status
|
||||
* doc: Fetch latest manual
|
||||
|
||||
-- James Valleroy <jvalleroy@mailbox.org> Mon, 20 Apr 2026 20:25:51 -0400
|
||||
|
||||
freedombox (26.6) unstable; urgency=medium
|
||||
|
||||
[ Coucouf ]
|
||||
|
||||
3
debian/control
vendored
3
debian/control
vendored
@ -11,6 +11,7 @@ Uploaders:
|
||||
James Valleroy <jvalleroy@mailbox.org>,
|
||||
Build-Depends:
|
||||
debhelper-compat (= 13),
|
||||
dh-sequence-installsysusers,
|
||||
dblatex,
|
||||
dh-python,
|
||||
docbook-xsl,
|
||||
@ -51,6 +52,7 @@ Build-Depends:
|
||||
python3-pytest-runner <!nocheck>,
|
||||
python3-requests,
|
||||
python3-ruamel.yaml,
|
||||
python3-segno <!nocheck>,
|
||||
python3-setuptools,
|
||||
python3-systemd,
|
||||
python3-typeshed <!nocheck>,
|
||||
@ -74,7 +76,6 @@ Depends:
|
||||
${python3:Depends},
|
||||
${misc:Depends},
|
||||
${freedombox:Depends},
|
||||
adduser,
|
||||
augeas-tools,
|
||||
bind9-dnsutils,
|
||||
curl,
|
||||
|
||||
12
debian/freedombox.postinst
vendored
12
debian/freedombox.postinst
vendored
@ -13,21 +13,9 @@ sed -i 's+-:ALL EXCEPT root fbx (admin) (sudo):ALL+-:ALL EXCEPT root fbx plinth
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
if ! getent group plinth >/dev/null; then
|
||||
addgroup --system --quiet plinth
|
||||
fi
|
||||
|
||||
if ! getent passwd plinth >/dev/null; then
|
||||
adduser --system --quiet --ingroup plinth --no-create-home --home /var/lib/plinth plinth
|
||||
fi
|
||||
|
||||
chown plinth: /var/lib/plinth
|
||||
chown plinth: /var/lib/plinth/sessions
|
||||
|
||||
if [ ! -e '/var/lib/freedombox/is-freedombox-disk-image' ]; then
|
||||
umask 377
|
||||
base64 < /dev/urandom | head -c 16 | sed -e 's+$+\n+' > /var/lib/plinth/firstboot-wizard-secret
|
||||
chown plinth:plinth /var/lib/plinth/firstboot-wizard-secret
|
||||
db_subst plinth/firstboot_wizard_secret secret $(cat /var/lib/plinth/firstboot-wizard-secret)
|
||||
db_input high plinth/firstboot_wizard_secret || true
|
||||
db_go
|
||||
|
||||
1
debian/freedombox.postrm
vendored
1
debian/freedombox.postrm
vendored
@ -4,7 +4,6 @@ set -e
|
||||
|
||||
case "$1" in
|
||||
purge)
|
||||
deluser --system --quiet plinth || true
|
||||
rm -rf /var/lib/plinth
|
||||
|
||||
# Remove legacy directory too
|
||||
|
||||
1
debian/freedombox.sysusers
vendored
Normal file
1
debian/freedombox.sysusers
vendored
Normal file
@ -0,0 +1 @@
|
||||
u! plinth - "FreedomBox service" /var/lib/plinth
|
||||
3
debian/freedombox.tmpfiles
vendored
Normal file
3
debian/freedombox.tmpfiles
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
d /var/lib/plinth 0755 plinth plinth
|
||||
d /var/lib/plinth/sessions 0755 plinth plinth
|
||||
Z /var/lib/plinth/firstboot-wizard-secret 0400 plinth plinth
|
||||
16
debian/tests/access-web-interface
vendored
Normal file
16
debian/tests/access-web-interface
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
# Wait for FreedomBox setup to complete.
|
||||
sleep 30
|
||||
|
||||
journalctl --unit=plinth --unit=freedombox-privileged
|
||||
|
||||
# Get FreedomBox status
|
||||
curl --location --cookie "" --fail --write-out "%{response_code}" --insecure \
|
||||
--stderr - https://localhost/freedombox/status/
|
||||
|
||||
# Access FreedomBox interface
|
||||
curl --location --cookie "" --fail --write-out "%{response_code}" --insecure \
|
||||
--stderr - https://localhost/freedombox/
|
||||
10
debian/tests/control
vendored
10
debian/tests/control
vendored
@ -16,3 +16,13 @@ Restrictions: needs-root, breaks-testbed
|
||||
Test-Command: PYTHONPATH='/usr/lib/python3/dist-packages/' py.test-3 -p no:cacheprovider --cov=plinth --cov-report=html:debci/htmlcov --cov-report=term
|
||||
Depends: e2fsprogs, git, python3-pytest, python3-pytest-cov, python3-pytest-django, @
|
||||
Restrictions: breaks-testbed
|
||||
|
||||
#
|
||||
# Try to access the FreedomBox web interface.
|
||||
#
|
||||
# iptables package installs alternatives files, with iptables-nft as default alternative.
|
||||
# Without it, firewalld has this error: INVALID_IPV: 'ipv4' is not a valid backend or is unavailable
|
||||
#
|
||||
Tests: access-web-interface
|
||||
Depends: iptables, @
|
||||
Restrictions: needs-root, isolation-machine, breaks-testbed
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#language en
|
||||
|
||||
##TAG:TRANSLATION-HEADER-START
|
||||
~- [[FreedomBox/Guide/Passkeys|English]] - [[DebianWiki/EditorGuide#translation|(+)]] -~
|
||||
~- [[FreedomBox/Guide/Passkeys|English]] - [[es/FreedomBox/Guide/Passkeys|Español]] - [[DebianWiki/EditorGuide#translation|(+)]] -~
|
||||
##TAG:TRANSLATION-HEADER-END
|
||||
|
||||
<<TableOfContents>>
|
||||
|
||||
@ -8,6 +8,23 @@ For more technical details, see the [[https://salsa.debian.org/freedombox-team/f
|
||||
|
||||
The following are the release notes for each !FreedomBox version.
|
||||
|
||||
== FreedomBox 26.8 (2026-05-11) ==
|
||||
|
||||
* locale: Update translations for German, Italian
|
||||
* api: Drop access-info API
|
||||
|
||||
== FreedomBox 26.7.1 (2026-04-28) ==
|
||||
|
||||
* radicale, bepasty: Fix issue with failed diagnostic test
|
||||
* radicale: Enable lc_username for case-insensitive auth
|
||||
* radicale: Fix issue with parsing new configuration file
|
||||
* radicale: tests: functional: Better checking for well-known URLs
|
||||
|
||||
== FreedomBox 26.7 (2026-04-20) ==
|
||||
|
||||
* debian: tests: Add test to access interface status
|
||||
* locale: Update translations for Albanian, Chinese (Simplified Han script), Czech, French, German, Italian, Swedish, Turkish
|
||||
|
||||
== FreedomBox 26.6 (2026-04-06) ==
|
||||
|
||||
=== Highlights ===
|
||||
|
||||
@ -1,6 +1,11 @@
|
||||
#language en
|
||||
|
||||
##For Translators - to have a constantly up to date translation header in you page, you can just add a line like the following (with the comment's character at the start of the line removed)
|
||||
## <<Include(sudo, ,from="^##TAG:TRANSLATION-HEADER-START",to="^##TAG:TRANSLATION-HEADER-END")>>
|
||||
##TAG:TRANSLATION-HEADER-START
|
||||
~- [[DebianWiki/EditorGuide#translation|Translation(s)]]: English - [[es/FreedomBox/Manual/Users|Español]] -~
|
||||
##TAG:TRANSLATION-HEADER-END
|
||||
----
|
||||
|
||||
<<TableOfContents()>>
|
||||
|
||||
|
||||
174
doc/manual/es/Passkeys.raw.wiki
Normal file
174
doc/manual/es/Passkeys.raw.wiki
Normal file
@ -0,0 +1,174 @@
|
||||
#language es
|
||||
|
||||
<<Include(FreedomBox/Guide/Passkeys, ,from="^##TAG:TRANSLATION-HEADER-START",to="^##TAG:TRANSLATION-HEADER-END")>>
|
||||
|
||||
<<TableOfContents>>
|
||||
|
||||
## BEGIN_INCLUDE
|
||||
|
||||
== Usa claves de acceso (passkeys) para mejorar la seguridad de inicio de sesión ==
|
||||
|
||||
{{{#!wiki tip
|
||||
Se recomiendan encarecidamente las claves de acceso frente a las contraseñas.
|
||||
}}}
|
||||
|
||||
'''Disponible desde''': !FreedomBox 26.6
|
||||
|
||||
!FreedomBox permite a los usuarios iniciar sesión en su cuenta con claves de acceso.
|
||||
Las claves de acceso son una forma de verificar la identidad del usuario usando firmas digitales. Son una alternativa más segura que las contraseñas.
|
||||
La información secreta se conserva con el usuario en su teléfono, portátil o en un token hardware y se desbloquea mediante un PIN, huella dactilar o reconocimiento facial.
|
||||
No se almacenan secretos en el servidor. El servidor solo conoce la información pública que puede usarse para verificar las firmas del usuario.
|
||||
|
||||
=== ¿Cómo funcionan las claves de acceso? ===
|
||||
|
||||
Después de que el usuario inicie sesión en su cuenta, se puede añadir una o más claves de acceso a la cuenta desde la página "Administrar claves de acceso".
|
||||
Al añadir una clave de acceso, el hardware de la clave de acceso (o autenticador) generará un par de claves pública/privada vinculado al dominio y a la cuenta de usuario.
|
||||
La clave privada se mantiene en el hardware y la clave pública se proporciona al servidor. El servidor almacena la clave pública junto con la cuenta de usuario.
|
||||
Más tarde, cuando un usuario intenta iniciar sesión en su cuenta, el servidor envía una larga cadena aleatoria al autenticador llamada santo (santo y seña).
|
||||
El hardware firma digitalmente el santo con la clave privada y la envía (la seña) al servidor.
|
||||
El servidor puede verificar que la firma la ha hecho el poseedor de la clave privada usando solo la clave pública que tiene (esto es una propiedad de los pares de claves pública/privada).
|
||||
Una vez verificada, el servidor inicia sesión en la cuenta de usuario asociada a esa clave pública.
|
||||
|
||||
Durante este proceso, el navegador actúa como intermediario de confianza entre el hardware de la clave de acceso y el servidor.
|
||||
Garantiza que el usuario se verifique proporcionando PIN, huella, reconocimiento facial, etc.
|
||||
También garantiza que una clave de acceso solo se use con el dominio para el que está destinada.
|
||||
|
||||
=== Mejor seguridad ===
|
||||
|
||||
Las claves de acceso ofrecen mayor seguridad que las contraseñas:
|
||||
|
||||
* '''Autenticación multifactor''': Durante el registro de una clave de acceso y durante el inicio de sesión,
|
||||
!FreedomBox solicita que el navegador verifique al usuario.
|
||||
Esto significa que el usuario necesitará desbloquear el dispositivo autenticador proporcionando un PIN, huella o reconocimiento facial.
|
||||
Esto actúa como uno de los factores de autenticación: "algo que sabes" o "algo que eres".
|
||||
Otro factor de autenticación es "algo que tienes": el hardware que almacena tu clave de acceso (como Solokey, Nitrokey o Yubikey) o un teléfono.
|
||||
Juntos, esto es similar a usar una contraseña con un segundo factor de autenticación.
|
||||
Por tanto, las claves de acceso pueden reemplazar la autenticación en dos pasos siendo mucho más cómodas y fáciles de usar.
|
||||
|
||||
* '''Sin reutilización''': Las claves de acceso nunca se reutilizan. Para cada dominio se genera y usa una clave de acceso separada.
|
||||
Los navegadores aseguran que la clave de acceso de un dominio nunca se use con otro dominio.
|
||||
A diferencia de las contraseñas reutilizadas, cuando un sitio web o servicio se ve comprometido, los maleantes no pueden usar eso para acceder a tu cuenta en otro sitio o servicio.
|
||||
Esto también previene ataques de phishing donde sitios impotores se hacen pasar por sitios legítimos.
|
||||
|
||||
* '''No hay secretos en el servidor''': El sitio que permite el uso de claves de acceso para el inicio de sesión no almacena información secreta.
|
||||
Solo guarda la parte pública de la clave de acceso. Si esta información es obtenida por un adversario, no podrá iniciar sesión en el sitio.
|
||||
Solo la clave privada almacenada en el dispositivo autenticador puede usarse para iniciar sesión
|
||||
(ya que solo una clave privada puede crear las firmas necesarias para el proceso de inicio de sesión).
|
||||
|
||||
* '''No adivinación''': La parte secreta de una clave de acceso es mucho más dificil de adivinar que una contraseña.
|
||||
No existe el riesgo de que alguien adivine tu contraseña y acceda a tu cuenta.
|
||||
No existe el riesgo de que configures accidentalmente una contraseña predecible.
|
||||
|
||||
* '''Comodidad''': Los usuarios no necesitan recordar nombre de usuario, correo electrónico o un secreto para iniciar sesión en un sitio.
|
||||
No necesitan recibir OTP por SMS o correo, usar una app TOTP ni confirmar el inicio desde una app móvil.
|
||||
Tras hacer clic en el botón "Login mediante clave de acceso", desbloquean su autenticador con un PIN, huella o reconocimiento facial.
|
||||
Luego tocan físicamente el autenticador (si es necesario). El usuario queda entonces autenticado. Hay menos cosas que recordar.
|
||||
Incluso el PIN de un autenticador hardware suele ser más fácil de recordar que una contraseña.
|
||||
Esta comodidad anima a los usuarios a usar este mecanismo, lo que a la larga mejora la seguridad.
|
||||
|
||||
=== Hardware necesario para claves de acceso ===
|
||||
|
||||
{{{#!wiki tip
|
||||
'''El proyecto !FreedomBox recomienda [[https://solokeys.com/|Solokeys]]''' para el almacenamiento de claves de acceso:
|
||||
|
||||
* El [[https://github.com/solokeys/solo2|firmware]] (el sistema operativo del hardware) es software libre.
|
||||
* Los [[https://github.com/solokeys/solo2-hw|diseños del hardware]] también son libres.
|
||||
* El equipo de Solokeys y el equipo de !FreedomBox colaboran entre sí.
|
||||
}}}
|
||||
|
||||
Hay varias formas de empezar con claves de acceso:
|
||||
|
||||
* '''Hardware de claves de acceso separado''': La forma recomendada de almacenar claves de acceso es en una llave hardware específica.
|
||||
En esta configuración, la clave privada de la clave de acceso nunca abandona el dispositivo hardware.
|
||||
Además, suelen estar diseñadas para que sea difícil para un atacante con acceso físico extraer la clave de acceso.
|
||||
Otra ventaja de estos dispositivos es que pueden utilizarse con todos tus dispositivos existentes, como teléfonos, portátiles y escritorios.
|
||||
Estos dispositivos interactúan con teléfonos y equipos mediante USB, Bluetooth o NFC.
|
||||
En caso de NFC, el dispositivo funciona por proximidad con el teléfono sin energía adicional.
|
||||
Al usar un hardware separado, sin embargo, debes tener un método de respaldo para iniciar sesión si pierdes el dispositivo hardware.
|
||||
Esto puede ser otra clave de acceso en otro hardware o una contraseña. Ver la sección de copia de seguridad más abajo.
|
||||
|
||||
* '''Hardware empotrado para claves de acceso''': Cuando no hay un dispositivo hardware separado, es preferible el hardware especializado, como un TPM, integrado en el equipo.
|
||||
Esta configuración seguirá asegurando que las claves de acceso no abandonen el hardware.
|
||||
Una desventaja es que la clave de acceso solo funciona con ese equipo y tendrás que registrar cada dispositivo que uses por separado.
|
||||
|
||||
* '''Administradores de contraseñas''': Como último recurso, se pueden usar gestores de contraseñas que soporten claves de acceso y funcionen con tu navegador o sistema operativo.
|
||||
Android, iOS y Windows ofrecen administradores así.
|
||||
Las claves de acceso guardadas en administradores suelen sincronizarse con la nube y una brecha en ese servicio/cuenta podría comprometer todas tus cuentas.
|
||||
Sin embargo, funcionan en múltiples dispositivos y normalmente no tienes que preocuparte por perder un solo dispositivo hardware.
|
||||
|
||||
=== Nombrar tu clave de acceso ===
|
||||
|
||||
En !FreedomBox, cuando se añade una clave de acceso a tu cuenta, por defecto se nombra 'Key 1'. La siguiente se llamará 'Key 2' y así sucesivamente.
|
||||
Sin embargo, es buena práctica nombrarlas para saber en qué dispositivo están almacenadas. Por ejemplo, puedes llamarlas 'Clave del Solokey primario', 'Clave del tfn Android', etc.
|
||||
Si se pierde un dispositivo, puedes iniciar sesión y eliminar esa clave de la lista de claves de acceso asociadas a tu cuenta.
|
||||
|
||||
=== Múltiples dominios ===
|
||||
|
||||
Cada clave de acceso está estrictamente ligada a un dominio y nunca se usa para otro dominio. Esto es necesario para evitar que un dominio impostor pueda suplantar a uno legítimo.
|
||||
Por tanto, si tu !FreedomBox está configurada con múltiples dominios, el navegador y el dispositivo autenticador tratarán cada dominio como cuentas separadas a efectos de autenticación con claves de acceso.
|
||||
Esto significa que debes registrar claves de acceso separadas para cada uno de tus dominios.
|
||||
|
||||
Por ejemplo, supón que tu !FreedomBox tiene configurados los dominios midominio1.fbx.one y midominio2.ejemplo.
|
||||
Visita midominio1.fbx.one, inicia sesión en tu cuenta y añade una clave de acceso. Esta clave de acceso quedará ligada a ese dominio.
|
||||
Cuando intentes iniciar sesión, la clave de acceso funcionará si accedes a midominio1.fbx.one pero no funcionará al acceder a midominio2.ejemplo.
|
||||
Para hacer que el segundo dominio funcione, necesitas añadir una segunda clave de acceso mientras accedes a tu !FreedomBox con el nombre de dominio midominio2.ejemplo.
|
||||
Entonces se almacenarán dos claves de acceso en tu token hardware. La primera estará ligada a midominio1.fbx.one y solo se usará cuando accedas a ese dominio.
|
||||
La segunda estará ligada a midominio2.ejemplo y solo se usará cuando accedas a ese dominio.
|
||||
|
||||
=== Múltiples cuentas de usuario ===
|
||||
|
||||
Cuando usas un hardware de claves de acceso para varias cuentas de usuario en el mismo !FreedomBox, se crearán claves de acceso separadas para cada cuenta.
|
||||
A cada clave de acceso se le asignará el nombre de usuario de la cuenta a la que esté ligada. Esta información se almacena en la clave de acceso así como en el servidor.
|
||||
Durante el inicio de sesión, el navegador te pedirá que selecciones la cuenta de usuario a la que quieres acceder.
|
||||
Si solo existe una clave de acceso para un dominio dado, no se mostrará el diálogo de selección y el usuario iniciará sesión en la cuenta correspondiente a esa clave de acceso.
|
||||
|
||||
=== Copia de seguridad de la clave de acceso ===
|
||||
|
||||
En caso de pérdida del dispositivo que almacena tu clave de acceso, necesitas métodos alternativos para iniciar sesión en tu cuenta:
|
||||
|
||||
1. Puedes registrar y mantener dos claves de acceso en dos dispositivos separados. Por ejemplo, tu clave de acceso primaria podría estar en un token Solokey y
|
||||
la segunda en un teléfono Android o en otro token Solokey. Si uno se pierde, puedes iniciar sesión con el otro. Este es el método recomendado.
|
||||
|
||||
1. !FreedomBox sigue soportando contraseñas incluso después de registrar claves de acceso.
|
||||
Así que, si se pierde un dispositivo con clave de acceso, puedes iniciar sesión con una contraseña.
|
||||
|
||||
1. Si olvidas tu contraseña y tu cuenta no es la única cuenta administradora en el !FreedomBox, puedes pedir a un administrador que restablezca tu contraseña.
|
||||
Después de eso podrás registrar una nueva clave de acceso almacenada en un nuevo dispositivo.
|
||||
|
||||
=== Plataformas compatibles ===
|
||||
|
||||
Las passkeys se basan en WebAuthn, un estándar publicado por el World Wide Web Consortium.
|
||||
Por tanto, la implementación de !FreedomBox debería funcionar allí donde funcionen las clave de acceso. Se ha probado de la siguiente manera:
|
||||
|
||||
|| '''SO/Dispositivo''' || '''Navegador''' || '''Autenticador''' || '''Resultado''' ||
|
||||
|| GNU/Linux || Firefox || Solokeys || Ok ||
|
||||
|| GNU/Linux || Firefox || Yubikey || Ok ||
|
||||
|| GNU/Linux || Chromium || Solokeys || Ok ||
|
||||
|| GNU/Linux || GNOME Web || - || KO (El navegador no soporta WebAuthn) ||
|
||||
|| Windows || Firefox || Windows Hello || Ok ||
|
||||
|| Windows || Firefox || Solokeys || Ok ||
|
||||
|| Windows || Firefox || Android Phone || Ok ||
|
||||
|| Windows || Chrome || Windows Hello || Ok ||
|
||||
|| Windows || Chrome || Solokeys || Ok ||
|
||||
|| Windows || Chrome || Android Phone || Ok ||
|
||||
|| Windows || Edge || Windows Hello || Ok ||
|
||||
|| Windows || Edge || Solokeys || Ok ||
|
||||
|| Windows || Edge || Android Phone || Ok ||
|
||||
|| Android || Firefox || Google Password Manager || Ok ||
|
||||
|| Android || Firefox || Solokeys USB || KO (No se detecta el toque tras introducir el PIN) ||
|
||||
|| Android || Firefox || Solokeys NFC || KO (Es necesario entender la configuración NFC) ||
|
||||
|| Android || Firefox || Otro dispositivo || Sin probar ||
|
||||
|| Android || Chrome || Google Password Manager || Ok ||
|
||||
|| Android || Chrome || Solokeys USB || KO (No se detecta el toque tras introducir el PIN) ||
|
||||
|| Android || Chrome || Solokeys NFC || KO (Es necesario entender la configuración NFC) ||
|
||||
|| Android || Chrome || Otro dispositivo || Sin probar ||
|
||||
|
||||
## END_INCLUDE
|
||||
|
||||
Volver a la [[es/FreedomBox/Features|descripción de Funcionalidades]] o a las páginas del [[es/FreedomBox/Manual|manual]].
|
||||
|
||||
|
||||
<<Include(es/FreedomBox/Portal)>>
|
||||
|
||||
----
|
||||
CategoryFreedomBox
|
||||
@ -8,6 +8,23 @@ For more technical details, see the [[https://salsa.debian.org/freedombox-team/f
|
||||
|
||||
The following are the release notes for each !FreedomBox version.
|
||||
|
||||
== FreedomBox 26.8 (2026-05-11) ==
|
||||
|
||||
* locale: Update translations for German, Italian
|
||||
* api: Drop access-info API
|
||||
|
||||
== FreedomBox 26.7.1 (2026-04-28) ==
|
||||
|
||||
* radicale, bepasty: Fix issue with failed diagnostic test
|
||||
* radicale: Enable lc_username for case-insensitive auth
|
||||
* radicale: Fix issue with parsing new configuration file
|
||||
* radicale: tests: functional: Better checking for well-known URLs
|
||||
|
||||
== FreedomBox 26.7 (2026-04-20) ==
|
||||
|
||||
* debian: tests: Add test to access interface status
|
||||
* locale: Update translations for Albanian, Chinese (Simplified Han script), Czech, French, German, Italian, Swedish, Turkish
|
||||
|
||||
== FreedomBox 26.6 (2026-04-06) ==
|
||||
|
||||
=== Highlights ===
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#language es
|
||||
|
||||
~- [[DebianWiki/EditorGuide#translation|Translation(s)]]: [[FreedomBox/Manual/Users|English]] - Español -~
|
||||
<<Include(FreedomBox/Manual/Users, ,from="^##TAG:TRANSLATION-HEADER-START",to="^##TAG:TRANSLATION-HEADER-END")>>
|
||||
|
||||
<<TableOfContents()>>
|
||||
|
||||
@ -9,25 +9,36 @@
|
||||
== Usuarios y Grupos ==
|
||||
|
||||
Puedes otorgar acceso a tu !FreedomBox a otros usuarios. Proporciona el nombre del usuario y su contraseña y asignale un grupo. Actualmente se soportan los grupos
|
||||
Esta app puede usarse para crear, editar y eliminar cuentas de usuario en !FreedomBox. Muchas apps con interfaz web en !FreedomBox admiten inicio de sesión único mediante OpenID Connect.
|
||||
Esto significa que si has iniciado sesión en la interfaz web de !FreedomBox, no es necesario iniciar sesión de forma separada en la app.
|
||||
Otras apps permiten usar las cuentas de !FreedomBox mediante LDAP.
|
||||
Finalmente, hay algunas apps que gestionan sus propias cuentas de usuario de forma independiente a las cuentas que tengas en !FreedomBox.
|
||||
|
||||
|
||||
|
||||
Puedes otorgar acceso a tu FreedomBox a otros usuarios. Proporciona el nombre del usuario y su contraseña y asignale un grupo. Actualmente se soportan los grupos:
|
||||
* admin
|
||||
* bit-torrent
|
||||
* calibre
|
||||
* ed2k
|
||||
* feed-reader
|
||||
* freedombox-share
|
||||
* freedombox-ssh
|
||||
* git-access
|
||||
* minidlna
|
||||
* syncthing
|
||||
* kiwix
|
||||
* syncthing-access
|
||||
* vpn
|
||||
* web-search
|
||||
* wiki
|
||||
|
||||
El usuario podrá ingresar a los servicios que soporten ingreso único (single-sign-on) mediante LDAP si figuran en el grupo apropriado.
|
||||
Los usuarios del grupo admin podrán ingresar en todos los servicios.
|
||||
También podrán acceder al sistema vía SSH y tendrán privilegios administrativos (sudo).
|
||||
Los grupos de un usuario pueden modificarse más adelante.
|
||||
|
||||
Los usuarios del grupo `admin` podrán ingresar en todos los servicios. También pueden ingresar al sistema por SSH y escalar a privilegios administrativos (sudo).
|
||||
!FreedomBox admite el inicio de sesión con claves de acceso.
|
||||
Las claves de acceso son una alternativa más segura que las contraseñas y son la forma recomendada de autenticarse en !FreedomBox.
|
||||
Lee más en la [[FreedomBox/Guide/Passkeys|guía de claves de acceso de FreedomBox]].
|
||||
|
||||
Estas características se pueden cambiar más tarde.
|
||||
|
||||
Asimismo es posible establecer una clave pública SSH que permitirá al usuario ingresar al sistema de modo seguro sin emplear su contraseña. Pueder dar de alta varias claves, una en cada línea. Las líneas en blanco o que comiencen por # se ignoran.
|
||||
Asimismo es posible establecer una clave pública SSH que permitirá al usuario ingresar al sistema de modo seguro sin emplear su contraseña. Puedes dar de alta varias claves, una en cada línea. Las líneas en blanco o que comiencen por # se ignoran.
|
||||
|
||||
El idioma de la interfaz se puede establecer individualmente para cada usuario. Por omisión se emplea el del navegador.
|
||||
|
||||
|
||||
@ -80,6 +80,7 @@
|
||||
<<Include(es/FreedomBox/Manual/Users, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
|
||||
= Guías =
|
||||
<<Include(es/FreedomBox/Guide/Passkeys, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(es/FreedomBox/Guide/ExposeLocalService,, from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
|
||||
= Hardware =
|
||||
|
||||
@ -3,4 +3,4 @@
|
||||
Package init file.
|
||||
"""
|
||||
|
||||
__version__ = '26.6'
|
||||
__version__ = '26.8'
|
||||
|
||||
@ -120,14 +120,6 @@ def service_disable(service_name: str, check: bool = False):
|
||||
except subprocess.CalledProcessError:
|
||||
pass
|
||||
|
||||
if service_name.endswith('.socket'):
|
||||
# Instead, may need to query the unit for associated .service file.
|
||||
base_name = service_name.rpartition('.')[0]
|
||||
try:
|
||||
service_stop(f'{base_name}.service', check=check)
|
||||
except subprocess.CalledProcessError:
|
||||
pass
|
||||
|
||||
|
||||
def service_mask(service_name: str, check: bool = False):
|
||||
"""Mask a service"""
|
||||
@ -143,25 +135,62 @@ def service_start(service_name: str, check: bool = False):
|
||||
"""Start a service with systemd."""
|
||||
service_action(service_name, 'start', check=check)
|
||||
|
||||
# When starting a .socket unit, there is not need to start the .service
|
||||
# unit as it will be automatically started when a request is received on
|
||||
# the socket.
|
||||
|
||||
|
||||
def _get_service_unit(socket_name: str) -> str:
|
||||
"""Return the .service unit name for a .socket unit."""
|
||||
# Instead, may need to query the unit for associated .service file.
|
||||
base_name = socket_name.rpartition('.')[0]
|
||||
return f'{base_name}.service'
|
||||
|
||||
|
||||
def service_stop(service_name: str, check: bool = False):
|
||||
"""Stop a service with systemd."""
|
||||
service_action(service_name, 'stop', check=check)
|
||||
|
||||
# When stopping a .socket unit, most of the time, we must also stop
|
||||
# .service unit. This frees up resources when disabling the app. It also
|
||||
# stops using resources that are being backed up.
|
||||
if service_name.endswith('.socket'):
|
||||
service_action(_get_service_unit(service_name), 'stop', check=check)
|
||||
|
||||
|
||||
def service_restart(service_name: str, check: bool = False):
|
||||
"""Restart a service with systemd."""
|
||||
if not service_name.endswith('.socket'):
|
||||
service_action(service_name, 'restart', check=check)
|
||||
else:
|
||||
# When restarting a .socket unit, most of the time, we actually want to
|
||||
# restart the corresponding .service unit. This reloads the
|
||||
# configuration changes as needed. To restart, all we need to do stop
|
||||
# the service. It will be automatically started again by .socket unit.
|
||||
service_action(_get_service_unit(service_name), 'stop', check=check)
|
||||
|
||||
|
||||
def service_try_restart(service_name: str, check: bool = False):
|
||||
"""Try to restart a service with systemd."""
|
||||
if not service_name.endswith('.socket'):
|
||||
service_action(service_name, 'try-restart', check=check)
|
||||
else:
|
||||
# When try-restarting a .socket unit, most of the time, we actually
|
||||
# want to restart the corresponding .service unit. This reloads the
|
||||
# configuration changes as needed. To restart, all we need to do stop
|
||||
# the service. It will be automatically started again by .socket unit.
|
||||
service_action(_get_service_unit(service_name), 'stop', check=check)
|
||||
|
||||
|
||||
def service_reload(service_name: str, check: bool = False):
|
||||
"""Reload a service with systemd."""
|
||||
if not service_name.endswith('.socket'):
|
||||
service_action(service_name, 'reload', check=check)
|
||||
else:
|
||||
# When reloading a .socket unit, most of the time, we actually want to
|
||||
# reload the corresponding .service unit. This reloads the
|
||||
# configuration changes as needed.
|
||||
service_action(_get_service_unit(service_name), 'reload', check=check)
|
||||
|
||||
|
||||
def service_try_reload_or_restart(service_name: str, check: bool = False):
|
||||
@ -169,7 +198,14 @@ def service_try_reload_or_restart(service_name: str, check: bool = False):
|
||||
|
||||
Do nothing if service is not running.
|
||||
"""
|
||||
if not service_name.endswith('.socket'):
|
||||
service_action(service_name, 'try-reload-or-restart', check=check)
|
||||
else:
|
||||
# When reloading a .socket unit, most of the time, we actually want to
|
||||
# reload the corresponding .service unit. This reloads the
|
||||
# configuration changes as needed.
|
||||
service_action(_get_service_unit(service_name),
|
||||
'try-reload-or-restart', check=check)
|
||||
|
||||
|
||||
def service_reset_failed(service_name: str, check: bool = False):
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2025-04-16 02:28+0000\n"
|
||||
"Last-Translator: MohammedSaalif <2300031323@kluniversity.in>\n"
|
||||
"Language-Team: Arabic <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -6386,7 +6386,7 @@ msgstr ""
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -6395,14 +6395,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr ""
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2020-06-10 15:41+0000\n"
|
||||
"Last-Translator: aiman an <an1f3@hotmail.com>\n"
|
||||
"Language-Team: Arabic (Saudi Arabia) <https://hosted.weblate.org/projects/"
|
||||
@ -6390,7 +6390,7 @@ msgstr ""
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -6399,14 +6399,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr ""
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: none\n"
|
||||
@ -6340,7 +6340,7 @@ msgstr ""
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -6349,14 +6349,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr ""
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2025-12-17 07:00+0000\n"
|
||||
"Last-Translator: 109247019824 "
|
||||
"<109247019824@users.noreply.hosted.weblate.org>\n"
|
||||
@ -6686,7 +6686,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -6695,14 +6695,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "Radicale"
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2025-04-01 03:02+0000\n"
|
||||
"Last-Translator: MURALA SAI GANESH <saiganeshmurala@gmail.com>\n"
|
||||
"Language-Team: Bengali <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -6409,7 +6409,7 @@ msgstr ""
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -6418,14 +6418,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr ""
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2026-02-06 23:02+0000\n"
|
||||
"Last-Translator: kosagi <marti.torra@natana.cat>\n"
|
||||
"Language-Team: Catalan <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -7170,7 +7170,7 @@ msgstr ""
|
||||
msgid "IRC"
|
||||
msgstr "IRC"
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7179,14 +7179,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "Radicale"
|
||||
|
||||
@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"PO-Revision-Date: 2026-03-08 18:48+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2026-04-09 10:09+0000\n"
|
||||
"Last-Translator: Jiří Podhorecký <j.podhorecky@volny.cz>\n"
|
||||
"Language-Team: Czech <https://hosted.weblate.org/projects/freedombox/"
|
||||
"freedombox/cs/>\n"
|
||||
@ -7160,7 +7160,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr "IRC"
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7174,7 +7174,7 @@ msgstr ""
|
||||
"klientská aplikace</a>. K Radicale má přístup každý uživatel s přihlašovacím "
|
||||
"jménem {box_name}."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
@ -7184,7 +7184,7 @@ msgstr ""
|
||||
"nových kalendářů a adresářů kontaktů. Nepodporuje přidávání událostí či "
|
||||
"kontaktů, to je třeba dělat v tomu určeném klientovi."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "Radicale"
|
||||
@ -9782,14 +9782,12 @@ msgstr "Upravit uživatele %(username)s"
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:30
|
||||
msgid "Logging in with passkey failed: "
|
||||
msgstr ""
|
||||
msgstr "Přihlášení pomocí passkey se nezdařilo: "
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:41
|
||||
#: plinth/modules/users/templates/users_passkeys.html:41
|
||||
#, fuzzy
|
||||
#| msgid "This app does not support diagnostics"
|
||||
msgid "Browser does not support passkeys."
|
||||
msgstr "Tato aplikace nepodporuje diagnostiku"
|
||||
msgstr "Prohlížeč nepodporuje přístupové klíče."
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:57
|
||||
msgid "Login"
|
||||
@ -9798,28 +9796,29 @@ msgstr "Přihlášení"
|
||||
#: plinth/modules/users/templates/users_login.html:70
|
||||
#: plinth/modules/users/templates/users_login.html:72
|
||||
msgid "Log in with passkey"
|
||||
msgstr ""
|
||||
msgstr "Přihlásit se pomocí přístupového klíče"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkey_edit.html:19
|
||||
#, fuzzy
|
||||
#| msgid "Update setup"
|
||||
msgid "Update Passkey"
|
||||
msgstr "Aktualizovat nastavení"
|
||||
msgstr "Aktualizovat přístupový klíč"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:30
|
||||
msgid "Adding passkey failed: "
|
||||
msgstr ""
|
||||
msgstr "Přidání přístupového klíče selhalo: "
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:48
|
||||
#: plinth/modules/users/views.py:314
|
||||
msgid "Passkeys"
|
||||
msgstr ""
|
||||
msgstr "Přístupové klíče"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:57
|
||||
msgid ""
|
||||
"Working with passkeys requires using browser's Javascript API. Please enable "
|
||||
"Javascript support in your browser to continue."
|
||||
msgstr ""
|
||||
"Práce s přístupovými klíči vyžaduje použití rozhraní JavaScript API "
|
||||
"prohlížeče. Chcete-li pokračovat, povolte ve svém prohlížeči podporu jazyka "
|
||||
"JavaScript."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:66
|
||||
msgid ""
|
||||
@ -9830,47 +9829,46 @@ msgid ""
|
||||
"server knows only the public information that can used to verify user's "
|
||||
"signatures."
|
||||
msgstr ""
|
||||
"Přístupové klíče jsou způsob, jak ověřit identitu uživatele pomocí "
|
||||
"digitálních podpisů. Jsou bezpečnější alternativou k heslům. Tajné informace "
|
||||
"jsou uchovávány u uživatele v jeho telefonu, notebooku nebo hardwarovém "
|
||||
"tokenu a odemykají se pomocí PINu, otisku prstu nebo identifikace obličeje. "
|
||||
"Na serveru nejsou uloženy žádné tajné informace. Server zná pouze veřejné "
|
||||
"informace, které lze použít k ověření podpisů uživatele."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:83
|
||||
#: plinth/modules/users/templates/users_passkeys.html:85
|
||||
#, fuzzy
|
||||
#| msgid "Add password"
|
||||
msgid "Add passkey"
|
||||
msgstr "Přidat heslo"
|
||||
msgstr "Přidat přístupový klíč"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:93
|
||||
#, fuzzy
|
||||
#| msgid "Domain"
|
||||
msgid "For Domain"
|
||||
msgstr "Doména"
|
||||
msgstr "Pro doménu"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:94
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
msgstr "Přidáno"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:95
|
||||
#, fuzzy
|
||||
#| msgid "Last scanned: "
|
||||
msgid "Last Used"
|
||||
msgstr "Naposledy skenováno: "
|
||||
msgstr "Naposledy použito"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:126
|
||||
msgid "No passkeys added to user account."
|
||||
msgstr ""
|
||||
msgstr "K uživatelskému účtu nebyly přidány žádné přístupové klíče."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:135
|
||||
msgid "Delete passkey <em class=\"passkey-name\"></em>?"
|
||||
msgstr ""
|
||||
msgstr "Smazat přístupový klíč <em class=\"passkey-name\"></em>?"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:145
|
||||
msgid "You will need this passkey's device to add it back again."
|
||||
msgstr ""
|
||||
"K opětovnému přidání tohoto přístupového klíče budete potřebovat zařízení."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:152
|
||||
#, fuzzy
|
||||
#| msgid "Delete user"
|
||||
msgid "Delete passkey"
|
||||
msgstr "Smazat uživatele"
|
||||
msgstr "Smazat přístupový klíč"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:155
|
||||
#: plinth/modules/users/templates/users_update.html:72
|
||||
@ -9886,6 +9884,8 @@ msgstr "Upravit uživatele %(username)s"
|
||||
#, python-format
|
||||
msgid "Use <a href=\"%(passkeys_url)s\">passkeys</a> for better security."
|
||||
msgstr ""
|
||||
"Pro lepší zabezpečení použijte <a href=\"%(passkeys_url)s\">přístupové "
|
||||
"klíče</a>."
|
||||
|
||||
#: plinth/modules/users/templates/users_update.html:29
|
||||
#, python-format
|
||||
@ -9951,20 +9951,16 @@ msgid "Password changed successfully."
|
||||
msgstr "Heslo úspěšně změněno."
|
||||
|
||||
#: plinth/modules/users/views.py:420
|
||||
#, fuzzy
|
||||
#| msgid "A share with this name already exists."
|
||||
msgid "Passkey with that identifier already exists."
|
||||
msgstr "Sdílení s tímto názvem už existuje."
|
||||
msgstr "Přístupový klíč s tímto identifikátorem již existuje."
|
||||
|
||||
#: plinth/modules/users/views.py:431
|
||||
#, fuzzy
|
||||
#| msgid "Edit User"
|
||||
msgid "Edit Passkey"
|
||||
msgstr "Upravit uživatele"
|
||||
msgstr "Upravit přístupový klíč"
|
||||
|
||||
#: plinth/modules/users/views.py:518 plinth/modules/users/views.py:542
|
||||
msgid "Passkey used is not known."
|
||||
msgstr ""
|
||||
msgstr "Použitý přístupový klíč není znám."
|
||||
|
||||
#: plinth/modules/wireguard/__init__.py:20
|
||||
msgid "WireGuard is a fast, modern, secure VPN tunnel."
|
||||
@ -10745,10 +10741,8 @@ msgid " System"
|
||||
msgstr " Systém"
|
||||
|
||||
#: plinth/templates/base.html:179 plinth/templates/base.html:180
|
||||
#, fuzzy
|
||||
#| msgid "Manage Aliases"
|
||||
msgid "Manage passkeys"
|
||||
msgstr "Správa aliasů"
|
||||
msgstr "Správa přístupových klíčů"
|
||||
|
||||
#: plinth/templates/base.html:186 plinth/templates/base.html:187
|
||||
msgid "Change password"
|
||||
@ -10804,7 +10798,7 @@ msgstr "Mobilní"
|
||||
|
||||
#: plinth/templates/clients.html:82
|
||||
msgid "Android APK"
|
||||
msgstr ""
|
||||
msgstr "Android APK"
|
||||
|
||||
#: plinth/templates/clients.html:91
|
||||
msgid "Play Store"
|
||||
|
||||
@ -9,7 +9,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: FreedomBox UI\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2022-09-14 17:19+0000\n"
|
||||
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
|
||||
"Language-Team: Danish <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -7365,7 +7365,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, fuzzy, python-brace-format
|
||||
#| msgid ""
|
||||
#| "Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7385,14 +7385,14 @@ msgstr ""
|
||||
"carddav-clients\">understøttet klient-applikation</a>. Radicale kan tilgås "
|
||||
"af enhver bruger der har et log ind til {box_name}."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr ""
|
||||
|
||||
@ -9,9 +9,9 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: FreedomBox UI\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"PO-Revision-Date: 2026-03-29 11:09+0000\n"
|
||||
"Last-Translator: Dietmar <sagen@permondes.de>\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2026-05-21 18:11+0000\n"
|
||||
"Last-Translator: Hosted Weblate user 151773 <paul.schell87@gmail.com>\n"
|
||||
"Language-Team: German <https://hosted.weblate.org/projects/freedombox/"
|
||||
"freedombox/de/>\n"
|
||||
"Language: de\n"
|
||||
@ -19,7 +19,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.17-dev\n"
|
||||
"X-Generator: Weblate 2026.6.dev0\n"
|
||||
|
||||
#: plinth/config.py:103
|
||||
#, python-brace-format
|
||||
@ -324,7 +324,7 @@ msgstr ""
|
||||
|
||||
#: plinth/modules/backups/forms.py:79
|
||||
msgid "Hour of the day to trigger backup operation"
|
||||
msgstr "Uhrzeit, zu der der Sicherungsvorgang ausgelöst werden soll"
|
||||
msgstr "Uhrzeit für den Start des Sicherungsvorgangs"
|
||||
|
||||
#: plinth/modules/backups/forms.py:81
|
||||
msgid ""
|
||||
@ -3810,7 +3810,7 @@ msgstr "Heimautomatisierung"
|
||||
|
||||
#: plinth/modules/homeassistant/manifest.py:63
|
||||
msgid "IoT"
|
||||
msgstr ""
|
||||
msgstr "IdD"
|
||||
|
||||
#: plinth/modules/homeassistant/manifest.py:64
|
||||
#: plinth/modules/networks/manifest.py:8
|
||||
@ -6722,7 +6722,7 @@ msgstr ""
|
||||
|
||||
#: plinth/modules/oidc/__init__.py:56
|
||||
msgid "OpenID Connect Provider"
|
||||
msgstr ""
|
||||
msgstr "OpenID Verbindungsanbieter"
|
||||
|
||||
#: plinth/modules/oidc/templates/oauth2_provider/authorize.html:14
|
||||
msgid "Application"
|
||||
@ -7303,7 +7303,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr "IRC"
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7317,7 +7317,7 @@ msgstr ""
|
||||
"clients\">unterstützte Client Software</a> notwendig. Radicale kann von "
|
||||
"jedem Benutzer mit einem {box_name}-Konto verwendet werden."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
@ -7328,7 +7328,7 @@ msgstr ""
|
||||
"Kontaktdaten wird nicht unterstützt; dies muss über einen separaten Client "
|
||||
"erfolgen."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "Radicale"
|
||||
@ -9996,14 +9996,12 @@ msgstr "Benutzer %(username)s bearbeiten"
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:30
|
||||
msgid "Logging in with passkey failed: "
|
||||
msgstr ""
|
||||
msgstr "Die Anmeldung mit dem Passkey ist fehlgeschlagen: "
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:41
|
||||
#: plinth/modules/users/templates/users_passkeys.html:41
|
||||
#, fuzzy
|
||||
#| msgid "This app does not support diagnostics"
|
||||
msgid "Browser does not support passkeys."
|
||||
msgstr "Diese App unterstützt keine Diagnose"
|
||||
msgstr "Der Browser unterstützt keine Passkeys."
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:57
|
||||
msgid "Login"
|
||||
@ -10012,28 +10010,29 @@ msgstr "Anmelden"
|
||||
#: plinth/modules/users/templates/users_login.html:70
|
||||
#: plinth/modules/users/templates/users_login.html:72
|
||||
msgid "Log in with passkey"
|
||||
msgstr ""
|
||||
msgstr "Mit Passkey anmelden"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkey_edit.html:19
|
||||
#, fuzzy
|
||||
#| msgid "Update setup"
|
||||
msgid "Update Passkey"
|
||||
msgstr "Übernehmen der Änderungen"
|
||||
msgstr "Passkey aktualisieren"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:30
|
||||
msgid "Adding passkey failed: "
|
||||
msgstr ""
|
||||
msgstr "Hinzufügen des Passkeys ist fehlgeschlagen: "
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:48
|
||||
#: plinth/modules/users/views.py:314
|
||||
msgid "Passkeys"
|
||||
msgstr ""
|
||||
msgstr "Passkeys"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:57
|
||||
msgid ""
|
||||
"Working with passkeys requires using browser's Javascript API. Please enable "
|
||||
"Javascript support in your browser to continue."
|
||||
msgstr ""
|
||||
"Für die Verwendung von Passkeys ist die JavaScript-API des Browsers "
|
||||
"erforderlich. Bitte aktivieren Sie JavaScript in Ihrem Browser, um "
|
||||
"fortzufahren."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:66
|
||||
msgid ""
|
||||
@ -10044,47 +10043,49 @@ msgid ""
|
||||
"server knows only the public information that can used to verify user's "
|
||||
"signatures."
|
||||
msgstr ""
|
||||
"Passkeys sind eine Methode zur Überprüfung der Benutzeridentität mithilfe "
|
||||
"digitaler Signaturen. Sie stellen eine sicherere Alternative zu Passwörtern "
|
||||
"dar. Die geheimen Informationen werden beim Benutzer auf seinem Smartphone, "
|
||||
"Laptop oder einem Hardware-Token gespeichert und mittels PIN, Fingerabdruck "
|
||||
"oder Gesichtserkennung entsperrt. Auf dem Server werden keine geheimen "
|
||||
"Informationen gespeichert. Der Server kennt lediglich die öffentlichen "
|
||||
"Informationen, die zur Überprüfung der Signaturen des Benutzers verwendet "
|
||||
"werden können."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:83
|
||||
#: plinth/modules/users/templates/users_passkeys.html:85
|
||||
#, fuzzy
|
||||
#| msgid "Add password"
|
||||
msgid "Add passkey"
|
||||
msgstr "Kennwort hinzufügen"
|
||||
msgstr "Passkey hinzufügen"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:93
|
||||
#, fuzzy
|
||||
#| msgid "Domain"
|
||||
msgid "For Domain"
|
||||
msgstr "Domain"
|
||||
msgstr "Für Domäne"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:94
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
msgstr "Hinzugefügt"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:95
|
||||
#, fuzzy
|
||||
#| msgid "Last scanned: "
|
||||
msgid "Last Used"
|
||||
msgstr "Zuletzt gescannt: "
|
||||
msgstr "Zuletzt verwendet"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:126
|
||||
msgid "No passkeys added to user account."
|
||||
msgstr ""
|
||||
msgstr "Dem Benutzerkonto wurden keine Passkeys hinzugefügt."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:135
|
||||
msgid "Delete passkey <em class=\"passkey-name\"></em>?"
|
||||
msgstr ""
|
||||
msgstr "Passkey <em class=\"passkey-name\"></em> löschen?"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:145
|
||||
msgid "You will need this passkey's device to add it back again."
|
||||
msgstr ""
|
||||
"Sie benötigen das Gerät, auf dem dieser Passkey gespeichert ist, um ihn "
|
||||
"erneut hinzuzufügen."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:152
|
||||
#, fuzzy
|
||||
#| msgid "Delete user"
|
||||
msgid "Delete passkey"
|
||||
msgstr "Benutzer löschen"
|
||||
msgstr "Passkey löschen"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:155
|
||||
#: plinth/modules/users/templates/users_update.html:72
|
||||
@ -10100,6 +10101,7 @@ msgstr "Benutzer <em>%(username)s</em> bearbeiten"
|
||||
#, python-format
|
||||
msgid "Use <a href=\"%(passkeys_url)s\">passkeys</a> for better security."
|
||||
msgstr ""
|
||||
"Verwenden Sie <a href=\"%(passkeys_url)s\">Passkeys</a> für mehr Sicherheit."
|
||||
|
||||
#: plinth/modules/users/templates/users_update.html:29
|
||||
#, python-format
|
||||
@ -10166,20 +10168,16 @@ msgid "Password changed successfully."
|
||||
msgstr "Passwort erfolgreich geändert."
|
||||
|
||||
#: plinth/modules/users/views.py:420
|
||||
#, fuzzy
|
||||
#| msgid "A share with this name already exists."
|
||||
msgid "Passkey with that identifier already exists."
|
||||
msgstr "Eine Freigabe mit diesem Namen existiert bereits."
|
||||
msgstr "Ein Passkey mit dieser Kennung existiert bereits."
|
||||
|
||||
#: plinth/modules/users/views.py:431
|
||||
#, fuzzy
|
||||
#| msgid "Edit User"
|
||||
msgid "Edit Passkey"
|
||||
msgstr "Benutzer bearbeiten"
|
||||
msgstr "Passkey bearbeiten"
|
||||
|
||||
#: plinth/modules/users/views.py:518 plinth/modules/users/views.py:542
|
||||
msgid "Passkey used is not known."
|
||||
msgstr ""
|
||||
msgstr "Der verwendete Passkey ist nicht bekannt."
|
||||
|
||||
#: plinth/modules/wireguard/__init__.py:20
|
||||
msgid "WireGuard is a fast, modern, secure VPN tunnel."
|
||||
@ -10335,17 +10333,15 @@ msgstr "Informationen zu dieser %(box_name)s:"
|
||||
|
||||
#: plinth/modules/wireguard/templates/wireguard.html:25
|
||||
msgid "Property"
|
||||
msgstr ""
|
||||
msgstr "Eigenschaft"
|
||||
|
||||
#: plinth/modules/wireguard/templates/wireguard.html:26
|
||||
msgid "Value"
|
||||
msgstr ""
|
||||
msgstr "Wert"
|
||||
|
||||
#: plinth/modules/wireguard/templates/wireguard.html:33
|
||||
#, fuzzy
|
||||
#| msgid "Endpoint"
|
||||
msgid "Endpoint(s)"
|
||||
msgstr "Endpunkt"
|
||||
msgstr "Endpunkt(e)"
|
||||
|
||||
#: plinth/modules/wireguard/templates/wireguard.html:41
|
||||
#, python-format
|
||||
@ -10720,7 +10716,7 @@ msgstr "Foto"
|
||||
|
||||
#: plinth/modules/zoph/manifest.py:26
|
||||
msgid "Organizer"
|
||||
msgstr ""
|
||||
msgstr "Organisator"
|
||||
|
||||
#: plinth/modules/zoph/templates/zoph-pre-setup.html:15
|
||||
#: plinth/modules/zoph/templates/zoph-pre-setup.html:28
|
||||
@ -10988,10 +10984,8 @@ msgid " System"
|
||||
msgstr " System"
|
||||
|
||||
#: plinth/templates/base.html:179 plinth/templates/base.html:180
|
||||
#, fuzzy
|
||||
#| msgid "Manage Aliases"
|
||||
msgid "Manage passkeys"
|
||||
msgstr "Aliase verwalten"
|
||||
msgstr "Passkeys verwalten"
|
||||
|
||||
#: plinth/templates/base.html:186 plinth/templates/base.html:187
|
||||
msgid "Change password"
|
||||
|
||||
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -6341,7 +6341,7 @@ msgstr ""
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -6350,14 +6350,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr ""
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2026-02-22 13:17+0000\n"
|
||||
"Last-Translator: James Valleroy <jvalleroy@mailbox.org>\n"
|
||||
"Language-Team: Greek <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -7441,7 +7441,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, fuzzy, python-brace-format
|
||||
#| msgid ""
|
||||
#| "Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7460,7 +7460,7 @@ msgstr ""
|
||||
"clients/\">πελάτη</a> . Το Radicale μπορεί να προσεγγιστεί από οποιονδήποτε "
|
||||
"χρήστη με {box_name} πιστοποιητικά."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
@ -7471,7 +7471,7 @@ msgstr ""
|
||||
"γεγονότων ή επαφών, το οποίο πρέπει να γίνει χρησιμοποιώντας ένα ξεχωριστό "
|
||||
"πελάτη."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "Radicale"
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2024-11-01 17:00+0000\n"
|
||||
"Last-Translator: gallegonovato <fran-carro@hotmail.es>\n"
|
||||
"Language-Team: Spanish <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -7381,7 +7381,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, fuzzy, python-brace-format
|
||||
#| msgid ""
|
||||
#| "Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7401,7 +7401,7 @@ msgstr ""
|
||||
"supported-clients\">aplicación cliente soportada</a>. Cualquier persona "
|
||||
"autenticada en {box_name} puede acceder a Radicale."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
@ -7411,7 +7411,7 @@ msgstr ""
|
||||
"de nuevos calendarios y agendas. No soporta añadir eventos o contactos, que "
|
||||
"debe hacerse usando un cliente separado."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "Radicale"
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2026-01-09 20:01+0000\n"
|
||||
"Last-Translator: Priit Jõerüüt <jrthwlate@users.noreply.hosted.weblate.org>\n"
|
||||
"Language-Team: Estonian <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -6384,7 +6384,7 @@ msgstr ""
|
||||
msgid "IRC"
|
||||
msgstr "IRC"
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -6393,14 +6393,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "Radicale"
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2022-09-14 17:19+0000\n"
|
||||
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
|
||||
"Language-Team: Persian <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -7062,7 +7062,7 @@ msgstr ""
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7071,14 +7071,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr ""
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Plinth 0.6\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2016-01-31 22:24+0530\n"
|
||||
"Last-Translator: Sunil Mohan Adapa <sunil@medhas.org>\n"
|
||||
"Language-Team: Plinth Developers <freedombox-"
|
||||
@ -7390,7 +7390,7 @@ msgstr ""
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7399,14 +7399,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr ""
|
||||
|
||||
@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: FreedomBox UI\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"PO-Revision-Date: 2026-03-29 11:09+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2026-04-16 15:09+0000\n"
|
||||
"Last-Translator: Coucouf <coucouf@coucouf.fr>\n"
|
||||
"Language-Team: French <https://hosted.weblate.org/projects/freedombox/"
|
||||
"freedombox/fr/>\n"
|
||||
@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||
"X-Generator: Weblate 5.17-dev\n"
|
||||
"X-Generator: Weblate 5.17.1-dev\n"
|
||||
|
||||
#: plinth/config.py:103
|
||||
#, python-brace-format
|
||||
@ -7326,7 +7326,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr "IRC"
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7342,7 +7342,7 @@ msgstr ""
|
||||
"a>. Tous les utilisateur disposant d’un compte sur la {box_name} ont accès à "
|
||||
"Radicale."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
@ -7353,7 +7353,7 @@ msgstr ""
|
||||
"charge l’ajout d’événements ou de contacts, opérations qui doivent être "
|
||||
"réalisées avec un client dédié."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "Radicale"
|
||||
@ -10049,14 +10049,12 @@ msgstr "Paramètres du compte %(username)s"
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:30
|
||||
msgid "Logging in with passkey failed: "
|
||||
msgstr ""
|
||||
msgstr "Échec de la connexion par clé d’accès : "
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:41
|
||||
#: plinth/modules/users/templates/users_passkeys.html:41
|
||||
#, fuzzy
|
||||
#| msgid "This app does not support diagnostics"
|
||||
msgid "Browser does not support passkeys."
|
||||
msgstr "Cette application n’est pas compatible avec les tests de diagnostic"
|
||||
msgstr "Le navigateur n’est pas compatible avec les clés d’accès."
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:57
|
||||
msgid "Login"
|
||||
@ -10065,28 +10063,28 @@ msgstr "S’identifier"
|
||||
#: plinth/modules/users/templates/users_login.html:70
|
||||
#: plinth/modules/users/templates/users_login.html:72
|
||||
msgid "Log in with passkey"
|
||||
msgstr ""
|
||||
msgstr "Connexion avec une clé d’accès"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkey_edit.html:19
|
||||
#, fuzzy
|
||||
#| msgid "Update setup"
|
||||
msgid "Update Passkey"
|
||||
msgstr "Appliquer les changements"
|
||||
msgstr "Mettre à jour la clé d’accès"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:30
|
||||
msgid "Adding passkey failed: "
|
||||
msgstr ""
|
||||
msgstr "Échec d’ajout d’une clé d’accès : "
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:48
|
||||
#: plinth/modules/users/views.py:314
|
||||
msgid "Passkeys"
|
||||
msgstr ""
|
||||
msgstr "Clés d’accès"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:57
|
||||
msgid ""
|
||||
"Working with passkeys requires using browser's Javascript API. Please enable "
|
||||
"Javascript support in your browser to continue."
|
||||
msgstr ""
|
||||
"L’utilisation de clés d’accès nécessite l’utilisation de l’API Javascript du "
|
||||
"navigateur. Veuillez activer Javascript dans votre navigateur pour continuer."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:66
|
||||
msgid ""
|
||||
@ -10097,47 +10095,48 @@ msgid ""
|
||||
"server knows only the public information that can used to verify user's "
|
||||
"signatures."
|
||||
msgstr ""
|
||||
"Les clés d’accès sont un moyen de vérifier l’identité de l’utilisateur au "
|
||||
"travers de signatures numériques. Elles présentent un alternative plus sure "
|
||||
"à l’usage des mots de passe. Les secrets sont conservés sur le téléphone, "
|
||||
"l’ordinateur ou le jeton d’authentification matériel et protégés par un code "
|
||||
"ou une empreinte biométrique. Aucun secret n’est conservé sur les serveur. "
|
||||
"Le serveur n’a besoin de connaître que les informations publiques permettant "
|
||||
"de vérifier la signature de l’utilisateurice."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:83
|
||||
#: plinth/modules/users/templates/users_passkeys.html:85
|
||||
#, fuzzy
|
||||
#| msgid "Add password"
|
||||
msgid "Add passkey"
|
||||
msgstr "Ajouter un mot de passe"
|
||||
msgstr "Ajouter une clé d’accès"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:93
|
||||
#, fuzzy
|
||||
#| msgid "Domain"
|
||||
msgid "For Domain"
|
||||
msgstr "Domaine"
|
||||
msgstr "Pour le domaine"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:94
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
msgstr "Ajoutée"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:95
|
||||
#, fuzzy
|
||||
#| msgid "Last scanned: "
|
||||
msgid "Last Used"
|
||||
msgstr "Dernière analyse : "
|
||||
msgstr "Dernière utilisation"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:126
|
||||
msgid "No passkeys added to user account."
|
||||
msgstr ""
|
||||
msgstr "Aucune clé d’accès pour ce compte."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:135
|
||||
msgid "Delete passkey <em class=\"passkey-name\"></em>?"
|
||||
msgstr ""
|
||||
msgstr "Supprimer la clé d’accès <em class=\"passkey-name\"></em> ?"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:145
|
||||
msgid "You will need this passkey's device to add it back again."
|
||||
msgstr ""
|
||||
"Vous aurez besoin de l’appareil contenant cette clé d’accès pour pouvoir "
|
||||
"l’ajouter à nouveau."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:152
|
||||
#, fuzzy
|
||||
#| msgid "Delete user"
|
||||
msgid "Delete passkey"
|
||||
msgstr "Supprimer l'utilisateur"
|
||||
msgstr "Supprimer la clé d’accès"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:155
|
||||
#: plinth/modules/users/templates/users_update.html:72
|
||||
@ -10153,6 +10152,8 @@ msgstr "Modifier l’utilisateur <em>%(username)s</em>"
|
||||
#, python-format
|
||||
msgid "Use <a href=\"%(passkeys_url)s\">passkeys</a> for better security."
|
||||
msgstr ""
|
||||
"Utilisez une <a href=\"%(passkeys_url)s\">clé d’accès</a> pour une meilleure "
|
||||
"sécurité."
|
||||
|
||||
#: plinth/modules/users/templates/users_update.html:29
|
||||
#, python-format
|
||||
@ -10220,20 +10221,16 @@ msgid "Password changed successfully."
|
||||
msgstr "Le mot de passe a été changé."
|
||||
|
||||
#: plinth/modules/users/views.py:420
|
||||
#, fuzzy
|
||||
#| msgid "A share with this name already exists."
|
||||
msgid "Passkey with that identifier already exists."
|
||||
msgstr "Un partage existe déjà avec ce nom."
|
||||
msgstr "Il y a déjà un clé d’accès avec cet identifiant."
|
||||
|
||||
#: plinth/modules/users/views.py:431
|
||||
#, fuzzy
|
||||
#| msgid "Edit User"
|
||||
msgid "Edit Passkey"
|
||||
msgstr "Modification de l’utilisateur"
|
||||
msgstr "Modifier la clé d’accès"
|
||||
|
||||
#: plinth/modules/users/views.py:518 plinth/modules/users/views.py:542
|
||||
msgid "Passkey used is not known."
|
||||
msgstr ""
|
||||
msgstr "La clé d’accès utilisée est inconnue."
|
||||
|
||||
#: plinth/modules/wireguard/__init__.py:20
|
||||
msgid "WireGuard is a fast, modern, secure VPN tunnel."
|
||||
@ -11036,10 +11033,8 @@ msgid " System"
|
||||
msgstr " Système"
|
||||
|
||||
#: plinth/templates/base.html:179 plinth/templates/base.html:180
|
||||
#, fuzzy
|
||||
#| msgid "Manage Aliases"
|
||||
msgid "Manage passkeys"
|
||||
msgstr "Configurer des alias"
|
||||
msgstr "Gérer les clés d’accès"
|
||||
|
||||
#: plinth/templates/base.html:186 plinth/templates/base.html:187
|
||||
msgid "Change password"
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2022-12-30 10:51+0000\n"
|
||||
"Last-Translator: gallegonovato <fran-carro@hotmail.es>\n"
|
||||
"Language-Team: Galician <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -6385,7 +6385,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -6394,14 +6394,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr ""
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2021-01-18 12:32+0000\n"
|
||||
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
|
||||
"Language-Team: Gujarati <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -6776,7 +6776,7 @@ msgstr ""
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -6785,14 +6785,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr ""
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2026-03-31 06:09+0000\n"
|
||||
"Last-Translator: bsurajpatra <ankitsuraj1111@gmail.com>\n"
|
||||
"Language-Team: Hindi <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -7329,7 +7329,7 @@ msgstr "क्वासेलड्रोइड"
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, fuzzy, python-brace-format
|
||||
#| msgid ""
|
||||
#| "Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7347,14 +7347,14 @@ msgstr ""
|
||||
"radicale.org/clients/\">समर्थित क्लाइंट एप्लिकेशन</a> कि जरुरत है. राडिकैल किसी "
|
||||
"{box_name} यूसर पहुंचा जा सकता है एक लॉगिन के साथ."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "राडिकैल"
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2025-06-04 15:01+0000\n"
|
||||
"Last-Translator: András Szűcs "
|
||||
"<andrascc86288f63c44cb5@users.noreply.hosted.weblate.org>\n"
|
||||
@ -7496,7 +7496,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, fuzzy, python-brace-format
|
||||
#| msgid ""
|
||||
#| "Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7517,7 +7517,7 @@ msgstr ""
|
||||
"alkalmazásra</a> is. A Radicale elérhető bármely felhasználó számára a "
|
||||
"{box_name} eszközön."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
@ -7527,7 +7527,7 @@ msgstr ""
|
||||
"címjegyzékek létrehozását támogatja. Nem támogatja az események vagy "
|
||||
"kapcsolatok hozzáadását, ezeket külön kliens segítségével kell elvégezni."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "Radicale"
|
||||
|
||||
@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Indonesian (FreedomBox)\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2022-09-14 17:19+0000\n"
|
||||
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
|
||||
"Language-Team: Indonesian <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -7047,7 +7047,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7056,14 +7056,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "Radicale"
|
||||
|
||||
@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"PO-Revision-Date: 2026-03-31 06:09+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2026-05-05 17:11+0000\n"
|
||||
"Last-Translator: Pierfrancesco Passerini <p.passerini@gmail.com>\n"
|
||||
"Language-Team: Italian <https://hosted.weblate.org/projects/freedombox/"
|
||||
"freedombox/it/>\n"
|
||||
@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.17-dev\n"
|
||||
"X-Generator: Weblate 5.17.1\n"
|
||||
|
||||
#: plinth/config.py:103
|
||||
#, python-brace-format
|
||||
@ -7219,7 +7219,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr "IRC"
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7233,7 +7233,7 @@ msgstr ""
|
||||
"client supportata</a>. Ogni utente con un profilo {box_name} può accedere a "
|
||||
"Radicale."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
@ -7243,7 +7243,7 @@ msgstr ""
|
||||
"nuovi calendari e rubriche. Non supporta l'aggiunta di eventi o contatti, "
|
||||
"che dovranno essere gestiti tramite un client separato."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "Radicale"
|
||||
@ -9872,14 +9872,12 @@ msgstr "Modifica l'utente %(username)s"
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:30
|
||||
msgid "Logging in with passkey failed: "
|
||||
msgstr ""
|
||||
msgstr "Aaccesso con passkey non riuscito: "
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:41
|
||||
#: plinth/modules/users/templates/users_passkeys.html:41
|
||||
#, fuzzy
|
||||
#| msgid "This app does not support diagnostics"
|
||||
msgid "Browser does not support passkeys."
|
||||
msgstr "Questa applicazione non supporta la diagnostica"
|
||||
msgstr "Il browser non supporta le passkey."
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:57
|
||||
msgid "Login"
|
||||
@ -9888,28 +9886,28 @@ msgstr "Login"
|
||||
#: plinth/modules/users/templates/users_login.html:70
|
||||
#: plinth/modules/users/templates/users_login.html:72
|
||||
msgid "Log in with passkey"
|
||||
msgstr ""
|
||||
msgstr "Accedi con passkey"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkey_edit.html:19
|
||||
#, fuzzy
|
||||
#| msgid "Update setup"
|
||||
msgid "Update Passkey"
|
||||
msgstr "Aggiorna impostazioni"
|
||||
msgstr "Aggiorna Passkey"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:30
|
||||
msgid "Adding passkey failed: "
|
||||
msgstr ""
|
||||
msgstr "Aggiunta di passkey non riuscita: "
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:48
|
||||
#: plinth/modules/users/views.py:314
|
||||
msgid "Passkeys"
|
||||
msgstr ""
|
||||
msgstr "Passkey"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:57
|
||||
msgid ""
|
||||
"Working with passkeys requires using browser's Javascript API. Please enable "
|
||||
"Javascript support in your browser to continue."
|
||||
msgstr ""
|
||||
"L'uso di passkey richiede l'accesso alle API Javascript del browser. Prima "
|
||||
"di continuare, accertati che tale supporto sia presente."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:66
|
||||
msgid ""
|
||||
@ -9920,47 +9918,46 @@ msgid ""
|
||||
"server knows only the public information that can used to verify user's "
|
||||
"signatures."
|
||||
msgstr ""
|
||||
"Le passkey permettono la verifica degli accessi mediante l'utilizzo di firme "
|
||||
"digitali. Rappresentano un'alternativa più sicura alle password. Le "
|
||||
"informazioni riservate vengono conservate dall'utente sul proprio telefono, "
|
||||
"laptop o su un token hardware e sbloccate tramite PIN, impronta digitale o "
|
||||
"riconoscimento del volto. Nessuna informazione riservata viene memorizzata "
|
||||
"sul server. Il server conosce solo le informazioni pubbliche che possono "
|
||||
"essere utilizzate per verificare le firme dell'utente."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:83
|
||||
#: plinth/modules/users/templates/users_passkeys.html:85
|
||||
#, fuzzy
|
||||
#| msgid "Add password"
|
||||
msgid "Add passkey"
|
||||
msgstr "Aggiungi la password"
|
||||
msgstr "Aggiungi Passkey"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:93
|
||||
#, fuzzy
|
||||
#| msgid "Domain"
|
||||
msgid "For Domain"
|
||||
msgstr "Dominio"
|
||||
msgstr "Per Dominio"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:94
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
msgstr "Aggiunto"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:95
|
||||
#, fuzzy
|
||||
#| msgid "Last scanned: "
|
||||
msgid "Last Used"
|
||||
msgstr "Ultima scansione: "
|
||||
msgstr "Ultimo utilizzo"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:126
|
||||
msgid "No passkeys added to user account."
|
||||
msgstr ""
|
||||
msgstr "Nessuna passkey aggiunta all'account utente."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:135
|
||||
msgid "Delete passkey <em class=\"passkey-name\"></em>?"
|
||||
msgstr ""
|
||||
msgstr "Elimina passkey <em class=\"passkey-name\"></em>?"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:145
|
||||
msgid "You will need this passkey's device to add it back again."
|
||||
msgstr ""
|
||||
msgstr "Avrai bisogno di questa passkey per aggiungere di nuovo il dispositivo."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:152
|
||||
#, fuzzy
|
||||
#| msgid "Delete user"
|
||||
msgid "Delete passkey"
|
||||
msgstr "Cancella l'utente"
|
||||
msgstr "Cancella Passkey"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:155
|
||||
#: plinth/modules/users/templates/users_update.html:72
|
||||
@ -9976,6 +9973,8 @@ msgstr "Modifica utente <em>%(username)s</em>"
|
||||
#, python-format
|
||||
msgid "Use <a href=\"%(passkeys_url)s\">passkeys</a> for better security."
|
||||
msgstr ""
|
||||
"Utilizzare <a href=\"%(passkeys_url)s\">passkey</a> per una maggiore "
|
||||
"sicurezza."
|
||||
|
||||
#: plinth/modules/users/templates/users_update.html:29
|
||||
#, python-format
|
||||
@ -10040,20 +10039,16 @@ msgid "Password changed successfully."
|
||||
msgstr "La password è stata aggiornata."
|
||||
|
||||
#: plinth/modules/users/views.py:420
|
||||
#, fuzzy
|
||||
#| msgid "A share with this name already exists."
|
||||
msgid "Passkey with that identifier already exists."
|
||||
msgstr "Una condivisione con questo nome esiste già."
|
||||
msgstr "Esiste già un Passkey con quell'identificatore."
|
||||
|
||||
#: plinth/modules/users/views.py:431
|
||||
#, fuzzy
|
||||
#| msgid "Edit User"
|
||||
msgid "Edit Passkey"
|
||||
msgstr "Modifica utente"
|
||||
msgstr "Modifica Passkey"
|
||||
|
||||
#: plinth/modules/users/views.py:518 plinth/modules/users/views.py:542
|
||||
msgid "Passkey used is not known."
|
||||
msgstr ""
|
||||
msgstr "Passkey sconosciuta."
|
||||
|
||||
#: plinth/modules/wireguard/__init__.py:20
|
||||
msgid "WireGuard is a fast, modern, secure VPN tunnel."
|
||||
@ -10842,10 +10837,8 @@ msgid " System"
|
||||
msgstr " Sistema"
|
||||
|
||||
#: plinth/templates/base.html:179 plinth/templates/base.html:180
|
||||
#, fuzzy
|
||||
#| msgid "Manage Aliases"
|
||||
msgid "Manage passkeys"
|
||||
msgstr "Gestire gli alias"
|
||||
msgstr "Gestire le Passkey"
|
||||
|
||||
#: plinth/templates/base.html:186 plinth/templates/base.html:187
|
||||
msgid "Change password"
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2025-10-24 16:02+0000\n"
|
||||
"Last-Translator: Jun Nogata <nogajun@gmail.com>\n"
|
||||
"Language-Team: Japanese <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -6348,7 +6348,7 @@ msgstr ""
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -6357,14 +6357,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr ""
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2020-07-16 16:41+0000\n"
|
||||
"Last-Translator: Yogesh <yogesh@karnatakaeducation.org.in>\n"
|
||||
"Language-Team: Kannada <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -6343,7 +6343,7 @@ msgstr ""
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -6352,14 +6352,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr ""
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2022-09-14 17:19+0000\n"
|
||||
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
|
||||
"Language-Team: Lithuanian <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -6363,7 +6363,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -6372,14 +6372,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr ""
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2022-09-14 17:20+0000\n"
|
||||
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
|
||||
"Language-Team: Latvian <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -6362,7 +6362,7 @@ msgstr ""
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -6371,14 +6371,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr ""
|
||||
|
||||
@ -15,7 +15,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: FreedomBox UI\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2024-10-27 23:30+0000\n"
|
||||
"Last-Translator: Sunil Mohan Adapa <sunil@medhas.org>\n"
|
||||
"Language-Team: Norwegian Bokmål <https://hosted.weblate.org/projects/"
|
||||
@ -7433,7 +7433,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, fuzzy, python-brace-format
|
||||
#| msgid ""
|
||||
#| "Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7451,7 +7451,7 @@ msgstr ""
|
||||
"href=\"http://radicale.org/clients/\">støttet klientprogram </a>. Radicale "
|
||||
"kan nås av alle brukere med {box_name}-innlogging."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
@ -7461,7 +7461,7 @@ msgstr ""
|
||||
"kalendre og adressebøker. Den tilbyr ikke å legge inn nye hendelser eller "
|
||||
"kontakter, det må gjøres med en egen klient."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "Radicale"
|
||||
|
||||
@ -7,9 +7,9 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"PO-Revision-Date: 2025-09-17 09:01+0000\n"
|
||||
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2026-05-21 18:11+0000\n"
|
||||
"Last-Translator: jay <jj8z@proton.me>\n"
|
||||
"Language-Team: Dutch <https://hosted.weblate.org/projects/freedombox/"
|
||||
"freedombox/nl/>\n"
|
||||
"Language: nl\n"
|
||||
@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.14-dev\n"
|
||||
"X-Generator: Weblate 2026.6.dev0\n"
|
||||
"X-Language: nl_NL\n"
|
||||
"X-Source-Language: C\n"
|
||||
|
||||
@ -412,10 +412,8 @@ msgid "Passphrase"
|
||||
msgstr "Wachtwoordzin"
|
||||
|
||||
#: plinth/modules/backups/forms.py:187
|
||||
#, fuzzy
|
||||
#| msgid "Passphrase; Only needed when using encryption."
|
||||
msgid "Only needed when using encryption."
|
||||
msgstr "Wachtwoordzin; Alleen nodig bij het gebruik van versleuteling."
|
||||
msgstr "Alleen nodig bij het gebruik van versleuteling."
|
||||
|
||||
#: plinth/modules/backups/forms.py:190
|
||||
msgid "Confirm Passphrase"
|
||||
@ -482,10 +480,8 @@ msgid "SSH server password"
|
||||
msgstr "SSH-server wachtwoord"
|
||||
|
||||
#: plinth/modules/backups/forms.py:262
|
||||
#, fuzzy
|
||||
#| msgid "Disable password authentication"
|
||||
msgid "Required for password-based authentication."
|
||||
msgstr "Wachtwoord authenticatie uitschakelen"
|
||||
msgstr "Benodigd voor wachtwoord authenticatie."
|
||||
|
||||
#: plinth/modules/backups/forms.py:275
|
||||
#, fuzzy
|
||||
@ -824,10 +820,9 @@ msgid "Authentication to remote server failed."
|
||||
msgstr "Authenticatie naar externe server is mislukt."
|
||||
|
||||
#: plinth/modules/backups/views.py:50
|
||||
#, fuzzy
|
||||
#| msgid "Error establishing connection to server: {}"
|
||||
msgid "Error establishing connection to server: {} {} {}"
|
||||
msgstr "Fout bij het tot stand brengen van een verbinding met de server: {}"
|
||||
msgstr ""
|
||||
"Fout bij het tot stand brengen van een verbinding met de server: {} {} {}"
|
||||
|
||||
#: plinth/modules/backups/views.py:82
|
||||
msgid "Backup schedule updated."
|
||||
@ -1470,14 +1465,7 @@ msgid "Webserver Home Page"
|
||||
msgstr "Startpagina van de webserver"
|
||||
|
||||
#: plinth/modules/config/forms.py:37
|
||||
#, fuzzy, python-brace-format
|
||||
#| msgid ""
|
||||
#| "Choose the default page that must be served when someone visits your "
|
||||
#| "{box_name} on the web. A typical use case is to set your blog or wiki as "
|
||||
#| "the home page when someone visits the domain name. Note that once the "
|
||||
#| "home page is set to something other than {box_name} Service (Plinth), "
|
||||
#| "your users must explicitly type /plinth or /freedombox to reach "
|
||||
#| "{box_name} Service (Plinth)."
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Choose the default page that must be served when someone visits your "
|
||||
"{box_name} on the web. A typical use case is to set your blog or wiki as the "
|
||||
@ -1489,8 +1477,8 @@ msgstr ""
|
||||
"{box_name} op internet bezoekt. Vaak wordt het blog of wiki ingesteld als de "
|
||||
"startpagina wanneer iemand de domeinnaam bezoekt. Merk op dat zodra de "
|
||||
"startpagina is ingesteld op iets anders dan {box_name} service (Plinth), "
|
||||
"gebruikers expliciet /plinth of /freedombox moeten typen om de {box_name} "
|
||||
"service (Plinth) te bereiken."
|
||||
"gebruikers expliciet /freedombox moeten typen om de {box_name} service "
|
||||
"(Plinth) te bereiken."
|
||||
|
||||
#: plinth/modules/config/forms.py:48
|
||||
msgid "Show advanced apps and features"
|
||||
@ -2446,16 +2434,12 @@ msgstr ""
|
||||
"automatisch aangemaakt en wijzen naar de eerste admin gebruiker."
|
||||
|
||||
#: plinth/modules/email/__init__.py:41
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "<a href=\"/plinth/apps/roundcube/\">Roundcube app</a> provides web "
|
||||
#| "interface for users to access email."
|
||||
msgid ""
|
||||
"<a href=\"/freedombox/apps/roundcube/\">Roundcube app</a> provides web "
|
||||
"interface for users to access email."
|
||||
msgstr ""
|
||||
"<a href=\"/plinth/apps/roundcube/\">Roundcube app</a> biedt gebruikers een "
|
||||
"webinterface om toegang te krijgen tot e-mail."
|
||||
"<a href=\"/freedombox/apps/roundcube/\">Roundcube app</a> biedt gebruikers "
|
||||
"een webinterface om toegang te krijgen tot e-mail."
|
||||
|
||||
#: plinth/modules/email/__init__.py:43
|
||||
msgid ""
|
||||
@ -7172,7 +7156,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr "IRC"
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7186,7 +7170,7 @@ msgstr ""
|
||||
"clienttoepassing</a> nodig. Radicale kan worden benaderd door elke "
|
||||
"{box_name} gebruiker."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
@ -7197,7 +7181,7 @@ msgstr ""
|
||||
"gebeurtenissen of contactpersonen, die moeten worden gedaan met behulp van "
|
||||
"een aparte client."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "Radicale"
|
||||
@ -9771,10 +9755,8 @@ msgstr ""
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:41
|
||||
#: plinth/modules/users/templates/users_passkeys.html:41
|
||||
#, fuzzy
|
||||
#| msgid "This app does not support diagnostics"
|
||||
msgid "Browser does not support passkeys."
|
||||
msgstr "Deze toepassing heeft geen diagnosetests"
|
||||
msgstr "De browser ondersteunt geen passkeys."
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:57
|
||||
msgid "Login"
|
||||
@ -9834,10 +9816,8 @@ msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:95
|
||||
#, fuzzy
|
||||
#| msgid "Last scanned: "
|
||||
msgid "Last Used"
|
||||
msgstr "Laatst gescand: "
|
||||
msgstr "Laatst gebruikt"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:126
|
||||
msgid "No passkeys added to user account."
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2024-07-13 12:09+0000\n"
|
||||
"Last-Translator: Monika <adamdomenek@protonmail.com>\n"
|
||||
"Language-Team: Polish <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -7012,7 +7012,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7021,14 +7021,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "Radicale"
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2025-04-09 22:41+0000\n"
|
||||
"Last-Translator: tuliogit <wikigeolog@gmx.com>\n"
|
||||
"Language-Team: Portuguese <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -7266,7 +7266,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr "IRC"
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7280,7 +7280,7 @@ msgstr ""
|
||||
"radicale.org/master.html#supported-clients\"></a> . O Radicale pode "
|
||||
"ser acessado por qualquer usuário com um login {box_name} ."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
@ -7290,7 +7290,7 @@ msgstr ""
|
||||
"novos calendários e catálogos de endereços. Não permite adicionar eventos ou "
|
||||
"contatos, o que deve ser feito usando um cliente separado."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "Radical"
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2026-03-15 18:09+0000\n"
|
||||
"Last-Translator: OwlGale <owlgale@users.noreply.hosted.weblate.org>\n"
|
||||
"Language-Team: Russian <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -7224,7 +7224,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr "IRC"
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7238,7 +7238,7 @@ msgstr ""
|
||||
"clients\">поддерживаемое клиентское приложение</a>. Доступ к Radicale может "
|
||||
"получить любой пользователь с логином {box_name}."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
@ -7248,7 +7248,7 @@ msgstr ""
|
||||
"создание новых календарей и адресных книг. Он не поддерживает добавление "
|
||||
"событий или контактов, для этого требуется отдельный клиент."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "Radicale"
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2021-04-27 13:32+0000\n"
|
||||
"Last-Translator: HelaBasa <R45XvezA@protonmail.ch>\n"
|
||||
"Language-Team: Sinhala <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -6343,7 +6343,7 @@ msgstr ""
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -6352,14 +6352,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr ""
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2022-09-14 17:19+0000\n"
|
||||
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
|
||||
"Language-Team: Slovenian <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -6698,7 +6698,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -6707,14 +6707,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr ""
|
||||
|
||||
@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"PO-Revision-Date: 2026-03-26 09:09+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2026-04-08 07:09+0000\n"
|
||||
"Last-Translator: Besnik Bleta <besnik@programeshqip.org>\n"
|
||||
"Language-Team: Albanian <https://hosted.weblate.org/projects/freedombox/"
|
||||
"freedombox/sq/>\n"
|
||||
@ -7237,7 +7237,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr "IRC"
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7252,7 +7252,7 @@ msgstr ""
|
||||
"Radicale mund të hyhet nga cilido përdorues me kredenciale hyrjeje në "
|
||||
"{box_name}."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
@ -7262,7 +7262,7 @@ msgstr ""
|
||||
"të ri dhe librash adresash. S’mbulon shtim veprimtarish ose kontaktesh, çka "
|
||||
"duhen bërë duke përdorur një tjetër klient."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "Radicale"
|
||||
@ -9899,14 +9899,12 @@ msgstr "Përpunoni përdoruesin %(username)s"
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:30
|
||||
msgid "Logging in with passkey failed: "
|
||||
msgstr ""
|
||||
msgstr "Hyrja me kyçkalim dështoi: "
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:41
|
||||
#: plinth/modules/users/templates/users_passkeys.html:41
|
||||
#, fuzzy
|
||||
#| msgid "This app does not support diagnostics"
|
||||
msgid "Browser does not support passkeys."
|
||||
msgstr "Ky aplikacion s’mbulon diagnostikime"
|
||||
msgstr "Shfletuesi s’mbulon kyçkalime."
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:57
|
||||
msgid "Login"
|
||||
@ -9915,28 +9913,28 @@ msgstr "Hyrje"
|
||||
#: plinth/modules/users/templates/users_login.html:70
|
||||
#: plinth/modules/users/templates/users_login.html:72
|
||||
msgid "Log in with passkey"
|
||||
msgstr ""
|
||||
msgstr "Hyni me kyçkalim"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkey_edit.html:19
|
||||
#, fuzzy
|
||||
#| msgid "Update setup"
|
||||
msgid "Update Passkey"
|
||||
msgstr "Përditësoni ujdisjen"
|
||||
msgstr "Përditësoni Kyçkalimin"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:30
|
||||
msgid "Adding passkey failed: "
|
||||
msgstr ""
|
||||
msgstr "Shtimi i kyçkalimit dështoi: "
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:48
|
||||
#: plinth/modules/users/views.py:314
|
||||
msgid "Passkeys"
|
||||
msgstr ""
|
||||
msgstr "Kyçkalime"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:57
|
||||
msgid ""
|
||||
"Working with passkeys requires using browser's Javascript API. Please enable "
|
||||
"Javascript support in your browser to continue."
|
||||
msgstr ""
|
||||
"Puna me kyçkalime lyp përdorim të API-t Javascript të shfletuesit. Ju "
|
||||
"lutemi, që të vazhdohet, aktivizoni mbulim Javascript-i në shfletuesin tuaj."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:66
|
||||
msgid ""
|
||||
@ -9947,47 +9945,46 @@ msgid ""
|
||||
"server knows only the public information that can used to verify user's "
|
||||
"signatures."
|
||||
msgstr ""
|
||||
"Kyçkalimet janë një mënyrë verifikimi identiteti përdoruesit duke përdorur "
|
||||
"nënshkrime dixhitale. Janë një alternativë më e siguruar se fjalëkalimet. "
|
||||
"Informacioni i fshehtë mbahet nga përdoruesi në telefonin e tij, portativin, "
|
||||
"ose token-in hardware dhe shkyçet duke përdorur një PIN, shenja gishtash ose "
|
||||
"“face ID”. S’ruhet të fshehta te shërbyesi. Shërbyesi njeh vetëm "
|
||||
"informacionin publik që mund të përdoret për të verifikuar nënshkrime të "
|
||||
"përdoruesit."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:83
|
||||
#: plinth/modules/users/templates/users_passkeys.html:85
|
||||
#, fuzzy
|
||||
#| msgid "Add password"
|
||||
msgid "Add passkey"
|
||||
msgstr "Shtoni fjalëkalim"
|
||||
msgstr "Shtoni kyçkalim"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:93
|
||||
#, fuzzy
|
||||
#| msgid "Domain"
|
||||
msgid "For Domain"
|
||||
msgstr "Përkatësi"
|
||||
msgstr "Për Përkatësi"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:94
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
msgstr "U shtua"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:95
|
||||
#, fuzzy
|
||||
#| msgid "Last scanned: "
|
||||
msgid "Last Used"
|
||||
msgstr "Skanuar së fundi më: "
|
||||
msgstr "Përdorur Së Fundi Më"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:126
|
||||
msgid "No passkeys added to user account."
|
||||
msgstr ""
|
||||
msgstr "Te llogari përdoruesi, s’u shtuan kyçkalime."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:135
|
||||
msgid "Delete passkey <em class=\"passkey-name\"></em>?"
|
||||
msgstr ""
|
||||
msgstr "Të fshihet kyçkalimi <em class=\"passkey-name\"></em>?"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:145
|
||||
msgid "You will need this passkey's device to add it back again."
|
||||
msgstr ""
|
||||
msgstr "Që ta rishtoni, do t’ju duhet pajisja e këtij kyçkalimi."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:152
|
||||
#, fuzzy
|
||||
#| msgid "Delete user"
|
||||
msgid "Delete passkey"
|
||||
msgstr "Fshi përdorues"
|
||||
msgstr "Fshije kyçkalimin"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:155
|
||||
#: plinth/modules/users/templates/users_update.html:72
|
||||
@ -10003,6 +10000,7 @@ msgstr "Përpunoni Përdoruesin <em>%(username)s</em>"
|
||||
#, python-format
|
||||
msgid "Use <a href=\"%(passkeys_url)s\">passkeys</a> for better security."
|
||||
msgstr ""
|
||||
"Për siguri më të mirë, përdorni <a href=\"%(passkeys_url)s\">kyçkalime</a>."
|
||||
|
||||
#: plinth/modules/users/templates/users_update.html:29
|
||||
#, python-format
|
||||
@ -10069,20 +10067,16 @@ msgid "Password changed successfully."
|
||||
msgstr "Fjalëkalimi u ndryshua me sukses."
|
||||
|
||||
#: plinth/modules/users/views.py:420
|
||||
#, fuzzy
|
||||
#| msgid "A share with this name already exists."
|
||||
msgid "Passkey with that identifier already exists."
|
||||
msgstr "Ka tashmë një pjesë me këtë emër."
|
||||
msgstr "Ka tashmë një kyçkalim me atë identifikues."
|
||||
|
||||
#: plinth/modules/users/views.py:431
|
||||
#, fuzzy
|
||||
#| msgid "Edit User"
|
||||
msgid "Edit Passkey"
|
||||
msgstr "Përpunoni Përdorues"
|
||||
msgstr "Përpunoni Kyçkalim"
|
||||
|
||||
#: plinth/modules/users/views.py:518 plinth/modules/users/views.py:542
|
||||
msgid "Passkey used is not known."
|
||||
msgstr ""
|
||||
msgstr "Kyçkalimi i përdorur s’njihet."
|
||||
|
||||
#: plinth/modules/wireguard/__init__.py:20
|
||||
msgid "WireGuard is a fast, modern, secure VPN tunnel."
|
||||
@ -10251,7 +10245,7 @@ msgstr "IP VPN-je %(box_name)s për shërbime"
|
||||
|
||||
#: plinth/modules/wireguard/templates/wireguard.html:50
|
||||
msgid "Peers"
|
||||
msgstr ""
|
||||
msgstr "Ortakë"
|
||||
|
||||
#: plinth/modules/wireguard/templates/wireguard.html:52
|
||||
msgid "Peers allowed to connect to this server:"
|
||||
@ -10873,10 +10867,8 @@ msgid " System"
|
||||
msgstr " Sistem"
|
||||
|
||||
#: plinth/templates/base.html:179 plinth/templates/base.html:180
|
||||
#, fuzzy
|
||||
#| msgid "Manage Aliases"
|
||||
msgid "Manage passkeys"
|
||||
msgstr "Administroni Aliase"
|
||||
msgstr "Administroni kyçkalime"
|
||||
|
||||
#: plinth/templates/base.html:186 plinth/templates/base.html:187
|
||||
msgid "Change password"
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2022-09-14 17:20+0000\n"
|
||||
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
|
||||
"Language-Team: Serbian <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -6597,7 +6597,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -6606,14 +6606,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr ""
|
||||
|
||||
@ -7,9 +7,9 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"PO-Revision-Date: 2026-03-11 22:09+0000\n"
|
||||
"Last-Translator: Daniel Wiik <d.wiik@outlook.com>\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2026-04-15 10:10+0000\n"
|
||||
"Last-Translator: bittin1ddc447d824349b2 <bittin@reimu.nl>\n"
|
||||
"Language-Team: Swedish <https://hosted.weblate.org/projects/freedombox/"
|
||||
"freedombox/sv/>\n"
|
||||
"Language: sv\n"
|
||||
@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.17-dev\n"
|
||||
"X-Generator: Weblate 5.17.1-dev\n"
|
||||
|
||||
#: plinth/config.py:103
|
||||
#, python-brace-format
|
||||
@ -7176,7 +7176,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr "IRC"
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7190,7 +7190,7 @@ msgstr ""
|
||||
"användarklient</a>. Radikal kan nås av alla användare med en {box_name} "
|
||||
"inloggning."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
@ -7200,7 +7200,7 @@ msgstr ""
|
||||
"skapandet av nya kalendrar och adressböcker. Det stöder inte att lägga till "
|
||||
"händelser eller kontakter, som måste göras med hjälp av en separat klient."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "Radicale"
|
||||
@ -9808,14 +9808,12 @@ msgstr "Redigera användare %(username)s"
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:30
|
||||
msgid "Logging in with passkey failed: "
|
||||
msgstr ""
|
||||
msgstr "Inloggning med lösennyckel misslyckades: "
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:41
|
||||
#: plinth/modules/users/templates/users_passkeys.html:41
|
||||
#, fuzzy
|
||||
#| msgid "This app does not support diagnostics"
|
||||
msgid "Browser does not support passkeys."
|
||||
msgstr "Den här appen stöder inte diagnostik"
|
||||
msgstr "Webbläsaren stöder inte lösennycklar."
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:57
|
||||
msgid "Login"
|
||||
@ -9824,28 +9822,28 @@ msgstr "Logga in"
|
||||
#: plinth/modules/users/templates/users_login.html:70
|
||||
#: plinth/modules/users/templates/users_login.html:72
|
||||
msgid "Log in with passkey"
|
||||
msgstr ""
|
||||
msgstr "Logga in med lösennyckel"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkey_edit.html:19
|
||||
#, fuzzy
|
||||
#| msgid "Update setup"
|
||||
msgid "Update Passkey"
|
||||
msgstr "Uppdatera inställningar"
|
||||
msgstr "Uppdatera lösennyckel"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:30
|
||||
msgid "Adding passkey failed: "
|
||||
msgstr ""
|
||||
msgstr "Att lägga till lösennyckel misslyckades: "
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:48
|
||||
#: plinth/modules/users/views.py:314
|
||||
msgid "Passkeys"
|
||||
msgstr ""
|
||||
msgstr "Lösennycklar"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:57
|
||||
msgid ""
|
||||
"Working with passkeys requires using browser's Javascript API. Please enable "
|
||||
"Javascript support in your browser to continue."
|
||||
msgstr ""
|
||||
"Att arbeta med lösennycklar kräver att du använder webbläsarens Javascript "
|
||||
"API. Vänligen aktivera Javascript stöd i din webbläsare för att fortsätta."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:66
|
||||
msgid ""
|
||||
@ -9856,47 +9854,45 @@ msgid ""
|
||||
"server knows only the public information that can used to verify user's "
|
||||
"signatures."
|
||||
msgstr ""
|
||||
"Lösennycklar är sätt att verifiera användarens identitet med hjälp av "
|
||||
"digitala signaturer. De är ett säkrare alternativ till lösenord. Hemlig "
|
||||
"information hålls med användaren på sin telefon, bärbar dator eller en "
|
||||
"hårdvaru token och låst med en PIN, fingeravtryck eller ansikte ID. Inga "
|
||||
"hemligheter lagras på servern. Servern vet bara den offentliga informationen "
|
||||
"som kan användas för att verifiera användarens signaturer."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:83
|
||||
#: plinth/modules/users/templates/users_passkeys.html:85
|
||||
#, fuzzy
|
||||
#| msgid "Add password"
|
||||
msgid "Add passkey"
|
||||
msgstr "Lägg till lösenord"
|
||||
msgstr "Lägg till lösennyckel"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:93
|
||||
#, fuzzy
|
||||
#| msgid "Domain"
|
||||
msgid "For Domain"
|
||||
msgstr "Domän"
|
||||
msgstr "För domän"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:94
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
msgstr "Tillagd"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:95
|
||||
#, fuzzy
|
||||
#| msgid "Last scanned: "
|
||||
msgid "Last Used"
|
||||
msgstr "Senast skannad: "
|
||||
msgstr "Senast använd"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:126
|
||||
msgid "No passkeys added to user account."
|
||||
msgstr ""
|
||||
msgstr "Inga lösennycklar har lagts till på användarkontot."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:135
|
||||
msgid "Delete passkey <em class=\"passkey-name\"></em>?"
|
||||
msgstr ""
|
||||
msgstr "Radera lösennyckel <em class=\"passkey-name\"></em>?"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:145
|
||||
msgid "You will need this passkey's device to add it back again."
|
||||
msgstr ""
|
||||
msgstr "Du behöver denna lösennyckels enhet för att lägga till den igen."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:152
|
||||
#, fuzzy
|
||||
#| msgid "Delete user"
|
||||
msgid "Delete passkey"
|
||||
msgstr "Radera användare"
|
||||
msgstr "Radera lösennyckel"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:155
|
||||
#: plinth/modules/users/templates/users_update.html:72
|
||||
@ -9912,6 +9908,7 @@ msgstr "Redigera användare <em>%(username)s</em>"
|
||||
#, python-format
|
||||
msgid "Use <a href=\"%(passkeys_url)s\">passkeys</a> for better security."
|
||||
msgstr ""
|
||||
"Använd <a href=\"%(passkeys_url)s\">lösennycklar</a> för bättre säkerhet."
|
||||
|
||||
#: plinth/modules/users/templates/users_update.html:29
|
||||
#, python-format
|
||||
@ -9977,20 +9974,16 @@ msgid "Password changed successfully."
|
||||
msgstr "Lösenordet har ändrats."
|
||||
|
||||
#: plinth/modules/users/views.py:420
|
||||
#, fuzzy
|
||||
#| msgid "A share with this name already exists."
|
||||
msgid "Passkey with that identifier already exists."
|
||||
msgstr "Det finns redan en share med det här namnet."
|
||||
msgstr "Lösennyckel med den identifieraren finns redan."
|
||||
|
||||
#: plinth/modules/users/views.py:431
|
||||
#, fuzzy
|
||||
#| msgid "Edit User"
|
||||
msgid "Edit Passkey"
|
||||
msgstr "Redigera användar"
|
||||
msgstr "Redigera Lösennyckel"
|
||||
|
||||
#: plinth/modules/users/views.py:518 plinth/modules/users/views.py:542
|
||||
msgid "Passkey used is not known."
|
||||
msgstr ""
|
||||
msgstr "Lösennyckel som används är inte känd."
|
||||
|
||||
#: plinth/modules/wireguard/__init__.py:20
|
||||
msgid "WireGuard is a fast, modern, secure VPN tunnel."
|
||||
@ -10777,10 +10770,8 @@ msgid " System"
|
||||
msgstr " System"
|
||||
|
||||
#: plinth/templates/base.html:179 plinth/templates/base.html:180
|
||||
#, fuzzy
|
||||
#| msgid "Manage Aliases"
|
||||
msgid "Manage passkeys"
|
||||
msgstr "Hantera alias"
|
||||
msgstr "Hantera lösennycklar"
|
||||
|
||||
#: plinth/templates/base.html:186 plinth/templates/base.html:187
|
||||
msgid "Change password"
|
||||
@ -10836,7 +10827,7 @@ msgstr "Mobil"
|
||||
|
||||
#: plinth/templates/clients.html:82
|
||||
msgid "Android APK"
|
||||
msgstr ""
|
||||
msgstr "Android APK"
|
||||
|
||||
#: plinth/templates/clients.html:91
|
||||
msgid "Play Store"
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2026-03-02 19:53+0000\n"
|
||||
"Last-Translator: James Valleroy <jvalleroy@mailbox.org>\n"
|
||||
"Language-Team: Tamil <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -7140,7 +7140,7 @@ msgstr "குவாசெல்ட்ராய்டு"
|
||||
msgid "IRC"
|
||||
msgstr "Irc"
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7153,7 +7153,7 @@ msgstr ""
|
||||
"radicale.org/master.html#supported-comients\"> ஆதரிக்கப்பட்ட கிளையன்ட் பயன்பாடு </"
|
||||
"a> தேவை. {box_name} உள்நுழைவுடன் எந்த பயனரும் ராடிகலை அணுகலாம்."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
@ -7163,7 +7163,7 @@ msgstr ""
|
||||
"முகவரி புத்தகங்களை உருவாக்குவதை மட்டுமே ஆதரிக்கிறது. இது நிகழ்வுகள் அல்லது "
|
||||
"தொடர்புகளைச் சேர்ப்பதை ஆதரிக்காது, இது ஒரு தனி கிளையண்டைப் பயன்படுத்தி செய்யப்பட வேண்டும்."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "தீவிரமான"
|
||||
|
||||
@ -9,7 +9,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: FreedomBox UI\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2025-05-14 17:03+0000\n"
|
||||
"Last-Translator: Sripath Roy Koganti <sripathroy@swecha.net>\n"
|
||||
"Language-Team: Telugu <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -7011,7 +7011,7 @@ msgstr "క్వాసెల్ డ్రొఇడ్"
|
||||
msgid "IRC"
|
||||
msgstr "IRC"
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7024,7 +7024,7 @@ msgstr ""
|
||||
"href=\"https://radicale.org/master.html#supported-clients\">మద్దతు ఉన్న క్లయింట్ "
|
||||
"అప్లికేషన్</a> అవసరం. {box_name} లాగిన్ ఉన్న ఏ యూజర్ అయినా Radicaleని యాక్సెస్ చేయవచ్చు."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
@ -7034,7 +7034,7 @@ msgstr ""
|
||||
"రూపొందించడానికి మాత్రమే మద్దతు ఇస్తుంది. ఈవెంట్లు లేదా పరిచయాలను జోడించడానికి ఇది మద్దతు ఇవ్వదు, ఇది "
|
||||
"ప్రత్యేక క్లయింట్ని ఉపయోగించి చేయాలి."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "రాడికేల్"
|
||||
|
||||
@ -6,8 +6,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"PO-Revision-Date: 2026-03-25 07:09+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2026-04-09 10:09+0000\n"
|
||||
"Last-Translator: Burak Yavuz <hitowerdigit@hotmail.com>\n"
|
||||
"Language-Team: Turkish <https://hosted.weblate.org/projects/freedombox/"
|
||||
"freedombox/tr/>\n"
|
||||
@ -7191,7 +7191,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr "IRC"
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7205,7 +7205,7 @@ msgstr ""
|
||||
"istemci uygulaması</a> gereklidir. Radicale'ye {box_name} oturum açma adı "
|
||||
"ile herhangi bir kullanıcı tarafından erişilebilir."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
@ -7215,7 +7215,7 @@ msgstr ""
|
||||
"temel bir web arayüzü sağlar. Ayrı bir istemci kullanılarak yapılması "
|
||||
"zorunlu olan olayların veya kişilerin eklenmesini desteklemez."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "Radicale"
|
||||
@ -9835,14 +9835,12 @@ msgstr "%(username)s kullanıcısını düzenle"
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:30
|
||||
msgid "Logging in with passkey failed: "
|
||||
msgstr ""
|
||||
msgstr "Geçiş anahtarıyla oturum açma başarısız oldu: "
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:41
|
||||
#: plinth/modules/users/templates/users_passkeys.html:41
|
||||
#, fuzzy
|
||||
#| msgid "This app does not support diagnostics"
|
||||
msgid "Browser does not support passkeys."
|
||||
msgstr "Bu uygulama tanılamayı desteklemiyor"
|
||||
msgstr "Tarayıcı geçiş anahtarlarını desteklemiyor."
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:57
|
||||
msgid "Login"
|
||||
@ -9851,28 +9849,29 @@ msgstr "Oturum aç"
|
||||
#: plinth/modules/users/templates/users_login.html:70
|
||||
#: plinth/modules/users/templates/users_login.html:72
|
||||
msgid "Log in with passkey"
|
||||
msgstr ""
|
||||
msgstr "Geçiş anahtarıyla oturum aç"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkey_edit.html:19
|
||||
#, fuzzy
|
||||
#| msgid "Update setup"
|
||||
msgid "Update Passkey"
|
||||
msgstr "Ayarlamayı güncelle"
|
||||
msgstr "Geçiş Anahtarını Güncelle"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:30
|
||||
msgid "Adding passkey failed: "
|
||||
msgstr ""
|
||||
msgstr "Geçiş anahtarını ekleme başarısız oldu: "
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:48
|
||||
#: plinth/modules/users/views.py:314
|
||||
msgid "Passkeys"
|
||||
msgstr ""
|
||||
msgstr "Geçiş anahtarları"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:57
|
||||
msgid ""
|
||||
"Working with passkeys requires using browser's Javascript API. Please enable "
|
||||
"Javascript support in your browser to continue."
|
||||
msgstr ""
|
||||
"Geçiş anahtarlarıyla çalışmak, tarayıcının Javascript API'sinin "
|
||||
"kullanılmasını gerektirir. Devam etmek için lütfen tarayıcınızda Javascript "
|
||||
"desteğini etkinleştirin."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:66
|
||||
msgid ""
|
||||
@ -9883,47 +9882,46 @@ msgid ""
|
||||
"server knows only the public information that can used to verify user's "
|
||||
"signatures."
|
||||
msgstr ""
|
||||
"Geçiş anahtarları, dijital imzaları kullanarak kullanıcının kimliğini "
|
||||
"doğrulamasının bir yoludur. Parolalara göre daha güvenli bir "
|
||||
"alternatiftirdir. Gizli bilgiler kullanıcının telefonunda, dizüstü "
|
||||
"bilgisayarında veya donanım belirtecinde saklanır ve PIN, parmak izi veya "
|
||||
"yüz kimliği kullanılarak kilidi açılır. Sunucuda hiçbir gizli anahtar "
|
||||
"saklanmaz. Sunucu sadece kullanıcının imzalarını doğrulamak için "
|
||||
"kullanılabilecek genel bilgileri bilir."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:83
|
||||
#: plinth/modules/users/templates/users_passkeys.html:85
|
||||
#, fuzzy
|
||||
#| msgid "Add password"
|
||||
msgid "Add passkey"
|
||||
msgstr "Parola ekle"
|
||||
msgstr "Geçiş anahtarı ekle"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:93
|
||||
#, fuzzy
|
||||
#| msgid "Domain"
|
||||
msgid "For Domain"
|
||||
msgstr "Etki alanı"
|
||||
msgstr "Etki Alanı İçin"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:94
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
msgstr "Eklenen"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:95
|
||||
#, fuzzy
|
||||
#| msgid "Last scanned: "
|
||||
msgid "Last Used"
|
||||
msgstr "Son taranan: "
|
||||
msgstr "Son Kullanılan"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:126
|
||||
msgid "No passkeys added to user account."
|
||||
msgstr ""
|
||||
msgstr "Kullanıcı hesabına eklenen geçiş anahtarları yok."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:135
|
||||
msgid "Delete passkey <em class=\"passkey-name\"></em>?"
|
||||
msgstr ""
|
||||
msgstr "<em class=\"passkey-name\"></em> geçiş anahtarı silinsin mi?"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:145
|
||||
msgid "You will need this passkey's device to add it back again."
|
||||
msgstr ""
|
||||
msgstr "Tekrar eklemek için bu geçiş anahtarının cihazına ihtiyacınız olacak."
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:152
|
||||
#, fuzzy
|
||||
#| msgid "Delete user"
|
||||
msgid "Delete passkey"
|
||||
msgstr "Kullanıcıyı sil"
|
||||
msgstr "Geçiş anahtarını sil"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:155
|
||||
#: plinth/modules/users/templates/users_update.html:72
|
||||
@ -9939,6 +9937,8 @@ msgstr "<em>%(username)s</em> Kullanıcısını Düzenleyin"
|
||||
#, python-format
|
||||
msgid "Use <a href=\"%(passkeys_url)s\">passkeys</a> for better security."
|
||||
msgstr ""
|
||||
"Daha iyi güvenlik için <a href=\"%(passkeys_url)s\">geçiş anahtarlarını</a> "
|
||||
"kullanın."
|
||||
|
||||
#: plinth/modules/users/templates/users_update.html:29
|
||||
#, python-format
|
||||
@ -10005,20 +10005,16 @@ msgid "Password changed successfully."
|
||||
msgstr "Parola başarılı olarak değiştirildi."
|
||||
|
||||
#: plinth/modules/users/views.py:420
|
||||
#, fuzzy
|
||||
#| msgid "A share with this name already exists."
|
||||
msgid "Passkey with that identifier already exists."
|
||||
msgstr "Bu ada sahip bir paylaşım zaten var."
|
||||
msgstr "Bu tanımlayıcıya sahip geçiş anahtarı zaten var."
|
||||
|
||||
#: plinth/modules/users/views.py:431
|
||||
#, fuzzy
|
||||
#| msgid "Edit User"
|
||||
msgid "Edit Passkey"
|
||||
msgstr "Kullanıcıyı Düzenle"
|
||||
msgstr "Geçiş Anahtarını Düzenle"
|
||||
|
||||
#: plinth/modules/users/views.py:518 plinth/modules/users/views.py:542
|
||||
msgid "Passkey used is not known."
|
||||
msgstr ""
|
||||
msgstr "Kullanılan geçiş anahtarı bilinmiyor."
|
||||
|
||||
#: plinth/modules/wireguard/__init__.py:20
|
||||
msgid "WireGuard is a fast, modern, secure VPN tunnel."
|
||||
@ -10802,10 +10798,8 @@ msgid " System"
|
||||
msgstr " Sistem"
|
||||
|
||||
#: plinth/templates/base.html:179 plinth/templates/base.html:180
|
||||
#, fuzzy
|
||||
#| msgid "Manage Aliases"
|
||||
msgid "Manage passkeys"
|
||||
msgstr "Kod Adlarını Yönet"
|
||||
msgstr "Geçiş anahtarlarını yönet"
|
||||
|
||||
#: plinth/templates/base.html:186 plinth/templates/base.html:187
|
||||
msgid "Change password"
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2025-12-17 07:00+0000\n"
|
||||
"Last-Translator: Максим Горпиніч <gorpinicmaksim0@gmail.com>\n"
|
||||
"Language-Team: Ukrainian <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -7224,7 +7224,7 @@ msgstr "Quasseldroid"
|
||||
msgid "IRC"
|
||||
msgstr "IRC"
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -7238,7 +7238,7 @@ msgstr ""
|
||||
"clients\">підтримувана клієнтська програма</a>. Radicale може отримати "
|
||||
"доступ будь-який користувач із логіном {box_name}."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
@ -7248,7 +7248,7 @@ msgstr ""
|
||||
"календарів та адресних книг. Він не підтримує додавання подій або контактів, "
|
||||
"для цього необхідно використовувати окремий клієнт."
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr "Radicale"
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2021-07-28 08:34+0000\n"
|
||||
"Last-Translator: bruh <quangtrung02hn16@gmail.com>\n"
|
||||
"Language-Team: Vietnamese <https://hosted.weblate.org/projects/freedombox/"
|
||||
@ -6774,7 +6774,7 @@ msgstr ""
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -6783,14 +6783,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr ""
|
||||
|
||||
@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Plinth\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"PO-Revision-Date: 2026-03-04 05:09+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2026-04-08 07:09+0000\n"
|
||||
"Last-Translator: 大王叫我来巡山 "
|
||||
"<hamburger2048@users.noreply.hosted.weblate.org>\n"
|
||||
"Language-Team: Chinese (Simplified Han script) <https://hosted.weblate.org/"
|
||||
@ -6542,7 +6542,7 @@ msgstr ""
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -6555,14 +6555,14 @@ msgstr ""
|
||||
"master.html#supported-clients\">支持的客户端应用程序</a>。任何拥有 "
|
||||
"{box_name} 登录名的用户都可以访问 Radicale。"
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr ""
|
||||
@ -8851,10 +8851,8 @@ msgstr ""
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:41
|
||||
#: plinth/modules/users/templates/users_passkeys.html:41
|
||||
#, fuzzy
|
||||
#| msgid "This app does not support diagnostics"
|
||||
msgid "Browser does not support passkeys."
|
||||
msgstr "此应用程序不支持诊断"
|
||||
msgstr "浏览器不支持 passkeys。"
|
||||
|
||||
#: plinth/modules/users/templates/users_login.html:57
|
||||
msgid "Login"
|
||||
@ -8866,10 +8864,8 @@ msgid "Log in with passkey"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/users/templates/users_passkey_edit.html:19
|
||||
#, fuzzy
|
||||
#| msgid "Update setup"
|
||||
msgid "Update Passkey"
|
||||
msgstr "更新安装程序"
|
||||
msgstr "更新 Passkey"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:30
|
||||
msgid "Adding passkey failed: "
|
||||
@ -8898,26 +8894,20 @@ msgstr ""
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:83
|
||||
#: plinth/modules/users/templates/users_passkeys.html:85
|
||||
#, fuzzy
|
||||
#| msgid "Add password"
|
||||
msgid "Add passkey"
|
||||
msgstr "添加密码"
|
||||
msgstr "添加 passkey"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:93
|
||||
#, fuzzy
|
||||
#| msgid "Domain"
|
||||
msgid "For Domain"
|
||||
msgstr "域名"
|
||||
msgstr "针对域名"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:94
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:95
|
||||
#, fuzzy
|
||||
#| msgid "Last scanned: "
|
||||
msgid "Last Used"
|
||||
msgstr "上次扫描: "
|
||||
msgstr "上次使用"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:126
|
||||
msgid "No passkeys added to user account."
|
||||
@ -8932,10 +8922,8 @@ msgid "You will need this passkey's device to add it back again."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:152
|
||||
#, fuzzy
|
||||
#| msgid "Delete user"
|
||||
msgid "Delete passkey"
|
||||
msgstr "删除用户"
|
||||
msgstr "删除 passkey"
|
||||
|
||||
#: plinth/modules/users/templates/users_passkeys.html:155
|
||||
#: plinth/modules/users/templates/users_update.html:72
|
||||
@ -9011,16 +8999,12 @@ msgid "Password changed successfully."
|
||||
msgstr "已成功更改密码。"
|
||||
|
||||
#: plinth/modules/users/views.py:420
|
||||
#, fuzzy
|
||||
#| msgid "A share with this name already exists."
|
||||
msgid "Passkey with that identifier already exists."
|
||||
msgstr "已存在同名共享。"
|
||||
msgstr "已存在该标识符的 Passkey。"
|
||||
|
||||
#: plinth/modules/users/views.py:431
|
||||
#, fuzzy
|
||||
#| msgid "Edit User"
|
||||
msgid "Edit Passkey"
|
||||
msgstr "编辑用户"
|
||||
msgstr "编辑 Passkey"
|
||||
|
||||
#: plinth/modules/users/views.py:518 plinth/modules/users/views.py:542
|
||||
msgid "Passkey used is not known."
|
||||
@ -9736,10 +9720,8 @@ msgid " System"
|
||||
msgstr " 系统"
|
||||
|
||||
#: plinth/templates/base.html:179 plinth/templates/base.html:180
|
||||
#, fuzzy
|
||||
#| msgid "Manage Aliases"
|
||||
msgid "Manage passkeys"
|
||||
msgstr "管理别名"
|
||||
msgstr "管理 passkeys"
|
||||
|
||||
#: plinth/templates/base.html:186 plinth/templates/base.html:187
|
||||
msgid "Change password"
|
||||
|
||||
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-04-07 00:12+0000\n"
|
||||
"POT-Creation-Date: 2026-04-28 22:01+0000\n"
|
||||
"PO-Revision-Date: 2025-02-07 12:01+0000\n"
|
||||
"Last-Translator: pesder <j_h_liau@yahoo.com.tw>\n"
|
||||
"Language-Team: Chinese (Traditional Han script) <https://hosted.weblate.org/"
|
||||
@ -6674,7 +6674,7 @@ msgstr ""
|
||||
msgid "IRC"
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:27
|
||||
#: plinth/modules/radicale/__init__.py:26
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
|
||||
@ -6683,14 +6683,14 @@ msgid ""
|
||||
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:33
|
||||
#: plinth/modules/radicale/__init__.py:32
|
||||
msgid ""
|
||||
"Radicale provides a basic web interface, which only supports creating new "
|
||||
"calendars and addressbooks. It does not support adding events or contacts, "
|
||||
"which must be done using a separate client."
|
||||
msgstr ""
|
||||
|
||||
#: plinth/modules/radicale/__init__.py:55
|
||||
#: plinth/modules/radicale/__init__.py:52
|
||||
#: plinth/modules/radicale/manifest.py:74
|
||||
msgid "Radicale"
|
||||
msgstr ""
|
||||
|
||||
@ -10,6 +10,4 @@ from plinth.modules.api import views
|
||||
|
||||
urlpatterns = [
|
||||
re_path(r'^api/(?P<version>[0-9]+)/shortcuts/?$', public(views.shortcuts)),
|
||||
re_path(r'^api/(?P<version>[0-9]+)/access-info/?$',
|
||||
public(views.access_info)),
|
||||
]
|
||||
|
||||
@ -7,22 +7,10 @@ import copy
|
||||
import json
|
||||
|
||||
from django.core.serializers.json import DjangoJSONEncoder
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.http import HttpResponse
|
||||
from django.templatetags.static import static
|
||||
|
||||
from plinth import frontpage
|
||||
from plinth.modules import names
|
||||
|
||||
|
||||
def access_info(request: HttpRequest, **kwargs) -> HttpResponse:
|
||||
"""API view to return a list of domains and types."""
|
||||
domains = [{
|
||||
'domain': domain.name,
|
||||
'type': domain.domain_type.component_id
|
||||
} for domain in names.components.DomainName.list()]
|
||||
response = {'domains': domains}
|
||||
|
||||
return HttpResponse(json.dumps(response), content_type='application/json')
|
||||
|
||||
|
||||
def shortcuts(request, **kwargs):
|
||||
|
||||
@ -91,8 +91,6 @@ def setup(domain_name: str):
|
||||
|
||||
# Migrate from old bepasty:bepasty ownership to root:root
|
||||
shutil.chown(CONF_FILE, user='root', group='root')
|
||||
action_utils.run(['deluser', 'bepasty'], check=False)
|
||||
action_utils.run(['delgroup', 'bepasty'], check=False)
|
||||
|
||||
|
||||
@privileged
|
||||
@ -151,6 +149,6 @@ def _generate_password():
|
||||
|
||||
@privileged
|
||||
def uninstall():
|
||||
"""Remove bepasty user, group and data."""
|
||||
"""Remove data and configuration file."""
|
||||
shutil.rmtree(DATA_DIR, ignore_errors=True)
|
||||
CONF_FILE.unlink(missing_ok=True)
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
# Create system user and group to run infinoted as system daemon (as opposed to
|
||||
# running in particular user's account). The user is created at boot or when
|
||||
# 'systemd-sysusers freedombox-infinoted.conf' is run. To override this file as
|
||||
# system administrator, create a file /etc/sysusers.d/freedombox-infinoted.conf
|
||||
# or link it to /dev/null.
|
||||
u! infinoted - "Infinoted collaborative editing server" /var/lib/infinoted
|
||||
@ -1,10 +1,8 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
"""Configure infinoted."""
|
||||
|
||||
import grp
|
||||
import os
|
||||
import pathlib
|
||||
import pwd
|
||||
import shutil
|
||||
import subprocess
|
||||
import time
|
||||
@ -126,21 +124,8 @@ def setup():
|
||||
|
||||
action_utils.service_daemon_reload()
|
||||
|
||||
# Create infinoted group if needed.
|
||||
try:
|
||||
grp.getgrnam('infinoted')
|
||||
except KeyError:
|
||||
action_utils.run(['addgroup', '--system', 'infinoted'], check=True)
|
||||
|
||||
# Create infinoted user if needed.
|
||||
try:
|
||||
pwd.getpwnam('infinoted')
|
||||
except KeyError:
|
||||
action_utils.run([
|
||||
'adduser', '--system', '--ingroup', 'infinoted', '--home',
|
||||
DATA_DIR, '--gecos', 'Infinoted collaborative editing server',
|
||||
'infinoted'
|
||||
], check=True)
|
||||
# Create an 'infinoted' system user and group, if needed.
|
||||
action_utils.run(['systemd-sysusers', 'freedombox-infinoted.conf'])
|
||||
|
||||
for directory in (DATA_DIR, KEY_DIR, SYNC_DIR):
|
||||
if not os.path.exists(directory):
|
||||
|
||||
@ -5,7 +5,6 @@ FreedomBox app for radicale.
|
||||
|
||||
import logging
|
||||
|
||||
import augeas
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from plinth import app as app_module
|
||||
@ -37,15 +36,13 @@ _description = [
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
CONFIG_FILE = '/etc/radicale/config'
|
||||
|
||||
|
||||
class RadicaleApp(app_module.App):
|
||||
"""FreedomBox app for Radicale."""
|
||||
|
||||
app_id = 'radicale'
|
||||
|
||||
_version = 5
|
||||
_version = 6
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Create components for the app."""
|
||||
@ -129,7 +126,7 @@ class RadicaleApp(app_module.App):
|
||||
if Version(package['new_version']) > Version('4~'):
|
||||
return False
|
||||
|
||||
rights = get_rights_value()
|
||||
rights = privileged.get_rights_value()
|
||||
install(['radicale'], force_configuration='new')
|
||||
privileged.setup()
|
||||
privileged.configure(rights)
|
||||
@ -140,28 +137,3 @@ class RadicaleApp(app_module.App):
|
||||
"""De-configure and uninstall the app."""
|
||||
super().uninstall()
|
||||
privileged.uninstall()
|
||||
|
||||
|
||||
def load_augeas():
|
||||
"""Prepares the augeas."""
|
||||
aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD +
|
||||
augeas.Augeas.NO_MODL_AUTOLOAD)
|
||||
|
||||
# INI file lens
|
||||
aug.set('/augeas/load/Puppet/lens', 'Puppet.lns')
|
||||
aug.set('/augeas/load/Puppet/incl[last() + 1]', CONFIG_FILE)
|
||||
|
||||
aug.load()
|
||||
return aug
|
||||
|
||||
|
||||
def get_rights_value():
|
||||
"""Returns the current Rights value."""
|
||||
aug = load_augeas()
|
||||
value = aug.get('/files' + CONFIG_FILE + '/rights/type')
|
||||
|
||||
if value == 'from_file':
|
||||
# Default rights file is equivalent to owner_only.
|
||||
value = 'owner_only'
|
||||
|
||||
return value
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
(* Radicale module for Augeas
|
||||
Based on Puppet lens.
|
||||
|
||||
Manage config file for http://radicale.org/
|
||||
/etc/radicale/config is a standard INI File.
|
||||
*)
|
||||
|
||||
|
||||
module Radicale =
|
||||
autoload xfm
|
||||
|
||||
(************************************************************************
|
||||
* INI File settings
|
||||
*
|
||||
* /etc/radicale/config only supports "#" as commentary and "=" as separator
|
||||
*************************************************************************)
|
||||
let comment = IniFile.comment "#" "#"
|
||||
let comment_re = /[#]/
|
||||
let sep = IniFile.sep "=" "="
|
||||
|
||||
|
||||
(************************************************************************
|
||||
* ENTRY
|
||||
* /etc/radicale/config uses standard INI File entries
|
||||
*************************************************************************)
|
||||
let entry = IniFile.entry_generic (Util.indent . key IniFile.entry_re) sep comment_re comment
|
||||
|
||||
|
||||
(************************************************************************
|
||||
* RECORD
|
||||
* /etc/radicale/config uses standard INI File records
|
||||
*************************************************************************)
|
||||
let title = IniFile.indented_title IniFile.record_re
|
||||
let record = IniFile.record title entry
|
||||
|
||||
|
||||
(************************************************************************
|
||||
* LENS & FILTER
|
||||
* /etc/radicale/config uses standard INI File records
|
||||
*************************************************************************)
|
||||
let lns = IniFile.lns record comment
|
||||
|
||||
let filter = (incl "/etc/radicale/config")
|
||||
|
||||
let xfm = transform lns filter
|
||||
@ -0,0 +1,81 @@
|
||||
module Test_radicale =
|
||||
|
||||
let conf = "
|
||||
[server]
|
||||
|
||||
[encoding]
|
||||
|
||||
[well-known]
|
||||
|
||||
[auth]
|
||||
|
||||
[git]
|
||||
|
||||
[rights]
|
||||
|
||||
[storage]
|
||||
|
||||
[logging]
|
||||
|
||||
[headers]
|
||||
Content-Security-Policy = default-src 'self'; object-src 'none'
|
||||
|
||||
"
|
||||
|
||||
test Radicale.lns get conf =
|
||||
{}
|
||||
{ "server"
|
||||
{} }
|
||||
{ "encoding"
|
||||
{} }
|
||||
{ "well-known"
|
||||
{} }
|
||||
{ "auth"
|
||||
{} }
|
||||
{ "git"
|
||||
{} }
|
||||
{ "rights"
|
||||
{} }
|
||||
{ "storage"
|
||||
{} }
|
||||
{ "logging"
|
||||
{} }
|
||||
{ "headers"
|
||||
{ "Content-Security-Policy" = "default-src 'self'; object-src 'none'" }
|
||||
{} }
|
||||
|
||||
test Radicale.lns put conf after
|
||||
set "server/hosts" "127.0.0.1:5232, [::1]:5232";
|
||||
set "server/base_prefix" "/radicale/";
|
||||
set "well-known/caldav" "/radicale/%(user)s/caldav/";
|
||||
set "well-known/cardav" "/radicale/%(user)s/carddav/";
|
||||
set "auth/type" "remote_user";
|
||||
set "rights/type" "owner_only";
|
||||
set "headers/Content-Security-Policy" "default-src 'self'; object-src 'none'"
|
||||
= "
|
||||
[server]
|
||||
|
||||
hosts=127.0.0.1:5232, [::1]:5232
|
||||
base_prefix=/radicale/
|
||||
[encoding]
|
||||
|
||||
[well-known]
|
||||
|
||||
caldav=/radicale/%(user)s/caldav/
|
||||
cardav=/radicale/%(user)s/carddav/
|
||||
[auth]
|
||||
|
||||
type=remote_user
|
||||
[git]
|
||||
|
||||
[rights]
|
||||
|
||||
type=owner_only
|
||||
[storage]
|
||||
|
||||
[logging]
|
||||
|
||||
[headers]
|
||||
Content-Security-Policy = default-src 'self'; object-src 'none'
|
||||
|
||||
"
|
||||
@ -24,6 +24,7 @@ def setup():
|
||||
"""
|
||||
aug = load_augeas()
|
||||
aug.set('auth/type', 'remote_user')
|
||||
aug.set('auth/lc_username', 'True')
|
||||
aug.save()
|
||||
# Service is started again by socket.
|
||||
action_utils.service_stop(SERVICE_NAME)
|
||||
@ -55,12 +56,24 @@ def load_augeas():
|
||||
aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD +
|
||||
augeas.Augeas.NO_MODL_AUTOLOAD)
|
||||
# INI file lens
|
||||
aug.transform('Puppet', CONFIG_FILE)
|
||||
aug.transform('Radicale', CONFIG_FILE)
|
||||
aug.set('/augeas/context', '/files' + CONFIG_FILE)
|
||||
aug.load()
|
||||
return aug
|
||||
|
||||
|
||||
def get_rights_value():
|
||||
"""Returns the current Rights value."""
|
||||
aug = load_augeas()
|
||||
value = aug.get('rights/type')
|
||||
|
||||
if value == 'from_file':
|
||||
# Default rights file is equivalent to owner_only.
|
||||
value = 'owner_only'
|
||||
|
||||
return value
|
||||
|
||||
|
||||
@privileged
|
||||
def uninstall():
|
||||
"""Remove all radicale collections."""
|
||||
|
||||
@ -83,21 +83,21 @@ def _set_access_rights(browser, access_rights_type):
|
||||
|
||||
def _calendar_is_available(browser):
|
||||
"""Return whether calendar is available at well-known URL."""
|
||||
conf = functional.config['DEFAULT']
|
||||
url = functional.base_url + '/.well-known/caldav'
|
||||
logging.captureWarnings(True)
|
||||
request = requests.get(url, auth=(conf['username'], conf['password']),
|
||||
verify=False)
|
||||
logging.captureWarnings(False)
|
||||
return request.status_code != 404
|
||||
return _well_known_available(browser, '/.well-known/caldav')
|
||||
|
||||
|
||||
def _addressbook_is_available(browser):
|
||||
"""Return whether addressbook is available at well-known URL."""
|
||||
return _well_known_available(browser, '/.well-known/carddav')
|
||||
|
||||
|
||||
def _well_known_available(browser, wellknown_url: str):
|
||||
"""Return whether a well-known URL redirects to radicale."""
|
||||
conf = functional.config['DEFAULT']
|
||||
url = functional.base_url + '/.well-known/carddav'
|
||||
url = functional.base_url + wellknown_url
|
||||
logging.captureWarnings(True)
|
||||
request = requests.get(url, auth=(conf['username'], conf['password']),
|
||||
verify=False)
|
||||
verify=False, allow_redirects=False)
|
||||
logging.captureWarnings(False)
|
||||
return request.status_code != 404
|
||||
return (request.status_code == 301
|
||||
and request.headers['Location'].endswith('/radicale/'))
|
||||
|
||||
@ -8,7 +8,7 @@ from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from plinth.views import AppView
|
||||
|
||||
from . import get_rights_value, privileged
|
||||
from . import privileged
|
||||
from .forms import RadicaleForm
|
||||
|
||||
|
||||
@ -20,13 +20,13 @@ class RadicaleAppView(AppView):
|
||||
def get_initial(self):
|
||||
"""Return the values to fill in the form."""
|
||||
initial = super().get_initial()
|
||||
initial['access_rights'] = get_rights_value()
|
||||
initial['access_rights'] = privileged.get_rights_value()
|
||||
return initial
|
||||
|
||||
def form_valid(self, form):
|
||||
"""Change the access control of Radicale service."""
|
||||
data = form.cleaned_data
|
||||
if get_rights_value() != data['access_rights']:
|
||||
if privileged.get_rights_value() != data['access_rights']:
|
||||
privileged.configure(data['access_rights'])
|
||||
messages.success(self.request,
|
||||
_('Access rights configuration updated'))
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
# Create system user and group to run syncthing as system daemon (as opposed to
|
||||
# running in particular user's account). The user is created at boot or when
|
||||
# 'systemd-sysusers freedombox-syncthing.conf' is run. To override this file as
|
||||
# system administrator, create a file /etc/sysusers.d/freedombox-syncthing.conf
|
||||
# or link it to /dev/null.
|
||||
u! syncthing - "Syncthing file synchronization server" /var/lib/syncthing
|
||||
@ -1,9 +1,7 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
"""Configure Syncthing."""
|
||||
|
||||
import grp
|
||||
import os
|
||||
import pwd
|
||||
import shutil
|
||||
import time
|
||||
|
||||
@ -32,21 +30,8 @@ def augeas_load(conf_file):
|
||||
@privileged
|
||||
def setup():
|
||||
"""Perform post-install actions for Syncthing."""
|
||||
# Create syncthing group if needed.
|
||||
try:
|
||||
grp.getgrnam('syncthing')
|
||||
except KeyError:
|
||||
action_utils.run(['addgroup', '--system', 'syncthing'], check=True)
|
||||
|
||||
# Create syncthing user if needed.
|
||||
try:
|
||||
pwd.getpwnam('syncthing')
|
||||
except KeyError:
|
||||
action_utils.run([
|
||||
'adduser', '--system', '--ingroup', 'syncthing', '--home',
|
||||
DATA_DIR, '--gecos', 'Syncthing file synchronization server',
|
||||
'syncthing'
|
||||
], check=True)
|
||||
# Create a 'syncthing' system user and group, if needed.
|
||||
action_utils.run(['systemd-sysusers', 'freedombox-syncthing.conf'])
|
||||
|
||||
if not os.path.exists(DATA_DIR):
|
||||
os.makedirs(DATA_DIR, mode=0o750)
|
||||
|
||||
@ -37,7 +37,7 @@ class WireguardApp(app_module.App):
|
||||
|
||||
app_id = 'wireguard'
|
||||
|
||||
_version = 1
|
||||
_version = 2
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Create components for the app."""
|
||||
@ -64,7 +64,8 @@ class WireguardApp(app_module.App):
|
||||
clients=info.clients)
|
||||
self.add(shortcut)
|
||||
|
||||
packages = Packages('packages-wireguard', ['wireguard'])
|
||||
packages = Packages('packages-wireguard',
|
||||
['wireguard', 'python3-segno'])
|
||||
self.add(packages)
|
||||
|
||||
firewall = Firewall('firewall-wireguard', info.name,
|
||||
|
||||
@ -55,14 +55,12 @@ def validate_endpoint(endpoint):
|
||||
raise ValidationError('Invalid endpoint.')
|
||||
|
||||
|
||||
def validate_ipv4_address_with_network(value: str):
|
||||
"""Check that value is a valid IPv4 address with an optional network."""
|
||||
def validate_ip_address_with_network(value: str):
|
||||
"""Check that value is a valid IP address with an optional network."""
|
||||
try:
|
||||
ipaddress.IPv4Interface(value)
|
||||
except ipaddress.AddressValueError:
|
||||
raise ValidationError(_('Enter a valid IPv4 address.'))
|
||||
except ipaddress.NetmaskValueError:
|
||||
raise ValidationError(_('Enter a valid network prefix or net mask.'))
|
||||
ipaddress.ip_interface(value)
|
||||
except ValueError:
|
||||
raise ValidationError(_('Not a valid IP address.'))
|
||||
|
||||
|
||||
class AddClientForm(forms.Form):
|
||||
@ -74,6 +72,11 @@ class AddClientForm(forms.Form):
|
||||
validators=[validate_key])
|
||||
|
||||
|
||||
class AutoAddClientForm(forms.Form):
|
||||
"""Empty form for auto-client addition UX."""
|
||||
pass
|
||||
|
||||
|
||||
class AddServerForm(forms.Form):
|
||||
"""Form to add server."""
|
||||
peer_endpoint = forms.CharField(
|
||||
@ -93,10 +96,11 @@ class AddServerForm(forms.Form):
|
||||
help_text=_(
|
||||
'IP address assigned to this machine on the VPN after connecting '
|
||||
'to the endpoint. This value is usually provided by the server '
|
||||
'operator. Example: 192.168.0.10. You can also specify the '
|
||||
'network. This will allow reaching machines in the network. '
|
||||
'operator. Example: 192.168.0.10 or '
|
||||
'2a03:7c80:4b2c:91a2:5d41:ffee:9b82:7c17. You can also specify '
|
||||
'the network. This will allow reaching machines in the network. '
|
||||
'Examples: 10.68.12.43/24 or 10.68.12.43/255.255.255.0.'),
|
||||
validators=[validate_ipv4_address_with_network])
|
||||
validators=[validate_ip_address_with_network])
|
||||
|
||||
private_key = forms.CharField(
|
||||
label=_('Private key of this machine'), strip=True, help_text=_(
|
||||
@ -120,31 +124,44 @@ class AddServerForm(forms.Form):
|
||||
'Typically checked for a VPN service through which all traffic '
|
||||
'is sent.'))
|
||||
|
||||
def _build_ipv4_settings(self, iface) -> dict:
|
||||
"""Build IPv4 NM settings from interfaces."""
|
||||
return {
|
||||
'method': 'manual',
|
||||
'address': str(iface.ip),
|
||||
'netmask': str(iface.netmask),
|
||||
'gateway': '',
|
||||
'dns': '',
|
||||
'second_dns': '',
|
||||
}
|
||||
|
||||
def _build_ipv6_settings(self, iface) -> dict:
|
||||
"""Build IPv6 NM settings from interfaces."""
|
||||
return {
|
||||
'method': 'manual',
|
||||
'address': str(iface.ip),
|
||||
'prefix': iface.network.prefixlen,
|
||||
'gateway': '',
|
||||
'dns': '',
|
||||
'second_dns': '',
|
||||
}
|
||||
|
||||
def get_settings(self) -> dict[str, dict]:
|
||||
"""Return NM settings dict from cleaned data."""
|
||||
ip_address_and_network = self.cleaned_data['ip_address_and_network']
|
||||
ip_address_and_network = ipaddress.IPv4Interface(
|
||||
ip_address_and_network)
|
||||
ip_address = str(ip_address_and_network.ip)
|
||||
prefixlen = ip_address_and_network.network.prefixlen
|
||||
ip_interface = ipaddress.ip_interface(
|
||||
self.cleaned_data['ip_address_and_network']
|
||||
)
|
||||
|
||||
if self.cleaned_data['default_route']:
|
||||
allowed_ips = ['0.0.0.0/0', '::/0']
|
||||
else:
|
||||
allowed_ips = [f'{ip_address}/{prefixlen}']
|
||||
allowed_ips = [str(ip_interface)]
|
||||
|
||||
settings = {
|
||||
'common': {
|
||||
'type': 'wireguard',
|
||||
'zone': 'external',
|
||||
},
|
||||
'ipv4': {
|
||||
'method': 'manual',
|
||||
'address': ip_address,
|
||||
'netmask': str(ip_address_and_network.netmask),
|
||||
'gateway': '',
|
||||
'dns': '',
|
||||
'second_dns': '',
|
||||
},
|
||||
'wireguard': {
|
||||
'peer_endpoint': self.cleaned_data['peer_endpoint'],
|
||||
'peer_public_key': self.cleaned_data['peer_public_key'],
|
||||
@ -153,4 +170,10 @@ class AddServerForm(forms.Form):
|
||||
'allowed_ips': allowed_ips,
|
||||
}
|
||||
}
|
||||
|
||||
if ip_interface.version == 4:
|
||||
settings['ipv4'] = self._build_ipv4_settings(ip_interface)
|
||||
else:
|
||||
settings['ipv6'] = self._build_ipv6_settings(ip_interface)
|
||||
|
||||
return settings
|
||||
|
||||
@ -85,6 +85,12 @@
|
||||
</div>
|
||||
|
||||
<div class="btn-toolbar">
|
||||
<a title="{% trans 'Auto add a new peer' %}"
|
||||
role="button" class="btn btn-primary btn-auto-add-client"
|
||||
href="{% url 'wireguard:auto-add-client' %}">
|
||||
{% icon 'magic' %}
|
||||
{% trans "Add Client Automatically" %}
|
||||
</a>
|
||||
<a title="{% trans 'Add a new peer' %}"
|
||||
role="button" class="btn btn-default btn-add-client"
|
||||
href="{% url 'wireguard:add-client' %}">
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
{% extends "base.html" %}
|
||||
{% comment %}
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
{% endcomment %}
|
||||
|
||||
{% load bootstrap %}
|
||||
{% load i18n %}
|
||||
{% load extras %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h3>{{ title }}</h3>
|
||||
|
||||
<form class="form form-auto-add-client" method="post">
|
||||
{% csrf_token %}
|
||||
|
||||
{{ form|bootstrap }}
|
||||
|
||||
{% if client_privkey %}
|
||||
<div class="form-group">
|
||||
<table class="table table-sm">
|
||||
<tr><td>{% trans "IP Address" %}</td><td>{{ next_ip }}</td></tr>
|
||||
<tr><td>{% trans "Endpoint" %}</td><td>{{ endpoint }}</td></tr>
|
||||
<tr><td>{% trans "Public Key" %}</td>
|
||||
<td class="pubkey-val">{{ client_pubkey }}</td></tr>
|
||||
<tr><td>{% trans "Private Key" %}</td>
|
||||
<td>
|
||||
<details class="privkey-val">
|
||||
<summary>{% trans "Click to reveal" %}</summary>
|
||||
{{ client_privkey }}
|
||||
</details>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
<div class="alert alert-warning">
|
||||
<strong>{% trans "Important:" %}</strong>
|
||||
{% trans "Save the private key now. This page shows it only once!" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<h4>{% trans "Client configuration file" %}</h4>
|
||||
<p>
|
||||
{% blocktrans trimmed %}
|
||||
Download the configuration file (.conf) for manual import,
|
||||
or use the QR code to import directly from your WireGuard mobile app.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
<p class="alert alert-warning">
|
||||
<strong>{% trans "Warning:" %}</strong>
|
||||
{% blocktrans trimmed %}
|
||||
Treat this QR code like a password.
|
||||
Anyone who scans it can gain VPN access if the connection is enabled.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
<div class="form-group">
|
||||
<div class="btn-toolbar">
|
||||
<a href="{% url 'wireguard:auto-add-client-download' %}"
|
||||
class="btn btn-default">
|
||||
{% icon 'download' %}
|
||||
{% trans "Download config file" %}
|
||||
</a>
|
||||
<a href="{% url 'wireguard:auto-add-client-qr' %}"
|
||||
class="btn btn-default" target="_blank">
|
||||
{% icon 'qrcode' %}
|
||||
{% trans "Show QR Code" %}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<input type="submit" class="btn btn-primary btn-auto-add-connection"
|
||||
value="{% trans "Add Connection" %}"/>
|
||||
<a href="{% url 'wireguard:index' %}" class="btn btn-secondary">
|
||||
{% trans "Cancel" %}
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@ -7,7 +7,7 @@ import pytest
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
from plinth.modules.wireguard.forms import (validate_endpoint,
|
||||
validate_ipv4_address_with_network,
|
||||
validate_ip_address_with_network,
|
||||
validate_key)
|
||||
|
||||
|
||||
@ -73,22 +73,33 @@ def test_validate_endpoint_invalid_patterns(endpoint):
|
||||
'1.2.3.4/24',
|
||||
'1.2.3.4/255.255.255.0',
|
||||
'1.2.3.4/0.0.0.255',
|
||||
'::1',
|
||||
'2001:db8::1',
|
||||
'2001:db8::1/64',
|
||||
'fe80::1/64',
|
||||
'::/0',
|
||||
])
|
||||
def test_validate_ipv4_address_with_network_valid_patterns(value):
|
||||
def test_validate_ip_address_with_network_valid_patterns(value):
|
||||
"""Test validating IPv4 address with network works for valid values."""
|
||||
validate_ipv4_address_with_network(value)
|
||||
validate_ip_address_with_network(value)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('value', [
|
||||
'::1',
|
||||
'1.2.3.4/',
|
||||
'invalid-ip/24',
|
||||
'1.2.3.4/x',
|
||||
'1.2.3.4/-1',
|
||||
'1.2.3.4/33',
|
||||
'1.2.3.4/9.8.7.6',
|
||||
'2001:db8::1/',
|
||||
'2001:db8::1/129',
|
||||
'2001:db8::1/x',
|
||||
'2001:db8::1/-1',
|
||||
'2001:db8::1/255.255.255.0',
|
||||
'2001:db8::1::1',
|
||||
'12345::1',
|
||||
])
|
||||
def test_validate_ipv4_address_with_network_invalid_patterns(value):
|
||||
def test_validate_ip_address_with_network_invalid_patterns(value):
|
||||
"""Test validating IPv4 address with network works for invalid values."""
|
||||
with pytest.raises(ValidationError):
|
||||
validate_ipv4_address_with_network(value)
|
||||
validate_ip_address_with_network(value)
|
||||
|
||||
@ -113,6 +113,53 @@ class TestWireguardApp(functional.BaseAppTests):
|
||||
assert not self._client_exists(session_browser,
|
||||
self._client_public_key2)
|
||||
|
||||
def test_auto_add_client(self, session_browser):
|
||||
"""Test the automatic client generation and addition flow."""
|
||||
functional.nav_to_module(session_browser, 'wireguard')
|
||||
|
||||
# Start server if needed (reuse existing logic)
|
||||
# Extract to reusable method
|
||||
start_server_button = session_browser.find_by_css('.btn-start-server')
|
||||
if start_server_button:
|
||||
with functional.wait_for_page_update(session_browser):
|
||||
start_server_button.first.click()
|
||||
|
||||
session_browser.find_by_css('.btn-auto-add-client').first.click()
|
||||
|
||||
client_pubkey = session_browser.find_by_css(
|
||||
'.pubkey-val').first.text.strip()
|
||||
|
||||
# Verify private key reveal
|
||||
privkey_reveal = session_browser.find_by_css(
|
||||
'.privkey-val')
|
||||
assert privkey_reveal, "Private key reveal should be present"
|
||||
privkey_reveal.click()
|
||||
client_privkey = session_browser.find_by_css(
|
||||
'.privkey-val').text.splitlines()[1]
|
||||
assert len(client_privkey) == 44, (("Private key should be base64 "
|
||||
"(44 chars)"))
|
||||
|
||||
# Verify config download and QR links
|
||||
download_link = session_browser.links.find_by_href(
|
||||
'/freedombox/apps/wireguard/client/auto-add/action/download/')
|
||||
qr_link = session_browser.links.find_by_href(
|
||||
'/freedombox/apps/wireguard/client/auto-add/action/qr/')
|
||||
assert download_link, "Download config link should exist"
|
||||
assert qr_link, "QR code link should exist"
|
||||
|
||||
# Submit to add the client
|
||||
with functional.wait_for_page_update(session_browser):
|
||||
session_browser.find_by_css(
|
||||
'.btn-auto-add-connection').first.click()
|
||||
|
||||
# Verify client was added successfully
|
||||
assert self._client_exists(session_browser, client_pubkey), ((
|
||||
"Auto-generated client should exist"))
|
||||
|
||||
# Clean up
|
||||
self._delete_client(session_browser, client_pubkey)
|
||||
assert not self._client_exists(session_browser, client_pubkey)
|
||||
|
||||
@staticmethod
|
||||
def _get_server_href(browser, key):
|
||||
"""Return the href for server show page."""
|
||||
|
||||
@ -13,6 +13,14 @@ urlpatterns = [
|
||||
views.EnableServerView.as_view(), name='enable-server'),
|
||||
re_path(r'^apps/wireguard/client/add/$', views.AddClientView.as_view(),
|
||||
name='add-client'),
|
||||
re_path(r'^apps/wireguard/client/auto-add/$',
|
||||
views.AutoAddClientView.as_view(), name='auto-add-client'),
|
||||
re_path(r'^apps/wireguard/client/auto-add/action/download/$',
|
||||
views.ClientActionsView.as_view(action='download'),
|
||||
name='auto-add-client-download'),
|
||||
re_path(r'^apps/wireguard/client/auto-add/action/qr/$',
|
||||
views.ClientActionsView.as_view(action='qr'),
|
||||
name='auto-add-client-qr'),
|
||||
re_path(r'^apps/wireguard/client/(?P<public_key>[^/]+)/show/$',
|
||||
views.ShowClientView.as_view(), name='show-client'),
|
||||
re_path(r'^apps/wireguard/client/(?P<public_key>[^/]+)/edit/$',
|
||||
|
||||
@ -19,6 +19,18 @@ IP_TEMPLATE = '10.84.0.{}'
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _get_nm_address_info(settings_ipv4, settings_ipv6) -> tuple[str, str]:
|
||||
"""Extract IP address info from NM IPv4/IPv6 settings."""
|
||||
for settings in [settings_ipv4, settings_ipv6]:
|
||||
if settings and settings.get_num_addresses():
|
||||
nm_address = settings.get_address(0)
|
||||
address = nm_address.get_address()
|
||||
prefix = str(nm_address.get_prefix())
|
||||
return address, address + '/' + prefix
|
||||
|
||||
return '', ''
|
||||
|
||||
|
||||
def get_nm_info():
|
||||
"""Get information from network manager."""
|
||||
setting_name = nm.SETTING_WIREGUARD_SETTING_NAME
|
||||
@ -64,12 +76,14 @@ def get_nm_info():
|
||||
info['default_route'] = True
|
||||
|
||||
settings_ipv4 = connection.get_setting_ip4_config()
|
||||
if settings_ipv4 and settings_ipv4.get_num_addresses():
|
||||
nm_address = settings_ipv4.get_address(0)
|
||||
address = nm_address.get_address()
|
||||
prefix = str(nm_address.get_prefix())
|
||||
info['ip_address'] = address
|
||||
info['ip_address_and_network'] = address + '/' + prefix
|
||||
settings_ipv6 = connection.get_setting_ip6_config()
|
||||
|
||||
ip_address, ip_address_and_network = _get_nm_address_info(
|
||||
settings_ipv4, settings_ipv6
|
||||
)
|
||||
|
||||
info['ip_address'] = ip_address
|
||||
info['ip_address_and_network'] = ip_address_and_network
|
||||
|
||||
connections[info['interface']] = info
|
||||
|
||||
@ -160,6 +174,13 @@ def _generate_private_key():
|
||||
return process.stdout.decode().strip()
|
||||
|
||||
|
||||
def generate_client_keypair():
|
||||
"""Generate client private/public keypair."""
|
||||
private_key = _generate_private_key()
|
||||
public_key = _get_public_key_from_private_key(private_key)
|
||||
return private_key, public_key
|
||||
|
||||
|
||||
def _find_next_interface():
|
||||
"""Find next unused wireguard interface name."""
|
||||
output = subprocess.check_output(['wg', 'show',
|
||||
@ -303,3 +324,25 @@ def remove_client(public_key):
|
||||
settings.remove_peer(peer_index)
|
||||
connection.commit_changes(True)
|
||||
network.reactivate_connection(connection.get_uuid())
|
||||
|
||||
|
||||
def build_client_config(client_ip: str, client_privkey: str,
|
||||
client_pubkey: str, endpoint: str) -> str:
|
||||
"""Generate WireGuard client config."""
|
||||
info = get_info()
|
||||
server_info = info['my_server']
|
||||
if not server_info:
|
||||
raise RuntimeError("WireGuard server not configured")
|
||||
|
||||
server_pubkey = server_info['public_key']
|
||||
|
||||
return f"""[Interface]
|
||||
PrivateKey = {client_privkey}
|
||||
Address = {client_ip}/32
|
||||
DNS = 10.84.0.1
|
||||
|
||||
[Peer]
|
||||
PublicKey = {server_pubkey}
|
||||
AllowedIPs = 0.0.0.0/0
|
||||
Endpoint = {endpoint}
|
||||
PersistentKeepalive = 25"""
|
||||
|
||||
@ -3,16 +3,19 @@
|
||||
Views for WireGuard application.
|
||||
"""
|
||||
|
||||
import segno
|
||||
import urllib.parse
|
||||
|
||||
from django.contrib import messages
|
||||
from django.contrib.messages.views import SuccessMessageMixin
|
||||
from django.http import Http404
|
||||
from django.http import Http404, HttpResponse
|
||||
from django.shortcuts import redirect
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.translation import gettext as _
|
||||
from django.views.generic import FormView, TemplateView, View
|
||||
|
||||
from io import BytesIO
|
||||
|
||||
from plinth import network
|
||||
from plinth.modules.names.components import DomainName
|
||||
from plinth.views import AppView
|
||||
@ -82,6 +85,126 @@ class AddClientView(SuccessMessageMixin, FormView):
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
class SessionClientDataMixin:
|
||||
"""Shared session data loading for auto-client views."""
|
||||
|
||||
def get_session_client_data(self, request):
|
||||
"""Extract client data from session."""
|
||||
next_ip = request.session.get('next_ip')
|
||||
pubkey = request.session.get('client_pubkey')
|
||||
privkey = request.session.get('client_privkey')
|
||||
endpoint = request.session.get('endpoint')
|
||||
|
||||
if not all([next_ip, privkey, pubkey, endpoint]):
|
||||
raise Http404("Session expired")
|
||||
|
||||
return {
|
||||
'next_ip': next_ip,
|
||||
'privkey': privkey,
|
||||
'pubkey': pubkey,
|
||||
'endpoint': endpoint
|
||||
}
|
||||
|
||||
def get_client_config(self, request):
|
||||
"""Rebuild client config from session."""
|
||||
data = self.get_session_client_data(request)
|
||||
|
||||
return utils.build_client_config(
|
||||
data['next_ip'], data['privkey'],
|
||||
data['pubkey'], data['endpoint']
|
||||
)
|
||||
|
||||
|
||||
class ClientActionsView(SessionClientDataMixin, View):
|
||||
action = None
|
||||
|
||||
def get(self, request):
|
||||
if self.action == 'download':
|
||||
config = self.get_client_config(request)
|
||||
response = HttpResponse(config, content_type='text/plain')
|
||||
response['Content-Disposition'] = \
|
||||
'attachment; filename="wg-client.conf"'
|
||||
return response
|
||||
elif self.action == 'qr':
|
||||
qrcode = segno.make(config)
|
||||
buffer = BytesIO()
|
||||
qrcode.save(buffer, kind='svg', scale=5)
|
||||
|
||||
return HttpResponse(buffer.getvalue(),
|
||||
content_type='image/svg+xml')
|
||||
|
||||
raise Http404("Invalid action")
|
||||
|
||||
|
||||
class AutoAddClientView(SuccessMessageMixin, FormView):
|
||||
"""View to add a client with keypair generation."""
|
||||
form_class = forms.AutoAddClientForm
|
||||
template_name = 'wireguard_auto_add_client.html'
|
||||
success_url = reverse_lazy('wireguard:index')
|
||||
success_message = _('Added new client.')
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
"""Return additional context for rendering the template."""
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['title'] = _('Add Allowed Client')
|
||||
|
||||
context['domains'] = []
|
||||
info = utils.get_info()
|
||||
server_info = info['my_server']
|
||||
|
||||
if server_info:
|
||||
domains = DomainName.list_names(filter_for_service='wireguard')
|
||||
filtered_domains = [
|
||||
domain for domain in domains if not domain.endswith('.local')
|
||||
]
|
||||
port = server_info.get('listen_port', 51820)
|
||||
endpoint = f"{filtered_domains[0]}:{port}"
|
||||
|
||||
try:
|
||||
client_privkey, client_pubkey = utils.generate_client_keypair()
|
||||
|
||||
# Get next IP
|
||||
connection = utils._server_connection()
|
||||
setting_name = utils.nm.SETTING_WIREGUARD_SETTING_NAME
|
||||
settings = connection.get_setting_by_name(setting_name)
|
||||
next_ip = utils._get_next_available_ip_address(settings)
|
||||
|
||||
data = {
|
||||
'next_ip': next_ip,
|
||||
'client_privkey': client_privkey,
|
||||
'client_pubkey': client_pubkey,
|
||||
'endpoint': endpoint
|
||||
}
|
||||
|
||||
# Add properties to template context
|
||||
context['domains'] = filtered_domains
|
||||
context.update(data)
|
||||
|
||||
# Store info on instance for reuse
|
||||
self.request.session.update(data)
|
||||
|
||||
except Exception as e:
|
||||
messages.warning(f"Client key generation failed: {e}")
|
||||
pass
|
||||
|
||||
return context
|
||||
|
||||
def form_valid(self, form):
|
||||
"""Add client using generated public key."""
|
||||
try:
|
||||
client_pubkey = self.request.session.pop('client_pubkey')
|
||||
utils.add_client(client_pubkey)
|
||||
except KeyError:
|
||||
messages.warning(self.request,
|
||||
_('Session expired. Please try again.'))
|
||||
return redirect('wireguard:auto-add-client')
|
||||
except ValueError:
|
||||
messages.warning(self.request, _('Client already exists'))
|
||||
return redirect('wireguard:index')
|
||||
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
class ShowClientView(SuccessMessageMixin, TemplateView):
|
||||
"""View to show a client's details."""
|
||||
template_name = 'wireguard_show_client.html'
|
||||
|
||||
@ -20,7 +20,8 @@ from plinth.action_utils import (get_addresses, get_hostname,
|
||||
service_try_reload_or_restart,
|
||||
service_try_restart, service_unmask, umask)
|
||||
|
||||
UNKNOWN = 'unknowndeamon'
|
||||
UNKNOWN = 'unknowndeamon.service'
|
||||
UNKNOWN_SOCKET = 'unknowndeamon.socket'
|
||||
|
||||
systemctl_path = pathlib.Path('/usr/bin/systemctl')
|
||||
systemd_installed = pytest.mark.skipif(not systemctl_path.exists(),
|
||||
@ -76,20 +77,101 @@ def test_service_enable_and_disable():
|
||||
|
||||
@patch('plinth.action_utils.service_action')
|
||||
@systemd_installed
|
||||
def test_service_actions(mock):
|
||||
"""Trivial white box test for trivial implementations."""
|
||||
def test_service_start(mock):
|
||||
"""Test staring a service."""
|
||||
service_start(UNKNOWN)
|
||||
mock.assert_called_with(UNKNOWN, 'start', check=False)
|
||||
mock.mock_calls = [call(UNKNOWN, 'start', check=False)]
|
||||
|
||||
mock.reset_mock()
|
||||
service_start(UNKNOWN, check=True)
|
||||
mock.mock_calls = [call(UNKNOWN, 'start', check=True)]
|
||||
|
||||
|
||||
@patch('plinth.action_utils.service_action')
|
||||
@systemd_installed
|
||||
def test_service_stop(mock):
|
||||
"""Test stopping a service."""
|
||||
service_stop(UNKNOWN)
|
||||
mock.assert_called_with(UNKNOWN, 'stop', check=False)
|
||||
assert mock.mock_calls == [call(UNKNOWN, 'stop', check=False)]
|
||||
|
||||
mock.reset_mock()
|
||||
service_stop(UNKNOWN, check=True)
|
||||
mock.mock_calls = [call(UNKNOWN, 'stop', check=True)]
|
||||
|
||||
mock.reset_mock()
|
||||
service_stop(UNKNOWN_SOCKET)
|
||||
assert mock.mock_calls == [
|
||||
call(UNKNOWN_SOCKET, 'stop', check=False),
|
||||
call(UNKNOWN, 'stop', check=False)
|
||||
]
|
||||
|
||||
|
||||
@patch('plinth.action_utils.service_action')
|
||||
@systemd_installed
|
||||
def test_service_restart(mock):
|
||||
"""Test restaring a service."""
|
||||
service_restart(UNKNOWN)
|
||||
mock.assert_called_with(UNKNOWN, 'restart', check=False)
|
||||
assert mock.mock_calls == [call(UNKNOWN, 'restart', check=False)]
|
||||
|
||||
mock.reset_mock()
|
||||
service_restart(UNKNOWN, check=True)
|
||||
mock.mock_calls = [call(UNKNOWN, 'restart', check=True)]
|
||||
|
||||
mock.reset_mock()
|
||||
service_restart(UNKNOWN_SOCKET)
|
||||
assert mock.mock_calls == [call(UNKNOWN, 'stop', check=False)]
|
||||
|
||||
|
||||
@patch('plinth.action_utils.service_action')
|
||||
@systemd_installed
|
||||
def test_service_try_restart(mock):
|
||||
"""Test try-restaring a service."""
|
||||
service_try_restart(UNKNOWN)
|
||||
mock.assert_called_with(UNKNOWN, 'try-restart', check=False)
|
||||
assert mock.mock_calls == [call(UNKNOWN, 'try-restart', check=False)]
|
||||
|
||||
mock.reset_mock()
|
||||
service_try_restart(UNKNOWN, check=True)
|
||||
mock.mock_calls = [call(UNKNOWN, 'try-restart', check=True)]
|
||||
|
||||
mock.reset_mock()
|
||||
service_restart(UNKNOWN_SOCKET)
|
||||
assert mock.mock_calls == [call(UNKNOWN, 'stop', check=False)]
|
||||
|
||||
|
||||
@patch('plinth.action_utils.service_action')
|
||||
@systemd_installed
|
||||
def test_service_reload(mock):
|
||||
"""Test reloading a service."""
|
||||
service_reload(UNKNOWN)
|
||||
mock.assert_called_with(UNKNOWN, 'reload', check=False)
|
||||
assert mock.mock_calls == [call(UNKNOWN, 'reload', check=False)]
|
||||
|
||||
mock.reset_mock()
|
||||
service_reload(UNKNOWN, check=True)
|
||||
mock.mock_calls = [call(UNKNOWN, 'reload', check=True)]
|
||||
|
||||
mock.reset_mock()
|
||||
service_reload(UNKNOWN_SOCKET)
|
||||
assert mock.mock_calls == [call(UNKNOWN, 'reload', check=False)]
|
||||
|
||||
|
||||
@patch('plinth.action_utils.service_action')
|
||||
@systemd_installed
|
||||
def test_service_try_reload_or_restart(mock):
|
||||
"""Test try-reload-or-restart on a service."""
|
||||
service_try_reload_or_restart(UNKNOWN)
|
||||
mock.assert_called_with(UNKNOWN, 'try-reload-or-restart', check=False)
|
||||
assert mock.mock_calls == [
|
||||
call(UNKNOWN, 'try-reload-or-restart', check=False)
|
||||
]
|
||||
|
||||
mock.reset_mock()
|
||||
service_try_reload_or_restart(UNKNOWN, check=True)
|
||||
mock.mock_calls = [call(UNKNOWN, 'try-reload-or-restart', check=True)]
|
||||
|
||||
mock.reset_mock()
|
||||
service_try_reload_or_restart(UNKNOWN_SOCKET)
|
||||
assert mock.mock_calls == [
|
||||
call(UNKNOWN, 'try-reload-or-restart', check=False)
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('needs_root')
|
||||
|
||||
@ -178,6 +178,7 @@ module = [
|
||||
"plinth.tests.config_local",
|
||||
"pytest_splinter.*",
|
||||
"ruamel.*",
|
||||
"segno.*",
|
||||
"selenium.*",
|
||||
"splinter.*",
|
||||
"stronghold.*",
|
||||
|
||||
10
static/themes/default/icons/magic.svg
Normal file
10
static/themes/default/icons/magic.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg
|
||||
width="512"
|
||||
height="512"
|
||||
viewBox="0 0 512 512"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor">
|
||||
<path
|
||||
d="M 363.74832,181.71778 455.38913,90.07697 421.92303,56.610874 330.28222,148.25168 Z M 503.55528,90.07697 c 0,5.317043 -1.8766,10.32132 -5.62981,14.07453 L 95.706781,506.37019 C 91.953574,510.1234 86.949297,512 81.632254,512 76.315211,512 71.310935,510.1234 67.557728,506.37019 L 5.6298106,444.44227 C 1.8766035,440.68907 0,435.68479 0,430.36775 0,425.0507 1.8766035,420.04643 5.6298106,416.29322 L 407.8485,14.074527 c 3.75321,-3.753208 8.75749,-5.6298111 14.07453,-5.6298111 5.31704,0 10.32132,1.8766031 14.07453,5.6298111 l 61.92791,61.927916 c 3.75321,3.753208 5.62981,8.757484 5.62981,14.074527 z M 81.00672,30.651191 111.65791,40.034209 81.00672,49.417227 71.623702,80.068418 62.240684,49.417227 31.589493,40.034209 62.240684,30.651191 71.623702,0 Z m 109.46854,50.668296 61.30238,18.766033 -61.30238,18.76604 -18.76604,61.30238 L 152.94319,118.85156 91.640806,100.08552 152.94319,81.319487 171.70922,20.017104 Z M 481.34881,230.82224 512,240.20525 l -30.65119,9.38302 -9.38302,30.65119 -9.38302,-30.65119 -30.65119,-9.38302 30.65119,-9.38301 9.38302,-30.6512 z M 281.17776,30.651191 l 30.6512,9.383018 -30.6512,9.383018 -9.38301,30.651191 -9.38302,-30.651191 -30.65119,-9.383018 30.65119,-9.383018 L 271.79475,0 Z"
|
||||
style="stroke-width:0.312767" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
15
static/themes/default/icons/qrcode.svg
Normal file
15
static/themes/default/icons/qrcode.svg
Normal file
@ -0,0 +1,15 @@
|
||||
<svg
|
||||
width="512"
|
||||
height="512"
|
||||
viewBox="0 0 512 512"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor">
|
||||
<path
|
||||
d="M 0,0 V 256 H 256 V 213.33333 H 42.666667 V 42.66667 H 213.33333 v 192 H 256 V 0 Z M 0,512 V 298.66667 H 213.33333 V 512 H 21.333333 V 469.33333 H 170.66667 v -128 H 42.666667 V 512 Z M 298.66667,213.33333 V 0 H 512 V 213.33333 H 320 v -42.66666 h 149.33333 v -128 h -128 v 170.66666 z"
|
||||
id="path1"
|
||||
style="stroke-width:0.333333" />
|
||||
<path
|
||||
d="m 85.333333,85.33333 h 85.333337 v 85.33334 H 85.333333 Z m 298.666667,0 h 42.66667 V 128 H 384 Z M 85.333333,384 H 128 v 42.66667 H 85.333333 Z M 256,298.66667 h 42.66667 v 42.66666 H 256 Z m 128,42.66666 h 42.66667 V 384 H 384 Z m 0,85.33334 h 42.66667 v 42.66666 H 384 Z M 341.33333,256 v 42.66667 h 85.33334 v 42.66666 h 42.66666 V 256 Z M 512,384 h -42.66667 v 85.33333 H 426.66667 V 512 H 512 Z M 341.33333,341.33333 H 298.66667 V 384 H 256 v 42.66667 h 85.33333 z M 256,469.33333 H 384 V 512 H 256 Z"
|
||||
id="path2"
|
||||
style="stroke-width:0.333333" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
Loading…
x
Reference in New Issue
Block a user