#1685 fixed the dashboard rebuilding a log row by hand and dropping
`origin` from it. One layer down, the same method was skipping something
larger: it ran a bare ActivityLog::query(), so ActivityLogScope never
applied.
That scope exists for this exact case, and says so in its own docblock —
`view_actions_log` is not the whole answer for a client-scoped staff
member, because a log entry carries the subject's *name*. An unscoped log
reads out the name of every file in the installation, and who touched it,
to somebody who gets a 403 on the files themselves.
Measured before the fix, one client-scoped viewer with the permission:
/activity → []
/dashboard → Uploaded the file "Q3 delinquent accounts"
Same person, same permission, opposite answers. The activity page and the
download history both apply the scope; the dashboard was the one caller
that did not, which is the same shape of gap #1685 was about.
More reachable than it looks: the Client Manager system role ships with
`view_actions_log`, so this is the default configuration rather than
something an administrator has to build.
Two tests: a scoped viewer sees only the entry about a file in their
library, and an unscoped one still sees everything.
transferSeries() is left alone on purpose. It is unscoped too, but it
returns per-day counts with no names or subjects attached, which is a
different exposure and arguably not one at all.
The Recent activity widget rebuilt each log entry inline instead of going
through ActivityPresenter, and the inline copy dropped `origin`. On the
frontend "System" and "Anonymous" are both actor_name null and only
`origin` tells them apart, so every actorless entry -- public and
share-link downloads, anonymous comments -- rendered as "System ...".
Present the entries through the shared ActivityPresenter, the same
sentence-ready shape the activity page and detail panels already use, so
the dashboard cannot drift from them again.
Client file sharing, rebuilt from the ground up: a private area per
client, resumable uploads, folders, groups and categories, sharing with
expiry dates and download limits, comments, file versions, an activity
log, a REST API, and sixteen languages.
This repository begins here. ProjectSend 2 was developed privately, and
that development history is not published — the previous generation
remains available, with its own history, at projectsend/legacy.
Free software under the GNU General Public License v2, or (at your
option) any later version.