Compare commits

...

314 Commits
v26.2 ... main

Author SHA1 Message Date
James Valleroy
350466940f
Release v26.9.1 to unstable
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-06-15 20:46:51 -04:00
James Valleroy
dff6698647
doc: Fetch latest manual
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-06-15 20:44:27 -04:00
James Valleroy
ceaccd7baf
wireguard: Get config for both download and qr actions
Re-arrange imports

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-06-15 20:15:14 -04:00
James Valleroy
629cc866b6
wireguard: Move segno import inside method
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-06-15 20:15:14 -04:00
Sunil Mohan Adapa
efcdc8cb5c
matrixsynapse: Allow installing new dependencies
Fixes: #2556

Should be merged after fix for https://bugs.debian.org/1122841 is in unstable.

- This fixes issue with Matrix Synapse app not being installable from current
unstable.

- matrix-synapse package depends on older version of python3-typing-extensions.
This causes the daemon to fail during startup when older version is installed.
This was reported as https://bugs.debian.org/1122841. After this bug is fixed
and a newer version of matrix-synapse is uploaded, the patch will work as
expected. An alternative was to allow unattended-upgrades to upgrade
python3-typing-extensions from unstable, but has to be done very carefully and
with a lot of testing.

Tests:

- Install Matrix Synapse apps works. This request installation of the latest
version python3-typing-extensions from unstable. The daemon is running properly
after installation.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-06-15 20:12:24 -04:00
Coucouf
0188ad38f7
Translated using Weblate (French)
Currently translated at 100.0% (1942 of 1942 strings)
2026-06-13 22:01:20 +02:00
Pierfrancesco Passerini
1086d52851
Translated using Weblate (Italian)
Currently translated at 100.0% (1942 of 1942 strings)
2026-06-13 22:01:17 +02:00
Pierfrancesco Passerini
3616ceb68d
Translated using Weblate (Italian)
Currently translated at 99.6% (1936 of 1942 strings)
2026-06-08 13:01:02 +00:00
Jiří Podhorecký
274dabb741
Translated using Weblate (Czech)
Currently translated at 100.0% (1942 of 1942 strings)
2026-06-04 20:01:02 +02:00
Besnik Bleta
9d24b4161a
Translated using Weblate (Albanian)
Currently translated at 99.6% (1936 of 1942 strings)
2026-06-03 05:01:05 +00:00
Burak Yavuz
d9a825ee36
Translated using Weblate (Turkish)
Currently translated at 100.0% (1942 of 1942 strings)
2026-06-03 05:01:03 +00:00
大王叫我来巡山
76efffb4e9
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 60.9% (1184 of 1942 strings)
2026-06-03 05:01:02 +00:00
James Valleroy
2590661fc8
Release v26.9 to unstable
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-06-01 21:20:28 -04:00
James Valleroy
bd733d4816
doc: Fetch latest manual
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-06-01 21:17:30 -04:00
James Valleroy
88e886046f
locale: Update translation strings
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-06-01 20:52:26 -04:00
Frederico Gomes
ad1b420397
wireguard: Enable FB to connect to a server using IPv6
This MR enables FreedomBox to connect as a "client" to a WireGuard
"server" using IPv6.

- Validate IPv4/6 with ip_interface
- Created helper functions to build NM settings for IPv4/6
- Modify get_settings to include settings for either IP version 4 or 6
- Created helper function to get NM address info
- Modify get_nm_info to work with IPv4 and IPv6
- Modified tests to use validate_ip_address_with_network
- Added IPv6 valid and invalid patterns to tests

Tested:

- IPv4 works unchanged
- IPv6 parsing + NM settings generation works
- IPv6 display in Show Server UI

Not tested:

- Needs IPv6 WireGuard server for full connectivity test

Closes: #1762

Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-26 18:41:20 -04:00
James Valleroy
9fd7a3b3af
debian/control: Add !nocheck for python3-segno
Tests:

- Succesfully build with nocheck profile:

gbp buildpackage --git-pbuilder --git-pbuilder-options="--profiles nocheck"

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 09:34:02 -04:00
Frederico Gomes
ea48448a72
wireguard: Added functional test for auto add client flow
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 08:55:51 -04:00
Frederico Gomes
050a5366c1
wireguard: Bump version
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 08:55:48 -04:00
Frederico Gomes
bc34a50a24
wireguard: Include python3-segno in app packages
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 08:55:46 -04:00
Frederico Gomes
ff2ac949cf
mypy: Added override for segno
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 08:55:43 -04:00
Frederico Gomes
941a597bc9
wireguard: Add security warning in template
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 08:55:38 -04:00
Frederico Gomes
5f25fc56a5
wireguard: Create URL for client config QR action
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 08:55:34 -04:00
Frederico Gomes
fa4e6002b3
wireguard: Add Show QR Code button
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 08:55:31 -04:00
Frederico Gomes
f9984ea9e4
themes-icons: Add QR Code icon
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 08:55:27 -04:00
Frederico Gomes
18d6f2d5db
wireguard: Add action for QR code generation
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 08:55:21 -04:00
Frederico Gomes
68e28cdebc
build-dependencies: Add python3-segno
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 08:54:58 -04:00
Frederico Gomes
79c978e03a
wireguard: Add client config file section and download button
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 08:54:53 -04:00
Frederico Gomes
ce2ce04979
wireguard: Create URL for client config download action
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 08:54:48 -04:00
Frederico Gomes
8e9b2a0631
wireguard: Create view to handle client config actions
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 08:54:32 -04:00
Frederico Gomes
60a6ac2a0d
wireguard: Create mixin for reusing generated client conf
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 08:54:09 -04:00
Frederico Gomes
bb6729a99a
wireguard: Create function for building conf files
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 08:54:03 -04:00
Frederico Gomes
81e60dff0e
wireguard: Add template to show generated client info
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 08:52:09 -04:00
Frederico Gomes
8cbcd39bb2
wireguard: Add empty form for AutoAddClientView
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 08:51:59 -04:00
Frederico Gomes
77a91fc357
wireguard/theme: Add icon to auto add client button
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 08:51:48 -04:00
Frederico Gomes
ebac5e86a3
wireguard: Add auto add client button
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 08:51:34 -04:00
Frederico Gomes
0a67183fe4
wireguard: Add URL for AutoAddClientView
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 08:51:29 -04:00
Frederico Gomes
36e1dd9e74
wireguard: Create AutoAddClientView
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 08:50:52 -04:00
Frederico Gomes
5fe11cedb6
wireguard: add wrapper function that generates client key pair
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-23 08:50:35 -04:00
jay
3d96f41053
Translated using Weblate (Dutch)
Currently translated at 93.9% (1813 of 1929 strings)
2026-05-21 18:11:36 +00:00
Hosted Weblate user 151773
511de5e106
Translated using Weblate (German)
Currently translated at 99.3% (1916 of 1929 strings)
2026-05-21 18:11:33 +00:00
Luca Boccassi
9abe624265
Install and use sysusers.d/tmpfiles.d config files
sysusers.d/tmpfiles.d config files allow a package to use
declarative configuration instead of manually written maintainer
scripts. This also allows image-based systems to be created
with /usr/ only, and also allows for factory resetting a system
and recreating /etc/ on boot.

https://www.freedesktop.org/software/systemd/man/latest/sysusers.d.html
https://www.freedesktop.org/software/systemd/man/latest/tmpfiles.d.html

Tests:

- /var/lib/plinth and /var/lib/plinth/sessions/ are created on package install.
  Ownership is plinth:plinth. 0755 is permissions.

- /var/lib/plinth/firstboot-wizard-secret file is created on package install.
  Ownership is plinth:plinth. 0400 is permissions. During first wizard,
  providing the secret works.

- /var/lib/plinth/backups-data is owned by root:root.

- When upgrading from old package to new the permissions don't change.

- When reinstalling the new package, the permissions do not change.

- User is created same as before.
  plinth987:987:FreedomBox service:/var/lib/plinth:/usr/sbin/nologin
- Group is created same as before.
  plinth987:
- id plinth
  uid=987(plinth) gid=987(plinth) groups=987(plinth)

- Upgrading from old package to new does not change user and group records.

- Reinstalling new version does not change user and group records.

[sunil: Don't recursively change ownership for /var/lib/plinth/]
[sunil: Change ownership specifically for /var/lib/plinth/firstboot-wizard-secret]
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
Tested-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-05-13 15:37:45 -07:00
Luca Boccassi
a4b3d53141
Stop deleting system user on remove/purge
This is widely considered bad practice, as the kernel recycles
UIDs/GIDs. So any potential leftover file/directory can then
become owned by the next user/group that gets added, with
unpredictable consequences.
2026-05-13 15:37:41 -07:00
Sunil Mohan Adapa
529bbf77df
bepasty: Don't remove old system user and group
As removing a system user and group is considered a bad practice.  Old unused
system accounts are mostly harmless.

Tests:

- Bepasty functional tests pass.

- Installing bepasty and uploading a file works.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-05-13 15:37:38 -07:00
Sunil Mohan Adapa
e48ff1afbc
infinoted: Use systemd-sysusers for creating a system user account
- Drop dependency on 'adduser' package.

Tests:

- Functional tests for infinoted work.

- Installing infinoted app works. The system user and group are created with
proper UID/GID, shell, gecos, and home directory.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-05-13 15:37:35 -07:00
Sunil Mohan Adapa
f4be9039d2
syncthing: Use systemd-sysusers for creating a system user account
- Drop dependency on 'adduser' package.

Tests:

- Functional tests for syncthing work.

- Installing syncthing app works. The system user and group are created with
proper UID/GID, shell, gecos, and home directory.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-05-13 15:37:32 -07:00
James Valleroy
0f98ed67e7
Release v26.8 to unstable
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-11 20:32:27 -04:00
James Valleroy
27e9b2ac0e
doc: Fetch latest manual
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-05-11 20:31:36 -04:00
Sunil Mohan Adapa
066f22ff35
api: Drop access-info API
This was meant to be used by the mobile client. But it is in unmaintained and
unusable state. We can re-introduce the API when mobile client is back in
action.

See: https://github.com/freedombox/FreedomBox/pull/1215

[Joseph]
This API is not called by the mobile client, so it is safe to remove.

Reviewed-by: Joseph Nuthalapati <njoseph@riseup.net>
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-05-10 18:32:35 +05:30
Dietmar
bacaa59725
Translated using Weblate (German)
Currently translated at 99.2% (1914 of 1929 strings)
2026-05-05 19:11:34 +02:00
Pierfrancesco Passerini
2b28850b63
Translated using Weblate (Italian)
Currently translated at 100.0% (1929 of 1929 strings)
2026-05-05 19:11:32 +02:00
Pierfrancesco Passerini
d0c20a74f9
Translated using Weblate (Italian)
Currently translated at 99.8% (1927 of 1929 strings)
2026-05-02 17:09:50 +02:00
James Valleroy
5c42e04813
Release v26.7.1 to unstable
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-04-28 18:26:58 -04:00
James Valleroy
91296b6e81
doc: Fetch latest manual
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-04-28 18:26:20 -04:00
James Valleroy
449b78ae81
locale: Update translation strings
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-04-28 18:01:49 -04:00
Sunil Mohan Adapa
495f5f8a0d
radicale: tests: functional: Better checking for well-known URLs
- When SOGO app is enabled, radicale functional tests fail.

Tests:

- Enable SOGO app and run radicale functional tests. They fail without patch and
pass with the patch.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-04-27 19:19:53 -04:00
Sunil Mohan Adapa
2bd33ed428
radicale: Fix issue with parsing new configuration file
The latest version of radicale calendar server's configuration file does not
parse with augeas. This is because it contains the following entry in [headers]
section:

Content-Security-Policy = default-src 'self'; object-src 'none'

The semicolon is treated as comment by the lens which is not correct. Fix this
by overriding comment_re in the lens.

Tests:

- Updated test case works when using augparse.

- With the patch, latest upstream configuration file parses without errors.

- Functional tests work for radicale in testing distribution. Without patch
radicale fails to install.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-04-27 19:19:47 -04:00
Sunil Mohan Adapa
ae50ceaeb0
radicale, bepasty: Fix issue with failed diagnostic test
Fixes: #2571.

- During backup, a service related to backup is stopped and then started back
again after the backup. In case of .socket unit, the .service unit is not being
stopped and it continues to listen on the socket path. When the .socket unit is
started back again, it tries to listen on the socket path and fails.

- To fix the issue, when running stop, restart, etc. operations on a .socket
file, try to perform that operations that we actually intend.

Tests:

- Unit tests pass

- Functional tests for bepasty and radicale work.

- After taking a radicale backup uwsgi-app@radicale.socket does not become
inactive (works when service is running or stopped). uwsgi-app@radicale.service
stops if it is running, backup doesn't fail if service is not running.

- After taking a radicale backup uwsgi-app@bepasty-freedombox.socket does not
become inactive (works when service is running or stopped).
uwsgi-app@bepasty-freedombox.service stops if it is running, backup doesn't fail
if service is not running.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-04-27 19:13:14 -04:00
Frederico Gomes
dc3439fd70
radicale: Enable lc_username for case-insensitive auth
Enable lc_username = True in [auth] section during setup.

Bump version.

Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-04-25 13:25:49 -04:00
James Valleroy
5cebe7ffe0
Release v26.7 to unstable
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-04-20 20:26:20 -04:00
James Valleroy
52ce78ca1e
doc: Fetch latest manual
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-04-20 20:25:18 -04:00
James Valleroy
5b615a169b
debian: tests: Add test to access interface status
Tests:

- Build the Debian package and run autopkgtest with qemu backend. The
  test is passed.

- Revert the recent fix for loading icons. Build the Debian package
  and run autopkgtests again. It is failed due to maximum redirects
  followed.

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-04-20 10:39:09 -07:00
Pierfrancesco Passerini
5b8e3b8f85
Translated using Weblate (Italian)
Currently translated at 99.4% (1918 of 1929 strings)
2026-04-18 23:09:49 +02:00
Coucouf
6b033b3f45
Translated using Weblate (French)
Currently translated at 100.0% (1929 of 1929 strings)
2026-04-16 15:09:51 +00:00
bittin1ddc447d824349b2
be84971c5a
Translated using Weblate (Swedish)
Currently translated at 100.0% (1929 of 1929 strings)
2026-04-15 10:10:34 +00:00
Dietmar
f9de7865ed
Translated using Weblate (Italian)
Currently translated at 99.3% (1917 of 1929 strings)
2026-04-09 10:09:55 +00:00
Jiří Podhorecký
cbb7998565
Translated using Weblate (Czech)
Currently translated at 100.0% (1929 of 1929 strings)
2026-04-09 10:09:54 +00:00
Burak Yavuz
a3c4d177df
Translated using Weblate (Turkish)
Currently translated at 100.0% (1929 of 1929 strings)
2026-04-09 10:09:52 +00:00
Dietmar
abc066a92b
Translated using Weblate (German)
Currently translated at 99.0% (1910 of 1929 strings)
2026-04-09 10:09:50 +00:00
大王叫我来巡山
516a8e23d0
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 60.9% (1176 of 1929 strings)
2026-04-08 09:09:54 +02:00
Besnik Bleta
6d7da4b43f
Translated using Weblate (Albanian)
Currently translated at 99.6% (1923 of 1929 strings)
2026-04-08 09:09:53 +02:00
Burak Yavuz
7ff91f3e86
Translated using Weblate (Turkish)
Currently translated at 99.2% (1914 of 1929 strings)
2026-04-08 09:09:49 +02:00
James Valleroy
02a6091722
Release v26.6 to unstable
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-04-06 20:41:55 -04:00
James Valleroy
640463e17e
doc: Fetch latest manual
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-04-06 20:41:21 -04:00
James Valleroy
2694cbc367
locale: Update translation strings
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-04-06 20:13:33 -04:00
Sunil Mohan Adapa
00dc06d1b6
users: Add link to guide on passkeys
Tests:

- Visiting the 'Manage passkeys' page show the learn more link. Clicking on the
link shows the page for passkeys guide.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-04-06 18:26:36 -04:00
Sunil Mohan Adapa
9d6c74c887
users: Add support for logging in with passkeys
Tests:

- Login
  - Login using passkeys works on testing container and stable container.
  - Login page show 'Log in with passkey' button as expected along with key
    icon.
  - On GNOME's Web browser, the login page does not show an error on load.
    Clicking on 'Log in with passkey' shows the error: 'Logging in with passkey
    failed: Browser does not support passkeys.'
  - On Chromium browser, with invalid TLS certficiate, the login page does not
    show an error on load. Clicking on 'Log in with passkey' shows the error:
    'Logging in with passkey failed: NotAllowedError: WebAuthn is not supported
    on sites with TLS certificate errors.'
  - Raising an error in the passkey_login_begin() method shows the error message
    when login page is loaded. Raising an error in the passkey_login_complete
    method shows the error message after passkey is unlocked. In both cases, 500
    is HTTP status code.
  - With primary hardware key register passkey each for 'tester' and 'tester2'
    accounts.
  - With secondary hardware key register passkey for 'tester' account.
  - In login page, loading the page shows the console message 'Signing in with a
    passkey. Condition: true'.
  - In login page, when username field is clicked, 'passkey' is shown in the
    autofill popup options. Selecting it prompts for hardware PIN and touch.
    User is logged in.
  - In login page, when 'Log in with passkey' is clicked, console message is
    show 'Log in initiated with button, conditional mediation aborted.'.
    Hardware PIN and touch is prompted. User is logged in.
  - During autofill login, canceling the hardware key PIN shows no error alert.
    Autofill passkey login is not available.
  - During autofill login, canceling the hardware touch prompt shows no error
    alert. Autofill passkey login is not available.
  - During button login, canceling the hardware key PIN shows '...user denied
    permission' error alert. Autofill passkey login is not available.
  - During button login, canceling the hardware touch prompt shows no '...user
    denied permission' error alert. Autofill passkey login is not available.
  - When multiple attempts fail, multiple error alerts are shown.
  - During login, with primary key account selection dialog is shown. Selecting
    'tester' logs into 'tester' account. Selecting 'tester2' logs into 'tester2'
    account.
  - During login, with secondary key, account selection dialog is not shown.
    User is logged into the 'tester' account.
  - Password based login continues to work as usual on Firefox, Chromium, and
    GNOME's web.
  - Logout, then visit /freedombox/sys/. This redirects to login page. After
    login with passkey the browser is redirected to /freedombox/sys page.
  - After passkey login, 'Last Used' for that key is updated. The value is not
    updated for remaining keys of the account.
  - After successful login, database is updated with the latest signature
    counter.
  - After successful login, for a user account with Spanish set as language, the
    UI language changes to Spanish.
  - If a key has been removed from list of passkeys and that passkey is
    attempted for login, 'Passkey used is not known' error alert is shown.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-31 07:48:54 -04:00
Sunil Mohan Adapa
1a8868f0cd
users: Add support registering, editing, and deleting passkeys
Tests:

- Setup: add domain name mystable.example. Add an entry in /etc/hosts on the
  test machine. In Firefox, in about:config, set
  'security.webauthn.allow_with_certificate_override' to 'true'.
- Registration
  - Passkey successful registration:
    - After passkey registration, created time is time at which key is created.
    - After passkey registration, domain is the domain with which the interface
      is accessed at the time of addition of passkey.
    - After passkey registration, Added and Last Used columns show the current
      time in UTC. Signature counter and extensions and aaguid values in the DB
      are as expected.
    - First key's name is 'Key 1'. After that it is 'Key 2' and so on. If a key
      is renamed as 'Key 4', then next key will be named 'Key 5'.
    - Registering passkeys using testing container stable container works.
  - Links:
    - 'Manage passkeys' link is show in the user menu in navbar in both desktop
      mode and mobile mode. Clicking on it redirects the browser to current
      user's passkey management page.
    - User's edit page shows 'Use passkeys for better security'. Clicking on the
      link redirects the browser to passkey management page for the user who's
      account is being edited.
  - Listing:
    - All passkeys are show properly. Name, domain, added, last used, and
      operations show correctly.
    - When using a browser without Javascript script shows an error alert.
    - If not passkeys are present "No passkeys added to user account." message
      is shown.
  - Editing the passkey shows correct page. Title, heading, form labels, form
    value, and buttons are as expected. After editing, passkey is updated
    properly.
  - Deleting the passkey shows a model dialog with correct details. After
    confirmation, passkey is removed and page is refreshed.
  - Error handling:
    - On GNOME's Web, clicking the 'Add Passkey' shows the error 'Browser does
      not support passkeys'.
    - On Chromium, clicking the 'Add passkey' shows the error 'NotAllowedError:
      WebAuthn is not supported on sites with TLS certificate errors.'
    - Raising an error in passkey_add_begin() results in correct error message
      shown with 'Add passkey' button is clicked. Status code is 500.
    - Raising an error in passkey_add_complete() results in correct error
      message shown after unlocking the hardware token. Status code is 500.
    - Canceling the PIN dialog results in '...user denied permission' error
      alert.
    - Canceling the touch dialog results in '...user denied permission' error
      alert.
    - Multiple failed attempts result in multiple alerts being shown at the same
      time.
  - Editing another user's passkeys:
    - Listing passkeys show correct list of passkeys for the user account being
      managed.
    - Adding passkeys adds correctly to the user account being managed.
    - Editing passkey correctly edits passkey of the user account being managed.
      Redirect happens to the correct page after.
    - Deleting passkey correctly edits passkey of the user account being
      managed. Redirect happens to the correct page after.
    - If a non-admin user tries to access passkeys list/edit/delete URL of
      another user, 403 Forbidden error is raised

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-31 07:48:50 -04:00
Sunil Mohan Adapa
fa22ecaa36
d/control: Add fido2 library as dependency
Tests:

- Building the package using cowbuilder works.

- Building the package using nocheck profile works.

- On a fresh stable machine, installing the package and patches works.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-31 07:48:46 -04:00
Sunil Mohan Adapa
46f13b2be9
views: Add a decorator to handle exceptions in JSON views
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-31 07:48:43 -04:00
Sunil Mohan Adapa
cc626be728
service: Capture stdout/stderr when running as systemd unit
- Avoid duplicate log messages by not logging to console when running as systemd
unit.

- Retain normal logging when running on the terminal.

Tests:

- When running as systemd unit, output to stdin/stdout is captured in systemd
journal and visible with 'sudo freedombox-logs'.

- When running on terminal manually with 'sudo --user plinth ./run --develop'
both log messages and stdout/stderr prints() are visible.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-31 07:48:38 -04:00
bsurajpatra
c0d603af07
Translated using Weblate (Hindi)
Currently translated at 43.9% (839 of 1908 strings)
2026-03-31 06:09:51 +00:00
Pierfrancesco Passerini
c8a6637cae
Translated using Weblate (Italian)
Currently translated at 100.0% (1908 of 1908 strings)
2026-03-31 06:09:50 +00:00
Dietmar
b3b218bc24
Translated using Weblate (German)
Currently translated at 99.0% (1889 of 1908 strings)
2026-03-29 11:09:54 +00:00
Dietmar
06ad575b12
Translated using Weblate (Italian)
Currently translated at 98.2% (1874 of 1908 strings)
2026-03-29 11:09:52 +00:00
Coucouf
dc49c4e8a7
Translated using Weblate (French)
Currently translated at 100.0% (1908 of 1908 strings)
2026-03-29 11:09:50 +00:00
James Valleroy
1b12d094ab
Release v26.5.1 to unstable
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-26 18:22:26 -04:00
Sunil Mohan Adapa
8cd1fbc6b9
web_server: Fix locating SVG icons on production setup
Tests:

- On a development setup, loading the home page and a few other pages works
without errors. FreedomBox icon in the navbar (and other icons) are shown.

- On a testing setup, without development mode, loading the home page and a few
other pages works without errors. FreedomBox icon in the navbar (and other
icons) are shown. Without the patch no page loads.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-26 18:17:27 -04:00
Sunil Mohan Adapa
ab8d87e71d
debian/copyright: Drop a removed file, correct path for another
Tests:

- lintian drops two 'superfluous-file-pattern' warnings.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-03-26 11:49:25 -07:00
Sunil Mohan Adapa
2f337741ec
debian/control: Fix building with nocheck profile
Closes: #1131956 (Debian)

- django-admin command from python3-django package is needed to build the .mo
translation files.

Tests:

- 'gbp buildpackage --git-pbuilder --git-pbuilder-options="--profiles=nocheck"'
works.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-03-26 11:49:00 -07:00
Besnik Bleta
e083ea00e7
Translated using Weblate (Albanian)
Currently translated at 99.6% (1901 of 1908 strings)
2026-03-26 10:09:48 +01:00
Burak Yavuz
79363b8e56
Translated using Weblate (Turkish)
Currently translated at 100.0% (1908 of 1908 strings)
2026-03-25 08:09:49 +01:00
James Valleroy
94f10a3bb5
Release v26.5 to unstable
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-23 20:38:37 -04:00
James Valleroy
ee9be81b38
doc: Fetch latest manual
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-23 20:24:51 -04:00
James Valleroy
bdf75fdb66
locale: Update translation strings
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-23 20:03:41 -04:00
Ettore Atalan
53563461c8
Translated using Weblate (German)
Currently translated at 97.3% (1859 of 1910 strings)
2026-03-22 23:09:49 +00:00
Sunil Mohan Adapa
db92e23c75
action_utils: Don't restart web interface when installing an app
Tests:

- systemd-run --pipe
--property=BindReadOnlyPaths=/usr/share/freedombox/etc/needrestart/conf.d/freedombox-self.conf:/etc/needrestart/conf.d/freedombox-self.conf
ls -la /etc/needrestart/conf.d/ shows that the new configuration is listed as
expected.

- Running about command with 'cat /etc/needrestart/conf.d/freedombox-self.conf'
shows that configuration content is as expected.

- Running functional tests for coturn app work as expected. systemd journal
shows that transient services are being created to run apt commands.

- After the execution of an operation an empty file is created as
/etc/needrestart/conf.d/freedombox-self.conf.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-21 11:10:25 -04:00
James Valleroy
0e698eb4b4
apache: Use a Uwsgi native socket systemd unit for each app
[Sunil]:

- Drop Uwsgi component entirely. After the changes, it mostly looks like Daemon
component minus some features. One change that Uwsgi component does is when
component is disabled, it also stops and disables the .service unit. Stopping
the service is useful and we can add this to Daemon component.

- Use /run instead of /var/run/ as 1) /var/run is a symlink to /run 2) /run/
path is what is listed in uwsgi-app@.socket unit file.

- Implement upgrade for apps from older version. Disable and mask uwsgi init.d
script. Enable the daemon component if the webserver component is enabled.

- Update manifest files to deal with .socket units instead of 'uwsgi' service.
Backup the /var/lib/private directories as that is actual directory to backup
with DynamicUser=yes.

- For bepasty load the configuration as a systemd provided credential since
DynamicUser=yes.

- Remove the /var/lib/private directories during uninstall.

- Don't create user/group for bepasty as it is not needed with DynamicUser=yes.

Tests:

- Radicale

  - Functional tests pass

  - Freshly install radicale.

  - Web interface works.

  - Create and edit calendars

  - Path of the storage directory is in /var/lib/private/radicale (after
  accessing web interface)

  - Permissions on the storage folder and files inside are set to nobody:nobody.

  - Uninstall removes the /var/lib/private/radicale directory.

  - Create a calender and backup the app. Uninstall the app. Re-install the app.
  The calendar is not available. After restoring the backup, the calendar is
  available.

  - Install radicale without patch and create a calendar. Apply patches and
  start plinth.service. Setup is run. UWSGI is disabled and masked. Service is
  running. Old calender is visible.

  - Install radicale without patch. Disable and apply patches and start
  plinth.service. Setup is run. UWSGI is disabled and masked. Service is not
  running. Enabling the service works.

  - After upgrade, data storage path got migrated to /var/lib/private/radicale.
  Old data is accessible.

  - After upgrade the directory is still owned by radicale:radicale.

  - Freshly install radicale with patch and restore an old backup. The data is
  available in the web interface and data was migrated to
  /var/lib/private/radicale.

- Bepasty

  - Functional tests pass

  - Freshly install bepasy.

  - Enabling and disabling rapidly works.

  - Uploading files works.

  - Path of the storage directory is /var/lib/private/bepasty.

  - Permissions on the storage folder are as expect 755 but on the parent are
  700.

  - Permissions on the stored files are 644 and owned by nobody:nobody.

  - Uninstall removes the /var/lib/private/bepasty directory.

  - Upload a picture and backup the app. Uninstall the app. Re-install the app.
  The uploaded file is not available. After restoring the backup, the uploaded
  file is available.

  - Install bepasty without patch and upload a file. Apply patches and start
  plinth.service. Setup is run. UWSGI is disabled and masked. Service is
  running. Old uploaded picture is visible.

  - Install bepasty without patch. Disable app. Apply patches and start
  plinth.service. Setup is run. UWSGI is disabled and masked. Service is not
  running. Enabling the service works.

  - After upgrade, data storage path got migrated to /var/lib/private/bepasty.
  Old data is accessible.

  - After upgrade the directory is still owned by bepasty:bepasty.

  - Freshly install bepasty with patch and restore an old backup. The uploaded
  file is available in the web interface and data was migrated to
  /var/lib/private/bepasty.

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-21 07:45:51 -07:00
Sunil Mohan Adapa
7cbbc3633b
action_utils: Stop associated service when stopping a socket unit
Tests:

- Unit tests pass.

- Radicale and Bepasty functional tests pass with changes to migrate to new
systemd socket-activated units.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-03-21 07:45:47 -07:00
Joseph Nuthalapati
65fecdc4cd
container: Fix image extension to .raw for systemd v260
The new version of systemd in Debian testing expects the symlinked file
to be ending with .raw as well. So, our .img files weren't being
recognized by machinectl as machine images.

Signed-off-by: Joseph Nuthalapati <njoseph@riseup.net>
[sunil: Remove old symlink forcefully]
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-03-20 17:02:17 -07:00
Joseph Nuthalapati
2307f5fbf2
container: Add option to skip install
Fixes #2561

- Running functional tests against the container works.

```
./container start --skip-install
./container run-tests --pytest-args --include-functional -m syncthing
```

Signed-off-by: Joseph Nuthalapati <njoseph@riseup.net>
[sunil: Ran yapf]
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org
2026-03-20 13:41:13 -07:00
Sunil Mohan Adapa
9169ef89d9
apache: Increase OpenID Connect RP session timeout activity
Tests:

- Without patch, open FeatherWiki wiki and save after 5 minutes. Save fails.

- Apply the patch, Apache app setup is run and mod_auth_openidc configuration
is updated. Open FeatherWiki wiki and save after 5 minutes. Save works, wiki
contents are saved.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Joseph Nuthalapati <njoseph@riseup.net>
2026-03-20 23:58:48 +05:30
Sunil Mohan Adapa
c66e78c203
app: Fix build issue with Django 5.x
Closes: #1131272 (Debian)

Tests:

- With Django 4.2 (stable container), syncthing app installs properly and home
page shows the tags properly.

- With Django 6.0 (unstable+experimental container), syncthing app installs
properly and home page shows the tags properly.

- With a cowbuilder base image of Ubuntu resolute distribution, freedombox
package builds successfully with gbp.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Joseph Nuthalapati <njoseph@riseup.net>
2026-03-20 23:44:38 +05:30
Sunil Mohan Adapa
7d3c4812e9
doc: Reduce verbosity when building documentation
- Also remove docbook.css file properly

Tests:

- 'make clean ; make' in doc/ directory yields terse output. dockbook.css is not
created.

- 'make build' in main directory does not result in creation of docbook.css.

[Joseph Nuthalapati]

- Align the prefixes so that the sentences start at the same position.
- Add a space in the redirection: `2> /dev/null`

Reviewed-by: Joseph Nuthalapati <njoseph@riseup.net>
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-03-20 23:31:53 +05:30
Sunil Mohan Adapa
adfbb1e2a4
janus: Drop unused reference to font-awesome
In the upstream demo, https://janus.conf.meetecho.com/demos/videoroom.html, the
font-awesome glyphicons were only being used to show the 'user' icon next to
alias text field. We have replaced that with a simple unicode character. We also
seem to have dropped the dependency on Debian package. However, we seem to
forgotten to remove the inclusion of the JS file. This leads to a 404 error when
loading Janus room.

Tests:

- The page loads and works as expected. The 'user' icon shows up. There are no
404 errors in the browser console.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-20 06:58:46 -04:00
Sunil Mohan Adapa
1d14d4a4d6
ui: Rename 'plinth_extras' template tags module to 'extras'
- Remove yet another reference to 'plinth'.

Tests:

- Some basic pages work.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:58 -04:00
Sunil Mohan Adapa
20ed01dfbc
ui: Drop fonts-fork-awesome as dependency
Closes: #2343.

- SVG icons from the project have been imported into the static/theme/icons
directory. In future, more icons from this and projects will be included in this
directory. We no longer use glyphicons from a font file.

- SVG icons are more flexible as we can mix and match icons from different
projects like fork-awesome. Each file can be individually tweaked to our needs.

- They do not get anti-aliased like icons from font files.

- They could end being much smaller than a font file which usually 100KiB+. Only
icons used on a page are included in the page.

- They work when font resources are blocked for security reasons like in case of
NoScript extension.

- They don't require separate resource to be loaded as SVG is typically inlined
in the HTML file. This should improve page load time.

- They can be animated and tweaked with CSS/JS.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:55 -04:00
Sunil Mohan Adapa
f768195a13
ui: Use inline SVG icons for theme switcher menu
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:53 -04:00
Sunil Mohan Adapa
bfa5f4b622
upgrades: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:49 -04:00
Sunil Mohan Adapa
07955b4e64
ui: Use inline SVG icons for navigation bar at the top
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:47 -04:00
Sunil Mohan Adapa
d0f1f95bbb
ui: Better placement for dropdown indicator in dropdown button
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:44 -04:00
Sunil Mohan Adapa
33d7bf641f
ui: Use inline SVG icons for all error/warn/info/success messages
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:42 -04:00
Sunil Mohan Adapa
53ee9c4ee2
ui: Use inline SVG icons for all spinners
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:39 -04:00
Sunil Mohan Adapa
928794ea1f
ui: Use inline SVG icons for all collapse buttons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:37 -04:00
Sunil Mohan Adapa
76caaaa4e3
ui: Use inline SVG icons for app install page
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:34 -04:00
Sunil Mohan Adapa
bd5b1730bc
backups: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:32 -04:00
Sunil Mohan Adapa
91d5a980c4
ui: Use inline SVG icons for operation waiting notifcation
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:29 -04:00
Sunil Mohan Adapa
310fa40a1e
ui: Use inline SVG icons for app's log page
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:27 -04:00
Sunil Mohan Adapa
4b1d14fa7f
ui: Use inline SVG icons for app's service-not-running message
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:24 -04:00
Sunil Mohan Adapa
e70478711a
firstboot: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:21 -04:00
Sunil Mohan Adapa
bcc6bdc922
networks: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:19 -04:00
Sunil Mohan Adapa
663a2eb5c4
ui: Use inline SVG icons for clients launch buttons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:17 -04:00
Sunil Mohan Adapa
bd20469ed0
ui: Use inline SVG icons for tag search
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:14 -04:00
Sunil Mohan Adapa
a2c362a1b3
gitweb: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:11 -04:00
Sunil Mohan Adapa
d8909277a5
storage: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:09 -04:00
Sunil Mohan Adapa
1b24a03774
diagnostics: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:06 -04:00
Sunil Mohan Adapa
fad1f7d58b
snapshot: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:04 -04:00
Sunil Mohan Adapa
fbdd0c269d
sharing: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:14:01 -04:00
Sunil Mohan Adapa
5533ac419a
security: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:13:58 -04:00
Sunil Mohan Adapa
887514a523
kiwix: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:13:55 -04:00
Sunil Mohan Adapa
1212504a10
calibre: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:13:53 -04:00
Sunil Mohan Adapa
54b270d8f3
bepasty: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:13:50 -04:00
Sunil Mohan Adapa
cc716e20e4
matrixsynapse: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:13:47 -04:00
Sunil Mohan Adapa
236f90bbd9
help: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:13:45 -04:00
Sunil Mohan Adapa
59218c16a8
email: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:13:42 -04:00
Sunil Mohan Adapa
d0d26866bd
users: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:13:39 -04:00
Sunil Mohan Adapa
66f2307a19
miniflux: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:13:37 -04:00
Sunil Mohan Adapa
340b7e6101
samba: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:13:34 -04:00
Sunil Mohan Adapa
165828934e
ikiwiki: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:13:31 -04:00
Sunil Mohan Adapa
acd5477b11
pagekite: Fix issue with adding custom services
Tests:

- Adding and deleting a custom service no longer results in an error message.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:13:28 -04:00
Sunil Mohan Adapa
6bb6969eef
pagekite: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:13:26 -04:00
Sunil Mohan Adapa
cc13bbb0e3
power: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:13:23 -04:00
Sunil Mohan Adapa
66a6783a43
ui: Use inline SVG icons for port fowarding info
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:13:19 -04:00
Sunil Mohan Adapa
69c44af700
help: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:13:16 -04:00
Sunil Mohan Adapa
7c07126fe9
dynamicdns: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:13:13 -04:00
Sunil Mohan Adapa
941b586cb9
wireguard: Use inline SVG icons
Tests:

- All the icons appear as before in both light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:13:10 -04:00
Sunil Mohan Adapa
72dd357d43
tiddlywiki: Use inline SVG icons for app
Tests:

- The icons appears as before in the app page in light/dark themes.

Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:13:06 -04:00
Sunil Mohan Adapa
536c4bb30b
featherwiki: Use inline SVG icons for app
Tests:

- The icons appears as before in the app page in light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:13:01 -04:00
Sunil Mohan Adapa
811b18c239
names: Use inline SVG icons for main app page
Tests:

- The icons appears as before on the add/edit/delete buttons in light/dark
themes.

- The icon appears as before on the error message.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:12:57 -04:00
Sunil Mohan Adapa
3e6c8e9b06
ui: Use inline SVG icons for internal zone message
Tests:

- In Privoxy app with only internal interface defined, the icon appears as
before in message in light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:12:53 -04:00
Sunil Mohan Adapa
f56d5f1b0f
ui: Use inline SVG icons for notification dropdown
Tests:

- The icon appears as before in navbar in light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:12:50 -04:00
Sunil Mohan Adapa
a951b5f606
ui: Use inline SVG icons for app toolbar
Tests:

- The icons appears as before in toolbar in light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:12:46 -04:00
Sunil Mohan Adapa
80730bc9b3
ui: Use inline SVG icons for breadcrumbs
Tests:

- The home icon appears as before in breadcrumb in light/dark themes.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:12:42 -04:00
Sunil Mohan Adapa
c12e4079c6
ui: Add rest of the icons used from fork-awesome set
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:12:38 -04:00
Sunil Mohan Adapa
aed23630fb
ui: Use inline SVG icons for system and help section page
Tests:

- All the icons appear as before.

- They change colors in light/dark mode.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:12:33 -04:00
Sunil Mohan Adapa
d02154e2f0
clients: Use SVG icons when showing external links
Tests:

- Icons works in light/dark mode.

- All icons appear as expected.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:12:28 -04:00
Sunil Mohan Adapa
4a3ca01059
html: Drop trailing slash from void elements
See: https://github.com/validator/validator/wiki/Markup-%C2%BB-Void-elements

Tests:

- Fewer info messages in w3c HTML validator.

- Page loads and works as usual.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:12:20 -04:00
Sunil Mohan Adapa
144efd71b8
html: Drop type attribute value of text/javascript
As is encouraged[1]

https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/script#attribute_is_not_set_default_an_empty_string_or_a_javascript_mime_type

Links:

- Apps page loads and javascript works as expected.

Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:12:14 -04:00
Sunil Mohan Adapa
6defd3e8ce
ui: Use inline SVG images for app icons for dark mode adaptation
- Use 'currentColor' as color in SVG images to make them adapt to light/dark
modes.

- Introduce a new {% icon %} template tag to read SVG files, attach attributes,
remove <?xml> header, and make all IDs inside unique.

- Use the {% icon %} template tag to inline SVGs in app page, home page,
app pages, and notifications.

- Relax the content security policy to allow inline styling with 'style='
attribute.

Tests:

- Allow the icons looks as before in the following pages: home page, apps page,
app specific page, and in notifications.

- Icons that are fully dark become white when theme is switched to dark mode.

- All the inlined SVG icons have a prefixed unique ID.

- W3C HTML validator shows no new errors.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:12:04 -04:00
Sunil Mohan Adapa
c0dcd15169
ui: Simplify SVG app icons for using them inline in HTML
- Drop unnecessary inkscape markup.

- Ensure that all the SVGs have viewBox='' attribute.

- Drop unnecessary id='' attributes.

- Prefix all IDs with 'autoidmagic-'. This will be replaced with a random string
for each inlining in HTML to avoid duplicate IDs.

Tests:

- All SVGs appear the same as before.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-19 19:11:54 -04:00
Sunil Mohan Adapa
31925252cb
tests: functional: Drop undefined 'sso' pytest mark
Remove the following warnings when running functional tests.

plinth/modules/calibre/tests/test_functional.py:13: PytestUnknownMarkWarning: Unknown pytest.mark.sso - is this a typo?  You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html
    pytestmark = [pytest.mark.apps, pytest.mark.sso, pytest.mark.calibre]

plinth/modules/kiwix/tests/test_functional.py:15: PytestUnknownMarkWarning: Unknown pytest.mark.sso - is this a typo?  You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html
    pytestmark = [pytest.mark.apps, pytest.mark.sso, pytest.mark.kiwix]

plinth/modules/searx/tests/test_functional.py:9: PytestUnknownMarkWarning: Unknown pytest.mark.sso - is this a typo?  You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html
    pytestmark = [pytest.mark.apps, pytest.mark.searx, pytest.mark.sso]

plinth/modules/syncthing/tests/test_functional.py:11: PytestUnknownMarkWarning: Unknown pytest.mark.sso - is this a typo?  You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html
    pytestmark = [pytest.mark.apps, pytest.mark.syncthing, pytest.mark.sso]

plinth/modules/transmission/tests/test_functional.py:13: PytestUnknownMarkWarning: Unknown pytest.mark.sso - is this a typo?  You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html
    pytestmark = [pytest.mark.apps, pytest.mark.transmission, pytest.mark.sso]

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-03-17 12:11:55 -07:00
Sunil Mohan Adapa
009e07b232
letsencrypt: Don't perform operations on apps that are not installed
Fixes: #2568.

When Let's Encrypts events are fired for all applications, they happen on apps
that install as well. They have not been a problem so far because seem to
succeed always. However, ejabberd recently changed to having '*' for list of
domains accepted and also has non-root account for certificate ownership. This
combination causes a certificate operation to fail as the package 'ejabberd' is
not installed and 'ejabberd' user is not available. Fix this by making limiting
certificate operations to apps that have been installed.

Tests:

- Add a new domain name to a production FreedomBox using the Dynamic DNS
'tester' account. 'ejabberd' app should not be installed. LE events fire and a
log message showing failure is noticed. All the events after the failure for
other apps also succeed. The failure is a minor and contained to ejabberd.

- Apply the patch and revoke the certificate. LE event is fired on all other
installed apps but not on ejabberd. No error is logged.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-16 20:30:58 -04:00
Sunil Mohan Adapa
b4c6748837
apache: Minor improvement to getting the request host
- Django's request.get_host() use X_FORWARDED_HOST when appropriate and falls
back to HTTP_HOST. In case of FreedomBox due to 'ProxyPreserveHost On' in Apache
configuration, both the values are the same. So, it makes no difference.

- Also document the need for 'ProxyPreserveHost On' in another validation.

Tests:

- Log the value of request_host, request.META['HTTP_HOST'], and
request.META['X_FORWARDED_HOST'] in DiscoverIDPView:get(). All the values are
same when accessing with IP address value not starting with 127.0.0.1.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-16 19:44:10 -04:00
OwlGale
b765e9b9c6
Translated using Weblate (Russian)
Currently translated at 98.5% (1882 of 1910 strings)
2026-03-15 19:09:48 +01:00
Frederico Gomes
6ce258152f
wireguard: Fix freedombox VPN IP for services
Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-03-13 17:21:28 -07:00
Daniel Wiik
4e928fe58e
Translated using Weblate (Swedish)
Currently translated at 100.0% (1910 of 1910 strings)
2026-03-11 22:09:50 +00:00
Sunil Mohan Adapa
0e773e7ad0
clients: Fix show empty clients in Desktop section
When a client has a package but no desktop package, an empty client entry
appears in the Desktop section.

Tests:

- For MiniDLNA, in the Desktop section, there is not empty entry for totem
anymore.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-03-09 15:26:17 -07:00
Frederico Gomes
f99f3bd382
clients: Fix formatting of package row in table
Adjust row so that package entries are evenly distributed

Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
[sunil: Fix indentation]
[sunil: Convert tabs to spaces]
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-03-09 15:25:23 -07:00
Frederico Gomes
15b7a34072
wireguard: Add entries for Homebrew and RPM packages
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-03-09 15:25:20 -07:00
Frederico Gomes
0ba4cbe259
wireguard: Add button for direct APK download
**clients.py**
- allow download type for mobile os

**manifest.py**
- add entry for apk download

**plinth/templates/clients.html**
- add logic to show button for apk download

**themes > icons**
- add icon for android

source: https://www.wireguard.com/install/

Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
[sunil: Minor indentation]
[sunil: Refactor logic to eliminate packages from Desktop clients list]
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-03-09 15:25:17 -07:00
Frederico Gomes
176bb97c88
wireguard: Update windows client link
Update download link to .exe provided by WireGuard.
A utility that downloads, verifies and executes provided MSIs.

source: https://www.wireguard.com/install/

Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-03-09 15:16:39 -07:00
Frederico Gomes
bd6780b81d
wireguard: Remove client entry for F-Droid which is not available
Link to the F-Droid WireGuard package returns 404 Not Found.
WireGuard seems to no longer be packaged by F-Droid.

Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-03-09 15:15:55 -07:00
OwlGale
831a18847e
Translated using Weblate (Russian)
Currently translated at 98.1% (1875 of 1910 strings)
2026-03-09 19:09:48 +00:00
James Valleroy
4db977ff4e
Release v26.4.2 to unstable
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-08 15:28:08 -04:00
James Valleroy
448d5d84ed
Merge remote-tracking branch 'freedombox-team/main' 2026-03-08 15:26:43 -04:00
James Valleroy
41640f5d3c
Release v26.4.1 to unstable
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-08 15:10:35 -04:00
James Valleroy
5381990e02
doc: Fetch latest manual
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-08 15:09:08 -04:00
OwlGale
5a2e8ddc16
Translated using Weblate (Russian)
Currently translated at 97.9% (1870 of 1910 strings)
2026-03-08 19:48:32 +01:00
Jiří Podhorecký
4d6ddcdcdb
Translated using Weblate (Czech)
Currently translated at 100.0% (1910 of 1910 strings)
2026-03-08 19:48:32 +01:00
Sunil Mohan Adapa
97a2d68ac6
apache2: Disable pubtkt authentication module
- Since FreedomBox does not depend on the package anymore, unattended-upgrades
will remove the package. This causes Apache2 to fail to start. Disable the
module from Apache2 configuration.

Tests:

- Remove the libapache2-mod-auth-pubtkt package. Re-run apache app setup by
incrementing it version number. Apache will fail to start. Apply the patch and
increment the version number. auth_pubtkt module will be disabled and Apache is
automatically running again.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-08 14:41:14 -04:00
Sunil Mohan Adapa
6128d3be16
d/control: Trim deps for nocheck build profile (Closes: #1129521)
Closes: #1129521

Tests:

- Build package successfully with the following command: gbp buildpackage
--git-debian-branch=debian-nocheck-build-profile --git-pbuilder
--git-pbuilder-options="--profiles=nocheck

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-08 09:14:09 -04:00
James Valleroy
bce25f465f
Vagrantfile: Enable public network for bridged networking
When testing OpenID Connect, I found that it wasn't working in a VM
with NAT port forwarding. However, vagrant can use bridged networking
instead. When the vagrant box is brought up, the user will be prompted
for which network interface to bridge.

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-03-07 13:12:36 -08:00
James Valleroy
71913580db
container: Hold freedombox packages during test setup
Fixes: #2567

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-03-07 13:10:19 -08:00
Jiří Podhorecký
eb709f8687
Translated using Weblate (Czech)
Currently translated at 99.7% (1906 of 1910 strings)
2026-03-06 22:09:48 +01:00
Burak Yavuz
cfc5d3acab
Translated using Weblate (Turkish)
Currently translated at 100.0% (1910 of 1910 strings)
2026-03-04 06:09:53 +01:00
Besnik Bleta
212d865b43
Translated using Weblate (Albanian)
Currently translated at 99.5% (1902 of 1910 strings)
2026-03-04 06:09:51 +01:00
大王叫我来巡山
9a55902f37
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 61.0% (1167 of 1910 strings)
2026-03-04 06:09:48 +01:00
James Valleroy
07845bc960
apache: Fix check_url test
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 21:49:41 -05:00
James Valleroy
abbc4e7557
Release v26.4 to unstable
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 21:36:08 -05:00
James Valleroy
af70c73f24
doc: Fetch latest manual
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 21:35:03 -05:00
James Valleroy
5ccb332ce6
locale: Update translation strings
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 21:01:26 -05:00
Sunil Mohan Adapa
e2047ec3a0
apache: Fix diagnosing URLs protected by OpenID Connect
Tests:

- Clear out the directory /var/cache/apache2/mod_auth_openidc/metadata/. Then
run diagnostics on Calibre app without the patch. Several URLs fail because 404
has been returned on <domain>/calibre URL. With the patch the diagnostics
succeed.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:51:46 -05:00
Sunil Mohan Adapa
a7584b465d
sso: Merge into users module, drop pubtkt related code
Tests:

- 'make install' removes enabled sso module

- Already logged in users stay logged in after update

- Apps need to re-authenticate of update (but this is transparent)

- Login and logout work as expected

- Failed login attempts lead to CAPTCHA form

- CAPTCHA form can't be skipped

- Answering CAPTCHA form will lead back to login page

- Users functional tests work

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:51:41 -05:00
Sunil Mohan Adapa
6fd85e3e46
sharing: Use OpenID Connect instead of pubtkt based SSO
- Migrate old configuration file to new format.

Tests:

- Admin user is able to access a share.

- User belonging to a group allowed to access the share is able to access the
application.

- Regular user is not able to access the application.

- Anonymous user is not able to access the application.

- Setup is run after applying patches.

- Old shares are migrated from old style auth from authpubtkt to oidc. Name,
path, is_public, groups are presevered

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:51:39 -05:00
Sunil Mohan Adapa
31e7997d2b
doc/dev: Use OpenID Connect instead of pubtkt based SSO
Tests:

- The built documentation has been updated as expected.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:51:36 -05:00
Sunil Mohan Adapa
68126c3ec6
transmission: Use OpenID Connect instead of pubtkt based SSO
Tests:

- Functional tests work.

- Admin user is able to access the application

- User belonging to special group is able to access the application

- Regular user is not able to access the application

- Anonymous user is not able to access the application

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:51:34 -05:00
Sunil Mohan Adapa
29ef56b51e
wordpress: Use OpenID Connect instead of pubtkt based SSO when private
Tests:

- Functional tests work.

- Admin user is able to access the application

- User belonging to special group is able to access the application

- Regular user is not able to access the application

- Anonymous user is not able to access the application

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:51:32 -05:00
Sunil Mohan Adapa
efe2bccb11
tiddlywiki: Use OpenID Connect instead of pubtkt based SSO
Tests:

- Functional tests work.

- Admin user is able to access the application

- User belonging to special group is able to access the application

- Regular user is not able to access the application

- Anonymous user is not able to access the application

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:51:29 -05:00
Sunil Mohan Adapa
64272a2bef
gitweb: Use OpenID Connect instead of pubtkt based SSO
- Regression: Users who to don't have git-access permission can't access the
public repositories.

Tests:

- Functional tests work.

- Admin user is able to view and access the repos when there are some public
repos and when there no public repos.

- User belonging to git-access are regular usrs are unable to access private
repos. But they are also not able to access the public repos. They have to
logout to be able to do that.

- Anonymous user is not able to access the application if all repos are private.
If there is at least one public repo, the repo listing can be accessed and
public repos can be seen and accessed.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:51:27 -05:00
Sunil Mohan Adapa
af892adb5e
deluge: Use OpenID Connect instead of pubtkt based SSO
Tests:

- Functional tests work.

- Admin user is able to access the application

- User belonging to special group is able to access the application

- Regular user is not able to access the application

- Anonymous user is not able to access the application

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:51:25 -05:00
Sunil Mohan Adapa
4ab2007c99
calibre: Use OpenID Connect instead of pubtkt based SSO
Tests:

- Functional tests work.

- Admin user is able to access the application

- User belonging to special group is able to access the application

- Regular user is not able to access the application

- Anonymous user is not able to access the application

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:51:22 -05:00
Sunil Mohan Adapa
3c1d801e15
email: Use OpenID Connect instead of pubtkt based SSO
Tests:

- Functional tests work.

- Admin user is able to access the application

- Regular user is not able to access the application

- Anonymous user is not able to access the application

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:51:20 -05:00
Sunil Mohan Adapa
e2da29cf25
rssbridge: Use OpenID Connect instead of pubtkt based SSO
Tests:

- Functional tests work.

- Admin user is able to access the application

- User belonging to special group is able to access the application

- Regular user is not able to access the application

- Anonymous user is not able to access the application

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:51:18 -05:00
Sunil Mohan Adapa
ce62fdb142
searx: Use OpenID Connect instead of pubtkt based SSO
Tests:

- Application is not installable in stable and testing. It is not functional in
unstable.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:51:15 -05:00
Sunil Mohan Adapa
cad6bc8ca0
syncthing: Use OpenID Connect instead of pubtkt based SSO
Tests:

- Functional tests work.

- Admin user is able to access the application

- User belonging to special group is able to access the application

- Regular user is not able to access the application

- Anonymous user is not able to access the application

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:51:13 -05:00
Sunil Mohan Adapa
483f28de83
featherwiki: Use OpenID Connect instead of pubtkt based SSO
Tests:

- Functional tests work.

- Admin user is able to access the application

- User belonging to special group is able to access the application

- Regular user is not able to access the application

- Anonymous user is not able to access the application

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:51:10 -05:00
Sunil Mohan Adapa
64f1a1c918
apache: Implement protecting apps using OpenID Connect
- Use the excellent Apache module auth_openidc.

- Implement macros that can be easily used to configure OpenID Connect.

Tests:

- Accessing /freedombox/apache/discover-idp/ shows

  - 'method' other than 'get' throw a 'bad request' error

  - oidc_callback should match host. Otherwise 'bad request' error is raised.

  - Mismatched host header is not allowed

  - Invalid domain setup is not allowed

  - target_link_uri is returned as is

  - method is returned as is and only 'get' is allowed.

  - x_csrf is returned as is

  - oidc_scopes is returned as 'email freedombox_groups'

  - HTTP request is answered and not redirected to https

- When logging in with OIDC, authorization is skipped. When authorization is
shown, it is shown as 'Web app protected by FreedomBox'.

- libapache2-mod-auth-openidc is added a dependency for freedombox package. It
is installable in stable, testing, and unstable distributions.

- On applying patches, Apache setup configuration is run and OpenIDC component
is created.

- When patches are applied and setup install is run, auth_openidc module,
10-freedombox, freedombox-openidc config is enabled in Apache.

- When setup is rerun, passphrase is not changed

- metadata directory and parent are created when apache setup is run. Mode is
0o700 and ownership is www-data.

- freedombox-openidc is created when apache setup is run and has 0o700
permissions.

- Metadata directory will contain the client id and client passphrase when
discovery happens for a particular domain.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:51:06 -05:00
Sunil Mohan Adapa
cdfbff0b6b
oidc: Style the page for authorizing an OIDC app
Tests:

- Appearance is acceptable: top margin, width of the readable text, heading
centering, list top/bottom margins, SVG icon for application, md mode icon size,
submit button width, margins.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:51:00 -05:00
Sunil Mohan Adapa
45076cc603
oidc: New app to implement OpenID Connect Provider
- Add a component to easily manage registration of client applications.

Tests:

- Package build is successful has dependency on python3-django-auto-toolkit

- python3-django-oauth-toolkit can be installed on stable, testing and unstable
containers

- /.well-known/openid-configuration and /.well-known/jwks.json are servered
properly.

- /o/ URLs don't require login to access

- When logging in list of claims includes 'sub', email, freedombox_groups.

- Logging in using IP address works. Also works with a port.

- Logging in using 127.0.0.1 address works. Also works with a port.

- Logging in using localhost works. Also works with a port.

- Logging in with IPv6 address works. Also works with a port.

- Logging in with IPv6 [::1] address works. Also works with a port.

- Logging in with IPv6 link-local address with zone ID is not possible (as
browsers don't support them).

- When authorization page is enabled, scopes show description as expected.

- When domain name is added/removed, all OIDC components are updated with
expected domains

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:50:46 -05:00
Sunil Mohan Adapa
f0b1aa34ac
apache: Preserve host header when proxying to service
- This allows us to perform some checks before redirecting for OpenID Connect.

Tests:

- Functional tests of many apps pass with the patch.

- OIDC related changes introduced later work due to this change.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:50:43 -05:00
Sunil Mohan Adapa
bced133d90
templates: Allow building pages without navigation bar and footer
Tests:

- Functional tests of many apps pass with the patch.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:50:41 -05:00
Sunil Mohan Adapa
a8e2d4cd69
web_framework: Allow FreedomBox apps to override templates
Tests:

- Functional tests of many apps pass with this change.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:50:38 -05:00
Sunil Mohan Adapa
bbbe2cf950
tests: functional: Fix expecting FreedomBox to be home page
In some cases, we are visiting / and expecting to reach the home page of
FreedomBox UI. When due to failed tests in config app, the home page is set to
something other than FreedomBox UI, these tests fail. Fix this by visiting
/freedombox explicitly instead.

Tests:

- When hope page is set to Syncthing, kiwix functional tests pass.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:50:36 -05:00
Sunil Mohan Adapa
168f662a17
*: Update URL base from /plinth to /freedombox
- Since we are going to be an OpenID Provider, we need to fix the URLs that
other apps will be configured with for authentication. So change now from
/plinth to /freedombox. If done later, it will be harder since all the
configuration files for all dependent apps will need to be updated.

Tests:

- App availability checking works. Request goes to /freedombox URL

- Favicon is served properly and through /favicon.ico URL

- Redirection happens from / to /freedombox directly

- UI is available on /freedombox and on /plinth

- Manual page show /freedombox as the URL in two places

- Static files are successfully served from /freedombox URLs. URLs inside page
start with /freedombox

- backup, bepasty, calibre, config, dynamicdns, ejabberd, featherwiki, gitweb,
ikiwiki, kiwix, miniflux, names, openvpn, shadowsocks, shadowsocksserver,
sharing, shapshot, tiddlywiki, users, wireguard, jsxc, matrixsynapse, first
wizard, storage, samba, tags functional tests work. Backup/restore test for
matrixsynapse fails due to an unrelated bug (server not restarted after
restore).

- Setting the home page works:

  - Having /plinth in the home page configuration works. Shows selection
    correctly.

  - Setting to app works. Shows selection correctly.

  - Setting to user home page (sets /freedombox). Shows selection correctly.

  - Setting to apache default works. Shows selection correctly.

  - Changing back to FreedomBox service works. Shows selection correctly.

- Unit tests work

- Configuration page shows /freedombox in description but not /plinth

- Diagnostics show /freedombox in tests

- Roundcube URL link in email app has /freedombox

- email loads the page /.well-known/autoconfig/mail/config-v1.1.xml correctly

- email app shows /freedombox/apps/roundcube for /roundcube if roundcube is not
installed.

- networks: router configuration page shows URL starting with /freedombox.

- snapshot: Shows URL starting with /freedombox on the app page

- js licenses page uses /freedombox prefix for JSXC.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:50:30 -05:00
Sunil Mohan Adapa
0d579012d7
web_server: Log requests to WSGI app
- This is quite useful for debugging even on production machines.

- CherryPy can't be used for logging as grafting a WSGI application bypasses the
usual mechanisms of logging.

- Keep requests for static files turned off in CherryPy as these are not very
useful.

Tests:

- Making a request print an INFO message on the log with method and path after
the /freedombox part. Logs can be seen in systemd journal.

- Requests for static files are not logged.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:50:28 -05:00
Sunil Mohan Adapa
854916c54c
syncthing: tests: Fix tests by allowing rapid restarts
Tests:

- Functional tests for syncthing pass.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:50:25 -05:00
Sunil Mohan Adapa
fde0a620f9
debian: Ensure that gbp creates a clean tarball prior to build
- Without the --git-export-dir option, gbp builds from the current directory
which contains .container and many other large files. All of these files will
get included into the tarball by default when 'gbp buildpackage' is executed in
an unclean folder.

- With the --git-export-dir option set, 'git export' is first executed to a
temporary directory and this git operation respects patterns in .gitignore. Thus
only expected files end up in the freedombox package source tarball.

Tests:

- When the source directory contains files in ./container, running 'gbp
buildpackage' results in freedombox*.tar.xz containing the disk images of the
containers.  With this change, the tarball is clean and none of the files in
.gitignore endup in the tarball.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:50:23 -05:00
Sunil Mohan Adapa
185559b43f
action_utils: Drop support for link-local IPv6 addresses
Tests:

- Diagnostics page for Calibre app does not show a test for link-local IPv6
address anymore.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:50:20 -05:00
Sunil Mohan Adapa
82d7cd0e8f
pyproject: Use new format to specify licenses
See:
https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license

This eliminates the following warning messages when building the package:

********************************************************************************
Please use a simple string containing a SPDX expression for `project.license`.
You can also use `project.license-files`. (Both options available on
setuptools>=77.0.0).

By 2026-Feb-18, you need to update your project and remove deprecated calls
or your builds will no longer be supported.

See
https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license
for details.
********************************************************************************

Tests:

- Debian package can be built successfully. Two fewer warning during python
package build step were noticed.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:50:17 -05:00
Sunil Mohan Adapa
0eca1394c0
Vagrantfile: Drop unnecessary sudo configuration for actions
- Actions have been completed removed due to implementation of privileged
daemon.

Tests:

- None

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:50:14 -05:00
Sunil Mohan Adapa
4371e2475d
cfg: Drop unused actions_dir option
Tests:

- Unit tests pass

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:50:11 -05:00
Sunil Mohan Adapa
a7ec37dbce
cfg: Drop unused config_dir option
Tests:

- Unit tests pass.

- When file /usr/share/freedombox/freedombox.conf is created, we can see log
message 'Configuration loaded from file - /usr/share/freedombox/freedombox.conf'

- When running in develop mode, we can see log message 'Configuration loaded
from file - /freedombox/plinth/develop.conf'

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:50:08 -05:00
Sunil Mohan Adapa
778c35f2bc
matrixsynapse: Update apache config to proxy Synapse client API
- Use the recommended configuration from Matrix Synapse documentation.

  - Preserve Host: header.

  - Set the X-Forwarded-Proto header.

  - Don't decode encoded slashes in the URLs during proxying.

- Also proxy Synapse client API.

Tests:

- Web app at app.element.io is able to connect to a local server using browser.
Two client can chat with each other.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:50:04 -05:00
Sunil Mohan Adapa
bf83cb5a5b
*: Remove some absolute file paths in SVGs
- They are not useful.

Tests:

- All the modified SVG files load and show as expected.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:50:01 -05:00
Sunil Mohan Adapa
284a384d3a
README/HACKING: Update weblate project path to /freedombox
Tests:

- The news links work.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 20:49:56 -05:00
Frederico Gomes
af6d1d9a4c
miniflux: Get credentials from dbconfig-common directly
Fixes: #2562

Newer miniflux package does not create a separate file called
/etc/miniflux/database. Instead it write the database URL directly into
/etc/miniflux/miniflux.conf. It is easier to create the database settings from
dbconfig-common that to read them from miniflux.conf.

Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-03-02 12:56:24 -08:00
Frederico Gomes
9a524b331b
db: Create a utility to get credentials from dbconfig
Create helper function that uses Augeas Shellvars to parse dbconfig-common
files.

Signed-off-by: Frederico Gomes fredericojfgomes@gmail.com
[sunil: Fix quotes not getting removed from values]
[sunil: Add test case]
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-03-02 12:55:54 -08:00
Frederico Gomes
72005d6205
miniflux: Revert workaround for a packaging bug with DB connection
This reverts commit 9af9a504e09b8021041a7d8fe4540574f42edc1c.

This workaround is no longer needed as the file is no longer used.
Reverted as per:
https://salsa.debian.org/freedombox-team/freedombox/-/merge_requests/2752#note_728315

**plinth/modules/miniflux/__init__.py**

- Keep version bump

**plinth/modules/miniflux/privileged.py**

- Keep docstring fix

Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-03-02 12:54:39 -08:00
Sunil Mohan Adapa
4b24fda3f5
wireguard: Accept/use netmask with IP address for server connection
- Currently, the value is hard-coded as /24. Instead take this as input and use
that value.

Tests:

- Entering invalid IPv4 address results in 'Enter a valid IPv4 address' error
message during form submission.

- Entering invalid prefix such as /33 results in 'Enter a valid network prefix
or net mask.' error during form submission.

- Both /32 and /255.255.255.255 formats are accepted.

- The description text for the form field 'IP address' is as expected.

- Changing the value of default route and IP address + netmask reflects in the
status page. Correct values is shown in the edit server and server status page.

- Not providing a netmask results in /32 being assigned.

- Unit and functional tests for wireguard pass. There are some intermittent
failures with functional tests that are unrelated to the patch.

- Setting the /32 prefix results in correct routing table as shown by 'ip route
show table all'. No default routes are network routes are present. 'traceroute
1.1.1.1' shows route taken via regular network.

- Setting the /24 prefix results in correct routing table. No default routes are
present. However, for the /24 network a route is present with device wg1.
'traceroute 1.1.1.1' shows route taken via regular network.

- Enabling the default route results in correct routing table. Default route is
shown for device wg1 with high priority. 'traceroute 1.1.1.1' shows route taken
via WireGuard network.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 15:22:36 -05:00
Sunil Mohan Adapa
ad9ebe2301
wireguard: Show status of default route in server information page
Tests:

- Create a server connection with default route setting 'on'. See that the
server status page reflects the value correctly. Repeat for 'off'.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 15:22:33 -05:00
Sunil Mohan Adapa
7e7e7a6ccf
wireguard: Fix showing default route setting in server edit form
- The default route is not decided by the subnet on the IP address assigned. It
is to be decided using the list of allowed peers in the wireguard settings.

Tests:

- Set the default route setting to 'on' while creating the connection. In the
edit server page, the value is shown correctly. Repeat with 'off' value.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 15:22:29 -05:00
Sunil Mohan Adapa
643a06c7cd
wireguard: Fix format when showing multiple endpoints of the server
- Show them in multiple lines using <pre> like before.

Tests:

- Multiple endpoints are shown in the one line each using <pre> tag.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 15:22:26 -05:00
Sunil Mohan Adapa
8a7e70aab2
gitweb: Fix issue with running post init due to missing method
Fixes: #2563.

Also see
https://salsa.debian.org/freedombox-team/freedombox/-/merge_requests/2740

Test:

- Functional tests for gitweb pass.

- Without the patch, install gitweb and enable it. Restart FreedomBox service.
The error message in #2563 is reproduced. With the patch, the error disappears.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-03-02 14:58:16 -05:00
James Valleroy
11d58134e5
Translated using Weblate (Tamil)
Currently translated at 100.0% (1885 of 1885 strings)
2026-03-02 20:53:52 +01:00
தமிழ்நேரம்
bc257af638
Translated using Weblate (Tamil)
Currently translated at 100.0% (1885 of 1885 strings)
2026-03-02 17:10:01 +01:00
Sunil Mohan Adapa
6ba35df665
ejabberd: Fix setting up certificates for multiple domains
Fixes: #2566.

Thanks to joeDoe for helping with identifying the bug and confirming a fix.

- Currently, when multiple domains are configured, only one certificate is
setup. One domains properly and other domains will end up using the certificate
for the configured domain. This leads to domain validation errors on the
client-side.

- Copy certificates for all domains to /etc/ejabberd/letsencrypt directory
whether they are configured for ejabberd or not.

- Use the new certfiles: directive to provide multiple certificates. Don't use
and remove the old s2s_certfile: directive. Migrate old configuration.

Tests:

- Functional tests for ejabberd work.

- Installing ejabberd freshly works. s2s_certfile: is not present in the
configuration file. certfiles: is present with wildcard for LE certs.

- Install ejabberd without the patch. s2s_certfile: is present and certfiles:
does not contain the wildcard for LE certificates. Apply the patch. Setup is
re-run for ejabberd app and succeeds. s2s_certfile: is removed from
configuration file. certfiles: contains wildcard for LE certificates.
/etc/ejabberd/letsencrypt/ contains certificates for all the configured domains
on the system.

- Adding domain works. Certificate for newly configured domain is copied into
the ejabberd LE cert directory. ejabberd daemon is reloaded. hosts: list is updated.

- Removing domain works. Certificate for the old domain is retained in the
ejabberd LE directory. ejabberd daemon is not reloaded.

- Setting the list of domains works. Old certificates are retained in the
ejabberd LE directory. ejabberd daemon is reloaded. hosts: list is updated.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-02-28 13:25:00 -05:00
Sunil Mohan Adapa
e4ee756918
bin: Add tool to change FreedomBox password in Django database
Tests:

- Run 'make build install'. The new binary is available as
/usr/bin/freedombox-change-password. Running 'freedombox-change-password
tester2' works as expected.

- Providing wrong username show proper error message.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-02-28 07:48:48 -05:00
Sunil Mohan Adapa
7f2b49f70c
locale/bg: Fix several translations with HTML links (Bulgarian)
The HTML attributes of the translation must be the same as English string. Newly
inserted characters lead to 404 page not found errors.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-27 08:38:30 -08:00
Sunil Mohan Adapa
36fb92a953
locale/de: Fix several translations with HTML links (German)
Fixes: #2560.

The HTML attributes of the translation must be the same as English string. Newly
inserted characters lead to 404 page not found errors.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-27 08:33:14 -08:00
Frederico Gomes
57816029e5
wireguard: Fix split tunneling
- Currently, when adding a server, we have an option for 'default route' but
unchecking it does not work. This is due to allowed_peers always containing
::0/0 and 0.0.0.0/0. Fix this by setting the allowed_peers to a value containing
only the IP of the WireGuard network.

Tests:

- When default routing it checked, routing table shows default route for
wireguard device. Traceroute confirms routing through WireGuard network.

- When default routing it unchecked, routing table does not show default route
for wireguard device. Traceroute confirms routing through regular network.

Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-26 23:06:30 -08:00
Sunil Mohan Adapa
3be73bad59
tests: functional: Fix reloading error page during install/uninstall
- When an error page is shown during installation/uninstallation, no automatic
refresh of the page happens. Fix this by reloading the page when error is shown.

- When error page is shown, the document.readyState is "interactive" (meaning
that page load is completed but other resources such as images are being
loaded). So, checking for error page is never happening.

- Also when reloading an error page, WebDriverException may happen so use the
wait_for_page_update() utility to perform the page reloads.

Tests:

- Run functional tests for bepasty. When installing the app, stop apache web
server. Let an error page be shown. Then start the server again. Without the
patch, the error page is never reloaded. With the patch, the error page is
reloaded and tests succeed.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-02-25 17:51:11 -05:00
Sunil Mohan Adapa
5e112bd8bf
js: When page load fails during install, show it to user
- Currently when HTMX tries to fetch a page and fails, it silently fails and
does not perform any further operations. So, the installation page is stuck.
This is also leading to functional test case failures.

- Handle errors in page response and errors while making requests and reload the
entire page. This will result in browser showing appropriate error page. User
will understand that the operation has failed.

- Also add HTMX event listeners on the body as shown in HTMX documentation.

Tests:

- Press install. After installation process has started, stop Apache web server.
Without the patch, HTMX fails silently and the installation progress is shown
indefinitely.

- With the patch applied, the connection error page is properly shown.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-02-25 17:51:08 -05:00
Sunil Mohan Adapa
68ccb46ecf
tests: functional: Increase systemd rate limits for starting units
- If functional tests run fast, daemon will be stopped and started many times.
This is hitting rate limit for some daemons.

Tests:

- Configuration file is created as expected. systemd read the value as shown by
'systemctl show'.

- Mumble functional tests pass without having to insert sleeps.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-24 12:52:13 -08:00
James Valleroy
2044fa3e84
mumble: murmurd renamed to mumble-server
- Update backup manifest config file location.

Fixes #2518

Tests:

- mumble functional tests are passed.

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-24 12:28:16 -08:00
Sunil Mohan Adapa
bc4730c33c
action_utils: Fix issue with type checking a generator
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-24 10:58:00 -08:00
Sunil Mohan Adapa
365c1c3484
doc/dev: Set new theme for developer documentation
- Change theme to 'Book' based on Sphinx pydata theme. It supports dark/light
modes. Looks more modern and better defaults/options.

- Add logo on the top left corner.

- Add menu to go to repository, view page source, edit page source, and report
issue on current page.

- Don't repeat 'FreedomBox Authors' in authors text and copyright text. Show
only once as suggested by the theme.

- Use theme option to show license link instead of overriding the template.

Tests:

- After building the theme, all options work as expected.

- Footer appears as expected.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-23 13:41:54 -08:00
Benedek Nagy
32fae4c3d3
doc/dev: always have an up-to-date copyright year
Signed-off-by: Benedek Nagy <contact@nbenedek.me>
2026-02-22 17:11:36 -08:00
Sunil Mohan Adapa
9a16e20fa9
letsencrypt: When copying certificate reset the umask reliably
- When there is an error writing to certificate files, the umask is not reset
properly. Fix this my using umask context manager from action utils. This could
be core reason behind: #2564.

Tests:

- Changing the domain name creates the file /var/lib/quassel/quasselCert.pem
with the proper permissions of 0o600. If in Quassel app's Let's Encrypt component
the certificate file path is changed, then two files are created on domain name
change. Private key is created with 0o600 permissions and certificate file is
created with 0o644 permissions.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-02-22 14:17:51 -05:00
Sunil Mohan Adapa
03b4a78fd0
quassel: Explicitly set permissions on the domain configuration file
Closes: #2564

Tests:

- Changing the domain name in quassel app page set the expected file
permissions. Changing the value in the code results in file getting created with
changed permissions.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-02-22 14:17:47 -05:00
Sunil Mohan Adapa
ac83de6635
action_utils: Implement utility to change umask temporarily
- When we set umask we typically want to change it back to original value after
the operation. Implement a context manager to help with this.

Tests:

- Unit tests pass.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-02-22 14:17:44 -05:00
James Valleroy
b1177a82f8
Translated using Weblate (Greek)
Currently translated at 46.1% (869 of 1885 strings)
2026-02-22 14:17:00 +01:00
Βασίλης Χατζηκαμάρης
77112e9faf
Translated using Weblate (Greek)
Currently translated at 45.5% (858 of 1885 strings)
2026-02-18 15:09:50 +00:00
Coucouf
d9f20b205b
Translated using Weblate (French)
Currently translated at 100.0% (1885 of 1885 strings)
2026-02-18 15:09:48 +00:00
Daniel Wiik
c0bd1c8280
Translated using Weblate (Swedish)
Currently translated at 100.0% (1885 of 1885 strings)
2026-02-16 13:09:55 +01:00
Frederico Gomes
f0a36f11ba
wireguard: show server vpn ip in show client page
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-02-15 10:00:00 -05:00
Frederico Gomes
b18c37a5f6
wireguard: improved server section UX flow
Originally aimed to show server info (public key, endpoints) in a table.

Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
[jvalleroy: Remove trailing spaces]
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-02-15 09:38:40 -05:00
Isak
ccf5231569
Translated using Weblate (Swedish)
Currently translated at 80.0% (1508 of 1885 strings)
2026-02-15 05:09:45 +01:00
Jiří Podhorecký
020ef6ae0c
Translated using Weblate (Czech)
Currently translated at 100.0% (1885 of 1885 strings)
2026-02-09 20:09:44 +01:00
kosagi
cc8fa47efe
Translated using Weblate (Catalan)
Currently translated at 55.2% (1042 of 1885 strings)
2026-02-07 00:02:02 +01:00
Daniel Wiik
59c3b49d8b
Translated using Weblate (Swedish)
Currently translated at 79.9% (1507 of 1885 strings)
2026-02-07 00:01:55 +01:00
Pierfrancesco Passerini
a4cfb824e8
Translated using Weblate (Italian)
Currently translated at 100.0% (1885 of 1885 strings)
2026-02-07 00:01:50 +01:00
Frederico Gomes
59329169e4
wireguard: filter .local addresses from showClient view
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-06 12:50:05 -08:00
Sunil Mohan Adapa
df7793916c
backups: Fix type checking errors
- Use the passed in argument for copy_ssh_client_public_key instead of
overwriting it.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-06 11:39:04 -08:00
Frederico Gomes
0c8cba3a13
container: Align terminology with !2731 in printed banner
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-06 08:16:53 -08:00
Sunil Mohan Adapa
5da5ef5f96
backups: Create a better comment in the generated SSH key file
Tests:

- When /var/lib/plinth/.ssh is deleted and add remote repository form is
visited, the directory along with SSH key files are created. The .pub file has
the expected comment freedombox@configured_domain.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-05 22:33:49 -08:00
Sunil Mohan Adapa
4ae66c034c
backups: Fix showing proper error for incorrect passphrase
Tests:

- Provide incorrect passphrase when adding a remote repository. Should show a
message that passphrase is incorrect and redirect back to add remote repository
form.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-05 22:33:46 -08:00
Sunil Mohan Adapa
e21ab91b21
backups: Create .ssh folder before creating SSH key
- As a safe guard although it should exist because of a prior verification of
SSH key.

- Minor refactor to make the method flatter.

Tests:

- Remove /var/lib/plinth/.ssh and visit add remote repository form. The public
key is displayed in the form. The files in /var/lib/plinth/.ssh are created with
expected permissions.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-05 22:33:42 -08:00
Sunil Mohan Adapa
dd0a0f56a6
backups: Simplify handling of migration to SSH keys
- Integrate SSH error handling into borg error handling.

- Move logic to migrate SSH keys into lower levels (Repository class) so that it
can performed at more instances such as when initializing repository. It also
provides better abstraction keeping the view logic simpler.

- Drop ability to mount repository using password. This is important next step
for mounting using systemd unit files.

- Use exceptions to eliminate return value checking.

- Create a special exception for exceptions raised during SSH operations. Raise
this at lower levels and handle these using the common error handler.

Tests:

- Adding a remote repository with key and password authentication works with and
without encryption. Adding works with SSH host key pre-verified works too.

- Trying to add a remote repository with incorrect passpharse fails with the
simplified error message. Redirect happens to add remote repository page. Error
message with SSH host key pre-verified works too. Repository is removed.

- Trying to provide wrong SSH password fails with a simplified error message.
Redirect happens to add remote repository page. Repository is removed.

- Mounting a repository after unmounting it works.

- Mounting a repository with SSH password in its configuration works. Migration
is performed and SSH password is replaced with SSH key file path.

- A schedule for a repository with SSH password runs successfully. An archive is
created. Migration is performed and SSH password is replaced with SSH key file
path.

- SSH identity files are created with plinth:plinth ownership. Private key file
is created with 0o600 permissions and public key file is created with 0o644
permissions.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-05 22:33:39 -08:00
Sunil Mohan Adapa
a7ef60015c
backups: Minor refactoring
Tests:

- Adding a remote repository with key and password authentication works with and
without encryption.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-05 22:33:36 -08:00
Sunil Mohan Adapa
2208a7b210
backups: tests: Simplify functional test using more classes
- This makes the functional test focus more on the repository that is added
rather than all remote repositories.

Tests:

- Functional tests for backups app works.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-05 22:33:33 -08:00
Sunil Mohan Adapa
ff7c3a53a5
backups: Tweak appearance of add remote location form
- Use bootstrapform templates where possible to reduce code.

- Fix incorrect tag for radio button for password authentication.

- Drop borders and instead:

  - Style each group as a section. This includes encryption section and
  repository path section.

  - Utilize the simplicity as passwords fields are not displayed.

- Retain <label> tag so that clicking on it works and it also easier for
accessibility tools.

Tests:

- The option for password authentication works are expected. The fields for
encryption passphrase, ssh password work as before.

- Clicking on form labels focuses the form element.

- Adding a repository with key and password authentication works with and
without encryption.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-05 22:33:30 -08:00
Sunil Mohan Adapa
7d3d930137
backups: Show/hide form elements instead of disabling for simplicity
- Unlike the case of network forms, for example, there is nothing the user could
infer from a disabled form element. If they see a disabled DNS field, they would
understand that it is an editable value but has been disabled due to other
option values. It is important to allow users to discover this. However, in case
of password fields, they are not needed to be shown to the user unless the
appropriate option is selected.

Tests:

- In the add remote repository form, selecting the authentication type radio
options shows and hides the password field. Selecting the value for encryption
type shows and hides the encryption password field.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-05 22:33:26 -08:00
Sunil Mohan Adapa
ad40072267
backups: Fix issue with Javascript in add remote location form
Tests:

- In remote repository add form, selecting radio options for authentication
types does not throw an error. The password field is shown/hidden as expected.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-05 22:33:23 -08:00
Sunil Mohan Adapa
305b1f01f5
backups: Avoid some repeated text in form help text
Tests:

- The remote repository add form shows form elements are updated as expected.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-05 22:33:20 -08:00
Sunil Mohan Adapa
58ecf9d3e4
actions, privileged_daemon: Drop some unused global statements
Tests:

- Make a privileged method throw and exception after spewing output to stdout
and stderr. The exception caught on the service daemon contains the expected
stdout and stderr messages.

- Sending SIGTERM to privileged daemon shuts down the daemon.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-05 22:33:17 -08:00
James Valleroy
3cb5d1a936
backups: Migrate to SSH key auth when mounting
Tests:

- On main branch, add a remote repository with SSH password. Unmount
  the remote location.

- Switch to branch with this change. Mount the remote location. Logs
  show that it is migrated from password to key authentication. Plinth
  database no longer contains password for this remote.

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-02-05 22:33:14 -08:00
James Valleroy
8b9413c719
backups: Arrange form for adding remote location
- Group together related fields with borders.

- Display errors on form and fields.

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-02-05 22:33:11 -08:00
James Valleroy
451e582c07
backups: Test adding/removing remote location
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-02-05 22:33:07 -08:00
James Valleroy
043bd44dec
backups: Use selected SSH credential for remote
- Use javascript to disable or enable password fields.

- If SSH key auth is selected, then try the connection.

- If SSH password auth is selected, then copy the key.

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-02-05 22:33:04 -08:00
James Valleroy
3558a26b2f
backups: Use SSH key instead of password
- After copying the SSH client public key to the remote host, replace
  the SSH password credential with keyfile.

- Also use SSH key when checking that remote directory exists.

Tests:

- Add remote backup location "tester@localhost:~backups". Test various
  operations like create backup, download backup, unmount and
  mount. Confirm that SSH password is no longer present in plinth
  sqlite database.

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-02-05 22:33:01 -08:00
James Valleroy
f689e1b3cf
backups: Copy SSH client public key to remote
Tests:

- In development VM, add a remote backup location of "tester@localhost:~/backups".
  Verify the SSH host key. plinth@freedombox key is listed in
  /home/tester/.ssh/authorized_keys.

- Remove the remote backup location, and delete /home/tester/.ssh/authorized_keys.
  Add the same remote backup location again. plinth@freedombox key is again
  listed in /home/tester/.ssh/authorized_keys.

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-02-05 22:32:58 -08:00
James Valleroy
7fb41313cd
backups: Display SSH public key when adding remote
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-02-05 22:32:55 -08:00
James Valleroy
156d0b761f
backups: Generate SSH client key if needed
Tests:

- Click on Add Remote Backup Location. Logs show that SSH client key is
  generated. The private key is readable only by plinth user.

- Go back, and click on Add Remote Backup Location again. Logs show that SSH
  client key already exists.

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-02-05 22:32:52 -08:00
Dietmar
33d05ef5be
Translated using Weblate (German)
Currently translated at 99.2% (1870 of 1885 strings)
2026-02-05 11:01:51 +00:00
Besnik Bleta
a1bd01f0c1
Translated using Weblate (Albanian)
Currently translated at 99.6% (1879 of 1885 strings)
2026-02-04 07:01:54 +01:00
Coucouf
ea4172a4c2
Translated using Weblate (French)
Currently translated at 100.0% (1885 of 1885 strings)
2026-02-04 07:01:52 +01:00
Burak Yavuz
0ee977a6b0
Translated using Weblate (Turkish)
Currently translated at 100.0% (1885 of 1885 strings)
2026-02-04 07:01:51 +01:00
大王叫我来巡山
6b7e518eed
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 61.3% (1157 of 1885 strings)
2026-02-04 07:01:49 +01:00
Sunil Mohan Adapa
196fcea328
ui: Add animation for notification dismissal
Tests:

- When a notification dismiss button is clicked, first it fades and collapses
at the same time.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Joseph Nuthalapati <njoseph@riseup.net>
2026-02-04 08:41:37 +05:30
Sunil Mohan Adapa
e37d26abee
ui: Refactor notification delete buttons to avoid repeating code
Tests:

- Through code changes, ensure that dist upgrade notification, updated to new
release notification, privacy notification, and app installed notification show
up. Ensure that they have correct hx- attributes and URL property for dismiss
button. Clicking dismiss button works as expected.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Joseph Nuthalapati <njoseph@riseup.net>
2026-02-04 08:40:43 +05:30
Joseph Nuthalapati
13a575017c
ui: Dismiss notifications without page reload
- Delete only the <li> of the notification using HTMX.
- Notifications list stays open. User can dismiss another notification.
- Decrement notification counter using JavaScript after removing
  notification from the list.
- Added HTMX to every kind of notification.
- Tested dismissing notifications from the top, middle and bottom of the
  list.

Signed-off-by: Joseph Nuthalapati <njoseph@riseup.net>
[sunil: Update comment format in .js file]
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-03 14:16:55 -08:00
James Valleroy
4e668c8a98
Release v26.3 to unstable
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-02-02 20:42:43 -05:00
James Valleroy
367b2d9f79
doc: Fetch latest manual
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-02-02 20:41:02 -05:00
James Valleroy
7eac69a1f8
locale: Update translation strings
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-02-02 20:14:26 -05:00
大王叫我来巡山
d0a73142ac
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 61.4% (1155 of 1880 strings)
2026-02-03 02:07:19 +01:00
Pierfrancesco Passerini
48929b9d75
Translated using Weblate (Italian)
Currently translated at 100.0% (1880 of 1880 strings)
2026-02-03 02:07:18 +01:00
Burak Yavuz
f5e487569f
Translated using Weblate (Turkish)
Currently translated at 100.0% (1880 of 1880 strings)
2026-02-03 02:07:18 +01:00
Sunil Mohan Adapa
04ba96a467
ui: Use HTMX to update notifications on partial page updates
Tests:

- When app install button is clicked, the new page shows that app is being
installed. However, when app installation is complete, the notification still
shows that app is being installed. With the patch, the issues is resolved.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-02 14:38:11 -08:00
Joseph Nuthalapati
01cafafcda
ui: Use HTMX to eliminate full page reloads
HTMX implementation is limited to HTML and JS files. No changes to Python files.

Signed-off-by: Joseph Nuthalapati <njoseph@riseup.net>
2026-02-02 13:49:51 -08:00
Joseph Nuthalapati
3c5f81ab8c
ui: Add HTMX as a dependency
Signed-off-by: Joseph Nuthalapati <njoseph@riseup.net>
[sunil: Sort dependency in list]
[sunil: Adjust spacing]
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-02 13:43:15 -08:00
Frederico Gomes
57f5105fd0
wireguard: show server endpoint on main app page
Display the WireGuard server endpoint (ip_address:listen_port)
alongside the public key on the main WireGuard page,
so users configuring clients can copy both values directly.

Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
[sunil: Keep the docstring]
[sunil: Adjust markup to eliminate <p> inside <p>]
[sunil: Produce a single <pre> tag instead of multiple for multiple domains]
[sunil: Minor refactoring for more concise code]
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-02-02 13:07:53 -08:00
Sunil Mohan Adapa
f4b1eb23ac
wireguard: Remove NM connections when app is uninstalled
Tests:

- Install WireGuard and start the server. Uninstall the app and re-install.
Without the patch, the connection remain after uninstall. With the patch, the
connections are removed after uninstall and return to pristine state after
re-install.

- Functional tests succeed.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2026-02-01 08:37:18 -05:00
Frederico Gomes
b0a841c63a
wireguard: Show next available client IP in Add Client form
Display the next available IP address that will be
automatically assigned when adding a new client.

Helps admins know what client IP to provide when configuring client
connections back to this server.

Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
[sunil: Turn the IP address styling into a form element]
[sunil: Update the comment style for consistency]
[sunil: Update the label for clarity]
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-01-28 13:05:51 -08:00
Sunil Mohan Adapa
0fa77cbe30
debian: Ignore lintian warning: service file missing Install section
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-01-26 12:27:46 -08:00
James Valleroy
7988cc737b
debian: Update copyright years
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-01-26 12:27:43 -08:00
James Valleroy
2bb2eaa6ec
debian: Remove preinst script
- freedombox 20.7 and 20.9 are considered ancient versions.

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-01-26 12:27:39 -08:00
James Valleroy
c19d2ab692
debian: Remove default Rules-Requires-Root
- As of dpkg version 1.22.13, this field is set to "no" by default.

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-01-26 12:27:36 -08:00
James Valleroy
01da6934be
debian: Follows policy 4.7.3
- Priority is now optional by default.

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-01-26 12:27:33 -08:00
James Valleroy
6960a57779
Makefile: Fix removing extra license file
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-01-26 12:27:30 -08:00
James Valleroy
2237d89745
lintian: Remove mismatched overrides
- The original lintian messages no longer appear.

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-01-26 12:27:27 -08:00
Ettore Atalan
e3b893277c
Translated using Weblate (German)
Currently translated at 99.2% (1865 of 1880 strings)
2026-01-25 15:02:39 +01:00
Frederico Gomes
6bf95de3bc
docs: update container script usage
Container usage docs have been updated to be in line with
merged request !2731.

Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-01-23 11:28:30 -08:00
James Valleroy
0614b5e509
wireguard: Update functional tests to handle Start Server button
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-01-21 20:47:21 -05:00
Frederico Gomes
53f7c75d8e
wireguard: add 'Start Server' button with confirmation page
Adds explicit UI flow to generate server keypair and interface.

- New EnableServerView
- Conditional 'Start Server' button on main page when no wg0
- Button switches to 'Add Client' after server setup

Solves circular dependency UX issue when connecting two FBs

EDIT: Following review feedback, I removed the intermediate
confirmation page.
The “Start WireGuard Server” button now sends a POST
directly from the main page.

Signed-off-by: Frederico Gomes <fredericojfgomes@gmail.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
[jvalleroy: Change from TemplateView to View]
[jvalleroy: Remove redundant import]
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2026-01-21 20:19:46 -05:00
497 changed files with 58453 additions and 41975 deletions

View File

@ -1,16 +0,0 @@
#!/usr/bin/python3
# -*- mode: python -*-
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Set required permissions for user "plinth" to run plinth in dev setup."""
import pathlib
content = '''
Cmnd_Alias FREEDOMBOX_ACTION_DEV = /usr/share/plinth/actions/actions, /freedombox/actions/actions
Defaults!FREEDOMBOX_ACTION_DEV closefrom_override
plinth ALL=(ALL:ALL) NOPASSWD:SETENV : FREEDOMBOX_ACTION_DEV
fbx ALL=(ALL:ALL) NOPASSWD : ALL
'''
sudoers_file = pathlib.Path('/etc/sudoers.d/01-freedombox-development')
sudoers_file.write_text(content)

View File

@ -66,7 +66,7 @@ development environment inside a systemd-nspawn container.
folder: (This step requires at least 16GB of free disk space) folder: (This step requires at least 16GB of free disk space)
```bash ```bash
host$ ./container up host$ ./container start
``` ```
1. To run unit tests: 1. To run unit tests:
@ -97,20 +97,20 @@ development environment inside a systemd-nspawn container.
1. Using an environment variable. 1. Using an environment variable.
```bash ```bash
host$ DISTRIBUTION=stable ./container up host$ DISTRIBUTION=stable ./container start
host$ DISTRIBUTION=stable ./container ssh host$ DISTRIBUTION=stable ./container ssh
``` ```
```bash ```bash
host$ export DISTRIBUTION=stable host$ export DISTRIBUTION=stable
host$ ./container up host$ ./container start
host$ ./container ssh host$ ./container ssh
``` ```
2. Using the `--distribution` option for each command. 2. Using the `--distribution` option for each command.
```bash ```bash
host$ ./container up --distribution=stable host$ ./container start --distribution=stable
host$ ./container ssh --distribution=stable host$ ./container ssh --distribution=stable
``` ```
@ -131,7 +131,7 @@ used simultaneously as they all use different disk images.
example, to bring up a virtual machine instead of a container run: example, to bring up a virtual machine instead of a container run:
```bash ```bash
host$ ./container up --machine-type=vm host$ ./container start --machine-type=vm
``` ```
#### Using after Setup #### Using after Setup
@ -164,9 +164,9 @@ Note: This development container has automatic upgrades disabled by default.
#### Troubleshooting #### Troubleshooting
* Sometimes `host$ ./container destroy && ./container up` doesn't work. In such * Sometimes `host$ ./container destroy && ./container start` doesn't work. In such
cases, try to delete the hidden `.container` folder and then `host$ cases, try to delete the hidden `.container` folder and then `host$
./container up`. ./container start`.
* Not all kinds of changes are automatically updated. Try `guest$ sudo mount -o * Not all kinds of changes are automatically updated. Try `guest$ sudo mount -o
remount /freedombox`. remount /freedombox`.
* I am getting an error that says `lo` is not managed by Network Manager * I am getting an error that says `lo` is not managed by Network Manager
@ -178,7 +178,7 @@ Note: This development container has automatic upgrades disabled by default.
```bash ```bash
host$ sudo touch /etc/NetworkManager/conf.d/10-globally-managed-devices.conf host$ sudo touch /etc/NetworkManager/conf.d/10-globally-managed-devices.conf
host$ sudo service network-manager restart host$ sudo service network-manager restart
host$ ./container destroy && ./container up host$ ./container destroy && ./container start
``` ```
* File/directory not found errors when running tests can be fixed by clearing `__pycache__` directories. * File/directory not found errors when running tests can be fixed by clearing `__pycache__` directories.
@ -416,7 +416,7 @@ for more details.
### Translating literals (contributing translations) ### Translating literals (contributing translations)
The easiest way to start translating is with your browser, by using The easiest way to start translating is with your browser, by using
[Weblate](https://hosted.weblate.org/projects/freedombox/plinth/). [Weblate](https://hosted.weblate.org/projects/freedombox/freedombox/).
Your changes will automatically get pushed to the code repository. Your changes will automatically get pushed to the code repository.
Alternatively, you can directly edit the `.po` file in your language directory Alternatively, you can directly edit the `.po` file in your language directory

View File

@ -35,7 +35,7 @@ FreedomBox [Manual](https://wiki.debian.org/FreedomBox/Manual/)'s
3. Access FreedomBox UI: 3. Access FreedomBox UI:
UI should be accessible at http://localhost:8000/plinth UI should be accessible at http://localhost:8000/freedombox
If you are installing FreedomBox Service (Plinth) for development purposes, see If you are installing FreedomBox Service (Plinth) for development purposes, see
HACKING.md instead. HACKING.md instead.

View File

@ -21,7 +21,8 @@ DISABLED_APPS_TO_REMOVE := \
tahoe \ tahoe \
mldonkey \ mldonkey \
i2p \ i2p \
ttrss ttrss \
sso
APP_FILES_TO_REMOVE := $(foreach app,$(DISABLED_APPS_TO_REMOVE),$(ENABLED_APPS_PATH)/$(app)) APP_FILES_TO_REMOVE := $(foreach app,$(DISABLED_APPS_TO_REMOVE),$(ENABLED_APPS_PATH)/$(app))
@ -101,11 +102,12 @@ install:
$(INSTALL) -d $(DESTDIR)$${lib_dir} && \ $(INSTALL) -d $(DESTDIR)$${lib_dir} && \
rm -rf $(DESTDIR)$${lib_dir}/plinth $(DESTDIR)$${lib_dir}/plinth*.dist-info && \ rm -rf $(DESTDIR)$${lib_dir}/plinth $(DESTDIR)$${lib_dir}/plinth*.dist-info && \
mv $${temp}/plinth $${temp}/plinth*.dist-info $(DESTDIR)$${lib_dir} && \ mv $${temp}/plinth $${temp}/plinth*.dist-info $(DESTDIR)$${lib_dir} && \
rm -f $(DESTDIR)$${lib_dir}/plinth*.dist-info/COPYING.md && \ rm -f $(DESTDIR)$${lib_dir}/plinth*.dist-info/licenses/COPYING.md && \
rm -f $(DESTDIR)$${lib_dir}/plinth*.dist-info/direct_url.json && \ rm -f $(DESTDIR)$${lib_dir}/plinth*.dist-info/direct_url.json && \
$(INSTALL) -D -t $(BIN_DIR) bin/plinth $(INSTALL) -D -t $(BIN_DIR) bin/plinth
$(INSTALL) -D -t $(LIB_DIR)/freedombox bin/freedombox-privileged $(INSTALL) -D -t $(LIB_DIR)/freedombox bin/freedombox-privileged
$(INSTALL) -D -t $(BIN_DIR) bin/freedombox-cmd $(INSTALL) -D -t $(BIN_DIR) bin/freedombox-cmd
$(INSTALL) -D -t $(BIN_DIR) bin/freedombox-change-password
# Static web server files # Static web server files
rm -rf $(STATIC_FILES_DIRECTORY) rm -rf $(STATIC_FILES_DIRECTORY)
@ -229,7 +231,7 @@ provision-dev:
sshpass bash-completion sshpass bash-completion
wait-while-first-setup: wait-while-first-setup:
while [ x$$(curl -k https://localhost/plinth/status/ 2> /dev/null | \ while [ x$$(curl -k https://localhost/freedombox/status/ 2> /dev/null | \
json_pp 2> /dev/null | grep 'is_first_setup_running' | \ json_pp 2> /dev/null | grep 'is_first_setup_running' | \
tr -d '[:space:]' | cut -d':' -f2 ) != 'xfalse' ] ; do \ tr -d '[:space:]' | cut -d':' -f2 ) != 'xfalse' ] ; do \
sleep 1; echo -n .; done sleep 1; echo -n .; done

15
Vagrantfile vendored
View File

@ -6,8 +6,7 @@ require 'etc'
Vagrant.configure(2) do |config| Vagrant.configure(2) do |config|
config.vm.box = "freedombox/freedombox-testing-dev" config.vm.box = "freedombox/freedombox-testing-dev"
config.vm.network "forwarded_port", guest: 443, host: 4430 config.vm.network "public_network"
config.vm.network "forwarded_port", guest: 445, host: 4450
config.vm.synced_folder ".", "/freedombox", owner: "plinth", group: "plinth" config.vm.synced_folder ".", "/freedombox", owner: "plinth", group: "plinth"
config.vm.provider "virtualbox" do |vb| config.vm.provider "virtualbox" do |vb|
vb.cpus = Etc.nprocessors vb.cpus = Etc.nprocessors
@ -28,17 +27,15 @@ Vagrant.configure(2) do |config|
SHELL SHELL
config.vm.provision "tests", run: "never", type: "shell", path: "plinth/tests/functional/install.sh" config.vm.provision "tests", run: "never", type: "shell", path: "plinth/tests/functional/install.sh"
config.vm.post_up_message = "FreedomBox virtual machine is ready config.vm.post_up_message = "FreedomBox virtual machine is ready
for development. Plinth will be available at https://localhost:4430/plinth for development. To get the IP address:
$ vagrant ssh
$ ip address show
FreedomBox interface will be available at https://<ip address>/freedombox
(with an invalid SSL certificate). To watch logs: (with an invalid SSL certificate). To watch logs:
$ vagrant ssh $ vagrant ssh
$ sudo freedombox-logs $ sudo freedombox-logs
" "
config.trigger.after [:up, :resume, :reload] do |trigger|
trigger.info = "Set plinth user permissions for development environment"
trigger.run_remote = {
path: ".vagrant-scripts/plinth-user-permissions.py"
}
end
config.vm.boot_timeout=1200 config.vm.boot_timeout=1200
end end

61
bin/freedombox-change-password Executable file
View File

@ -0,0 +1,61 @@
#!/usr/bin/python3
# SPDX-License-Identifier: AGPL-3.0-or-later
"""
Utility to change user password in FreedomBox's Django database.
Usage:
$ freedombox-change-password <username>
"""
import argparse
import getpass
import sys
import plinth.web_framework
from plinth.modules.users import privileged
def main():
"""Ask for new password, setup Django and update a user's password."""
try:
plinth.web_framework.init()
except Exception:
_print('Error initializing Django.')
return
parser = argparse.ArgumentParser()
parser.add_argument('username',
help='Username of the account to change password for')
args = parser.parse_args()
username = args.username
password = getpass.getpass('Enter new password: ')
try:
_change_password(username, password)
privileged._set_user_password(username, password)
privileged._set_samba_user(username, password)
_print('Password updated in web interface, LDAP, and samba databases.')
except Exception as exception:
_print('Error setting password:', str(exception))
def _print(*args, **kwargs):
"""Write to stderr."""
print(*args, **kwargs, file=sys.stderr)
def _change_password(username: str, password: str):
"""Update the password in SQLite database file."""
from django.contrib.auth.models import User
try:
user = User.objects.get(username=username)
user.set_password(password)
user.save()
except User.DoesNotExist:
_print('User account does not exist:', username)
raise
if __name__ == '__main__':
main()

View File

@ -227,6 +227,7 @@ fi
echo "> In machine: Upgrade packages" echo "> In machine: Upgrade packages"
apt-get update apt-get update
apt-mark hold freedombox freedombox-doc-en freedombox-doc-es
DEBIAN_FRONTEND=noninteractive apt-get -yq --with-new-pkgs upgrade DEBIAN_FRONTEND=noninteractive apt-get -yq --with-new-pkgs upgrade
# Install requirements for tests if not already installed as root # Install requirements for tests if not already installed as root
@ -483,6 +484,9 @@ def parse_arguments() -> argparse.Namespace:
help='Disk image size to resize to after download') help='Disk image size to resize to after download')
subparser.add_argument('--hkp-client', choices=('gpg', 'wget'), subparser.add_argument('--hkp-client', choices=('gpg', 'wget'),
default='gpg', help='Client for key retrieval') default='gpg', help='Client for key retrieval')
subparser.add_argument(
'--skip-install', action='store_true',
help='Skip running make provision-dev in the container')
# Print IP address # Print IP address
subparser = subparsers.add_parser( subparser = subparsers.add_parser(
@ -685,10 +689,27 @@ def _verify_signature(hkp_client: str, data_file: pathlib.Path,
def _extract_image(compressed_file: pathlib.Path): def _extract_image(compressed_file: pathlib.Path):
"""Extract the image file.""" """Extract the image file."""
decompressed_file = compressed_file.with_suffix('') # Strip the .xz extension, then replace .img with .raw
decompressed_file = compressed_file.with_suffix('').with_suffix('.raw')
older_image = compressed_file.with_suffix('')
if decompressed_file.exists(): if decompressed_file.exists():
return decompressed_file return decompressed_file
# Rename older image and its corresponding state files.
if older_image.exists():
logger.info('Renaming .img file to .raw')
older_image.rename(decompressed_file)
for ext in ['.setup', '.provisioned']:
old_state = older_image.with_suffix(older_image.suffix + ext)
new_state = decompressed_file.with_suffix(
decompressed_file.suffix + ext)
if old_state.exists():
old_state.rename(new_state)
return decompressed_file
logger.info('Decompressing file %s', compressed_file) logger.info('Decompressing file %s', compressed_file)
partial_file = compressed_file.with_suffix('.partial') partial_file = compressed_file.with_suffix('.partial')
with partial_file.open('w', encoding='utf-8') as file_handle: with partial_file.open('w', encoding='utf-8') as file_handle:
@ -711,7 +732,8 @@ def _get_compressed_image_path(distribution: str) -> pathlib.Path:
def _get_image_file(distribution: str) -> pathlib.Path: def _get_image_file(distribution: str) -> pathlib.Path:
"""Return the path of the image file.""" """Return the path of the image file."""
compressed_image = _get_compressed_image_path(distribution) compressed_image = _get_compressed_image_path(distribution)
return compressed_image.with_suffix('') # Strip the .xz extension, then replace .img with .raw
return compressed_image.with_suffix('').with_suffix('.raw')
def _get_project_folder() -> pathlib.Path: def _get_project_folder() -> pathlib.Path:
@ -945,7 +967,7 @@ def _setup_ssh(image_file: pathlib.Path):
_runc(image_file, ['chown', 'fbx:fbx', '/home/fbx/.ssh/authorized_keys']) _runc(image_file, ['chown', 'fbx:fbx', '/home/fbx/.ssh/authorized_keys'])
def _setup_image(image_file: pathlib.Path): def _setup_image(image_file: pathlib.Path, skip_install: bool = False):
"""Prepare the image for execution.""" """Prepare the image for execution."""
setup_file = image_file.with_suffix(image_file.suffix + '.setup') setup_file = image_file.with_suffix(image_file.suffix + '.setup')
if setup_file.exists(): if setup_file.exists():
@ -957,6 +979,7 @@ def _setup_image(image_file: pathlib.Path):
_runc(image_file, ['tee', '/etc/apt/apt.conf.d/20auto-upgrades'], _runc(image_file, ['tee', '/etc/apt/apt.conf.d/20auto-upgrades'],
input=contents.encode()) input=contents.encode())
if not skip_install:
logger.info('In image: Disabling FreedomBox service') logger.info('In image: Disabling FreedomBox service')
_runc(image_file, ['systemctl', 'disable', 'plinth'], _runc(image_file, ['systemctl', 'disable', 'plinth'],
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
@ -1017,11 +1040,15 @@ def _is_provisioned(distribution: str) -> bool:
return provision_file.exists() return provision_file.exists()
def _provision(image_file: pathlib.Path, machine_type: str, distribution: str): def _provision(image_file: pathlib.Path, machine_type: str, distribution: str,
skip_install: bool = False):
"""Run app setup inside the container.""" """Run app setup inside the container."""
if _is_provisioned(distribution): if _is_provisioned(distribution):
return return
if skip_install:
logger.info('Skipping provision step (--skip-install)')
else:
machine = Machine.get_instance(machine_type, distribution) machine = Machine.get_instance(machine_type, distribution)
ssh_command = machine.get_ssh_command() ssh_command = machine.get_ssh_command()
subprocess.run(ssh_command + ['bash'], check=True, subprocess.run(ssh_command + ['bash'], check=True,
@ -1064,7 +1091,7 @@ Terminal login : sudo machinectl login fbx-{distribution}
Open a root shell : sudo machinectl shell fbx-{distribution} Open a root shell : sudo machinectl shell fbx-{distribution}
Shutdown : {script} stop {options} Shutdown : {script} stop {options}
Destroy : {script} destroy {options} Destroy : {script} destroy {options}
Reset : {script} destroy {options}; {script} up {options}''' Reset : {script} destroy {options}; {script} start {options}'''
logger.info(message) logger.info(message)
@ -1328,9 +1355,8 @@ VirtualEthernet=yes
if result.returncode: if result.returncode:
raise Exception(f'Image file {image_link} is not a symlink.') raise Exception(f'Image file {image_link} is not a symlink.')
subprocess.run(['sudo', 'rm', '--force', # May be linked to wrong place (such as old .img file)
str(image_link)], check=False) subprocess.run(['sudo', 'rm', '--force', str(image_link)], check=False)
subprocess.run([ subprocess.run([
'sudo', 'ln', '--symbolic', 'sudo', 'ln', '--symbolic',
str(image_file.resolve()), str(image_file.resolve()),
@ -1475,10 +1501,11 @@ def subcommand_start(arguments: argparse.Namespace):
arguments.hkp_client) arguments.hkp_client)
_resize_disk_image(image_file, arguments.image_size, _resize_disk_image(image_file, arguments.image_size,
arguments.distribution) arguments.distribution)
_setup_image(image_file) _setup_image(image_file, arguments.skip_install)
machine.setup() machine.setup()
machine.launch() machine.launch()
_provision(image_file, arguments.machine_type, arguments.distribution) _provision(image_file, arguments.machine_type, arguments.distribution,
arguments.skip_install)
_print_banner(arguments.machine_type, arguments.distribution) _print_banner(arguments.machine_type, arguments.distribution)

View File

@ -12,6 +12,7 @@
# Don't redirect for onion sites as it is not needed and leads to # Don't redirect for onion sites as it is not needed and leads to
# unnecessary warning. # unnecessary warning.
RewriteCond %{HTTP_HOST} !^.*\.onion$ [NC] RewriteCond %{HTTP_HOST} !^.*\.onion$ [NC]
RewriteCond %{REQUEST_URI} !^/freedombox/apache/discover-idp/$ [NC]
ReWriteCond %{HTTPS} !=on ReWriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</LocationMatch> </LocationMatch>

View File

@ -39,16 +39,16 @@
</If> </If>
## ##
## Redirect traffic on home to /plinth as part of turning the machine ## Redirect traffic on home to /freedombox as part of turning the machine
## into FreedomBox server. Plinth then acts as a portal to reach all ## into FreedomBox server. Plinth then acts as a portal to reach all
## other services. ## other services.
## ##
<IfFile !/etc/apache2/conf-enabled/freedombox-apache-homepage.conf> <IfFile !/etc/apache2/conf-enabled/freedombox-apache-homepage.conf>
RedirectMatch "^/$" "/plinth" RedirectMatch "^/$" "/freedombox"
</IfFile> </IfFile>
## ##
## On all sites, provide FreedomBox on a default path: /plinth ## On all sites, provide FreedomBox on a default path: /freedombox
## ##
## Requires the following Apache modules to be enabled: ## Requires the following Apache modules to be enabled:
## mod_headers ## mod_headers
@ -56,7 +56,8 @@
## mod_proxy_http ## mod_proxy_http
## ##
<Location /freedombox> <Location /freedombox>
ProxyPass http://127.0.0.1:8000/plinth ProxyPass http://127.0.0.1:8000/freedombox
ProxyPreserveHost On
## Send the scheme from user's request to enable Plinth to redirect ## Send the scheme from user's request to enable Plinth to redirect
## URLs, set cookies, set absolute URLs (if any) properly. ## URLs, set cookies, set absolute URLs (if any) properly.
RequestHeader set X-Forwarded-Proto 'https' env=HTTPS RequestHeader set X-Forwarded-Proto 'https' env=HTTPS
@ -70,7 +71,20 @@
RequestHeader unset X-Forwarded-For RequestHeader unset X-Forwarded-For
</Location> </Location>
<Location /plinth> <Location /plinth>
ProxyPass http://127.0.0.1:8000/plinth ProxyPass http://127.0.0.1:8000/freedombox
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto 'https' env=HTTPS
RequestHeader unset X-Forwarded-For
</Location>
<Location /.well-known/openid-configuration>
ProxyPass http://127.0.0.1:8000/freedombox/o/.well-known/openid-configuration
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto 'https' env=HTTPS
RequestHeader unset X-Forwarded-For
</Location>
<Location /.well-known/jwks.json>
ProxyPass http://127.0.0.1:8000/freedombox/o/.well-known/jwks.json
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto 'https' env=HTTPS RequestHeader set X-Forwarded-Proto 'https' env=HTTPS
RequestHeader unset X-Forwarded-For RequestHeader unset X-Forwarded-For
</Location> </Location>
@ -82,7 +96,7 @@
<Location ~ ^/favicon\.ico$> <Location ~ ^/favicon\.ico$>
<IfModule mod_rewrite.c> <IfModule mod_rewrite.c>
RewriteEngine On RewriteEngine On
RewriteRule /favicon\.ico$ "/plinth/static/theme/img/favicon.ico" [PT] RewriteRule /favicon\.ico$ "/freedombox/static/theme/img/favicon.ico" [PT]
</IfModule> </IfModule>
</Location> </Location>

View File

@ -17,8 +17,6 @@ RestartSec=5
ExecReload=/bin/kill -HUP $MAINPID ExecReload=/bin/kill -HUP $MAINPID
User=plinth User=plinth
Group=plinth Group=plinth
StandardOutput=null
StandardError=null
NotifyAccess=main NotifyAccess=main
# Uploaded files in /var/tmp/ are shared with FreedomBox privileged service by # Uploaded files in /var/tmp/ are shared with FreedomBox privileged service by
# joining namespaces. # joining namespaces.

483
debian/changelog vendored
View File

@ -1,3 +1,486 @@
freedombox (26.9.1) unstable; urgency=medium
[ 大王叫我来巡山 ]
* Translated using Weblate (Chinese (Simplified Han script))
[ Burak Yavuz ]
* Translated using Weblate (Turkish)
[ Besnik Bleta ]
* Translated using Weblate (Albanian)
[ Jiří Podhorecký ]
* Translated using Weblate (Czech)
[ Pierfrancesco Passerini ]
* Translated using Weblate (Italian)
[ Coucouf ]
* Translated using Weblate (French)
[ Sunil Mohan Adapa ]
* matrixsynapse: Allow installing new dependencies
[ James Valleroy ]
* wireguard: Move segno import inside method
* wireguard: Get config for both download and qr actions
* doc: Fetch latest manual
-- James Valleroy <jvalleroy@mailbox.org> Mon, 15 Jun 2026 20:46:29 -0400
freedombox (26.9) unstable; urgency=medium
[ Sunil Mohan Adapa ]
* syncthing: Use systemd-sysusers for creating a system user account
* infinoted: Use systemd-sysusers for creating a system user account
* bepasty: Don't remove old system user and group
[ Luca Boccassi ]
* Stop deleting system user on remove/purge
* Install and use sysusers.d/tmpfiles.d config files
[ Hosted Weblate user 151773 ]
* Translated using Weblate (German)
[ jay ]
* Translated using Weblate (Dutch)
[ Frederico Gomes ]
* wireguard: Auto-generate client keypairs
* wireguard: Provide download and QR code for client config
* wireguard: Enable connection to a server using IPv6
[ James Valleroy ]
* debian/control: Add !nocheck for python3-segno
* locale: Update translation strings
* doc: Fetch latest manual
-- James Valleroy <jvalleroy@mailbox.org> Mon, 01 Jun 2026 21:17:46 -0400
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 ]
* Translated using Weblate (French)
[ Dietmar ]
* Translated using Weblate (Italian)
* Translated using Weblate (German)
[ Pierfrancesco Passerini ]
* Translated using Weblate (Italian)
[ bsurajpatra ]
* Translated using Weblate (Hindi)
[ Sunil Mohan Adapa ]
* service: Capture stdout/stderr when running as systemd unit
* views: Add a decorator to handle exceptions in JSON views
* d/control: Add fido2 library as dependency
* users: Add support for registering, editing, and deleting passkeys
* users: Add support for logging in with passkeys
* users: Add link to guide on passkeys
[ James Valleroy ]
* locale: Update translation strings
* doc: Fetch latest manual
-- James Valleroy <jvalleroy@mailbox.org> Mon, 06 Apr 2026 20:41:35 -0400
freedombox (26.5.1) unstable; urgency=medium
[ Burak Yavuz ]
* Translated using Weblate (Turkish)
[ Besnik Bleta ]
* Translated using Weblate (Albanian)
[ Sunil Mohan Adapa ]
* debian/control: Fix building with nocheck profile (Closes: #1131956)
* debian/copyright: Drop a removed file, correct path for another
* web_server: Fix locating SVG icons on production setup (Closes: #1131892)
-- James Valleroy <jvalleroy@mailbox.org> Thu, 26 Mar 2026 18:21:43 -0400
freedombox (26.5) unstable; urgency=medium
[ OwlGale ]
* Translated using Weblate (Russian)
[ Frederico Gomes ]
* wireguard: Remove client entry for F-Droid which is not available
* wireguard: Update windows client link
* wireguard: Add button for direct APK download
* wireguard: Add entries for Homebrew and RPM packages
* clients: Fix formatting of package row in table
* wireguard: Fix freedombox VPN IP for services
[ Sunil Mohan Adapa ]
* clients: Fix show empty clients in Desktop section
* apache: Minor improvement to getting the request host
* letsencrypt: Don't perform operations on apps that are not installed
* tests: functional: Drop undefined 'sso' pytest mark
* ui: Simplify SVG app icons for using them inline in HTML
* ui: Use inline SVG images for app icons for dark mode adaptation
* html: Drop type attribute value of text/javascript
* html: Drop trailing slash from void elements
* clients: Use SVG icons when showing external links
* ui: Use inline SVG icons for system and help section page
* ui: Add rest of the icons used from fork-awesome set
* ui: Use inline SVG icons for breadcrumbs
* ui: Use inline SVG icons for app toolbar
* ui: Use inline SVG icons for notification dropdown
* ui: Use inline SVG icons for internal zone message
* names: Use inline SVG icons for main app page
* featherwiki: Use inline SVG icons for app
* tiddlywiki: Use inline SVG icons for app
* wireguard: Use inline SVG icons
* dynamicdns: Use inline SVG icons
* help: Use inline SVG icons
* ui: Use inline SVG icons for port forwarding info
* power: Use inline SVG icons
* pagekite: Use inline SVG icons
* pagekite: Fix issue with adding custom services
* ikiwiki: Use inline SVG icons
* samba: Use inline SVG icons
* miniflux: Use inline SVG icons
* users: Use inline SVG icons
* email: Use inline SVG icons
* help: Use inline SVG icons
* matrixsynapse: Use inline SVG icons
* bepasty: Use inline SVG icons
* calibre: Use inline SVG icons
* kiwix: Use inline SVG icons
* security: Use inline SVG icons
* sharing: Use inline SVG icons
* snapshot: Use inline SVG icons
* diagnostics: Use inline SVG icons
* storage: Use inline SVG icons
* gitweb: Use inline SVG icons
* ui: Use inline SVG icons for tag search
* ui: Use inline SVG icons for clients launch buttons
* networks: Use inline SVG icons
* firstboot: Use inline SVG icons
* ui: Use inline SVG icons for app's service-not-running message
* ui: Use inline SVG icons for app's log page
* ui: Use inline SVG icons for operation waiting notification
* backups: Use inline SVG icons
* ui: Use inline SVG icons for app install page
* ui: Use inline SVG icons for all collapse buttons
* ui: Use inline SVG icons for all spinners
* ui: Use inline SVG icons for all error/warn/info/success messages
* ui: Better placement for dropdown indicator in dropdown button
* ui: Use inline SVG icons for navigation bar at the top
* upgrades: Use inline SVG icons
* ui: Use inline SVG icons for theme switcher menu
* ui: Drop fonts-fork-awesome as dependency
* ui: Rename 'plinth_extras' template tags module to 'extras'
* janus: Drop unused reference to font-awesome
* doc: Reduce verbosity when building documentation
* app: Fix build issue with Django 5.x (Closes: #1131272)
* apache: Increase OpenID Connect RP session timeout activity
* action_utils: Stop associated service when stopping a socket unit
* action_utils: Don't restart web interface when installing an app
[ Daniel Wiik ]
* Translated using Weblate (Swedish)
[ Joseph Nuthalapati ]
* container: Add option to skip install
* container: Fix image extension to .raw for systemd v260
[ James Valleroy ]
* apache: Use a Uwsgi native socket systemd unit for each app
* locale: Update translation strings
* doc: Fetch latest manual
[ Ettore Atalan ]
* Translated using Weblate (German)
-- James Valleroy <jvalleroy@mailbox.org> Mon, 23 Mar 2026 20:25:07 -0400
freedombox (26.4.2) unstable; urgency=medium
[ Jiří Podhorecký ]
* Translated using Weblate (Czech)
[ OwlGale ]
* Translated using Weblate (Russian)
-- James Valleroy <jvalleroy@mailbox.org> Sun, 08 Mar 2026 15:27:13 -0400
freedombox (26.4.1) unstable; urgency=high
[ 大王叫我来巡山 ]
* Translated using Weblate (Chinese (Simplified Han script))
[ Besnik Bleta ]
* Translated using Weblate (Albanian)
[ Burak Yavuz ]
* Translated using Weblate (Turkish)
[ Jiří Podhorecký ]
* Translated using Weblate (Czech)
[ James Valleroy ]
* container: Hold freedombox packages during test setup
* Vagrantfile: Enable public network for bridged networking
* doc: Fetch latest manual
[ Sunil Mohan Adapa ]
* d/control: Trim deps for nocheck build profile (Closes: #1129521)
* apache2: Disable pubtkt authentication module
-- James Valleroy <jvalleroy@mailbox.org> Sun, 08 Mar 2026 15:09:38 -0400
freedombox (26.4) unstable; urgency=medium
[ Joseph Nuthalapati ]
* ui: Dismiss notifications without page reload
[ Sunil Mohan Adapa ]
* ui: Refactor notification delete buttons to avoid repeating code
* ui: Add animation for notification dismissal
* actions, privileged_daemon: Drop some unused global statements
* backups: Avoid some repeated text in form help text
* backups: Fix issue with Javascript in add remote location form
* backups: Show/hide form elements instead of disabling for simplicity
* backups: Tweak appearance of add remote location form
* backups: tests: Simplify functional test using more classes
* backups: Minor refactoring
* backups: Simplify handling of migration to SSH keys
* backups: Create .ssh folder before creating SSH key
* backups: Fix showing proper error for incorrect passphrase
* backups: Create a better comment in the generated SSH key file
* backups: Fix type checking errors
* action_utils: Implement utility to change umask temporarily
* quassel: Explicitly set permissions on the domain configuration file
* letsencrypt: When copying certificate reset the umask reliably
* doc/dev: Set new theme for developer documentation
* action_utils: Fix issue with type checking a generator
* tests: functional: Increase systemd rate limits for starting units
* js: When page load fails during install, show it to user
* tests: functional: Fix reloading error page during install/uninstall
* locale/de: Fix several translations with HTML links (German)
* locale/bg: Fix several translations with HTML links (Bulgarian)
* bin: Add tool to change FreedomBox password in Django database
* ejabberd: Fix setting up certificates for multiple domains
* gitweb: Fix issue with running post init due to missing method
* wireguard: Fix format when showing multiple endpoints of the server
* wireguard: Fix showing default route setting in server edit form
* wireguard: Show status of default route in server information page
* wireguard: Accept/use netmask with IP address for server connection
* README/HACKING: Update weblate project path to /freedombox
* *: Remove some absolute file paths in SVGs
* matrixsynapse: Update apache config to proxy Synapse client API
* cfg: Drop unused config_dir option
* cfg: Drop unused actions_dir option
* Vagrantfile: Drop unnecessary sudo configuration for actions
* pyproject: Use new format to specify licenses
* action_utils: Drop support for link-local IPv6 addresses
* debian: Ensure that gbp creates a clean tarball prior to build
* syncthing: tests: Fix tests by allowing rapid restarts
* web_server: Log requests to WSGI app
* *: Update URL base from /plinth to /freedombox
* tests: functional: Fix expecting FreedomBox to be home page
* web_framework: Allow FreedomBox apps to override templates
* templates: Allow building pages without navigation bar and footer
* apache: Preserve host header when proxying to service
* oidc: New app to implement OpenID Connect Provider
* oidc: Style the page for authorizing an OIDC app
* apache: Implement protecting apps using OpenID Connect
* featherwiki: Use OpenID Connect instead of pubtkt based SSO
* syncthing: Use OpenID Connect instead of pubtkt based SSO
* searx: Use OpenID Connect instead of pubtkt based SSO
* rssbridge: Use OpenID Connect instead of pubtkt based SSO
* email: Use OpenID Connect instead of pubtkt based SSO
* calibre: Use OpenID Connect instead of pubtkt based SSO
* deluge: Use OpenID Connect instead of pubtkt based SSO
* gitweb: Use OpenID Connect instead of pubtkt based SSO
* tiddlywiki: Use OpenID Connect instead of pubtkt based SSO
* wordpress: Use OpenID Connect instead of pubtkt based SSO when private
* transmission: Use OpenID Connect instead of pubtkt based SSO
* doc/dev: Use OpenID Connect instead of pubtkt based SSO
* sharing: Use OpenID Connect instead of pubtkt based SSO
* sso: Merge into users module, drop pubtkt related code
* apache: Fix diagnosing URLs protected by OpenID Connect
[ 大王叫我来巡山 ]
* Translated using Weblate (Chinese (Simplified Han script))
[ Burak Yavuz ]
* Translated using Weblate (Turkish)
[ Coucouf ]
* Translated using Weblate (French)
* Translated using Weblate (French)
[ Besnik Bleta ]
* Translated using Weblate (Albanian)
[ Dietmar ]
* Translated using Weblate (German)
[ James Valleroy ]
* backups: Generate SSH client key if needed
* backups: Display SSH public key when adding remote
* backups: Copy SSH client public key to remote
* backups: Use SSH key instead of password
* backups: Use selected SSH credential for remote
* backups: Test adding/removing remote location
* backups: Arrange form for adding remote location
* backups: Migrate to SSH key auth when mounting
* Translated using Weblate (Greek)
* mumble: murmurd renamed to mumble-server
* Translated using Weblate (Tamil)
* locale: Update translation strings
* doc: Fetch latest manual
* apache: Fix check_url test
[ Frederico Gomes ]
* container: Align terminology in printed banner
* wireguard: filter .local addresses from showClient view
* wireguard: improved server section UX flow
* wireguard: show server vpn ip in show client page
* wireguard: Fix split tunneling
* miniflux: Revert workaround for a packaging bug with DB connection
* db: Create a utility to get credentials from dbconfig
* miniflux: Get credentials from dbconfig-common directly
[ Pierfrancesco Passerini ]
* Translated using Weblate (Italian)
[ Daniel Wiik ]
* Translated using Weblate (Swedish)
* Translated using Weblate (Swedish)
[ kosagi ]
* Translated using Weblate (Catalan)
[ Jiří Podhorecký ]
* Translated using Weblate (Czech)
[ Isak ]
* Translated using Weblate (Swedish)
[ Βασίλης Χατζηκαμάρης ]
* Translated using Weblate (Greek)
[ Benedek Nagy ]
* doc/dev: always have an up-to-date copyright year
[ தமிழ்நேரம் ]
* Translated using Weblate (Tamil)
-- James Valleroy <jvalleroy@mailbox.org> Mon, 02 Mar 2026 21:35:46 -0500
freedombox (26.3) unstable; urgency=medium
[ Frederico Gomes ]
* wireguard: Add 'Start Server' button
* docs: Update container script usage
* wireguard: Show next available client IP in Add Client form
* wireguard: Show server endpoint on main app page
[ James Valleroy ]
* wireguard: Update functional tests to handle Start Server button
* lintian: Remove mismatched overrides
* Makefile: Fix removing extra license file
* debian: Follows policy 4.7.3
* debian: Remove default Rules-Requires-Root
* debian: Remove preinst script
* debian: Update copyright years
* locale: Update translation strings
* doc: Fetch latest manual
[ Ettore Atalan ]
* Translated using Weblate (German)
[ Sunil Mohan Adapa ]
* debian: Ignore lintian warning: service file missing Install section
* wireguard: Remove NM connections when app is uninstalled
* ui: Use HTMX to update notifications on partial page updates
[ Joseph Nuthalapati ]
* ui: Add HTMX as a dependency
* ui: Use HTMX to eliminate full page reloads
[ Burak Yavuz ]
* Translated using Weblate (Turkish)
[ Pierfrancesco Passerini ]
* Translated using Weblate (Italian)
[ 大王叫我来巡山 ]
* Translated using Weblate (Chinese (Simplified Han script))
-- James Valleroy <jvalleroy@mailbox.org> Mon, 02 Feb 2026 20:41:30 -0500
freedombox (26.2) unstable; urgency=medium freedombox (26.2) unstable; urgency=medium
[ Pierfrancesco Passerini ] [ Pierfrancesco Passerini ]

52
debian/control vendored
View File

@ -1,6 +1,5 @@
Source: freedombox Source: freedombox
Section: web Section: web
Priority: optional
Maintainer: FreedomBox packaging team <freedombox-pkg-team@lists.alioth.debian.org> Maintainer: FreedomBox packaging team <freedombox-pkg-team@lists.alioth.debian.org>
Uploaders: Uploaders:
Tzafrir Cohen <tzafrir@debian.org>, Tzafrir Cohen <tzafrir@debian.org>,
@ -12,55 +11,59 @@ Uploaders:
James Valleroy <jvalleroy@mailbox.org>, James Valleroy <jvalleroy@mailbox.org>,
Build-Depends: Build-Depends:
debhelper-compat (= 13), debhelper-compat (= 13),
dh-sequence-installsysusers,
dblatex, dblatex,
dh-python, dh-python,
docbook-xsl, docbook-xsl,
e2fsprogs, e2fsprogs <!nocheck>,
gir1.2-nm-1.0, gir1.2-nm-1.0,
libjs-bootstrap5, libjs-bootstrap5 <!nocheck>,
libjs-htmx <!nocheck>,
# Older libjs-bootstrap5 does not have proper dependency on popper.js >= 2.0 # Older libjs-bootstrap5 does not have proper dependency on popper.js >= 2.0
node-popper2, node-popper2 <!nocheck>,
pybuild-plugin-pyproject, pybuild-plugin-pyproject,
python3-all:any, python3-all:any,
python3-apt, python3-apt <!nocheck>,
python3-augeas, python3-augeas,
python3-bootstrapform, python3-bootstrapform <!nocheck>,
python3-build, python3-build,
python3-cherrypy3, python3-cherrypy3,
python3-configobj, python3-configobj <!nocheck>,
python3-cryptography, python3-cryptography <!nocheck>,
python3-dbus, python3-dbus,
python3-django, python3-django,
python3-django-axes, python3-django-axes <!nocheck>,
python3-django-captcha, python3-django-captcha <!nocheck>,
# Explictly depend on ipware as it is optional dependecy of django-axes # Explictly depend on ipware as it is optional dependecy of django-axes
python3-django-ipware, python3-django-ipware <!nocheck>,
python3-django-stronghold, python3-django-oauth-toolkit <!nocheck>,
python3-django-stronghold <!nocheck>,
python3-fido2 <!nocheck>,
python3-gi, python3-gi,
python3-markupsafe, python3-markupsafe,
python3-mypy, python3-mypy <!nocheck>,
python3-pampy, python3-pampy <!nocheck>,
python3-pexpect, python3-pexpect,
python3-pip, python3-pip,
python3-psutil, python3-psutil,
python3-pytest, python3-pytest <!nocheck>,
python3-pytest-cov, python3-pytest-cov <!nocheck>,
python3-pytest-django, python3-pytest-django <!nocheck>,
python3-pytest-runner, python3-pytest-runner <!nocheck>,
python3-requests, python3-requests,
python3-ruamel.yaml, python3-ruamel.yaml,
python3-segno <!nocheck>,
python3-setuptools, python3-setuptools,
python3-systemd, python3-systemd,
python3-typeshed, python3-typeshed <!nocheck>,
python3-yaml, python3-yaml,
sshpass, sshpass <!nocheck>,
xmlto, xmlto,
xsltproc xsltproc
Standards-Version: 4.6.2 Standards-Version: 4.7.3
Homepage: https://salsa.debian.org/freedombox-team/freedombox Homepage: https://salsa.debian.org/freedombox-team/freedombox
Vcs-Git: https://salsa.debian.org/freedombox-team/freedombox.git Vcs-Git: https://salsa.debian.org/freedombox-team/freedombox.git
Vcs-Browser: https://salsa.debian.org/freedombox-team/freedombox Vcs-Browser: https://salsa.debian.org/freedombox-team/freedombox
Rules-Requires-Root: no
Package: freedombox Package: freedombox
Breaks: Breaks:
@ -73,12 +76,10 @@ Depends:
${python3:Depends}, ${python3:Depends},
${misc:Depends}, ${misc:Depends},
${freedombox:Depends}, ${freedombox:Depends},
adduser,
augeas-tools, augeas-tools,
bind9-dnsutils, bind9-dnsutils,
curl, curl,
debconf, debconf,
fonts-fork-awesome,
# sgdisk is used in storage app to expand GPT disks # sgdisk is used in storage app to expand GPT disks
gdisk, gdisk,
gettext, gettext,
@ -89,6 +90,7 @@ Depends:
# For gdbus used to call hooks into service # For gdbus used to call hooks into service
libglib2.0-bin, libglib2.0-bin,
libjs-bootstrap5, libjs-bootstrap5,
libjs-htmx,
lsof, lsof,
netcat-openbsd, netcat-openbsd,
network-manager, network-manager,
@ -108,7 +110,9 @@ Depends:
python3-django-captcha, python3-django-captcha,
# Explictly depend on ipware as it is optional dependecy of django-axes # Explictly depend on ipware as it is optional dependecy of django-axes
python3-django-ipware, python3-django-ipware,
python3-django-oauth-toolkit,
python3-django-stronghold, python3-django-stronghold,
python3-fido2,
python3-gi, python3-gi,
python3-markupsafe, python3-markupsafe,
python3-pampy, python3-pampy,

207
debian/copyright vendored
View File

@ -2,7 +2,7 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Source: https://salsa.debian.org/freedombox-team/freedombox Source: https://salsa.debian.org/freedombox-team/freedombox
Files: * Files: *
Copyright: 2011-2025 FreedomBox Authors Copyright: 2011-2026 FreedomBox Authors
License: AGPL-3+ License: AGPL-3+
Files: plinth/modules/jsxc/static/icons/jsxc.png Files: plinth/modules/jsxc/static/icons/jsxc.png
@ -32,8 +32,7 @@ Copyright: 2012 FreedomBox Foundation
Comment: Original Author: Robert Martinez Comment: Original Author: Robert Martinez
License: GPL-3+ License: GPL-3+
Files: static/themes/default/icons/app-store.png Files: static/themes/default/icons/app-store.svg
static/themes/default/icons/app-store.svg
Copyright: Marie Van den Broeck (https://thenounproject.com/marie49/) Copyright: Marie Van den Broeck (https://thenounproject.com/marie49/)
Comment: https://thenounproject.com/icon/162372/ Comment: https://thenounproject.com/icon/162372/
License: CC-BY-SA-3.0 License: CC-BY-SA-3.0
@ -79,6 +78,7 @@ Files: plinth/modules/ejabberd/static/icons/ejabberd.png
plinth/modules/rssbridge/static/icons/rssbridge.svg plinth/modules/rssbridge/static/icons/rssbridge.svg
plinth/modules/zoph/static/icons/zoph.png plinth/modules/zoph/static/icons/zoph.png
plinth/modules/zoph/static/icons/zoph.svg plinth/modules/zoph/static/icons/zoph.svg
static/themes/default/img/application.svg
static/themes/default/img/network-connection.svg static/themes/default/img/network-connection.svg
static/themes/default/img/network-connection-vertical.svg static/themes/default/img/network-connection-vertical.svg
static/themes/default/img/network-ethernet.svg static/themes/default/img/network-ethernet.svg
@ -100,14 +100,6 @@ Copyright: 2020 Adwaita Icon Theme Authors, GNOME Project
Comment: https://github.com/GNOME/adwaita-icon-theme/ http://www.gnome.org Comment: https://github.com/GNOME/adwaita-icon-theme/ http://www.gnome.org
License: LGPL-3 or CC-BY-SA-3.0-US License: LGPL-3 or CC-BY-SA-3.0-US
Files: static/themes/default/icons/f-droid.png
static/themes/default/icons/f-droid.svg
Copyright: 2012 William Theaker
2013 Robert Martinez
2015 Andrew Nayenko
Comment: https://gitlab.com/fdroid/artwork/blob/master/fdroid-logo-2015/fdroid-logo.svg
License: CC-BY-SA-3.0 or GPL-3+
Files: plinth/modules/featherwiki/static/icons/featherwiki.png Files: plinth/modules/featherwiki/static/icons/featherwiki.png
plinth/modules/featherwiki/static/icons/featherwiki.svg plinth/modules/featherwiki/static/icons/featherwiki.svg
Copyright: 2022 Robbie Antenesse <dev@alamantus.com> Copyright: 2022 Robbie Antenesse <dev@alamantus.com>
@ -120,15 +112,6 @@ Copyright: 2010 Git Authors
Comment: https://github.com/git/git/blob/master/gitweb/static/git-logo.png Comment: https://github.com/git/git/blob/master/gitweb/static/git-logo.png
License: GPL-2 License: GPL-2
Files: static/themes/default/icons/google-play.png
Copyright: Chameleon Design (https://thenounproject.com/Chamedesign/)
Comment: https://thenounproject.com/icon/887917/
License: CC-BY-3.0-US
Files: static/themes/default/icons/gnu-linux.png
Copyright: 2017 Cowemoji
License: CC0-1.0
Files: plinth/modules/homeassistant/static/icons/homeassistant.png Files: plinth/modules/homeassistant/static/icons/homeassistant.png
plinth/modules/homeassistant/static/icons/homeassistant.svg plinth/modules/homeassistant/static/icons/homeassistant.svg
Copyright: Home Assistant Core Developers Copyright: Home Assistant Core Developers
@ -160,12 +143,6 @@ Copyright: 2020 The other Kiwix guy
Comment: https://commons.wikimedia.org/wiki/File:Kiwix_logo_v3.svg Comment: https://commons.wikimedia.org/wiki/File:Kiwix_logo_v3.svg
License: CC-BY-SA-4.0 License: CC-BY-SA-4.0
Files: static/themes/default/icons/macos.png
static/themes/default/icons/macos.svg
Copyright: Vectors Market (https://thenounproject.com/vectorsmarket/)
Comment: https://thenounproject.com/icon/1203053/
License: CC-BY-SA-3.0
Files: plinth/modules/matrixsynapse/static/icons/matrixsynapse.png Files: plinth/modules/matrixsynapse/static/icons/matrixsynapse.png
Copyright: 2017 Kishan Raval Copyright: 2017 Kishan Raval
Comment: https://github.com/thekishanraval/Logos Comment: https://github.com/thekishanraval/Logos
@ -339,12 +316,6 @@ Copyright: 2011-2021 WordPress Contributors
Comment: https://github.com/WordPress/wordpress-develop/blob/master/src/wp-admin/images/wordpress-logo.svg Comment: https://github.com/WordPress/wordpress-develop/blob/master/src/wp-admin/images/wordpress-logo.svg
License: GPL-2+ License: GPL-2+
Files: static/themes/default/icons/windows.png
static/themes/default/icons/windows.svg
Copyright: 2007 ruli (https://thenounproject.com/2007ruli/)
Comment: https://thenounproject.com/icon/1206946/
License: CC-BY-SA-3.0
Files: plinth/modules/wireguard/static/icons/wireguard.png Files: plinth/modules/wireguard/static/icons/wireguard.png
plinth/modules/wireguard/static/icons/wireguard.svg plinth/modules/wireguard/static/icons/wireguard.svg
Copyright: 2019 WireGuard LLC Copyright: 2019 WireGuard LLC
@ -356,9 +327,88 @@ Copyright: 2008 GNOME icon artists
Comment: https://commons.wikimedia.org/wiki/File:Gnome-computer.svg Comment: https://commons.wikimedia.org/wiki/File:Gnome-computer.svg
License: LGPL-3+ or CC-BY-SA-3.0 License: LGPL-3+ or CC-BY-SA-3.0
Files: static/themes/default/icons/adjust.svg
static/themes/default/icons/android.svg
static/themes/default/icons/arrow-right.svg
static/themes/default/icons/ban.svg
static/themes/default/icons/bar-chart.svg
static/themes/default/icons/bars.svg
static/themes/default/icons/bell-o.svg
static/themes/default/icons/book.svg
static/themes/default/icons/check-circle.svg
static/themes/default/icons/check.svg
static/themes/default/icons/chevron-right.svg
static/themes/default/icons/clock-o.svg
static/themes/default/icons/cog.svg
static/themes/default/icons/comments.svg
static/themes/default/icons/compass.svg
static/themes/default/icons/debian.svg
static/themes/default/icons/download.svg
static/themes/default/icons/eject.svg
static/themes/default/icons/exclamation-triangle.svg
static/themes/default/icons/external-link.svg
static/themes/default/icons/eye-slash.svg
static/themes/default/icons/eye.svg
static/themes/default/icons/f-droid.svg
static/themes/default/icons/files-o.svg
static/themes/default/icons/film.svg
static/themes/default/icons/flag.svg
static/themes/default/icons/freedombox.svg
static/themes/default/icons/frown-o.svg
static/themes/default/icons/globe-w.svg
static/themes/default/icons/gnu-linux.svg
static/themes/default/icons/google-play.svg
static/themes/default/icons/hdd-o.svg
static/themes/default/icons/heartbeat.svg
static/themes/default/icons/heart.svg
static/themes/default/icons/home.svg
static/themes/default/icons/hourglass-o.svg
static/themes/default/icons/info-circle.svg
static/themes/default/icons/key.svg
static/themes/default/icons/life-ring.svg
static/themes/default/icons/line-chart.svg
static/themes/default/icons/lock.svg
static/themes/default/icons/macos.svg
static/themes/default/icons/moon.svg
static/themes/default/icons/pencil-square-o.svg
static/themes/default/icons/plus.svg
static/themes/default/icons/power-off.svg
static/themes/default/icons/question-circle.svg
static/themes/default/icons/refresh.svg
static/themes/default/icons/repeat.svg
static/themes/default/icons/rocket.svg
static/themes/default/icons/shield.svg
static/themes/default/icons/signal.svg
static/themes/default/icons/smile-o.svg
static/themes/default/icons/spinner.svg
static/themes/default/icons/star.svg
static/themes/default/icons/sun.svg
static/themes/default/icons/tags.svg
static/themes/default/icons/tag.svg
static/themes/default/icons/terminal.svg
static/themes/default/icons/th.svg
static/themes/default/icons/times.svg
static/themes/default/icons/trash-o.svg
static/themes/default/icons/trash.svg
static/themes/default/icons/upload.svg
static/themes/default/icons/user.svg
static/themes/default/icons/users.svg
static/themes/default/icons/wifi.svg
static/themes/default/icons/windows.svg
static/themes/default/icons/wrench.svg
Copyright: 2018, Fork Awesome
Comment: https://github.com/ForkAwesome/Fork-Awesome/tree/master/src/icons/svg/
License: OFL-1.1
Files: static/themes/default/icons/fedora.svg
static/themes/default/icons/homebrew.svg
Copyright: 2026, Simple Icons
Comment: https://github.com/simple-icons/simple-icons/
License: CC0-1.0
Files: debian/* Files: debian/*
Copyright: 2013 Tzafrir Cohen Copyright: 2013 Tzafrir Cohen
2013-2024 FreedomBox Authors 2013-2026 FreedomBox Authors
License: GPL-2+ License: GPL-2+
License: AGPL-3+ License: AGPL-3+
@ -2847,3 +2897,94 @@ License: Zlib
. .
3. This notice may not be removed or altered from any source 3. This notice may not be removed or altered from any source
distribution. distribution.
License: OFL-1.1
This Font Software is licensed under the SIL Open Font License,
Version 1.1.
.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
.
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
.
PREAMBLE The goals of the Open Font License (OFL) are to stimulate
worldwide development of collaborative font projects, to support the font
creation efforts of academic and linguistic communities, and to provide
a free and open framework in which fonts may be shared and improved in
partnership with others.
.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves.
The fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply to
any document created using the fonts or their derivatives.
.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such.
This may include source files, build scripts and documentation.
.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
.
"Original Version" refers to the collection of Font Software components
as distributed by the Copyright Holder(s).
.
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting ? in part or in whole ?
any of the components of the Original Version, by changing formats or
by porting the Font Software to a new environment.
.
"Author" refers to any designer, engineer, programmer, technical writer
or other person who contributed to the Font Software.
.
PERMISSION & CONDITIONS
.
Permission is hereby granted, free of charge, to any person obtaining a
copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
.
1) Neither the Font Software nor any of its individual components, in
Original or Modified Versions, may be sold by itself.
.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the
corresponding Copyright Holder. This restriction only applies to the
primary font name as presented to the users.
.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
.
5) The Font Software, modified or unmodified, in part or in whole, must
be distributed entirely under this license, and must not be distributed
under any other license. The requirement for fonts to remain under
this license does not apply to any document created using the Font
Software.
.
TERMINATION
This license becomes null and void if any of the above conditions are not met.
.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER
DEALINGS IN THE FONT SOFTWARE.

View File

@ -24,3 +24,7 @@ freedombox: package-contains-documentation-outside-usr-share-doc [usr/lib/python
# meant for user. However, don't install to /usr/libexec and follow systemd # meant for user. However, don't install to /usr/libexec and follow systemd
# convention instead. # convention instead.
freedombox: executable-in-usr-lib [usr/lib/freedombox/freedombox-privileged] freedombox: executable-in-usr-lib [usr/lib/freedombox/freedombox-privileged]
# [Install] section is missing for the privileged daemon service because it is
# socket activated.
freedombox: systemd-service-file-missing-install-key [usr/lib/systemd/system/freedombox-privileged.service]

View File

@ -13,21 +13,9 @@ sed -i 's+-:ALL EXCEPT root fbx (admin) (sudo):ALL+-:ALL EXCEPT root fbx plinth
case "$1" in case "$1" in
configure) 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 if [ ! -e '/var/lib/freedombox/is-freedombox-disk-image' ]; then
umask 377 umask 377
base64 < /dev/urandom | head -c 16 | sed -e 's+$+\n+' > /var/lib/plinth/firstboot-wizard-secret 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_subst plinth/firstboot_wizard_secret secret $(cat /var/lib/plinth/firstboot-wizard-secret)
db_input high plinth/firstboot_wizard_secret || true db_input high plinth/firstboot_wizard_secret || true
db_go db_go

View File

@ -4,7 +4,6 @@ set -e
case "$1" in case "$1" in
purge) purge)
deluser --system --quiet plinth || true
rm -rf /var/lib/plinth rm -rf /var/lib/plinth
# Remove legacy directory too # Remove legacy directory too

View File

@ -1,43 +0,0 @@
#!/bin/sh
set -e
case "$1" in
upgrade)
# Handle removing freedombox-setup-repositories.timer from 20.5.
if dpkg --compare-versions "$2" le 20.7; then
if [ -x "/usr/bin/deb-systemd-invoke" ]; then
deb-systemd-invoke stop freedombox-setup-repositories.timer >/dev/null 2>/dev/null || true
fi
if [ -x "/usr/bin/deb-systemd-helper" ]; then
deb-systemd-helper purge freedombox-setup-repositories.timer >/dev/null || true
deb-systemd-helper unmask freedombox-setup-repositories.timer >/dev/null || true
fi
if [ -d /run/systemd/system ]; then
systemctl daemon-reload
fi
fi
# Handle removing freedombox-udiskie.service from 20.9.
if dpkg --compare-versions "$2" le 20.9; then
if [ -x "/usr/bin/deb-systemd-invoke" ]; then
deb-systemd-invoke stop freedombox-udiskie.service >/dev/null 2>/dev/null || true
fi
if [ -x "/usr/bin/deb-systemd-helper" ]; then
deb-systemd-helper purge freedombox-udiskie.service >/dev/null || true
deb-systemd-helper unmask freedombox-udiskie.service >/dev/null || true
fi
if [ -d /run/systemd/system ]; then
systemctl daemon-reload
fi
fi
;;
esac
#DEBHELPER#
exit 0

1
debian/freedombox.sysusers vendored Normal file
View File

@ -0,0 +1 @@
u! plinth - "FreedomBox service" /var/lib/plinth

3
debian/freedombox.tmpfiles vendored Normal file
View 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

3
debian/gbp.conf vendored
View File

@ -1,6 +1,9 @@
[DEFAULT] [DEFAULT]
debian-branch = main debian-branch = main
[buildpackage]
export-dir = ../build-area/
[dch] [dch]
git-log = --no-merges git-log = --no-merges
multimaint-merge = True multimaint-merge = True

View File

@ -5,7 +5,4 @@
very-long-line-length-in-source-file * [doc/manual/*.raw.wiki:*] very-long-line-length-in-source-file * [doc/manual/*.raw.wiki:*]
# Misc. files which can't be fixed to have short line lengths. # Misc. files which can't be fixed to have short line lengths.
very-long-line-length-in-source-file * [plinth/modules/deluge/tests/data/sample.torrent:*]
very-long-line-length-in-source-file * [plinth/modules/transmission/tests/data/sample.torrent:*]
very-long-line-length-in-source-file * [doc/visual_design/FreedomBox-Logo.7z:*]
very-long-line-length-in-source-file * [COPYING.md:*] very-long-line-length-in-source-file * [COPYING.md:*]

16
debian/tests/access-web-interface vendored Normal file
View 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
View File

@ -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 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, @ Depends: e2fsprogs, git, python3-pytest, python3-pytest-cov, python3-pytest-django, @
Restrictions: breaks-testbed 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

View File

@ -109,20 +109,25 @@ manual-pages-xml:=$(patsubst %.raw.wiki, %.xml, $(manual-pages-raw-wiki))
manual-pages: $(manual-pages-part-html) manual-pages: $(manual-pages-part-html)
$(manual-pdfs): %.pdf: %.xml $(manual-pdfs): %.pdf: %.xml
xmlto $(XMLTO_DEBUG_FLAGS) --with-dblatex pdf -o $(dir $@) $< @echo "[PDF] $<"
@xmlto $(XMLTO_DEBUG_FLAGS) --with-dblatex pdf -o $(dir $@) $< 2> /dev/null
$(manual-pages-part-html): %.part.html: %.xml $(manual-pages-part-html): %.part.html: %.xml
xsltproc /usr/share/xml/docbook/stylesheet/docbook-xsl/xhtml5/docbook.xsl $< | \ @echo "[XSLT] $<"
@xsltproc /usr/share/xml/docbook/stylesheet/docbook-xsl/xhtml5/docbook.xsl $< 2> /dev/null | \
perl -pe 'BEGIN {undef $$/} s/.*<body[^>]*>(.*)<\/body\s*>.*/$$1/si' > $@ perl -pe 'BEGIN {undef $$/} s/.*<body[^>]*>(.*)<\/body\s*>.*/$$1/si' > $@
@rm -f $(dir $@)docbook.css @rm -f docbook.css
$(manual-xmls) $(manual-pages-xml): %.xml: %.raw.wiki $(SCRIPTS_DIR)/wikiparser.py $(manual-xmls) $(manual-pages-xml): %.xml: %.raw.wiki $(SCRIPTS_DIR)/wikiparser.py
$(SCRIPTS_DIR)/wikiparser.py $< | xmllint --format - > $@ @echo "[WIKIPARSE] $<"
@$(SCRIPTS_DIR)/wikiparser.py $< | xmllint --format - > $@
%.1: %.xml %.1: %.xml
xmlto man $< @echo "[MAN] $<"
@xmlto man $< 2> /dev/null
.PHONY: clean .PHONY: clean
clean: clean:
rm -f $(manual-pages-part-html) $(manual-pages-xml) $(manual-xmls) @echo "[RM] {part-htmls} {xmls} {manuals} {outputs}"
rm -f $(OUTPUTS) @rm -f $(manual-pages-part-html) $(manual-pages-xml) $(manual-xmls)
@rm -f $(OUTPUTS)

View File

@ -19,6 +19,7 @@ Install the following Debian packages:
* python3-sphinx * python3-sphinx
* python3-sphinx-autobuild * python3-sphinx-autobuild
* python3-sphinx-book-theme
* python3-django * python3-django
* python3-django-axes * python3-django-axes
* python3-django-captcha * python3-django-captcha

122
doc/dev/_static/logo.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -1,15 +0,0 @@
{%- extends "alabaster/layout.html" %}
{%- block footer %}
<div class="footer">
{% if show_copyright %}&copy;{{ copyright }} | {% endif %}
Licensed under the <a href="https://creativecommons.org/licenses/by-sa/4.0/">
CC BY-SA 4.0</a> license
{%- if show_source and has_source and sourcename %}
{% if show_copyright or theme_show_powered_by %}|{% endif %}
<a href="{{ pathto('_sources/' + sourcename, true)|e }}"
rel="nofollow">{{ _('Page source') }}</a>
{%- endif %}
</div>
{% endblock %}

View File

@ -15,6 +15,7 @@ list see the documentation: http://www.sphinx-doc.org/en/master/config
# #
import os import os
import sys import sys
from datetime import datetime
import django import django
@ -26,7 +27,7 @@ django.setup()
# pylint: disable=invalid-name # pylint: disable=invalid-name
project = 'FreedomBox' project = 'FreedomBox'
copyright = '2021-2025, FreedomBox Authors' copyright = f'2021-{datetime.now().year}'
author = 'FreedomBox Authors' author = 'FreedomBox Authors'
# The short X.Y version # The short X.Y version
@ -82,15 +83,23 @@ pygments_style = None
# The theme to use for HTML and HTML Help pages. See the documentation for # The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes. # a list of builtin themes.
# #
html_theme = 'alabaster' html_theme = 'sphinx_book_theme'
# Theme options are theme-specific and customize the look and feel of a theme # Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the # further. For a list of options available for each theme, see the
# documentation. # documentation.
# #
html_theme_options = { html_theme_options = {
'fixed_sidebar': True, 'home_page_in_toc': True,
'show_related': True, 'repository_provider': 'gitlab',
'repository_url': 'https://salsa.debian.org/freedombox-team/freedombox/',
'use_edit_page_button': True,
'use_source_button': True,
'use_repository_button': True,
'use_issues_button': True,
'path_to_docs': 'doc/dev/',
'extra_footer': 'Licensed under the <a href="https://creativecommons.org/'
'licenses/by-sa/4.0/">CC BY-SA 4.0</a> license.',
} }
# Add any paths that contain custom static files (such as style sheets) here, # Add any paths that contain custom static files (such as style sheets) here,
@ -221,3 +230,4 @@ autodoc_mock_imports = [
] ]
html_favicon = './_static/favicon.ico' html_favicon = './_static/favicon.ico'
html_logo = './_static/logo.svg'

View File

@ -8,6 +8,3 @@ Webserver
.. autoclass:: plinth.modules.apache.components.WebserverRoot .. autoclass:: plinth.modules.apache.components.WebserverRoot
:members: :members:
.. autoclass:: plinth.modules.apache.components.Uwsgi
:members:

View File

@ -291,10 +291,8 @@ file ``transmission-plinth.conf``, add the following.
<Location /transmission> <Location /transmission>
... ...
Include includes/freedombox-single-sign-on.conf Use AuthOpenIDConnect
<IfModule mod_auth_pubtkt.c> Use RequireGroup bit-torrent
TKTAuthToken "admin" "bit-torrent"
</IfModule>
</Location> </Location>
Showing a shortcut in the front page Showing a shortcut in the front page

View File

@ -12,7 +12,17 @@ In addition to supporting various single board computers and other devices, any
== Recommended Hardware == == Recommended Hardware ==
On April 22nd, 2019, the !FreedomBox Foundation announced the [[https://freedomboxfoundation.org/buy/|sales]] of the Pioneer Edition !FreedomBox Home Server Kits. This is the recommended pre-installed hardware for all users who don't wish to build their own !FreedomBox by choosing the right components, downloading the image and preparing an SD card with !FreedomBox. === Libre Crafts FreedomBox ===
Libre Crafts in an endeavor from the !FreedomBox developers themselves to bring you a powerful !FreedomBox device capable of hosting even the most demanding home server needs. The device is crafted, tested, and delivered to you by !FreedomBox developers. Your purchase helps !FreedomBox development.
This hardware features a powerful CPU, plenty of main memory, a fast OS disk, ability to add two high capacity hard disk drives, dual multi-gigabit Ethernet ports, all with a low power consumption. Use it to host all your photos, to backup all home devices, as a NAS, as home automation hub, as a desktop computer, and more all at once.
||<style="text-align: center;"> [[FreedomBox/Hardware/LibreCrafts|{{attachment:libre-crafts.png|Libre Crafts FreedomBox|height=300}}]]<<BR>> [[FreedomBox/Hardware/LibreCrafts|Libre Crafts FreedomBox]] ||
=== Olimex's FreedomBox Pioneer Edition ===
On April 22nd, 2019, the !FreedomBox Foundation announced the [[https://freedomboxfoundation.org/buy/|sales]] of the Pioneer Edition !FreedomBox Home Server Kits. This pre-installed hardware is for all users who don't wish to build their own !FreedomBox by choosing the right components, downloading the image and preparing an SD card with !FreedomBox.
The kit includes all the hardware needed for launching a !FreedomBox home server on an Olimex A20-OLinuXino-LIME2 board. This product provides the perfect combination of open source hardware and free and open source software. By purchasing this product, you also support the !FreedomBox Foundation's efforts to create and promote its free and open source server software. The kit includes all the hardware needed for launching a !FreedomBox home server on an Olimex A20-OLinuXino-LIME2 board. This product provides the perfect combination of open source hardware and free and open source software. By purchasing this product, you also support the !FreedomBox Foundation's efforts to create and promote its free and open source server software.

View File

@ -12,7 +12,7 @@
=== Availability === === Availability ===
* [[https://www.aliexpress.com/store/group/Allwinner-H2/1553371_516093180.html|AliExpress]] * [[https://www.aliexpress.com/item/3256803323773726.html|AliExpress]]
=== Hardware === === Hardware ===

View File

@ -0,0 +1,117 @@
#language en
##TAG:TRANSLATION-HEADER-START
~- [[FreedomBox/Guide/Passkeys|English]] - [[es/FreedomBox/Guide/Passkeys|Español]] - [[DebianWiki/EditorGuide#translation|(+)]] -~
##TAG:TRANSLATION-HEADER-END
<<TableOfContents>>
## BEGIN_INCLUDE
== Use Passkeys to Improve Login Security ==
{{{#!wiki tip
Passkeys are strongly recommended over passwords.
}}}
'''Available since''': !FreedomBox 26.6
!FreedomBox allows users to login to their account with passkeys. Passkeys are way to verify user's identity using digital signatures. They are a more secure alternative to passwords. Secret information is kept with the user on their phone, laptop, or a hardware token and unlocked using a PIN, fingerprint, or face ID. No secrets are stored on the server. The server knows only the public information that can be used to verify user's signatures.
=== How do passkeys work? ===
After the user logs into their account, one or more passkeys can be added to the account from the 'Manage Passkeys' page. At the time of adding passkeys, the passkey hardware (or authenticator), will generate a public and private key pair that is tied to the domain and user account. The private key is kept in the hardware and public key is provided to the server. The server stores the public key along with user account. Later when a user is trying to log in to their account, the server sends a long randomly generated string to the authenticator called the challenge. The hardware digitally signs the challenge using the private key and sends it to the server. The server is able to verify that the signature is made by the holder of private key by just using the public key that it has (this is a feature of public/private key pairs). Once verified, the server logs into the user account associated with that public key.
During this process, the browser acts as a trusted intermediary between the passkey hardware and the server. It ensures that the user is verified by providing PIN, fingerprint, face ID, etc. It also ensures that a passkey is only used with the domain it is meant for.
=== Better security ===
Passkeys provide better security than passwords:
* '''Multi-factor authentication''': During registration of a passkey and during login, !FreedomBox requests that the browser verify the user. This means the user will need to unlock the authenticator device by providing a PIN, fingerprint, face ID, etc. This acts as one of the authentication factors: "something you know" or "something your are". Another authentication factor is "something that you have": the hardware that stores your passkey (such as Solokey, Nitrokey, or Yubikey) or a phone. Together, this is similar to using a password along with a second factor authentication. So, passkeys can replace two-factor authentication while being much more convenient and easier to use.
* '''No reuse''': Passkeys are never reused. For each domain a separate passkey is generated and used. Browsers ensure that passkey for a domain is never used with another domain. Unlike reused passwords, when a website or a service is compromised, adversaries can't use that to gain access to your account in different website or service. This also prevents phishing attacks were adversarial websites pretend to be legitimate ones.
* '''No secrets on the server''': The website allowing use of passkeys for login does not store any secret information. It only stores the public key part of the passkey. If this information is obtained by an adversary, they will not be able to login to the website. Only the private key stored on the authenticator device can be used to login to the website (since only a private key can create signatures needed for login process).
* '''No guessing''': The secret part of a passkey is much more impractical to guess compared to a password. There is no risk that someone will be able to guess your password and access your account. There is no risk that you might accidentally set a predictable password.
* '''Convenience''': Users don't need to remember username, email, or a secret to login to a website. They don't need to receive OTP via text or email, use TOTP app, or confirm login using a mobile app. After clicking on the 'Login with passkey' button, they unlock their authenticator using a PIN, fingerprint, or face ID. Then they physically tap on the authenticator (if necessary). The user is then logged in. There are fewer things to remember. Even the PIN for a hardware authenticator is typically easier to remember than a password. This convenience encourages users to use this mechanism, ultimately leading to better security.
=== Hardware Needed for Passkeys ===
{{{#!wiki tip
'''[[https://solokeys.com/|Solokeys]]''' are recommend for passkey storage by the !FreedomBox project.
* The [[https://github.com/solokeys/solo2|firmware]] (the OS for the hardware) is free software.
* The [[https://github.com/solokeys/solo2-hw|hardware]] designs are free too.
* The Solokeys team and the !FreedomBox team collaborate.
}}}
There are many ways to get started with passkeys:
* '''Separate passkey hardware''': The recommended way to store passkeys is on a specific hardware key. In this setup, the private key part of the passkey never leaves the hardware device. They are also typically built such that it is hard for an adversary with physical access the device to extract passkey from it. Another advantage of these devices is that the hardware can be used with all your existing devices such as phones, laptops, and desktops. These devices interact with phones and desktops using USB, Bluetooth, or NFC tap. In case of NFC, the device works with proximity from the phone without additional power. When using a separate hardware, however, you must have a backup way of logging into your account in the event that you loose the hardware device. This could be an additional passkey hardware or a password. See the section on backup below.
* '''Builtin passkey hardware''': When a separate hardware device is not available, specialized hardware, such as a TPM, built into the computer is preferable. This setup will still ensure that passkeys do not leave the hardware. One disadvantage of this approach is that the passkey only works with that device and you will need register each device you use separately.
* '''Password managers''': As a last resort, one could use password managers that support passkeys and work with your browser or OS. Android, iOS, and Windows offer such password managers. Passkeys stored in password managers are typically synchronized to the cloud and a breach of that service/account could result in compromise of all your accounts. However, they work across multiple devices and you typically don't have to worry about loosing a single hardware device.
=== Naming Your Passkey ===
In !FreedomBox, when a passkey is added to your account, it by default named as 'Key 1'. The next one will be named 'Key 2' and so on. However, it is good practice to name them such that you know which device they are stored on. For example, you can name them 'Key on Primary Solokey', 'Key on Android Phone', etc. If a device is lost, you can login to your account and remove that key from the list of passkeys associated with your account.
=== Multiple Domains ===
Each passkey is strictly tied to a domain and never used for another domain. This necessary to ensure that a malicious domain does not impersonate a legitimate domain. Hence, if your !FreedomBox is configured with multiple domains, then the browser and hardware authenticator device will treat them as separate accounts for the purpose of authentication with passkeys. This means you need to register separate passkeys for each of your domains.
For example, assume your !FreedomBox has two domains configured mydomain1.fbx.one and mydomain2.example. Visit mydomain1.fbx.one, log in to your account, and add a passkey. This passkey will be tied to this domain. When you are trying to log in, the passkey will work if you are accessing mydomain1.fbx.one but it won't work when accessing mydomain2.example. To make the second domain work, you need to add a second passkey while accessing your !FreedomBox with the domain name mydomain2.example. Two passkeys are then stored in your hardware token. First one will be tied to mydomain1.fbx.one and will only be used when accessing that domain. Second one will be tied to mydomain2.example and will only be used when accessing that domain.
=== Multiple User Accounts ===
When you use a passkey hardware for multiple user accounts on the same !FreedomBox, separate passkeys will be created for each of the accounts. Each passkey will be assigned the username of the account it is tied to. This information is stored in the passkey as well as the server. During login, the browser will prompt to select the user account you want to log into. If only a single passkey exists for a given domain name, then the selection dialog is not shown and user will login to the account corresponding to the passkey.
=== Backup for Passkey ===
In case the device storing your passkey is lost, you need alternate ways to login to you account:
1. You can register and maintain two passkeys on two separate devices. For example, your primary passkey could be on a Solokey hardware token and the second passkey could be on an Android phone or another Solokey hardware token. If one is lost, you can login with the other. This is the recommended approach.
1. !FreedomBox continues to support passwords even after passkeys are registered. So, if a passkey device is lost, you can login with a password.
1. If you forget your password and if your user account is not the only administrator account on the !FreedomBox, you can ask an administrator to reset your password. After that you can register a new passkey stored on a new device.
=== Supported Platforms ===
Passkeys are based on WebAuthn, a standard published by World Wide Web Consortium. So, !FreedomBox's implementation is expected to work wherever passkeys work. It has been tested as follows:
|| '''OS/Device''' || '''Browser''' || '''Authenticator''' || '''Result''' ||
|| GNU/Linux || Firefox || Solokeys || Pass ||
|| GNU/Linux || Firefox || Yubikey || Pass ||
|| GNU/Linux || Chromium || Solokeys || Pass ||
|| GNU/Linux || GNOME Web || - || Fail (Browser does not support Webauthn) ||
|| Windows || Firefox || Windows Hello || Pass ||
|| Windows || Firefox || Solokeys || Pass ||
|| Windows || Firefox || Android Phone || Pass ||
|| Windows || Chrome || Windows Hello || Pass ||
|| Windows || Chrome || Solokeys || Pass ||
|| Windows || Chrome || Android Phone || Pass ||
|| Windows || Edge || Windows Hello || Pass ||
|| Windows || Edge || Solokeys || Pass ||
|| Windows || Edge || Android Phone || Pass ||
|| Android || Firefox || Google Password Manager || Pass ||
|| Android || Firefox || Solokeys USB || Fail (Touch is not detected after PIN entry) ||
|| Android || Firefox || Solokeys NFC || Fail (Need to understand NFC setup) ||
|| Android || Firefox || Another device || Untested ||
|| Android || Chrome || Google Password Manager || Pass ||
|| Android || Chrome || Solokeys USB || Fail (Touch is not detected after PIN entry) ||
|| Android || Chrome || Solokeys NFC || Fail (Need to understand NFC setup) ||
|| Android || Chrome || Another device || Untested ||
## END_INCLUDE
Back to [[FreedomBox/Features|Features introduction]] or [[FreedomBox/Manual|manual]] pages.
<<Include(FreedomBox/Portal)>>
----
CategoryFreedomBox

View File

@ -25,7 +25,8 @@ The [[https://www.olimex.com/Products/OLinuXino/Home-Server/Pioneer-FreedomBox-H
* an optional storage add-on for hard disk (HDD) or solid-state drive (SSD) * an optional storage add-on for hard disk (HDD) or solid-state drive (SSD)
=== Recommended Hardware === === Recommended Hardware ===
This is the hardware recommended for all users who just want a turn-key !FreedomBox, and '''don't''' want to '''build''' their own one.
This is a hardware recommended for all users who just want a turn-key !FreedomBox, and '''don't''' want to '''build''' their own one.
(Building your own !FreedomBox means some technical stuff like choosing and buying the right components, downloading the image and preparing the SD card). (Building your own !FreedomBox means some technical stuff like choosing and buying the right components, downloading the image and preparing the SD card).

View File

@ -8,6 +8,240 @@ For more technical details, see the [[https://salsa.debian.org/freedombox-team/f
The following are the release notes for each !FreedomBox version. The following are the release notes for each !FreedomBox version.
== FreedomBox 26.9.1 (2026-06-15) ==
* locale: Update translations for Albanian, Chinese (Simplified Han script), Czech, French, Italian, Turkish
* matrixsynapse: Allow installing new dependencies
* wireguard: Get config for both download and qr actions
* wireguard: Move segno import inside method
== FreedomBox 26.9 (2026-06-01) ==
=== Highlights ===
* wireguard: Auto-generate client keypairs
* wireguard: Provide download and QR code for client config
=== Other Changes ===
* bepasty: Don't remove old system user and group
* debian: Install and use sysusers.d/tmpfiles.d config files
* debian: Stop deleting system user on remove/purge
* infinoted: Use systemd-sysusers for creating a system user account
* locale: Update translations for Dutch, German
* syncthing: Use systemd-sysusers for creating a system user account
* wireguard: Enable !FreedomBox to connect to a server using IPv6
== 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 ===
* users: Add support for logging in with passkeys
=== Other Changes ===
* d/control: Add fido2 library as dependency
* locale: Update translations for French, German, Hindi, Italian
* service: Capture stdout/stderr when running as systemd unit
* users: Add link to guide on passkeys
* users: Add support for registering, editing, and deleting passkeys
* views: Add a decorator to handle exceptions in JSON views
== FreedomBox 26.5.1 (2026-03-26) ==
* debian/control: Fix building with nocheck profile
* debian/copyright: Drop a removed file, correct path for another
* locale: Update translations for Albanian, Turkish
* web_server: Fix locating SVG icons on production setup
== FreedomBox 26.5 (2026-03-23) ==
=== Highlights ===
* action_utils: Don't restart web interface when installing an app
* apache: Use a Uwsgi native socket systemd unit for each app
* ui: Use inline SVG icons for all apps
* wireguard: Fix freedombox VPN IP for services
=== Other Changes ===
* action_utils: Stop associated service when stopping a socket unit
* apache: Increase OpenID Connect RP session timeout activity
* apache: Minor improvement to getting the request host
* app: Fix build issue with Django 5.x
* clients: Fix formatting of package row in table
* clients: Fix show empty clients in Desktop section
* clients: Use SVG icons when showing external links
* container: Add option to skip install
* container: Fix image extension to .raw for systemd v260
* doc: Reduce verbosity when building documentation
* html: Drop trailing slash from void elements
* html: Drop type attribute value of text/javascript
* janus: Drop unused reference to font-awesome
* letsencrypt: Don't perform operations on apps that are not installed
* locale: Update translations for German, Russian, Swedish
* pagekite: Fix issue with adding custom services
* tests: functional: Drop undefined 'sso' pytest mark
* ui: Add rest of the icons used from fork-awesome set
* ui: Better placement for dropdown indicator in dropdown button
* ui: Drop fonts-fork-awesome as dependency
* ui: Rename 'plinth_extras' template tags module to 'extras'
* ui: Simplify SVG app icons for using them inline in HTML
* ui: Use inline SVG icons for buttons, messages, spinners, etc.
* wireguard: Add button for direct APK download
* wireguard: Add entries for Homebrew and RPM packages
* wireguard: Remove client entry for F-Droid which is not available
* wireguard: Update windows client link
== FreedomBox 26.4.2 (2026-03-08) ==
=== Highlights ===
* apache2: Disable pubtkt authentication module
=== Other Changes ===
* container: Hold freedombox packages during test setup
* d/control: Trim deps for nocheck build profile
* locale: Update translations for Albanian, Chinese (Simplified Han script), Czech, Russian, Turkish
* Vagrantfile: Enable public network for bridged networking
== FreedomBox 26.4 (2026-03-02) ==
=== Highlights ===
* backups: Enable key-based SSH authentication for remote backups
* oidc: New app to implement OpenID Connect Provider
* apache: Implement protecting apps using OpenID Connect
* wireguard: Improve server section user experience flow
=== Other Changes ===
* *: Remove some absolute file paths in SVGs
* *: Update URL base from /plinth to /freedombox
* README/HACKING: Update weblate project path to /freedombox
* Vagrantfile: Drop unnecessary sudo configuration for actions
* action_utils: Drop support for link-local IPv6 addresses
* action_utils: Fix issue with type checking a generator
* action_utils: Implement utility to change umask temporarily
* actions, privileged_daemon: Drop some unused global statements
* apache: Fix diagnosing URLs protected by OpenID Connect
* apache: Preserve host header when proxying to service
* backups: Arrange form for adding remote location
* backups: Avoid some repeated text in form help text
* backups: Copy SSH client public key to remote
* backups: Create .ssh folder before creating SSH key
* backups: Create a better comment in the generated SSH key file
* backups: Display SSH public key when adding remote
* backups: Fix issue with Javascript in add remote location form
* backups: Fix showing proper error for incorrect passphrase
* backups: Fix type checking errors
* backups: Generate SSH client key if needed
* backups: Migrate to SSH key auth when mounting
* backups: Minor refactoring
* backups: Show/hide form elements instead of disabling for simplicity
* backups: Simplify handling of migration to SSH keys
* backups: Test adding/removing remote location
* backups: Tweak appearance of add remote location form
* backups: Use SSH key instead of password
* backups: Use selected SSH credential for remote
* backups: tests: Simplify functional test using more classes
* bin: Add tool to change !FreedomBox password in Django database
* calibre: Use OpenID Connect instead of pubtkt based SSO
* cfg: Drop unused actions_dir option
* cfg: Drop unused config_dir option
* container: Align terminology in printed banner
* db: Create a utility to get credentials from dbconfig
* debian: Ensure that gbp creates a clean tarball prior to build
* deluge: Use OpenID Connect instead of pubtkt based SSO
* doc/dev: Set new theme for developer documentation
* doc/dev: Use OpenID Connect instead of pubtkt based SSO
* doc/dev: always have an up-to-date copyright year
* ejabberd: Fix setting up certificates for multiple domains
* email: Use OpenID Connect instead of pubtkt based SSO
* featherwiki: Use OpenID Connect instead of pubtkt based SSO
* gitweb: Fix issue with running post init due to missing method
* gitweb: Use OpenID Connect instead of pubtkt based SSO
* js: When page load fails during install, show it to user
* letsencrypt: When copying certificate reset the umask reliably
* locale/bg: Fix several translations with HTML links (Bulgarian)
* locale/de: Fix several translations with HTML links (German)
* locale: Update translations for Albanian, Catalan, Chinese (Simplified Han script), Czech, French, German, Greek, Italian, Swedish, Tamil, Turkish
* matrixsynapse: Update apache config to proxy Synapse client API
* miniflux: Get credentials from dbconfig-common directly
* miniflux: Revert workaround for a packaging bug with DB connection
* mumble: murmurd renamed to mumble-server
* oidc: Style the page for authorizing an OIDC app
* pyproject: Use new format to specify licenses
* quassel: Explicitly set permissions on the domain configuration file
* rssbridge: Use OpenID Connect instead of pubtkt based SSO
* searx: Use OpenID Connect instead of pubtkt based SSO
* sharing: Use OpenID Connect instead of pubtkt based SSO
* sso: Merge into users module, drop pubtkt related code
* syncthing: Use OpenID Connect instead of pubtkt based SSO
* syncthing: tests: Fix tests by allowing rapid restarts
* templates: Allow building pages without navigation bar and footer
* tests: functional: Fix expecting !FreedomBox to be home page
* tests: functional: Fix reloading error page during install/uninstall
* tests: functional: Increase systemd rate limits for starting units
* tiddlywiki: Use OpenID Connect instead of pubtkt based SSO
* transmission: Use OpenID Connect instead of pubtkt based SSO
* ui: Add animation for notification dismissal
* ui: Dismiss notifications without page reload
* ui: Refactor notification delete buttons to avoid repeating code
* web_framework: Allow !FreedomBox apps to override templates
* web_server: Log requests to WSGI app
* wireguard: Accept/use netmask with IP address for server connection
* wireguard: Fix format when showing multiple endpoints of the server
* wireguard: Fix showing default route setting in server edit form
* wireguard: Fix split tunneling
* wireguard: Show status of default route in server information page
* wireguard: filter .local addresses from showClient view
* wireguard: show server vpn ip in show client page
* wordpress: Use OpenID Connect instead of pubtkt based SSO when private
== FreedomBox 26.3 (2026-02-02) ==
=== Highlights ===
* ui: Use HTMX to eliminate full page reloads
* wireguard: Add 'Start Server' button to help with client setup
=== Other Changes ===
* debian: Follows policy 4.7.3
* debian: Ignore lintian warning: service file missing Install section
* debian: Remove default Rules-Requires-Root
* debian: Remove preinst script
* debian: Update copyright years
* docs: Update container script usage
* lintian: Remove mismatched overrides
* locale: Update translations for Chinese (Simplified Han script), German, Italian, Turkish
* Makefile: Fix removing extra license file
* ui: Add HTMX as a dependency
* ui: Use HTMX to update notifications on partial page updates
* wireguard: Remove NM connections when app is uninstalled
* wireguard: Show next available client IP in Add Client form
* wireguard: Update functional tests to handle Start Server button
* wireguard: Show server endpoint on main app page
== FreedomBox 26.2 (2026-01-20) == == FreedomBox 26.2 (2026-01-20) ==
* gitweb: Fix deleting last repo disables app * gitweb: Fix deleting last repo disables app

View File

@ -20,15 +20,13 @@ The content can be shared publicly or restricted to the users of listed allowed
=== Setting Up Shares === === Setting Up Shares ===
For the users to access the content through their browser it must exist and have a share. A share is an entry in the Sharing app relating: * In !FreedomBox web interface, enable the Sharing App. Only admins can create, edit or remove shares. They'll find the Sharing app in the Apps section of the !FreedomBox web interface. Many shares can coexist in the same server.
* the Name (an thereby the URL) with which the users will ask for the content, * Add a new share
* the Disk Path of the content to be served and * Give it a name (an thereby the URL) with which the users will ask for the content. In the example above it would be called ''content_name''.
* the sharing mode. On restricted mode, it also has the list of allowed groups. * The Disk Path of the content to be served. This path is relative to ''root'' on your !FreedomBox. For instance ''/var/lib/freedombox/sharing/content_name'' might be a choice.
Many shares can coexist in the same server. * Sharing mode. On restricted mode, it also has the list of allowed groups. Only groups recognized by !FreedomBox service can be combined in the list of allowed groups. Groups created in the CLI won't be offered by the Sharing app.
* Create the directory specified under ''Disk Path'' on your !FreedomBox through ''Cockpit'', ''Nautilus'' or remote login.
Only admins can create, edit or remove shares. They'll find the Sharing app in the Apps section of !FreedomBox web interface. Sharing app is an easy to use web application with an evident interface. * Make sure the user, who will provide the content, has write access to that directory for instance by making him the owner of that directory.
Each share has its own sharing mode (public or restricted) setting. Only groups recognized by !FreedomBox service can be combined in the list of allowed groups. Groups created in the CLI won't be offered by the Sharing app.
=== Providing/Updating Content === === Providing/Updating Content ===

View File

@ -1,6 +1,11 @@
#language en #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]] -~ ~- [[DebianWiki/EditorGuide#translation|Translation(s)]]: English - [[es/FreedomBox/Manual/Users|Español]] -~
##TAG:TRANSLATION-HEADER-END
----
<<TableOfContents()>> <<TableOfContents()>>
@ -8,25 +13,25 @@
== Users and Groups == == Users and Groups ==
You can grant access to your !FreedomBox for other users. Provide the Username with a password and assign a group to it. Currently the groups This app can be used to create, edit, and remove user accounts on !FreedomBox. Many apps with web interface in !FreedomBox support single sign-on using OpenID Connect. This means that if you are logged into !FreedomBox web interface, there is no need to login to the app separately. Other apps support using the !FreedomBox user accounts via LDAP. Finally, there are some apps that manage their own user accounts separate from the accounts you have in !FreedomBox.
Access to an app is allowed if the user accessing the app is part of the app's group. You can grant access to apps in !FreedomBox for specific users by adding them to the following groups:
* admin * admin
* bit-torrent * bit-torrent
* calibre * calibre
* ed2k
* feed-reader * feed-reader
* freedombox-share * freedombox-share
* freedombox-ssh
* git-access * git-access
* minidlna * kiwix
* syncthing * syncthing-access
* vpn
* web-search * web-search
* wiki * wiki
are supported.
The user will be able to log in to services that support single sign-on through LDAP, if they are in the appropriate group. Users in the admin group will be able to log in to all services. They can also log in to the system through SSH and have administrative privileges (sudo). A user's groups can also be changed later.
Users in the admin group will be able to log in to all services. They can also log in to the system through SSH and have administrative privileges (sudo). !FreedomBox supports logging in with passkeys. Passkeys are a secure alternative to passwords and are the recommended way of authenticating to !FreedomBox. Read more in the [[FreedomBox/Guide/Passkeys|FreedomBox's guide to passkeys]].
A user's groups can also be changed later.
It is also possible to set an SSH public key which will allow this user to securely log in to the system without using a password. You may enter multiple keys, one on each line. Blank lines and lines starting with # will be ignored. It is also possible to set an SSH public key which will allow this user to securely log in to the system without using a password. You may enter multiple keys, one on each line. Blank lines and lines starting with # will be ignored.

View File

@ -83,6 +83,7 @@
<<Include(FreedomBox/Manual/Users, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>> <<Include(FreedomBox/Manual/Users, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
= Guides = = Guides =
<<Include(FreedomBox/Guide/Passkeys, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
<<Include(FreedomBox/Guide/ExposeLocalService, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>> <<Include(FreedomBox/Guide/ExposeLocalService, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
= Hardware = = Hardware =

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

View File

@ -11,8 +11,19 @@ Además de soportar varios SBC's (single board computers) y otros dispositivos,
== Hardware Recomendado == == Hardware Recomendado ==
El 22 de Abril de 2019, la ''!FreedomBox Foundation'' anunció que los kits ''Pioneer Edition !FreedomBox Home Server'' salían a la [[https://freedomboxfoundation.org/buy/|venta]]. Este es el hardware preinstalado recomendado para todos los usuarios que no quieran construirse su propia (máquina) !FreedomBox eligiendo los componentes adecuados, descargando la imagen y preparando una tarjeta SD con (el software) !FreedomBox. === Libre Crafts FreedomBox ===
Libre Crafts es una iniviativa de los propios desarrolladores de !FreedomBox para proporcionar una !FreedomBox potente capaz de alojar las necesidades más exigentes de un servidor casero.
Los propios desarrolladores de !FreedomBox la montan. prueban y entregan. Tu compra ayuda al desarrollo de !FreedomBox.
Esta máquina lleva un procesador potente, mucha memoria, CPU, un disco de sitema operativo rápido, posibilidad de añador discos duros de alta capacidad, puertos Ethernet multi-gigabit duales, todo ello con bajo consumo.
Úsalo para alojar todas tus fotos, las copias de respaldo de tus otros dispositivos, como NAS, como centro de control de domótica, como ordenador de sobremesa, y más, todo a la vez.
||<style="text-align: center;"> [[FreedomBox/Hardware/LibreCrafts|{{attachment:FreedomBox/libre-crafts.png|FreedomBox de Libre Crafts|height=300}}]]<<BR>> [[FreedomBox/Hardware/LibreCrafts|FreedomBox de Libre Crafts]] ||
=== Olimex's FreedomBox Pioneer Edition ===
On April 22nd, 2019, the !FreedomBox Foundation announced the [[https://freedomboxfoundation.org/buy/|sales]] of the Pioneer Edition !FreedomBox Home Server Kits. This pre-installed hardware is for all users who don't wish to build their own !FreedomBox by choosing the right components, downloading the image and preparing an SD card with !FreedomBox.
El kit incluye todo el hardware necesario para arrancar un servidor casero !FreedomBox sobre una placa ''Olimex A20-OLinuXino-LIME2''. Este producto proporciona la combinación perfecta de hardware de fuentes abiertas y software libre. Al comprar este producto, soportas también los esfuerzos de la ''!FreedomBox Foundation'' para crear y promover su software de servidor libre. El kit incluye todo el hardware necesario para arrancar un servidor casero !FreedomBox sobre una placa ''Olimex A20-OLinuXino-LIME2''. Este producto proporciona la combinación perfecta de hardware de fuentes abiertas y software libre. Al comprar este producto, soportas también los esfuerzos de la ''!FreedomBox Foundation'' para crear y promover su software de servidor libre.
||<style="text-align: center;"> [[es/FreedomBox/Hardware/PioneerEdition|{{attachment:FreedomBox/Hardware/pioneer-edition_thumb.jpg|Kits de servidor doméstico FreedomBox edición Pioneer|width=320,height=257}}]]<<BR>> [[es/FreedomBox/Hardware/PioneerEdition|Kits de servidor doméstico FreedomBox edición Pioneer]] || ||<style="text-align: center;"> [[es/FreedomBox/Hardware/PioneerEdition|{{attachment:FreedomBox/Hardware/pioneer-edition_thumb.jpg|Kits de servidor doméstico FreedomBox edición Pioneer|width=320,height=257}}]]<<BR>> [[es/FreedomBox/Hardware/PioneerEdition|Kits de servidor doméstico FreedomBox edición Pioneer]] ||

View File

@ -83,6 +83,7 @@
<<Include(FreedomBox/Manual/Users, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>> <<Include(FreedomBox/Manual/Users, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
= Guides = = Guides =
<<Include(FreedomBox/Guide/Passkeys, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
<<Include(FreedomBox/Guide/ExposeLocalService, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>> <<Include(FreedomBox/Guide/ExposeLocalService, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
= Hardware = = Hardware =

View File

@ -12,7 +12,7 @@
=== Availability === === Availability ===
* [[https://www.aliexpress.com/store/group/Allwinner-H2/1553371_516093180.html|AliExpress]] * [[https://www.aliexpress.com/item/3256803323773726.html|AliExpress]]
=== Hardware === === Hardware ===

View 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

View File

@ -16,7 +16,7 @@ Los servidores caseros !FreedomBox Pioneer Edition los fabrica y vende Olimex, u
== Características del Producto == == Características del Producto ==
=== HW Recomendado === === HW Recomendado ===
Éste es el hardware recomendado para los usuarios que quieran simplemente una !FreedomBox llave en mano, y '''no''' quieran '''construirse''' una. Éste es un hardware recomendado para los usuarios que quieran simplemente una !FreedomBox llave en mano, y '''no''' quieran '''construirse''' una.
(Construir tu propia !FreedomBox implica algunos tecnicismos como elegir y comprar los componentes adecuados, descargar la imágen y preparar una tarjeta SD). (Construir tu propia !FreedomBox implica algunos tecnicismos como elegir y comprar los componentes adecuados, descargar la imágen y preparar una tarjeta SD).

View File

@ -8,6 +8,240 @@ For more technical details, see the [[https://salsa.debian.org/freedombox-team/f
The following are the release notes for each !FreedomBox version. The following are the release notes for each !FreedomBox version.
== FreedomBox 26.9.1 (2026-06-15) ==
* locale: Update translations for Albanian, Chinese (Simplified Han script), Czech, French, Italian, Turkish
* matrixsynapse: Allow installing new dependencies
* wireguard: Get config for both download and qr actions
* wireguard: Move segno import inside method
== FreedomBox 26.9 (2026-06-01) ==
=== Highlights ===
* wireguard: Auto-generate client keypairs
* wireguard: Provide download and QR code for client config
=== Other Changes ===
* bepasty: Don't remove old system user and group
* debian: Install and use sysusers.d/tmpfiles.d config files
* debian: Stop deleting system user on remove/purge
* infinoted: Use systemd-sysusers for creating a system user account
* locale: Update translations for Dutch, German
* syncthing: Use systemd-sysusers for creating a system user account
* wireguard: Enable !FreedomBox to connect to a server using IPv6
== 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 ===
* users: Add support for logging in with passkeys
=== Other Changes ===
* d/control: Add fido2 library as dependency
* locale: Update translations for French, German, Hindi, Italian
* service: Capture stdout/stderr when running as systemd unit
* users: Add link to guide on passkeys
* users: Add support for registering, editing, and deleting passkeys
* views: Add a decorator to handle exceptions in JSON views
== FreedomBox 26.5.1 (2026-03-26) ==
* debian/control: Fix building with nocheck profile
* debian/copyright: Drop a removed file, correct path for another
* locale: Update translations for Albanian, Turkish
* web_server: Fix locating SVG icons on production setup
== FreedomBox 26.5 (2026-03-23) ==
=== Highlights ===
* action_utils: Don't restart web interface when installing an app
* apache: Use a Uwsgi native socket systemd unit for each app
* ui: Use inline SVG icons for all apps
* wireguard: Fix freedombox VPN IP for services
=== Other Changes ===
* action_utils: Stop associated service when stopping a socket unit
* apache: Increase OpenID Connect RP session timeout activity
* apache: Minor improvement to getting the request host
* app: Fix build issue with Django 5.x
* clients: Fix formatting of package row in table
* clients: Fix show empty clients in Desktop section
* clients: Use SVG icons when showing external links
* container: Add option to skip install
* container: Fix image extension to .raw for systemd v260
* doc: Reduce verbosity when building documentation
* html: Drop trailing slash from void elements
* html: Drop type attribute value of text/javascript
* janus: Drop unused reference to font-awesome
* letsencrypt: Don't perform operations on apps that are not installed
* locale: Update translations for German, Russian, Swedish
* pagekite: Fix issue with adding custom services
* tests: functional: Drop undefined 'sso' pytest mark
* ui: Add rest of the icons used from fork-awesome set
* ui: Better placement for dropdown indicator in dropdown button
* ui: Drop fonts-fork-awesome as dependency
* ui: Rename 'plinth_extras' template tags module to 'extras'
* ui: Simplify SVG app icons for using them inline in HTML
* ui: Use inline SVG icons for buttons, messages, spinners, etc.
* wireguard: Add button for direct APK download
* wireguard: Add entries for Homebrew and RPM packages
* wireguard: Remove client entry for F-Droid which is not available
* wireguard: Update windows client link
== FreedomBox 26.4.2 (2026-03-08) ==
=== Highlights ===
* apache2: Disable pubtkt authentication module
=== Other Changes ===
* container: Hold freedombox packages during test setup
* d/control: Trim deps for nocheck build profile
* locale: Update translations for Albanian, Chinese (Simplified Han script), Czech, Russian, Turkish
* Vagrantfile: Enable public network for bridged networking
== FreedomBox 26.4 (2026-03-02) ==
=== Highlights ===
* backups: Enable key-based SSH authentication for remote backups
* oidc: New app to implement OpenID Connect Provider
* apache: Implement protecting apps using OpenID Connect
* wireguard: Improve server section user experience flow
=== Other Changes ===
* *: Remove some absolute file paths in SVGs
* *: Update URL base from /plinth to /freedombox
* README/HACKING: Update weblate project path to /freedombox
* Vagrantfile: Drop unnecessary sudo configuration for actions
* action_utils: Drop support for link-local IPv6 addresses
* action_utils: Fix issue with type checking a generator
* action_utils: Implement utility to change umask temporarily
* actions, privileged_daemon: Drop some unused global statements
* apache: Fix diagnosing URLs protected by OpenID Connect
* apache: Preserve host header when proxying to service
* backups: Arrange form for adding remote location
* backups: Avoid some repeated text in form help text
* backups: Copy SSH client public key to remote
* backups: Create .ssh folder before creating SSH key
* backups: Create a better comment in the generated SSH key file
* backups: Display SSH public key when adding remote
* backups: Fix issue with Javascript in add remote location form
* backups: Fix showing proper error for incorrect passphrase
* backups: Fix type checking errors
* backups: Generate SSH client key if needed
* backups: Migrate to SSH key auth when mounting
* backups: Minor refactoring
* backups: Show/hide form elements instead of disabling for simplicity
* backups: Simplify handling of migration to SSH keys
* backups: Test adding/removing remote location
* backups: Tweak appearance of add remote location form
* backups: Use SSH key instead of password
* backups: Use selected SSH credential for remote
* backups: tests: Simplify functional test using more classes
* bin: Add tool to change !FreedomBox password in Django database
* calibre: Use OpenID Connect instead of pubtkt based SSO
* cfg: Drop unused actions_dir option
* cfg: Drop unused config_dir option
* container: Align terminology in printed banner
* db: Create a utility to get credentials from dbconfig
* debian: Ensure that gbp creates a clean tarball prior to build
* deluge: Use OpenID Connect instead of pubtkt based SSO
* doc/dev: Set new theme for developer documentation
* doc/dev: Use OpenID Connect instead of pubtkt based SSO
* doc/dev: always have an up-to-date copyright year
* ejabberd: Fix setting up certificates for multiple domains
* email: Use OpenID Connect instead of pubtkt based SSO
* featherwiki: Use OpenID Connect instead of pubtkt based SSO
* gitweb: Fix issue with running post init due to missing method
* gitweb: Use OpenID Connect instead of pubtkt based SSO
* js: When page load fails during install, show it to user
* letsencrypt: When copying certificate reset the umask reliably
* locale/bg: Fix several translations with HTML links (Bulgarian)
* locale/de: Fix several translations with HTML links (German)
* locale: Update translations for Albanian, Catalan, Chinese (Simplified Han script), Czech, French, German, Greek, Italian, Swedish, Tamil, Turkish
* matrixsynapse: Update apache config to proxy Synapse client API
* miniflux: Get credentials from dbconfig-common directly
* miniflux: Revert workaround for a packaging bug with DB connection
* mumble: murmurd renamed to mumble-server
* oidc: Style the page for authorizing an OIDC app
* pyproject: Use new format to specify licenses
* quassel: Explicitly set permissions on the domain configuration file
* rssbridge: Use OpenID Connect instead of pubtkt based SSO
* searx: Use OpenID Connect instead of pubtkt based SSO
* sharing: Use OpenID Connect instead of pubtkt based SSO
* sso: Merge into users module, drop pubtkt related code
* syncthing: Use OpenID Connect instead of pubtkt based SSO
* syncthing: tests: Fix tests by allowing rapid restarts
* templates: Allow building pages without navigation bar and footer
* tests: functional: Fix expecting !FreedomBox to be home page
* tests: functional: Fix reloading error page during install/uninstall
* tests: functional: Increase systemd rate limits for starting units
* tiddlywiki: Use OpenID Connect instead of pubtkt based SSO
* transmission: Use OpenID Connect instead of pubtkt based SSO
* ui: Add animation for notification dismissal
* ui: Dismiss notifications without page reload
* ui: Refactor notification delete buttons to avoid repeating code
* web_framework: Allow !FreedomBox apps to override templates
* web_server: Log requests to WSGI app
* wireguard: Accept/use netmask with IP address for server connection
* wireguard: Fix format when showing multiple endpoints of the server
* wireguard: Fix showing default route setting in server edit form
* wireguard: Fix split tunneling
* wireguard: Show status of default route in server information page
* wireguard: filter .local addresses from showClient view
* wireguard: show server vpn ip in show client page
* wordpress: Use OpenID Connect instead of pubtkt based SSO when private
== FreedomBox 26.3 (2026-02-02) ==
=== Highlights ===
* ui: Use HTMX to eliminate full page reloads
* wireguard: Add 'Start Server' button to help with client setup
=== Other Changes ===
* debian: Follows policy 4.7.3
* debian: Ignore lintian warning: service file missing Install section
* debian: Remove default Rules-Requires-Root
* debian: Remove preinst script
* debian: Update copyright years
* docs: Update container script usage
* lintian: Remove mismatched overrides
* locale: Update translations for Chinese (Simplified Han script), German, Italian, Turkish
* Makefile: Fix removing extra license file
* ui: Add HTMX as a dependency
* ui: Use HTMX to update notifications on partial page updates
* wireguard: Remove NM connections when app is uninstalled
* wireguard: Show next available client IP in Add Client form
* wireguard: Update functional tests to handle Start Server button
* wireguard: Show server endpoint on main app page
== FreedomBox 26.2 (2026-01-20) == == FreedomBox 26.2 (2026-01-20) ==
* gitweb: Fix deleting last repo disables app * gitweb: Fix deleting last repo disables app

View File

@ -19,15 +19,15 @@ El contenido se puede compartir públicamente o restringido a usuarios de una li
=== Editando comparticiones === === Editando comparticiones ===
Para que los usuarios accedan al contenido mediante su navegador debe existir y tener una compartición. Una compartición es una entrada en la aplicación Sharing que relaciona: Cada compartición tiene su propio ajuste de modo de compartición (pública o restringida). Sólo los grupos que reconoce el servicio !FreedomBox se pueden combinar en la lista de grupos autorizados. La aplicación ''Sharing'' no ofrecerá los grupos creados en el interfaz de línea de órdenes.
* El Nombre (y por tanto la URL) que usarán los usuarios para solicitar el contenido,
* el Ruta de acceso al contenido a servir y
* el modo de compartición. Si es restringido, también contendrá la lista de grupos autorizados.
En el mismo servidor pueden coexistir múltiples comparticiones.
Sólo los administradores pueden crear, editar o eliminar comparticiones. Encontrarán la aplicación ''Sharing'' en la sección Aplicacions del interfaz web de !FreedomBox. La aplicación ''Sharing'' es una aplicación web fácil de usar y con un interfaz evidente. * In el interfaz web de !FreedomBox, habilita la App ''Sharing''. Sólo los administradores pueden crear, editar o eliminar comparticiones. Encontrarán la aplicación ''Sharing'' en la sección Aplicaciones del interfaz web de !FreedomBox. En el mismo servidor pueden coexistir múltiples comparticiones.
* Añadir una nueva compartición:
Cada compartición tiene su priopio ajuste de modo de compartición (pública o restrigida). Sólo los grupos que reconoce el servicio !FreedomBox se pueden combinar en la lista de grupos autorizados. La aplicación ''Sharing'' no ofrecerá los grupos creados en el interfaz de línea de órdenes. * Dale un nombre (y por tanto la URL) que usarán los usuarios para solicitar el contenido, En el ejemplo anterior se llamaría ''nombre del contenido''.
* La Ruta completa de acceso al contenido a servir. Por ejemplo ''/var/lib/freedombox/sharing/nombre_del_contenido''.
* El modo de compartición. Si es restringido, también contendrá la lista de grupos autorizados. Solo los grupos reconocidos por el servicio !FreedomBox se pueden combinar en la lista de grupos autorizados. La app no ofrecerá los grupos creados sólo en la línea de órdenes.
* Crea el directorio especificado en ''Ruta de Disco'' en !FreedomBox mediante ''Cockpit'', ''Nautilus'' o ingreso remoto.
* Asegúrate de que el usuario que proporcione el contenido tiene permiso para escribir en el directorio, por ejemplo, haciéndole dueño del directorio.
=== Provisionar/actualizar el contenido === === Provisionar/actualizar el contenido ===

View File

@ -1,6 +1,6 @@
#language es #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()>> <<TableOfContents()>>
@ -9,25 +9,36 @@
== Usuarios y Grupos == == 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 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 * admin
* bit-torrent * bit-torrent
* calibre * calibre
* ed2k
* feed-reader * feed-reader
* freedombox-share * freedombox-share
* freedombox-ssh
* git-access * git-access
* minidlna * kiwix
* syncthing * syncthing-access
* vpn
* web-search * web-search
* wiki * 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. Puedes 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. Pueder 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. El idioma de la interfaz se puede establecer individualmente para cada usuario. Por omisión se emplea el del navegador.

View File

@ -80,6 +80,7 @@
<<Include(es/FreedomBox/Manual/Users, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>> <<Include(es/FreedomBox/Manual/Users, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
= Guías = = Guías =
<<Include(es/FreedomBox/Guide/Passkeys, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
<<Include(es/FreedomBox/Guide/ExposeLocalService,, from="## BEGIN_INCLUDE", to="## END_INCLUDE")>> <<Include(es/FreedomBox/Guide/ExposeLocalService,, from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
= Hardware = = Hardware =

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

View File

@ -73,8 +73,8 @@
<para> <para>
This the URL fragment under which Plinth will provide its services. This the URL fragment under which Plinth will provide its services.
Plinth is shipped with a default value of Plinth is shipped with a default value of
<filename>/plinth</filename>. This means that Plinth will be <filename>/freedombox</filename>. This means that Plinth will be
available as http://localhost:8000/plinth by default. available as http://localhost:8000/freedombox by default.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -194,7 +194,7 @@
<synopsis>$ plinth --server_dir='/myurl'</synopsis> <synopsis>$ plinth --server_dir='/myurl'</synopsis>
<para> <para>
Run Plinth with the '/myurl' prefix. Note that Apache forwards requests Run Plinth with the '/myurl' prefix. Note that Apache forwards requests
to '/plinth' by default, so /myurl is not accessible outside of your to '/freedombox' by default, so /myurl is not accessible outside of your
FreedomBox without adapting the apache configuration. FreedomBox without adapting the apache configuration.
</para> </para>
</example> </example>

View File

@ -13,7 +13,7 @@ from pathlib import Path
from xml.sax.saxutils import escape from xml.sax.saxutils import escape
BASE_URL = 'https://wiki.debian.org/' BASE_URL = 'https://wiki.debian.org/'
LOCAL_BASE = '/plinth/help/manual/{lang}/' LOCAL_BASE = '/freedombox/help/manual/{lang}/'
ICONS_DIR = 'icons' ICONS_DIR = 'icons'
DEFAULT_LANGUAGE = 'en' DEFAULT_LANGUAGE = 'en'
@ -624,21 +624,21 @@ def resolve_url(url, context):
Locally available page in default language => shortcut to local copy: Locally available page in default language => shortcut to local copy:
>>> resolve_url('FreedomBox/Contribute', {'language': '', 'title': ''}) >>> resolve_url('FreedomBox/Contribute', {'language': '', 'title': ''})
'/plinth/help/manual/en/Contribute#' '/freedombox/help/manual/en/Contribute#'
Translated available page => shortcut to local copy: Translated available page => shortcut to local copy:
>>> resolve_url('es/FreedomBox/Contribute', {'language': '', 'title': ''}) >>> resolve_url('es/FreedomBox/Contribute', {'language': '', 'title': ''})
'/plinth/help/manual/es/Contribute#' '/freedombox/help/manual/es/Contribute#'
Available page in default language refferred as translated => shortcut to Available page in default language refferred as translated => shortcut to
local copy: local copy:
>>> resolve_url('en/FreedomBox/Contribute', {'language': '', 'title': ''}) >>> resolve_url('en/FreedomBox/Contribute', {'language': '', 'title': ''})
'/plinth/help/manual/en/Contribute#' '/freedombox/help/manual/en/Contribute#'
Unrecognized language => handle considering it as default language: Unrecognized language => handle considering it as default language:
>>> resolve_url('missing/FreedomBox/Contribute', {'language': '', \ >>> resolve_url('missing/FreedomBox/Contribute', {'language': '', \
'title': ''}) 'title': ''})
'/plinth/help/manual/en/Contribute#' '/freedombox/help/manual/en/Contribute#'
""" """
# Process first all easy, straight forward cases: # Process first all easy, straight forward cases:
@ -1191,11 +1191,11 @@ from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>')
[Paragraph([PlainText('a')]), Paragraph([PlainText('b ')])] [Paragraph([PlainText('a')]), Paragraph([PlainText('b ')])]
>>> parse_wiki('{{{#!wiki caution\\n\\nOnce some other app is set as the \ >>> parse_wiki('{{{#!wiki caution\\n\\nOnce some other app is set as the \
home page, you can only navigate to the !FreedomBox Service (Plinth) by \ home page, you can only navigate to the !FreedomBox Service (Plinth) by \
typing https://myfreedombox.rocks/plinth/ into the browser. <<BR>>\\n\ typing https://myfreedombox.rocks/freedombox/ into the browser. <<BR>>\\n\
''/freedombox'' can also be used as an alias to ''/plinth''\\n}}}') ''/freedombox'' can also be used as an alias to ''/plinth''\\n}}}')
[Admonition('caution', [Paragraph([PlainText('Once some other app is set \ [Admonition('caution', [Paragraph([PlainText('Once some other app is set \
as the home page, you can only navigate to the FreedomBox Service (Plinth) by \ as the home page, you can only navigate to the FreedomBox Service (Plinth) by \
typing '), Url('https://myfreedombox.rocks/plinth/'), PlainText(' into the \ typing '), Url('https://myfreedombox.rocks/freedombox/'), PlainText(' into the \
browser. ')]), Paragraph([PlainText('/freedombox can also be used as an alias \ browser. ')]), Paragraph([PlainText('/freedombox can also be used as an alias \
to /plinth ')])])] to /plinth ')])])]
@ -1761,7 +1761,7 @@ Features introduction</ulink>'
>>> generate_inner_docbook([Link('../../Contribute', \ >>> generate_inner_docbook([Link('../../Contribute', \
[PlainText('Contribute')])], context={'title': 'FreedomBox/Manual/Hardware'}) [PlainText('Contribute')])], context={'title': 'FreedomBox/Manual/Hardware'})
'<ulink url="/plinth/help/manual/en/Contribute#">\ '<ulink url="/freedombox/help/manual/en/Contribute#">\
Contribute</ulink>' Contribute</ulink>'
>>> generate_inner_docbook([Link('/Code', \ >>> generate_inner_docbook([Link('/Code', \
@ -1772,9 +1772,9 @@ Code</ulink>'
>>> generate_inner_docbook([Link('DebianBug:1234', [PlainText('Bug')])]) >>> generate_inner_docbook([Link('DebianBug:1234', [PlainText('Bug')])])
'<ulink url="https://bugs.debian.org/1234#">Bug</ulink>' '<ulink url="https://bugs.debian.org/1234#">Bug</ulink>'
>>> generate_inner_docbook([Link('DebianPkg:plinth', \ >>> generate_inner_docbook([Link('DebianPkg:freedombox', \
[PlainText('Plinth')])]) [PlainText('Plinth')])])
'<ulink url="https://packages.debian.org/plinth#">Plinth</ulink>' '<ulink url="https://packages.debian.org/freedombox#">Plinth</ulink>'
>>> generate_inner_docbook([Link('AliothList:freedombox-discuss', \ >>> generate_inner_docbook([Link('AliothList:freedombox-discuss', \
[PlainText('Discuss')])]) [PlainText('Discuss')])])
@ -1911,7 +1911,7 @@ PlainText(' on it. ')])])
'<para>An alternative to downloading these images is to \ '<para>An alternative to downloading these images is to \
<ulink url="https://wiki.debian.org/InstallingDebianOn/TI/BeagleBone#">\ <ulink url="https://wiki.debian.org/InstallingDebianOn/TI/BeagleBone#">\
install Debian</ulink> on the BeagleBone and then \ install Debian</ulink> on the BeagleBone and then \
<ulink url="/plinth/help/manual/en/Debian#">install \ <ulink url="/freedombox/help/manual/en/Debian#">install \
FreedomBox</ulink> on it. </para>' FreedomBox</ulink> on it. </para>'
>>> generate_inner_docbook([Paragraph([PlainText('After Roundcube is \ >>> generate_inner_docbook([Paragraph([PlainText('After Roundcube is \

View File

@ -3,4 +3,4 @@
Package init file. Package init file.
""" """
__version__ = '26.2' __version__ = '26.9.1'

View File

@ -10,6 +10,7 @@ import shutil
import subprocess import subprocess
import tempfile import tempfile
from contextlib import contextmanager from contextlib import contextmanager
from typing import Generator
import augeas import augeas
@ -17,9 +18,6 @@ from . import actions
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
UWSGI_ENABLED_PATH = '/etc/uwsgi/apps-enabled/{config_name}.ini'
UWSGI_AVAILABLE_PATH = '/etc/uwsgi/apps-available/{config_name}.ini'
# Flag on disk to indicate if freedombox package was held by # Flag on disk to indicate if freedombox package was held by
# plinth. This is a backup in case the process is interrupted and hold # plinth. This is a backup in case the process is interrupted and hold
# is not released. # is not released.
@ -137,25 +135,62 @@ def service_start(service_name: str, check: bool = False):
"""Start a service with systemd.""" """Start a service with systemd."""
service_action(service_name, 'start', check=check) 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): def service_stop(service_name: str, check: bool = False):
"""Stop a service with systemd.""" """Stop a service with systemd."""
service_action(service_name, 'stop', check=check) 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): def service_restart(service_name: str, check: bool = False):
"""Restart a service with systemd.""" """Restart a service with systemd."""
if not service_name.endswith('.socket'):
service_action(service_name, 'restart', check=check) 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): def service_try_restart(service_name: str, check: bool = False):
"""Try to restart a service with systemd.""" """Try to restart a service with systemd."""
if not service_name.endswith('.socket'):
service_action(service_name, 'try-restart', check=check) 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): def service_reload(service_name: str, check: bool = False):
"""Reload a service with systemd.""" """Reload a service with systemd."""
if not service_name.endswith('.socket'):
service_action(service_name, 'reload', check=check) 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): def service_try_reload_or_restart(service_name: str, check: bool = False):
@ -163,7 +198,14 @@ def service_try_reload_or_restart(service_name: str, check: bool = False):
Do nothing if service is not running. Do nothing if service is not running.
""" """
if not service_name.endswith('.socket'):
service_action(service_name, 'try-reload-or-restart', check=check) 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): def service_reset_failed(service_name: str, check: bool = False):
@ -309,43 +351,6 @@ class WebserverChange:
self.actions_required.add(action_required) self.actions_required.add(action_required)
def uwsgi_is_enabled(config_name):
"""Return whether a uwsgi config is enabled."""
enabled_path = UWSGI_ENABLED_PATH.format(config_name=config_name)
return os.path.exists(enabled_path)
def uwsgi_enable(config_name):
"""Enable a uwsgi configuration that runs under uwsgi."""
if uwsgi_is_enabled(config_name):
return
# uwsgi is started/stopped using init script. We don't know if it can
# handle some configuration already running against newly enabled
# configuration. So, stop first before enabling new configuration.
service_stop('uwsgi')
enabled_path = UWSGI_ENABLED_PATH.format(config_name=config_name)
available_path = UWSGI_AVAILABLE_PATH.format(config_name=config_name)
os.symlink(available_path, enabled_path)
service_enable('uwsgi')
service_start('uwsgi')
def uwsgi_disable(config_name):
"""Disable a uwsgi configuration that runs under uwsgi."""
if not uwsgi_is_enabled(config_name):
return
# If uwsgi is restarted later, it won't stop the just disabled
# configuration due to how init scripts are written for uwsgi.
service_stop('uwsgi')
enabled_path = UWSGI_ENABLED_PATH.format(config_name=config_name)
os.unlink(enabled_path)
service_start('uwsgi')
def get_addresses() -> list[dict[str, str | bool]]: def get_addresses() -> list[dict[str, str | bool]]:
"""Return a list of IP addresses and hostnames.""" """Return a list of IP addresses and hostnames."""
addresses = get_ip_addresses() addresses = get_ip_addresses()
@ -370,12 +375,13 @@ def get_addresses() -> list[dict[str, str | bool]]:
'url_address': hostname 'url_address': hostname
}) })
# XXX: When a hostname is resolved to IPv6 address, it may likely # When a hostname is resolved to IPv6 address, it may likely be link-local
# be link-local address. Link local IPv6 addresses are valid only # address. Link local IPv6 addresses are valid only for a given link and
# for a given link and need to be scoped with interface name such # need to be scoped with interface name such as '%eth0' to work. Browsers
# as '%eth0' to work. Tools such as curl don't seem to handle # refused to implement support for link-local addresses (with zone IDs) in
# URLs due to platform specific parsing rules and other implementation
# difficulties. mod_auth_openidc does not support them either.
# this correctly. # this correctly.
# addresses.append({'kind': '6', 'address': hostname, 'numeric': False})
return addresses return addresses
@ -397,12 +403,14 @@ def get_ip_addresses() -> list[dict[str, str | bool]]:
} }
if address['kind'] == '6' and address['numeric']: if address['kind'] == '6' and address['numeric']:
if address['scope'] != 'link':
address['url_address'] = '[{0}]'.format(address['address']) address['url_address'] = '[{0}]'.format(address['address'])
else:
address['url_address'] = '[{0}%{1}]'.format(
address['url_address'], address['interface'])
if address['scope'] != 'link':
# Do not include link local addresses. Browsers refused to
# implement support for link-local addresses (with zone IDs) in
# URLs due to platform specific parsing rules and other
# implementation difficulties. mod_auth_openidc does not support
# them either.
addresses.append(address) addresses.append(address)
return addresses return addresses
@ -465,9 +473,31 @@ def is_disk_image():
return os.path.exists('/var/lib/freedombox/is-freedombox-disk-image') return os.path.exists('/var/lib/freedombox/is-freedombox-disk-image')
def run_apt_command(arguments, enable_triggers: bool = False): def run_apt_command(arguments, enable_triggers: bool = False,
allow_freedombox_restart=False):
"""Run apt-get with provided arguments.""" """Run apt-get with provided arguments."""
command = ['apt-get', '--assume-yes', '--quiet=2'] + arguments command = []
if not allow_freedombox_restart:
# Don't restart the freedombox web service. This configuration is only
# used when apt command is invoked from freedombox web service itself
# (such as during an app's installation/uninstallation).
#
# If this is not done, a freedombox web service restart is attempted.
# needsrestart will wait until the restart is completed. apt command
# will wait until needsrestart is completed. The restart mechanism in
# service will wait until all currently running threads are completed.
# One thread that has invoked this apt command will not finish as it
# waits for apt command to finish. This results in a deadlock. Avoid
# this by not attempting to restart freedombox web service when apt
# command is invoked from freedombox web service.
mount_path = '/etc/needrestart/conf.d/freedombox-self.conf'
orig_path = f'/usr/share/freedombox{mount_path}'
command = [
'systemd-run', '--pipe',
f'--property=BindReadOnlyPaths={orig_path}:{mount_path}'
]
command += ['apt-get', '--assume-yes', '--quiet=2'] + arguments
env = os.environ.copy() env = os.environ.copy()
env['DEBIAN_FRONTEND'] = 'noninteractive' env['DEBIAN_FRONTEND'] = 'noninteractive'
@ -838,3 +868,13 @@ def run(command, **kwargs):
raise exception raise exception
return process return process
@contextmanager
def umask(mask) -> Generator:
"""Set the umask temporarily for a operation and then revert it."""
old_umask = os.umask(mask)
try:
yield
finally:
os.umask(old_umask)

View File

@ -369,7 +369,6 @@ class JSONEncoder(json.JSONEncoder):
def _setup_thread_storage(): def _setup_thread_storage():
"""Setup collection of stdout/stderr from any process in this thread.""" """Setup collection of stdout/stderr from any process in this thread."""
global thread_storage
thread_storage.stdout = b'' thread_storage.stdout = b''
thread_storage.stderr = b'' thread_storage.stderr = b''
@ -380,14 +379,12 @@ def _clear_thread_storage():
Python documentation is silent on whether thread local storage will be Python documentation is silent on whether thread local storage will be
cleaned up after a thread terminates. cleaned up after a thread terminates.
""" """
global thread_storage
thread_storage.stdout = None thread_storage.stdout = None
thread_storage.stderr = None thread_storage.stderr = None
def get_return_value_from_exception(exception): def get_return_value_from_exception(exception):
"""Return the value to return from server when an exception is raised.""" """Return the value to return from server when an exception is raised."""
global thread_storage
return_value = { return_value = {
'result': 'exception', 'result': 'exception',
'exception': { 'exception': {

View File

@ -574,10 +574,19 @@ class Info(FollowerComponent):
except ImproperlyConfigured: except ImproperlyConfigured:
# Hack to allow apps to be instantiated without Django # Hack to allow apps to be instantiated without Django
# initialization as required by privileged process. # initialization as required by privileged process.
return [ def _make_str(tag):
tag._proxy____args[0] if isinstance(tag, Promise) else tag """Return the string without casting."""
for tag in self._tags if not isinstance(tag, Promise):
] return tag
# Django 4.2
if hasattr(tag, '_proxy____args'):
return tag._proxy____args[0]
# Django 5.x
return tag._args[0]
return [_make_str(tag) for tag in self._tags]
class EnableState(LeaderComponent): class EnableState(LeaderComponent):

View File

@ -12,13 +12,11 @@ logger = logging.getLogger(__name__)
# [Path] section # [Path] section
file_root = '/usr/share/plinth' file_root = '/usr/share/plinth'
config_dir = '/etc/plinth'
data_dir = '/var/lib/plinth' data_dir = '/var/lib/plinth'
custom_static_dir = '/var/www/plinth/custom/static' custom_static_dir = '/var/www/plinth/custom/static'
store_file = data_dir + '/plinth.sqlite3' store_file = data_dir + '/plinth.sqlite3'
actions_dir = '/usr/share/plinth/actions'
doc_dir = '/usr/share/freedombox' doc_dir = '/usr/share/freedombox'
server_dir = '/plinth' server_dir = '/freedombox'
# [Network] section # [Network] section
host = '127.0.0.1' host = '127.0.0.1'
@ -111,11 +109,9 @@ def read_file(config_path):
config_items = ( config_items = (
('Path', 'file_root', 'string'), ('Path', 'file_root', 'string'),
('Path', 'config_dir', 'string'),
('Path', 'data_dir', 'string'), ('Path', 'data_dir', 'string'),
('Path', 'custom_static_dir', 'string'), ('Path', 'custom_static_dir', 'string'),
('Path', 'store_file', 'string'), ('Path', 'store_file', 'string'),
('Path', 'actions_dir', 'string'),
('Path', 'doc_dir', 'string'), ('Path', 'doc_dir', 'string'),
('Path', 'server_dir', 'string'), ('Path', 'server_dir', 'string'),
('Network', 'host', 'string'), ('Network', 'host', 'string'),

View File

@ -44,7 +44,8 @@ def _check(client, condition):
def _client_has_desktop(client): def _client_has_desktop(client):
"""Filter to find out whether an application has desktop clients""" """Filter to find out whether an application has desktop clients"""
return _check( return _check(
client, lambda platform: platform.get('os') in enum_values(Desktop_OS)) client, lambda platform: platform.get('os') in enum_values(Desktop_OS)
and platform.get('type') != 'package')
def _client_has_mobile(client): def _client_has_mobile(client):
@ -116,7 +117,7 @@ def _validate_platform_package(platform):
def _validate_platform_download(platform): def _validate_platform_download(platform):
"""Validate a platform of type download.""" """Validate a platform of type download."""
assert platform['os'] in enum_values(Desktop_OS) assert platform['os'] in enum_values(Desktop_OS) + enum_values(Mobile_OS)
assert isinstance(platform['url'], (str, Promise)) assert isinstance(platform['url'], (str, Promise))

View File

@ -64,10 +64,10 @@ def fixture_load_cfg():
"""Load test configuration.""" """Load test configuration."""
from plinth import cfg from plinth import cfg
keys = ('file_root', 'config_dir', 'data_dir', 'custom_static_dir', keys = ('file_root', 'data_dir', 'custom_static_dir', 'store_file',
'store_file', 'actions_dir', 'doc_dir', 'server_dir', 'host', 'doc_dir', 'server_dir', 'host', 'port', 'use_x_forwarded_for',
'port', 'use_x_forwarded_for', 'use_x_forwarded_host', 'use_x_forwarded_host', 'secure_proxy_ssl_header', 'box_name',
'secure_proxy_ssl_header', 'box_name', 'develop') 'develop')
saved_state = {} saved_state = {}
for key in keys: for key in keys:
saved_state[key] = getattr(cfg, key) saved_state[key] = getattr(cfg, key)

40
plinth/db/dbconfig.py Normal file
View File

@ -0,0 +1,40 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Utilities for parsing dbconfig-common files with Augeas."""
import pathlib
import augeas
def get_credentials(dbconfig_path: str) -> dict[str, str]:
"""Parse dbconfig-common file with Augeas Shellvars lens."""
if not pathlib.Path(dbconfig_path).is_file():
raise FileNotFoundError(f'DB config not found: {dbconfig_path}')
aug = _load_augeas(dbconfig_path)
required = ['dbc_dbuser', 'dbc_dbpass', 'dbc_dbname']
credentials = {}
for key in required + ['dbc_dbserver']:
credentials[key] = aug.get(key).strip('\'"')
if not all(credentials.get(key) for key in required):
raise ValueError('Missing required dbconfig-common credentials')
return {
'user': credentials['dbc_dbuser'],
'password': credentials['dbc_dbpass'],
'database': credentials['dbc_dbname'],
'host': credentials['dbc_dbserver'] or 'localhost'
}
def _load_augeas(config_path: str):
"""Initialize Augeas."""
aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD +
augeas.Augeas.NO_MODL_AUTOLOAD)
pathstr = str(config_path)
aug.transform('Shellvars', pathstr)
aug.set('/augeas/context', f'/files{pathstr}')
aug.load()
return aug

View File

@ -1,5 +1,3 @@
[Path] [Path]
file_root = %(parent_parent_dir)s file_root = %(parent_parent_dir)s
config_dir = %(file_root)s/data/etc/plinth
actions_dir = %(file_root)s/actions
doc_dir = %(file_root)s/doc doc_dir = %(file_root)s/doc

View File

@ -10,7 +10,7 @@ translating the PO file from your language directory.
Introducing yourself is important since some work may have been done Introducing yourself is important since some work may have been done
already on Debian translators discussion lists and Weblate already on Debian translators discussion lists and Weblate
localization platform. localization platform.
https://hosted.weblate.org/projects/freedombox/plinth/ https://hosted.weblate.org/projects/freedombox/freedombox/
https://www.debian.org/MailingLists/subscribe https://www.debian.org/MailingLists/subscribe
## Wiki: translators landing page ## Wiki: translators landing page

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More