From 7a7a837af2fc984c82b3af79dd6c0a61487ca6d6 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Tue, 24 Mar 2026 14:34:50 -0600 Subject: [PATCH] Users logging in with no password will be immediately bounced to the profile page, where they MUST set a password --- CODE-OF-CONDUCT.md | 2 +- README.md | 13 +++++-------- login.go | 30 +++++++++++++++++++++++++----- userdata.go | 6 ++++++ 4 files changed, 37 insertions(+), 14 deletions(-) diff --git a/CODE-OF-CONDUCT.md b/CODE-OF-CONDUCT.md index bafb1ea..ff4a499 100644 --- a/CODE-OF-CONDUCT.md +++ b/CODE-OF-CONDUCT.md @@ -36,7 +36,7 @@ Participants in the Amsterdam project are expected to: Contributions must be the _own work_ of the contributor. Plagiarism in any form is unacceptable. -All project contributions must be submitted by _identifiable human participants_ who accept full responibility for their content. +All project contributions must be submitted by _identifiable human participants_ who accept full responsibility for their content. Automated agents, bots, or autonomous AI systems _may not_ independently submit issues, pull requests, or other contributions. Contributors may use software tools, including AI-assisted tools, but the submitting contributor _must:_ diff --git a/README.md b/README.md index 435840d..921b5de 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ It provides: * Multiple communities hosted on a single site * A discussion system featuring the linear conferencing model * Long-form conversation spaces -* User identities shared acrioss communities +* User identities shared across communities * Moderation and community management tools It is designed for _human-scale communities_ - hundreds or thousands of users, rather than millions. @@ -98,16 +98,14 @@ Dutch Golden Age. * Multiple communities hosted on a single site * A discussion system featuring the linear conferencing model * Long-form conversation spaces -* User identities shared acrioss communities +* User identities shared across communities * Moderation and community management tools * Archival support for historic communities * Modern HTML rendering ## Project status -Amsterdam is in its first (early) public release. - -The software is capable of running a full community site, and is currently being used to host [Electric Minds Reborn](https://electricminds.org). +Amsterdam is in its first (early) public release. The software is capable of running a full community site. The project is under active development, and APIs and internal structures may change between releases. @@ -180,11 +178,10 @@ or with the `AMSTERDAM_CONFIG` environment variable. The exact format of the configuration file is shown in the `config/default.yaml` file. When creating an Amsterdam configuration file, you do not have to specify options for which you do not wish to change the default. -## Initial Login +### Initial Login After starting Amsterdam, you can log into the administrator account, which has the user name "Administrator" with -no password. _Please set a password as soon as possible!_ Click the "Profile" link in the top bar to change the -password. +no password. After logging in, you will be immediately bounced to the profile page, where you _must_ set a password. ## Contributing diff --git a/login.go b/login.go index 26a8c00..dbed6b2 100644 --- a/login.go +++ b/login.go @@ -140,7 +140,11 @@ func Login(ctxt ui.AmContext) (string, any) { } } if user.VerifyEMail { - return "redirect", target + if user.Passhash == "" { + return "redirect", "/profile?tgt=" + url.QueryEscape(target) + } else { + return "redirect", target + } } else { return "redirect", "/verify?tgt=" + url.QueryEscape(target) } @@ -199,7 +203,11 @@ func VerifyEmailForm(ctxt ui.AmContext) (string, any) { // If user is already verified, this is a no-op. if user.VerifyEMail { - return "redirect", target + if user.Passhash == "" { + return "redirect", "/profile?tgt=" + url.QueryEscape(target) + } else { + return "redirect", target + } } dlg, err := ui.AmLoadDialog("verify_email") @@ -255,12 +263,20 @@ func VerifyEMail(ctxt ui.AmContext) (string, any) { // If user is already verified, this is a no-op. if user.VerifyEMail { - return "redirect", target + if user.Passhash == "" { + return "redirect", "/profile?tgt=" + url.QueryEscape(target) + } else { + return "redirect", target + } } action := dlg.WhichButton(ctxt) if action == "cancel" { // Cancel button pressed - return "redirect", target + if user.Passhash == "" { + return "redirect", "/profile?tgt=" + url.QueryEscape(target) + } else { + return "redirect", target + } } if action == "sendagain" { var ci *database.ContactInfo @@ -283,7 +299,11 @@ func VerifyEMail(ctxt ui.AmContext) (string, any) { cn, _ := dlg.Field("num").ValueInt() err = user.ConfirmEMailAddress(ctxt.Ctx(), int32(cn), ctxt.RemoteIP()) if err == nil { - return "redirect", target + if user.Passhash == "" { + return "redirect", "/profile?tgt=" + url.QueryEscape(target) + } else { + return "redirect", target + } } } return dlg.RenderError(ctxt, err.Error()) diff --git a/userdata.go b/userdata.go index 71cd6b3..6707498 100644 --- a/userdata.go +++ b/userdata.go @@ -107,6 +107,9 @@ func EditProfileForm(ctxt ui.AmContext) (string, any) { dlg.Field("no_mass_mail").SetChecked(u.FlagValue(ctxt.Ctx(), database.UserFlagMassMailOptOut)) dlg.Field("locale").Value = prefs.ReadLocale() dlg.Field("tz").Value = prefs.TimeZoneID + if u.Passhash == "" { + ctxt.VarMap().Set("__infoMessage", "Your password is not set. Please set one.") + } return dlg.Render(ctxt) } } @@ -157,6 +160,9 @@ func EditProfile(ctxt ui.AmContext) (string, any) { if err != nil { return dlg.RenderError(ctxt, err.Error()) } + if u.Passhash == "" && dlg.Field("pass1").IsEmpty() && dlg.Field("pass2").IsEmpty() { + return dlg.RenderError(ctxt, "Your password is not set. Please set one.") + } var ci *database.ContactInfo ci, err = u.ContactInfo(ctxt.Ctx()) if err == nil {