import posts at least partially tested, we should do some more work on it - also, a few other bugs have been stomped

This commit is contained in:
2026-02-28 22:58:56 -07:00
parent 210712a58d
commit 9a3860f796
10 changed files with 96 additions and 44 deletions
+8
View File
@@ -19,5 +19,13 @@
"program": "${workspaceFolder}",
"args": ["-C", "${workspaceFolder}/test.yaml"]
},
{
"name": "Import Test",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}",
"args": ["-C", "${workspaceFolder}/test2.yaml"]
},
]
}
+3 -4
View File
@@ -782,11 +782,10 @@ func CreateCommunity(ctxt ui.AmContext) (string, any) {
}
var testcomm *database.Community
testcomm, err = database.AmGetCommunityByAlias(ctxt.Ctx(), dlg.Field("alias").Value)
if err != nil {
return dlg.RenderError(ctxt, err.Error())
}
if testcomm != nil {
if err == nil {
return dlg.RenderError(ctxt, fmt.Sprintf("A community with the alias \"%s\" already exists; please try again.", testcomm.Alias))
} else if err != database.ErrNoCommunity {
return dlg.RenderError(ctxt, err.Error())
}
var hideDir, hideSearch bool
switch dlg.Field("hidemode").Value {
+6 -1
View File
@@ -765,6 +765,7 @@ func ConferenceImport(ctxt ui.AmContext) (string, any) {
if ctxt.Verb() == "GET" {
ctxt.VarMap().Set("confName", conf.Name)
ctxt.VarMap().Set("selfLink", fmt.Sprintf("/comm/%s/conf/%s/import", comm.Alias, ctxt.GetScratch("currentAlias")))
ctxt.SetFrameTitle("Import Messages: " + conf.Name)
return "framed", "conf_import.jet"
}
@@ -784,6 +785,7 @@ func ConferenceImport(ctxt ui.AmContext) (string, any) {
default:
ctxt.VarMap().Set("errorMessage", "Invalid matching parameter.")
ctxt.VarMap().Set("confName", conf.Name)
ctxt.VarMap().Set("selfLink", fmt.Sprintf("/comm/%s/conf/%s/import", comm.Alias, ctxt.GetScratch("currentAlias")))
ctxt.SetFrameTitle("Import Messages: " + conf.Name)
return "framed", "conf_import.jet"
}
@@ -792,6 +794,7 @@ func ConferenceImport(ctxt ui.AmContext) (string, any) {
if err != nil {
ctxt.VarMap().Set("errorMessage", err.Error())
ctxt.VarMap().Set("confName", conf.Name)
ctxt.VarMap().Set("selfLink", fmt.Sprintf("/comm/%s/conf/%s/import", comm.Alias, ctxt.GetScratch("currentAlias")))
ctxt.SetFrameTitle("Import Messages: " + conf.Name)
return "framed", "conf_import.jet"
}
@@ -799,6 +802,7 @@ func ConferenceImport(ctxt ui.AmContext) (string, any) {
if err != nil {
ctxt.VarMap().Set("errorMessage", err.Error())
ctxt.VarMap().Set("confName", conf.Name)
ctxt.VarMap().Set("selfLink", fmt.Sprintf("/comm/%s/conf/%s/import", comm.Alias, ctxt.GetScratch("currentAlias")))
ctxt.SetFrameTitle("Import Messages: " + conf.Name)
return "framed", "conf_import.jet"
}
@@ -807,11 +811,12 @@ func ConferenceImport(ctxt ui.AmContext) (string, any) {
if err != nil {
ctxt.VarMap().Set("errorMessage", err.Error())
ctxt.VarMap().Set("confName", conf.Name)
ctxt.VarMap().Set("selfLink", fmt.Sprintf("/comm/%s/conf/%s/import", comm.Alias, ctxt.GetScratch("currentAlias")))
ctxt.SetFrameTitle("Import Messages: " + conf.Name)
return "framed", "conf_import.jet"
}
ctxt.VarMap().Set("backLink", "/sysadmin")
ctxt.VarMap().Set("backLink", fmt.Sprintf("/comm/%s/conf/%s/manage", comm.Alias, ctxt.GetScratch("currentAlias")))
ctxt.VarMap().Set("headline", fmt.Sprintf("Processed %d topic(s) and added %d new post(s).", topics, posts))
ctxt.VarMap().Set("scroll", scroll)
ctxt.SetFrameTitle("Import Results")
+19 -3
View File
@@ -568,8 +568,17 @@ func (c *Conference) TouchPost(ctx context.Context, tx *sqlx.Tx, u *User, lastPo
// UnreadMessages returns the total number of unread messages in a conference for a user.
func (c *Conference) UnreadMessages(ctx context.Context, u *User) (int32, error) {
var count int32
err := amdb.GetContext(ctx, &count, `SELECT COUNT(*) FROM topics t LEFT JOIN topicsettings s
ON t.topicid = s.topicid AND s.uid = ? WHERE t.confid = ? AND t.archived = 0 AND (s.hidden IS NULL OR s.hidden = 0)`, u.Uid, c.ConfId)
if err != nil {
return -1, err
}
if count == 0 {
return 0, nil
}
var rc int32
err := amdb.GetContext(ctx, &rc, `SELECT SUM(t.top_message - IFNULL(s.last_message,-1))
err = amdb.GetContext(ctx, &rc, `SELECT SUM(t.top_message - IFNULL(s.last_message,-1))
FROM topics t LEFT JOIN topicsettings s ON t.topicid = s.topicid AND s.uid = ?
WHERE t.confid = ? AND t.archived = 0 AND (s.hidden IS NULL OR s.hidden = 0)`, u.Uid, c.ConfId)
return rc, err
@@ -1284,10 +1293,17 @@ func AmCreateConference(ctx context.Context, comm *Community, name, alias, descr
}
// Get the current "last" sequence number.
var seq int
if err = tx.GetContext(ctx, &seq, "SELECT MAX(sequence) FROM commtoconf WHERE commid = ?", comm.Id); err != nil {
seq := 0
count := 0
if err = tx.GetContext(ctx, &count, "SELECT COUNT(*) FROM commtoconf WHERE commid = ?", comm.Id); err != nil {
return nil, err
}
if count > 0 {
if err = tx.GetContext(ctx, &seq, "SELECT MAX(sequence) FROM commtoconf WHERE commid = ?", comm.Id); err != nil {
return nil, err
}
}
// else assume we start with a 0 sequence
// Link the conference into the community, and set the hide flag.
if _, err = tx.ExecContext(ctx, "INSERT INTO commtoconf (commid, confid, sequence, hide_list) VALUES (?, ?, ?, ?)", comm.Id, rc.ConfId,
+3 -1
View File
@@ -757,9 +757,11 @@ func AmCreateNewUser(ctx context.Context, username string, password string, remi
}
// Insert the user record.
ecn := util.GenerateRandomConfirmationNumber()
log.Debugf("generated E-mail confirmation number %d", ecn)
_, err = tx.ExecContext(ctx, `INSERT INTO users (username, passhash, verify_email, lockout, email_confnum,
base_lvl, created, lastaccess, passreminder, description, dob) VALUES (?, ?, 0, 0, ?, ?, NOW(), NOW(), ?, '', ?)`,
username, hashPassword(password), util.GenerateRandomConfirmationNumber(), AmDefaultRole("Global.NewUser").Level(),
username, hashPassword(password), ecn, AmDefaultRole("Global.NewUser").Level(),
reminder, dob)
if err != nil {
return nil, err
+1 -1
View File
@@ -61,7 +61,7 @@ CREATE TABLE users (
verify_email TINYINT DEFAULT 0,
lockout TINYINT DEFAULT 0,
access_tries SMALLINT DEFAULT 0,
email_confnum MEDIUMINT DEFAULT 0,
email_confnum INT DEFAULT 0,
base_lvl SMALLINT UNSIGNED NOT NULL,
created DATETIME NOT NULL,
lastaccess DATETIME,
+1 -1
View File
@@ -69,7 +69,7 @@ CREATE TABLE users (
verify_email TINYINT DEFAULT 0,
lockout TINYINT DEFAULT 0,
access_tries SMALLINT DEFAULT 0,
email_confnum MEDIUMINT DEFAULT 0,
email_confnum INT DEFAULT 0,
base_lvl SMALLINT UNSIGNED NOT NULL,
created DATETIME NOT NULL,
lastaccess DATETIME,
+1 -1
View File
@@ -31,7 +31,7 @@
{{ end }}
<!-- Upload Form -->
<form method="POST" enctype="multipart/form-data" action="/sysadmin/import" class="max-w-3xl">
<form method="POST" enctype="multipart/form-data" action="{{ selfLink }}" class="max-w-3xl">
<div class="bg-gray-50 p-6 rounded-lg">
<div class="mb-6 flex gap-2">
<label for="idata" class="block text-black text-sm font-medium mb-2">
+31 -27
View File
@@ -18,36 +18,40 @@
<div class="max-w-4xl">
<div class="bg-gray-50 p-6 rounded-lg mb-6">
<div class="space-y-6">
{{ range i, c := conferences }}
<div class="flex items-start gap-3">
<span class="text-lg pt-0.5 flex-shrink-0">🟣</span>
<div class="flex-1">
<div class="mb-2">
<a href="/comm/{{ commAlias }}/conf/{{ c.Alias }}"
class="text-blue-700 hover:text-blue-900 font-bold text-lg">{{ c.Name }}</a>
<span class="text-gray-600 text-sm ml-2">- Latest activity: {{ DisplayActivity(c.LastUpdate, .) }}</span>
{{ if newflag[i] }}
<span class="ml-2" title="There are new messages in this conference">🔔</span>
{{ end }}
</div>
<div class="text-sm text-gray-700 mb-1">
{{ if len(c.Hosts) == 1 }}
<span class="font-medium">Host:</span>
{{ else }}
<span class="font-medium">Hosts:</span>
{{ end }}
{{ if len(c.Hosts) > 0 }}
{{ range j, u := c.Hosts }}
{{ if j > 0 }}, {{ end }}
<a href="/users/{{ u }}" class="text-blue-700 hover:text-blue-900">{{ u }}</a>
{{ if len(conferences) > 0 }}
{{ range i, c := conferences }}
<div class="flex items-start gap-3">
<span class="text-lg pt-0.5 flex-shrink-0">🟣</span>
<div class="flex-1">
<div class="mb-2">
<a href="/comm/{{ commAlias }}/conf/{{ c.Alias }}"
class="text-blue-700 hover:text-blue-900 font-bold text-lg">{{ c.Name }}</a>
<span class="text-gray-600 text-sm ml-2">- Latest activity: {{ DisplayActivity(c.LastUpdate, .) }}</span>
{{ if newflag[i] }}
<span class="ml-2" title="There are new messages in this conference">🔔</span>
{{ end }}
{{ else }}
None
{{ end }}
</div>
<div class="text-sm text-gray-700 mb-1">
{{ if len(c.Hosts) == 1 }}
<span class="font-medium">Host:</span>
{{ else }}
<span class="font-medium">Hosts:</span>
{{ end }}
{{ if len(c.Hosts) > 0 }}
{{ range j, u := c.Hosts }}
{{ if j > 0 }}, {{ end }}
<a href="/users/{{ u }}" class="text-blue-700 hover:text-blue-900">{{ u }}</a>
{{ end }}
{{ else }}
None
{{ end }}
</div>
<div class="italic text-gray-600 text-sm">{{ c.Description }}</div>
</div>
<div class="italic text-gray-600 text-sm">{{ c.Description }}</div>
</div>
</div>
{{ end }}
{{ else }}
<div class="italic text-gray-600 text-lg">No conferences in this community.</div>
{{ end }}
</div>
</div>
+23 -5
View File
@@ -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
@@ -12,8 +12,9 @@ package util
import (
crand "crypto/rand"
"fmt"
"io"
mrand "math/rand"
"math/big"
"strings"
log "github.com/sirupsen/logrus"
@@ -49,6 +50,15 @@ var syllabary = [...]string{
"za", "ze", "zi", "zo", "zu",
}
// RCN_BASE is the base for generating random confirmation numbers.
var RCN_BASE *big.Int = big.NewInt(900000)
// RCN_OFFSET is what we add to a generated random number to get a proper confirmation number.
const RCN_OFFSET = 1000000
// RCN_MAX is the maximum value of a confirmation number.
const RCN_MAX = 9999999
// GenerateRandomAuthString generates a random authentication string.
func GenerateRandomAuthString() string {
b := make([]byte, authStringLen)
@@ -64,10 +74,18 @@ func GenerateRandomAuthString() string {
// GenerateRandomConfirmationNumber generates a random 7-digit confirmation number.
func GenerateRandomConfirmationNumber() int32 {
rc := mrand.Int31n(9000000) + 1000000
for rc < 1000000 || rc > 9999999 {
v1, err := crand.Int(crand.Reader, RCN_BASE)
if err != nil {
panic(fmt.Sprintf("GRCN ERR %v", err))
}
rc := int32(v1.Int64()) + RCN_OFFSET
for rc < RCN_OFFSET || rc > RCN_MAX {
log.Errorf("*** GRCN out of range error! %d", rc)
rc = mrand.Int31n(9000000) + 1000000
v1, err = crand.Int(crand.Reader, RCN_BASE)
if err != nil {
panic(fmt.Sprintf("GRCN ERR %v", err))
}
rc = int32(v1.Int64()) + RCN_OFFSET
}
return rc
}