mirror of
https://github.com/profullstack/agentbbs.git
synced 2026-08-13 14:27:27 +00:00
feat(files): web file browser at files.<host> with webmail-password login
Adds a browser-based file manager so members can use their files without an SSH key. Served on a loopback HTTP server (AGENTBBS_FILES_WEB_ADDR, default 127.0.0.1:8092) that Caddy fronts at files.<host>. Members sign in with their webmail username + password, verified against the Mailu IMAP backend (mailbox.VerifyLogin), and browse the same virtual /me + /public areas as SFTP — no home directory is ever exposed. Upload/download/mkdir/delete with the private-area quota enforced; reuses internal/files confinement (fs.go). setup.sh renders the files.<DOMAIN> Caddy site + env knob. Unit tests cover the auth gate and an upload/list/download/delete round trip. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
1dbb2c70e2
commit
cddd9819cc
7 changed files with 835 additions and 1 deletions
|
|
@ -58,6 +58,27 @@ func NewIMAPTransport(cfg IMAPConfig) (Transport, error) {
|
|||
return &imapTransport{cfg: cfg, c: c}, nil
|
||||
}
|
||||
|
||||
// VerifyLogin checks a username/password against the IMAP backend by logging in
|
||||
// and immediately logging out. It returns nil only when the credentials are
|
||||
// accepted. The web file browser uses this to authenticate members with their
|
||||
// webmail (Mailu/Dovecot) password — the same credential Roundcube uses.
|
||||
func VerifyLogin(addr, user, pass string, plaintext bool) error {
|
||||
dial := imapclient.DialTLS
|
||||
if plaintext {
|
||||
dial = imapclient.DialInsecure
|
||||
}
|
||||
c, err := dial(addr, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("imap dial %s: %w", addr, err)
|
||||
}
|
||||
defer func() { _ = c.Close() }()
|
||||
if err := c.Login(user, pass).Wait(); err != nil {
|
||||
return fmt.Errorf("imap login: %w", err)
|
||||
}
|
||||
_ = c.Logout().Wait()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *imapTransport) Close() error {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue