diff --git a/conference_ops.go b/conference_ops.go index aaeefaa..7591614 100644 --- a/conference_ops.go +++ b/conference_ops.go @@ -122,6 +122,47 @@ func AttachmentSend(ctxt ui.AmContext) (string, any, error) { return "bytes", data, nil } +/* ConfManage displays the "manage conference" page. + * Parameters: + * ctxt - The AmContext for the request. + * Returns: + * Command string dictating what to be rendered. + * Data as a parameter for the command string. + * Standard Go error status. + */ +func ConfManage(ctxt ui.AmContext) (string, any, error) { + comm := ctxt.CurrentCommunity() + conf := ctxt.GetScratch("currentConference").(*database.Conference) + myLevel := ctxt.GetScratch("levelInConference").(uint16) + urlStem := fmt.Sprintf("/comm/%s/conf/%s", comm.Alias, ctxt.GetScratch("currentAlias")) + ctxt.VarMap().Set("confName", conf.Name) + ctxt.VarMap().Set("urlStem", urlStem) + + pseud, err := conf.DefaultPseud(ctxt.Ctx(), ctxt.CurrentUser()) + if err != nil { + return ui.ErrorPage(ctxt, err) + } + ctxt.VarMap().Set("pseud", pseud) + + if ctxt.CurrentUser().IsAnon { + ctxt.VarMap().Set("canInvite", false) + } else { + member, _, _, err := comm.Membership(ctxt.Ctx(), ctxt.CurrentUser()) + if err != nil { + return ui.ErrorPage(ctxt, err) + } + ctxt.VarMap().Set("canInvite", member) + } + + if conf.TestPermission("Conference.Change", myLevel) || conf.TestPermission("Conference.Delete", myLevel) { + menu := ui.AmMenu("confhost").FilterConference(comm, ctxt.GetScratch("currentAlias").(string)) + ctxt.VarMap().Set("menu", menu) + } + + ctxt.VarMap().Set("amsterdam_pageTitle", "Manage Conference: "+conf.Name) + return "framed_template", "manage_conf.jet", nil +} + /* AddToHotlist adds the current community and conference to the user's hotlist.. * Parameters: * ctxt - The AmContext for the request. diff --git a/database/user.go b/database/user.go index 4b88bbf..78d780a 100644 --- a/database/user.go +++ b/database/user.go @@ -564,8 +564,14 @@ func AmAuthenticateUser(ctx context.Context, name string, password string, remot ar = AmNewAudit(AuditLoginFail, user.Uid, remoteIP, "Account locked out") return nil, errors.New("this account has been administratively locked; please contact the system administrator for assistance") } - h := hashPassword(password) - if h != user.Passhash { + passok := false + if user.Passhash == "" { + passok = (password == "") + } else { + h := hashPassword(password) + passok = strings.EqualFold(h, user.Passhash) + } + if !passok { log.Warn("...invalid password") ar = AmNewAudit(AuditLoginFail, user.Uid, remoteIP, "Bad password") return nil, errors.New("the password you have specified is incorrect; please try again") diff --git a/docs/MISSINGFUNCS.md b/docs/MISSINGFUNCS.md index 21a8a22..efc8074 100644 --- a/docs/MISSINGFUNCS.md +++ b/docs/MISSINGFUNCS.md @@ -49,5 +49,17 @@ _(italicized items can be deferred)_ - Sidebox configuration - Topics view: - Find - - Manage + - Manage: + - Set pseud + - Fixseen + - Send invite + - Change information + - Manage aliases + - Manage members + - Custom appearance + - Activity reports + - E-mail + - Export Messages + - Import Messages + - Delete Conference - ~~Add to Hotlist/Remove from Hotlist~~ diff --git a/main.go b/main.go index f1240d9..900d898 100644 --- a/main.go +++ b/main.go @@ -101,6 +101,7 @@ func setupEcho() *echo.Echo { confGroup.GET("", ui.AmWrap(Topics)) confGroup.GET("/new_topic", ui.AmWrap(NewTopicForm)) confGroup.POST("/new_topic", ui.AmWrap(NewTopic)) + confGroup.GET("/manage", ui.AmWrap(ConfManage)) confGroup.GET("/hotlist", ui.AmWrap(AddToHotlist)) confGroup.GET("/r/:topic", ui.AmWrap(ReadPosts), ui.SetTopic) confGroup.POST("/r/:topic", ui.AmWrap(PostInTopic), ui.SetTopic) diff --git a/ui/menudefs.yaml b/ui/menudefs.yaml index dcc2925..d7f3e43 100644 --- a/ui/menudefs.yaml +++ b/ui/menudefs.yaml @@ -1,6 +1,6 @@ # # Amsterdam Web Communities System -# Copyright (c) 2025 Erbosoft Metaverse Design Solutions, All Rights Reserved +# Copyright (c) 2025-2026 Erbosoft Metaverse Design Solutions, All Rights Reserved # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this @@ -84,3 +84,29 @@ menudefs: link: "/TODO/comm/[CID]/admin/delete" permission: "Community.Delete" hazard: true + - id: "confhost" + title: "Host Tools" + permset: "conference" + warning: > + Note: These tools provide access to sensitive administrative features for the + conference. Use with care and review all changes before applying them to the conference. + items: + - text: "Change Conference Information" + link: "/TODO/comm/[CID]/conf/[CONFID]/info" + - text: "Manage Conference Aliases" + link: "/TODO/comm/[CID]/conf/[CONFID]/aliases" + - text: "Manage Conference Members" + link: "/TODO/comm/[CID]/conf/[CONFID]/members" + - text: "Customize Conference Appearance" + link: "/TODO/comm/[CID]/conf/[CONFID]/custom" + - text: "Conference Activity Reports" + link: "/TODO/comm/[CID]/conf/[CONFID]/activity" + - text: "Conference E-Mail" + link: "/TODO/comm/[CID]/conf/[CONFID]/email" + - text: "Export Messages" + link: "/TODO/comm/[CID]/conf/[CONFID]/export" + - text: "Import Messages" + link: "/TODO/comm/[CID]/conf/[CONFID]/import" + - text: "Delete Conference" + link: "/TODO/comm/[CID]/conf/[CONFID]/delete" + hazard: true diff --git a/ui/menus.go b/ui/menus.go index 47e7e7e..c419eaa 100644 --- a/ui/menus.go +++ b/ui/menus.go @@ -1,6 +1,6 @@ /* * Amsterdam Web Communities System - * Copyright (c) 2025 Erbosoft Metaverse Design Solutions, All Rights Reserved + * Copyright (c) 2025-2026 Erbosoft Metaverse Design Solutions, All Rights Reserved * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -98,6 +98,30 @@ func (mdef *MenuDefinition) FilterCommunity(comm *database.Community) *MenuDefin return &newmd } +// FilterConference creates a copy of this menu filtered to the specified community and conference. +func (mdef *MenuDefinition) FilterConference(comm *database.Community, confAlias string) *MenuDefinition { + newmd := MenuDefinition{ + ID: mdef.ID, + Title: mdef.Title, + Subtitle: strings.ReplaceAll(mdef.Subtitle, "[CNAME]", comm.Name), + PermSet: mdef.PermSet, + Warning: mdef.Warning, + Items: make([]MenuItem, len(mdef.Items)), + Tag: mdef.Tag, + } + for i, it := range mdef.Items { + newmd.Items[i].Text = it.Text + s1 := strings.ReplaceAll(it.Link, "[CID]", comm.Alias) + newmd.Items[i].Link = strings.ReplaceAll(s1, "[CONFID]", confAlias) + newmd.Items[i].Disabled = it.Disabled + newmd.Items[i].Hazard = it.Hazard + newmd.Items[i].Permission = it.Permission + newmd.Items[i].Ifdef = it.Ifdef + newmd.Items[i].P = &newmd + } + return &newmd +} + // MenuDefs represents the set of all menu definitions. type MenuDefs struct { D []MenuDefinition `yaml:"menudefs"` diff --git a/ui/views/manage_conf.jet b/ui/views/manage_conf.jet new file mode 100644 index 0000000..f758336 --- /dev/null +++ b/ui/views/manage_conf.jet @@ -0,0 +1,91 @@ +{* + * Amsterdam Web Communities System + * Copyright (c) 2025-2026 Erbosoft Metaverse Design Solutions, All Rights Reserved + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + *} +
+ +
+

Manage Conference:

+ {{ confName }} +
+
+ + +
+ Return to Topic List +
+ + +
+
+ + + +
+
+ + +
+ Mark entire conference as read (fixseen) +
+ + {{ if canInvite }} + +
+

Send Invitation

+
+
+ + +
+ You may send an invitation via E-mail to outside individuals to join this community and read this conference. +
+
+ Click here to send an invitation +
+ {{ end }} + + {{ if isset(menu) }} + +
+

{{ menu.Title }}

+
+
+ + +
+
+ +
+ {{ if menu.Warning != "" }} +
+

{{ menu.Warning | raw }}

+
+ {{ end }} +
+ {{ end }} + +
diff --git a/ui/views/topiclist.jet b/ui/views/topiclist.jet index bb3e4a3..791d688 100644 --- a/ui/views/topiclist.jet +++ b/ui/views/topiclist.jet @@ -36,7 +36,7 @@ class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded text-sm font-medium transition-colors"> Find - Manage