Commit Graph

8068 Commits

Author SHA1 Message Date
Jakob Borg
97fb677887 chore(api): deflake TestHTTPLogin on Windows (#10667)
Hopefully deflakes TestHTTPLogin on Windows, where it currently often
times out, presumably in the config saving stage after already having
started a shutdown of the API and being CPU constrained due to password
hashing.

---------

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-04-24 15:07:16 +02:00
Jakob Borg
124f6979a4 build: parallelise linux builds slightly (#10666)
They currently take like 25 minutes. This reduces that to approximately
a third, wall-clock wise.

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-04-24 13:16:12 +02:00
JRNitre
39778de04b fix(gui): fix tabs visually disabled but still clickable during ignore patterns setup (fixes #10634) (#10651)
### Purpose

Fixes issue #10634.

### Testing

Manually tested by reproducing the issue:

- Created a new folder with "Add ignore patterns" enabled
- Verified that after saving, only the "Ignore Patterns" tab remains
accessible
- Confirmed that other tabs are visually disabled and no longer
clickable

### Screenshots

No visible UI changes.

### Explanation of the Fix

**Cause**

The issue was caused by only visually disabling tabs in the UI by
setting
their `href` attribute to an empty string (`href=""`). This made the
tabs
appear disabled, but they were still clickable, leading to confusing
behavior
where users could interact with the tabs without any actual navigation.

**Fix**

- Introduced `isFolderTabDisabled` to centralize the logic for
determining
  whether a tab should be disabled
- Added `onFolderTabClick` to prevent interaction with disabled tabs
- Updated the HTML to remove tab behavior (such as `data-toggle="tab"`
and
  `href`) when a tab is disabled

### Documentation

No documentation changes required.

Signed-off-by: JRNitre <nichinichisou67@outlook.com>
Co-authored-by: Jakob Borg <jakob@kastelo.net>
2026-04-24 09:53:35 +02:00
Jakob Borg
bcaabedc8e chore(scanner): deflake TestStopWalk (#10664)
The test expected the stopped scanner to produce at most numHashers
additional results, but there's also the case where a directory is
encountered (which doesn't require hashing) and sent directly.

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-04-24 09:52:50 +02:00
Jakob Borg
46fb888ea3 chore(model): deflake TestCompletionEmptyGlobal (#10663)
There was a race condition where using IndexUpdate would trigger a pull,
which would sync the delete we are looking for, making the completion
100%. By doing the insert directly into the database we are not
triggering these things and get the expected completion percentage
always.

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-04-24 09:52:27 +02:00
Jakob Borg
36c3331696 chore(model): deflake cluster config tests (#10662)
These have been flaky for a long time, seemingly because the multiple
connection code slightly changed the timing of cluster config sending by
moving them to the connection promotion loop. This adds some resiliency
to that, instead of assuming that the CC:s will be immediately available
after adding the connection.

---------

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-04-24 07:41:17 +00:00
RealCharlesChia
2850b3a46c fix(gui): fallback to folder ID when label is empty in remove dialog (#10657)
## Summary

Fixes issue #10458: When removing a folder without a Folder Label, the
confirmation dialog now shows the folder ID instead of an empty string.

### Before
> Are you sure you want to remove folder **?**

### After  
> Are you sure you want to remove folder **dnjdr-hssze**?

### Changes

Modified `gui/default/syncthing/folder/removeFolderDialogView.html`:
```html
<!-- Before -->
<p translate translate-value-label="{{currentFolder.label}}">

<!-- After -->
<p translate translate-value-label="{{currentFolder.label || currentFolder.id}}">
```

### Testing

1. Create a folder without a label
2. Open the folder edit dialog
3. Click remove
4. Verify the confirmation dialog shows the folder ID instead of blank

Fixes #10458

Signed-off-by: RealCharlesChia <161665317+RealCharlesChia@users.noreply.github.com>
2026-04-23 09:02:25 +00:00
Jakob Borg
2721b7b522 chore(model): more efficient tracking of renames during scan (#10653) 2026-04-23 07:20:52 +02:00
Jakob Borg
b1ccf3f3fd chore: trivial fixes (#10650)
... which keep getting filed by AI agents.

Closes #10649, closes #10486, closes #10648, closes #10499, closes
#10647, closes #10635, closes #10636, closes #10607.

---------

Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-04-22 06:38:05 +00:00
Syncthing Release Automation
199e07e3d2 chore(gui, man, authors): update docs, translations, and contributors 2026-04-20 04:46:00 +00:00
Syncthing Release Automation
74997c05e8 chore(gui, man, authors): update docs, translations, and contributors 2026-04-13 04:46:14 +00:00
Ben Norcombe
017ef5a57b fix(gui): order folders alphabetically and ensure local device stays hidden (ref #10563, ref #10631)
### Purpose

There were some additional regression created during #10563 and #10631 which are:

* Folders were not being ordered by their label within their group
* Local device could still show up randomly with the list of remote devices

The respective fixes in this PR does the following:

* Ensure sorting of the grouped folders (and devices) are done by group name (the top level map key) and then by the specified nested object property or a fallback property if specified property value is empty. So in the case of the folders it's `label` and device is `name`.
* When populating the `devicesGrouped` using `$scope.otherDevices`, do this within a watcher on `$scope.myID` as this is what `$scope.otherDevices` relies on to determine what is a remote device. This is required because `$scope.myID` might not be populated yet given the indeterministic call order being made to `refreshSystem` and `refreshConfig`.

### Testing

Populate folders and devices into different groups, and ensure the ordering is correct and the local device is not showing in remote devices even after many, many refreshes on the UI or restarts of syncthing entirely.

### Screenshots

Before the fix

<img width="1108" height="951" alt="Screenshot_20260409_083910" src="https://github.com/user-attachments/assets/6eb8cacc-5924-4612-aa70-29ed4f691233" />

After the fix

<img width="1090" height="934" alt="Screenshot_20260409_084553" src="https://github.com/user-attachments/assets/f5b74391-228a-43d3-b5ee-433958236d84" />

### Documentation

N/A

## Authorship

Ben Norcombe [bennorcombe@pm.me](mailto:bennorcombe@pm.me)
2026-04-11 13:52:20 +02:00
Ben Norcombe
6b9fa76c01 fix(gui): don't show local device under remote devices (ref #10563) (#10631)
### Purpose

Regression was introduced in PR #10563 due to new devices grouping
feature not utlising the otherDevices utility function to ensure the
local device is not shown in the remote devices list

### Testing

Open web GUI and ensure your local device isn't listed under Remote
Devices

### Screenshots

Regression before fix 

<img width="589" height="601" alt="Screenshot_20260407_202526"
src="https://github.com/user-attachments/assets/ffa315e4-f901-4d0c-8755-15b0c31464b3"
/>

Fix

<img width="598" height="555" alt="Screenshot_20260407_202656"
src="https://github.com/user-attachments/assets/8f0721c0-3fd2-4ae5-9db5-23c0d46c268e"
/>


### Documentation

N/A

## Authorship

Ben Norcombe [bennorcombe@pm.me](mailto:bennorcombe@pm.me)

Signed-off-by: Ben Norcombe <bennorcombe@pm.me>
Co-authored-by: Jakob Borg <jakob@kastelo.net>
2026-04-08 16:30:46 +00:00
Jakob Borg
a211fafdc4 policy: pushing invalidates PR approval
Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-04-08 17:48:27 +02:00
Jakob Borg
e4e9402cd9 docs: add release notes for 2.1
Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-04-07 17:25:53 +02:00
Jakob Borg
f806967958 Merge branch 'infrastructure'
* infrastructure:
  chore(stdiscosrv): smooth retry-after delays over a slightly larger normal distribution
  chore(stdiscosrv): optionally delay shutdown
  chore(stdiscosrv): adjust desired seen and unseen rate separately
2026-04-07 17:22:35 +02:00
Ben Norcombe
6a26d56ad9 feat(gui, config): support simple folder grouping (fixes #2070) (#10563)
Adds a very simple way to group up folders to help with organising from
the GUI. 

Signed-off-by: Ben Norcombe <bennorcombe@pm.me>
2026-04-07 17:05:41 +02:00
Jakob Borg
5d877f65f5 build: have dependabot group PRs and use cooldown (#10630)
Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-04-07 16:57:42 +02:00
dagecko
e36bf6d6b1 build: pin 20 third-party actions to immutable commit SHAs (#10625)
fix: pin 20 third-party actions to immutable commit SHAs

Signed-off-by: Chris Nyhuis <cnyhuis@vigilantnow.com>
2026-04-07 16:55:54 +02:00
Jakob Borg
5febc056a8 fix(protocol): limit size of incoming request messages (#10629)
Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-04-07 16:28:18 +02:00
dagecko
f234a61fb4 build: extract github.ref_name expression to env mapping (#10624)
Signed-off-by: Chris Nyhuis <cnyhuis@vigilantnow.com>
2026-04-06 15:24:12 +00:00
Jakob Borg
3ac9b83f40 chore(stdiscosrv): smooth retry-after delays over a slightly larger normal distribution
Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-04-06 14:49:13 +02:00
Jakob Borg
1d4df9c1f4 chore(stdiscosrv): optionally delay shutdown
Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-04-06 11:06:25 +02:00
Jakob Borg
a80b53d113 chore(stdiscosrv): adjust desired seen and unseen rate separately
Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-04-06 10:42:24 +02:00
Jakob Borg
b594b7491f chore: systematic syncthing_build_info metric
Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-04-06 09:44:49 +02:00
Syncthing Release Automation
e2cb283155 chore(gui, man, authors): update docs, translations, and contributors 2026-04-06 04:38:32 +00:00
bt90
ab9b11749c fix(gui): disable autocomplete for folder password (#10342)
Disable autocomplete

Signed-off-by: bt90 <btom1990@googlemail.com>
2026-04-05 14:29:56 +00:00
Syncthing Release Automation
1a3cbca017 chore(gui, man, authors): update docs, translations, and contributors 2026-03-30 04:38:35 +00:00
Marcus Spencer
76f91750c1 build(deps): temporarily switch to fork of gateway discovery library (fixes #10593) (#10594)
Signed-off-by: Marcus B Spencer <marcus@marcusspencer.us>
Signed-off-by: Jakob Borg <jakob@kastelo.net>
Co-authored-by: Jakob Borg <jakob@kastelo.net>
2026-03-29 22:05:06 +02:00
cui
1106e2e332 fix(stdiscosrv): close file descriptor on flush error in write (#10615)
The error path after bw.Flush() failed referenced fd.Close without calling it, so the descriptor was not closed when flush failed.

Signed-off-by: Weixie Cui <cuiweixie@gmail.com>
2026-03-26 00:37:34 +00:00
Syncthing Release Automation
351be52481 chore(gui, man, authors): update docs, translations, and contributors 2026-03-23 04:35:31 +00:00
Jakob Borg
b39c56f82d chore: remove tracking inode change time (#10579)
Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-03-22 20:24:03 -07:00
Syncthing Release Automation
3b05ba2a8f chore(gui, man, authors): update docs, translations, and contributors 2026-03-16 04:37:43 +00:00
Jakob Borg
9ffce6e3ff chore(sqlite): reduce max open connections, keep them open permanently (fixes #10592) (#10596)
chore(sqlite): reduce max open connections, keep them open permanently (fixes #10592)

Reduces connection churn, possibly tickling concurrency bug on Windows.

Signed-off-by: Jakob Borg <jakob@kastelo.net>
v2.0.16-rc.2 v2.0.16
2026-03-13 12:03:22 +00:00
Val Markovic
077a7a0378 fix(systemd): add back chown allowed syscalls (#10605)
fix(systemd): Add back chown allowed syscalls

IFF the user enables the `syncOwnership` feature AND sets
`AmbientCapabilities=CAP_CHOWN CAP_FOWNER` as the docs in
https://docs.syncthing.net/users/autostart.html#permissions state,
THEN syncthing needs to use the `chown` syscall.

PR #10421 added a comprehensive sandbox that breaks `syncOwnership`.
In PR #10602 we fixed one part, which is expanding the default
`CapabilityBoundingSet` (see the PR for details).

But there's a very subtle bug that this PR fixes. PR #10421 sets the
following properties:

    SystemCallFilter=@system-service
    SystemCallFilter=~@privileged io_uring_enter io_uring_register io_uring_setup

(Systemd merges `SystemCallFilter` values; we had to set the property
twice because to negate syscalls, the whole list has to start with `~`.)

The goal was to allow all syscalls in the `@system-service` set, BUT
disallow any `@privileged` syscalls and the `io_uring*` syscalls.

But the sets are not disjoint; `chown` is in both `@system-service` and
in `@privileged`, so it is removed from the allow list by the second
property value.

This property is also parsed in a very peculiar way. From systemd docs:

> If you specify both types of this option (i.e. allow-listing and
> deny-listing), the first encountered will take precedence and will
> dictate the default action (termination or approval of a system call).
> Then the next occurrences of this option will add or delete the listed
> system calls from the set of the filtered system calls, depending of its
> type and the default action. (For example, if you have started with an
> allow list rule for read() and write(), and right after it add a deny
> list rule for write(), then write() will be removed from the set.)

Not only does the order of `SystemCallFilter` properties matter (later
ones can undo effects of prior ones), but the _type_ of the _first_
property sets the overall behavior of the syscall filter: if the first
`SystemCallFilter` value is an allow list, then all syscalls that are
not specified are disallowed by default (and reverse if the first value
is a deny list).

Of course, this is completely different from how other allow/deny lists
are implemented in systemd; for example, `IPAddress[Allow|Deny]`
properties don't work like this at all. >:(

Since this complexity has bit us once, we're removing the additional
deny list of syscalls and sticking with just
`SystemCallFilter=@system-service`.

This leaves some privileged syscalls in the allow list. Other options
would require entering the "deny list by default" mode and deny lists
are less secure than allow lists in general because they have to be
maintained (the kernel always adds new syscalls). The rest of the
sandbox (capability bounds) should be sufficient.

Fixes #10603

Signed-off-by: Val Markovic <val@markovic.io>
2026-03-13 12:53:36 +01:00
Val Markovic
c4ff02def7 fix(systemd): support overrides for syncOwnership (#10602)
Syncthing docs in https://docs.syncthing.net/users/autostart.html#permissions
tell the user to set `AmbientCapabilities=CAP_CHOWN CAP_FOWNER` if the
user wishes to use the `syncOwnership` option.

https://github.com/syncthing/syncthing/pull/10421 broke `syncOwnership`
for users that followed that advice because the PR introduced
`CapabilityBoundingSet=` which cancels out any additional capabilities
granted with `AmbientCapabilities`.

(`AmbientCapabilities` _adds_ capabilities; `CapabilityBoundingSet`
_limits_ maximum capabilities to the specified set. Setting
`CapabilityBoundingSet` to an empty list prevents any capabilities from
being acquired in any way.)

This PR fixes the breakage by explicitly setting

    CapabilityBoundingSet=CAP_CHOWN CAP_FOWNER

This does _not_ grant any additional access rights to syncthing if the
user is not explicitly setting `AmbientCapabilities` as well, but it
does loosen the sandbox _a bit_. An attacker compromising the syncthing
process could now more easily expand their access to include
CAP_CHOWN/CAP_FOWNER even if the user is not setting
`AmbientCapabilities`.

Signed-off-by: Val Markovic <val@markovic.io>
2026-03-11 14:11:50 +01:00
Syncthing Release Automation
55d3b7c5db chore(gui, man, authors): update docs, translations, and contributors 2026-03-09 04:28:28 +00:00
Jakob Borg
fd129825b2 fix(protocol): verify compressed message length before decompression (#10595) 2026-03-07 16:29:14 +01:00
Jakob Borg
8c7c413f5c build(deps): update dependencies (#10588)
Signed-off-by: Jakob Borg <jakob@kastelo.net>
2026-03-04 07:38:45 +01:00
Jakob Borg
9c7e34b3d1 chore: trigger rebuild v2.0.16-rc.1 2026-03-03 22:36:13 +01:00
Syncthing Release Automation
55d89d0efb chore(gui, man, authors): update docs, translations, and contributors 2026-03-02 04:25:40 +00:00
Syncthing Release Automation
76db7c6c7b chore(gui, man, authors): update docs, translations, and contributors 2026-02-23 04:32:49 +00:00
Syncthing Release Automation
ddafc5f6e5 chore(gui, man, authors): update docs, translations, and contributors 2026-02-16 04:33:52 +00:00
Marcus B Spencer
75dd940128 chore(config, connections): use same reconnection interval for QUIC and TCP (fixes #10507) (#10573)
Signed-off-by: Marcus B Spencer <marcus@marcusspencer.us>
2026-02-12 10:41:30 +01:00
Jakob Borg
dc2a77ab8e chore: build with Go 1.26; use Go 1.25 features (#10570)
WaitGroup.Go and built-in gomaxprocs handling.

Signed-off-by: Jakob Borg <jakob@kastelo.net>
v2.0.15-rc.1 v2.0.15
2026-02-11 10:41:38 +00:00
Val Markovic
478d8a007d chore(etc): add more comprehensive systemd sandboxing (#10421)
Update the existing minimal service hardening with a comprehensive
sandbox to minimize blast damage from service compromise.

Please see the detailed code comments for an explanation of what is
sandboxed.

Roughly, we limit: /dev, /proc, /tmp, AF_UNIX, AF_PACKET, execution of
_any_ binary other than "/usr/bin/syncthing" and "/usr/lib",
uncommon syscalls plus io_uring, tons of kernel internals and more. We
also enable a bunch of kernel namespaces for isolation.

In short, pretty much everything is sandboxed and specifically tuned for
syncthing's behavior.

Sadly, we cannot use ProtectSystem=strict by default because we don't
know the directories that the user will be sharing. There's a big
comment block explaining how users can enable it for "extra credit". :)

If the user did add the following options as the unit file recommends:

- ProtectSystem=strict
- ReadWritePaths=/my/shared/dir1 /my/shared/dir2
- ProtectHome=true

Then the user would end up with a *far* more comprehensive sandbox than
anything a container runtime (like Docker/Podman/whatever) would
provide.

Much (but not all) of these options could be ported to the
user/syncthing.service file, BUT it would require work. Systemd does not
allow all of these options to be used with the user service manager,
although using PrivateUsers=true would help with most of it.

I cannot justify the time investment to develop, audit and test the
port to user/syncthing.service so I leave that for interested
contributors.

Tested on Debian Trixie (13) with the following versions:
- v1.29.5, Linux (64-bit Intel/AMD)
- latest HEAD (d3d3fc2d0 committed on Mon Oct 6 01:42:58 2025)

Signed-off-by: Val Markovic <val@markovic.io>
2026-02-11 11:05:49 +01:00
Michael Wang 汪東陽
2ecdc1a593 fix(gui): remove width limit for language select items (#10531)
Signed-off-by: Michael Wang <michael19920327@gmail.com>
2026-02-11 10:54:08 +01:00
Tao
f86c1d83db fix(gui): show restarting modal during upgrade restart (fixes #1248) (#10566)
Signed-off-by: steadytao <mail@steadytao.com>
Signed-off-by: Jakob Borg <jakob@kastelo.net>
Co-authored-by: Jakob Borg <jakob@kastelo.net>
2026-02-11 09:46:37 +00:00
Tommy van der Vorst
5cf9168dc2 chore(db): add ability to wait for programmatically started database maintenance, query last maintenance time (#10565)
Also adds a method to query the last database maintenance time.

Signed-off-by: Tommy van der Vorst <tommy@pixelspark.nl>
Co-authored-by: Jakob Borg <jakob@kastelo.net>
2026-02-11 09:28:11 +00:00
Syncthing Release Automation
0b5a08c99a chore(gui, man, authors): update docs, translations, and contributors 2026-02-09 04:34:38 +00:00