files: make ~member browsable before first session

A valid member's ~name 404'd until they'd opened their first SFTP/web
session, because joining onto a not-yet-created site dir tripped the
safeJoin escape guard (it walks up to sites/, outside the per-user root).
AnonRoot now materializes the idempotent site dir for a known member, so
~name renders an empty listing the moment the account exists. Missing
sub-paths and unknown members still 404. Adds a regression test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Anthony Ettinger 2026-06-26 01:03:12 +00:00
parent 192b117fc1
commit 87fb2b4a1f
3 changed files with 48 additions and 1 deletions

View file

@ -229,6 +229,12 @@ func (s *Service) AnonRoot(name string) (root string, ok bool, err error) {
if !found || u.Banned {
return "", false, nil
}
// Materialize the (idempotent) site dir so ~name is browsable the moment the
// account exists — before the member's first SFTP/web session creates it.
// Without this, joining onto a missing root trips the escape guard.
if err := s.ensureSite(u.Name); err != nil {
return "", false, err
}
return s.siteRoot(u.Name), true, nil
}