Users logging in with no password will be immediately bounced to the profile page, where they MUST set a password

This commit is contained in:
2026-03-24 14:34:50 -06:00
parent e62656eabe
commit 7a7a837af2
4 changed files with 37 additions and 14 deletions
+1 -1
View File
@@ -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. 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. 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:_ Contributors may use software tools, including AI-assisted tools, but the submitting contributor _must:_
+5 -8
View File
@@ -19,7 +19,7 @@ It provides:
* Multiple communities hosted on a single site * Multiple communities hosted on a single site
* A discussion system featuring the linear conferencing model * A discussion system featuring the linear conferencing model
* Long-form conversation spaces * Long-form conversation spaces
* User identities shared acrioss communities * User identities shared across communities
* Moderation and community management tools * Moderation and community management tools
It is designed for _human-scale communities_ - hundreds or thousands of users, rather than millions. 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 * Multiple communities hosted on a single site
* A discussion system featuring the linear conferencing model * A discussion system featuring the linear conferencing model
* Long-form conversation spaces * Long-form conversation spaces
* User identities shared acrioss communities * User identities shared across communities
* Moderation and community management tools * Moderation and community management tools
* Archival support for historic communities * Archival support for historic communities
* Modern HTML rendering * Modern HTML rendering
## Project status ## Project status
Amsterdam is in its first (early) public release. Amsterdam is in its first (early) public release. The software is capable of running a full community site.
The software is capable of running a full community site, and is currently being used to host [Electric Minds Reborn](https://electricminds.org).
The project is under active development, and APIs and internal structures may change between releases. 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 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. 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 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 no password. After logging in, you will be immediately bounced to the profile page, where you _must_ set a password.
password.
## Contributing ## Contributing
+25 -5
View File
@@ -140,7 +140,11 @@ func Login(ctxt ui.AmContext) (string, any) {
} }
} }
if user.VerifyEMail { if user.VerifyEMail {
return "redirect", target if user.Passhash == "" {
return "redirect", "/profile?tgt=" + url.QueryEscape(target)
} else {
return "redirect", target
}
} else { } else {
return "redirect", "/verify?tgt=" + url.QueryEscape(target) 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 is already verified, this is a no-op.
if user.VerifyEMail { 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") 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 is already verified, this is a no-op.
if user.VerifyEMail { if user.VerifyEMail {
return "redirect", target if user.Passhash == "" {
return "redirect", "/profile?tgt=" + url.QueryEscape(target)
} else {
return "redirect", target
}
} }
action := dlg.WhichButton(ctxt) action := dlg.WhichButton(ctxt)
if action == "cancel" { // Cancel button pressed 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" { if action == "sendagain" {
var ci *database.ContactInfo var ci *database.ContactInfo
@@ -283,7 +299,11 @@ func VerifyEMail(ctxt ui.AmContext) (string, any) {
cn, _ := dlg.Field("num").ValueInt() cn, _ := dlg.Field("num").ValueInt()
err = user.ConfirmEMailAddress(ctxt.Ctx(), int32(cn), ctxt.RemoteIP()) err = user.ConfirmEMailAddress(ctxt.Ctx(), int32(cn), ctxt.RemoteIP())
if err == nil { 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()) return dlg.RenderError(ctxt, err.Error())
+6
View File
@@ -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("no_mass_mail").SetChecked(u.FlagValue(ctxt.Ctx(), database.UserFlagMassMailOptOut))
dlg.Field("locale").Value = prefs.ReadLocale() dlg.Field("locale").Value = prefs.ReadLocale()
dlg.Field("tz").Value = prefs.TimeZoneID 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) return dlg.Render(ctxt)
} }
} }
@@ -157,6 +160,9 @@ func EditProfile(ctxt ui.AmContext) (string, any) {
if err != nil { if err != nil {
return dlg.RenderError(ctxt, err.Error()) 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 var ci *database.ContactInfo
ci, err = u.ContactInfo(ctxt.Ctx()) ci, err = u.ContactInfo(ctxt.Ctx())
if err == nil { if err == nil {