mirror of
https://github.com/profullstack/agentbbs.git
synced 2026-08-13 14:27:27 +00:00
fix(join): stop rotating a returning member's webmail password (#104)
handleJoin called setWebmailPassword unconditionally, so every visit to join@ minted a fresh Roundcube password -- including for members who registered and verified long ago. join@ is the address people remember, so returning members type it out of habit. Doing so silently invalidated their webmail login: the replacement password scrolled past once in the join output, the old one was already dead, and nothing in the session said a credential had changed. The failure surfaces later, as "my password stopped working", with no way to connect it back to having typed join@ -- and it reads like a compromised account, which is an alarming thing to hand someone over a no-op visit. Mint the password only while actually onboarding: a new key registering, or an account that completes email verification in this session. A returning member is told the password is unchanged and pointed at passwd@, which already sets one password across git, mail and chat and is key-gated, so it doubles as the forgot-password path. Also replace the bare webmail URL line shown when no password is minted with the full url/login block, so the address and where to get credentials are always visible, and distinguish "unchanged" (returning) from "not set yet" (onboarding, but Mailu was unreachable). Verified by inspection only: this box has no Go toolchain (repo needs 1.26), so the build is left to CI. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
20cdb6432d
commit
41174eec03
1 changed files with 46 additions and 6 deletions
|
|
@ -753,6 +753,10 @@ func (a *app) handleJoin(s ssh.Session) {
|
|||
wish.Fatalln(s, "registration error: "+err.Error())
|
||||
return
|
||||
}
|
||||
// Whether this session actually onboarded anyone: a brand-new key here, or an
|
||||
// account that finishes email verification below. Everything with a credential
|
||||
// side effect keys off this rather than off reaching join@ at all.
|
||||
onboarding := !found
|
||||
if !found {
|
||||
// New key: show the acceptable-use terms and require acceptance before
|
||||
// creating the account, then let the visitor pick their own handle (a
|
||||
|
|
@ -783,6 +787,7 @@ func (a *app) handleJoin(s ssh.Session) {
|
|||
return
|
||||
}
|
||||
a.notifySignup(u)
|
||||
onboarding = true
|
||||
}
|
||||
|
||||
// Every verified member gets a homepage at https://<host>/~<name> and a
|
||||
|
|
@ -791,11 +796,26 @@ func (a *app) handleJoin(s ssh.Session) {
|
|||
_ = a.ensureMailbox(u)
|
||||
// Give them a webmail password so free members can log into webmail. The
|
||||
// in-BBS reader uses the gateway master user and needs no password, but
|
||||
// Roundcube does. (Re)set on each join@; they can change it in webmail.
|
||||
webmailPW := a.setWebmailPassword(u)
|
||||
// Roundcube does.
|
||||
//
|
||||
// Only while ONBOARDING. This used to run on every join@, which quietly broke
|
||||
// returning members: join@ is the address people remember, so typing it again
|
||||
// out of habit rotated a live Roundcube password: the replacement scrolled past
|
||||
// in this output once, the old one was already dead, and nothing said a
|
||||
// credential had changed. Rotating a working password must never be a side
|
||||
// effect of saying hello -- passwd@ is the deliberate way to change one, and it
|
||||
// is already key-gated, so it doubles as the forgot-password path.
|
||||
var webmailPW string
|
||||
if onboarding {
|
||||
webmailPW = a.setWebmailPassword(u)
|
||||
}
|
||||
|
||||
lead := " You're in. One login gets you everything — no other servers to ssh into:"
|
||||
if !onboarding {
|
||||
lead = " You're already a member — nothing changed. One login gets you everything:"
|
||||
}
|
||||
includes := []string{
|
||||
" You're in. One login gets you everything — no other servers to ssh into:",
|
||||
lead,
|
||||
"",
|
||||
" ssh " + u.Name + "@" + a.host,
|
||||
"",
|
||||
|
|
@ -806,7 +826,8 @@ func (a *app) handleJoin(s ssh.Session) {
|
|||
" • the arcade & games",
|
||||
" • your homepage https://" + a.host + "/~" + u.Name,
|
||||
}
|
||||
if a.webmailURL != "" && webmailPW != "" {
|
||||
switch {
|
||||
case a.webmailURL != "" && webmailPW != "":
|
||||
includes = append(includes,
|
||||
"",
|
||||
" Webmail (read your mail in a browser):",
|
||||
|
|
@ -814,8 +835,27 @@ func (a *app) handleJoin(s ssh.Session) {
|
|||
" • login "+a.mailAddress(u.Name),
|
||||
" • password "+webmailPW+" (change it in webmail Settings)",
|
||||
)
|
||||
} else if a.webmailURL != "" {
|
||||
includes = append(includes, " • webmail "+a.webmailURL)
|
||||
case a.webmailURL != "" && !onboarding:
|
||||
// Say the password is untouched. A returning member who came here looking
|
||||
// for their credentials needs to know this visit did not change them, and
|
||||
// where to go if they have lost them.
|
||||
includes = append(includes,
|
||||
"",
|
||||
" Webmail (read your mail in a browser):",
|
||||
" • url "+a.webmailURL,
|
||||
" • login "+a.mailAddress(u.Name),
|
||||
" • password unchanged — forgot it? ssh passwd@"+a.host,
|
||||
)
|
||||
case a.webmailURL != "":
|
||||
// Onboarding, but minting the password failed (Mailu down or unconfigured).
|
||||
// Don't imply one is waiting for them -- point at the way to set one.
|
||||
includes = append(includes,
|
||||
"",
|
||||
" Webmail (read your mail in a browser):",
|
||||
" • url "+a.webmailURL,
|
||||
" • login "+a.mailAddress(u.Name),
|
||||
" • password not set yet — set one: ssh passwd@"+a.host,
|
||||
)
|
||||
}
|
||||
wish.Println(s, "\n"+strings.Join(includes, "\n"))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue