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:
Vendored
+8
@@ -19,5 +19,13 @@
|
|||||||
"program": "${workspaceFolder}",
|
"program": "${workspaceFolder}",
|
||||||
"args": ["-C", "${workspaceFolder}/test.yaml"]
|
"args": ["-C", "${workspaceFolder}/test.yaml"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Import Test",
|
||||||
|
"type": "go",
|
||||||
|
"request": "launch",
|
||||||
|
"mode": "auto",
|
||||||
|
"program": "${workspaceFolder}",
|
||||||
|
"args": ["-C", "${workspaceFolder}/test2.yaml"]
|
||||||
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-4
@@ -782,11 +782,10 @@ func CreateCommunity(ctxt ui.AmContext) (string, any) {
|
|||||||
}
|
}
|
||||||
var testcomm *database.Community
|
var testcomm *database.Community
|
||||||
testcomm, err = database.AmGetCommunityByAlias(ctxt.Ctx(), dlg.Field("alias").Value)
|
testcomm, err = database.AmGetCommunityByAlias(ctxt.Ctx(), dlg.Field("alias").Value)
|
||||||
if err != nil {
|
if err == nil {
|
||||||
return dlg.RenderError(ctxt, err.Error())
|
|
||||||
}
|
|
||||||
if testcomm != nil {
|
|
||||||
return dlg.RenderError(ctxt, fmt.Sprintf("A community with the alias \"%s\" already exists; please try again.", testcomm.Alias))
|
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
|
var hideDir, hideSearch bool
|
||||||
switch dlg.Field("hidemode").Value {
|
switch dlg.Field("hidemode").Value {
|
||||||
|
|||||||
+6
-1
@@ -765,6 +765,7 @@ func ConferenceImport(ctxt ui.AmContext) (string, any) {
|
|||||||
|
|
||||||
if ctxt.Verb() == "GET" {
|
if ctxt.Verb() == "GET" {
|
||||||
ctxt.VarMap().Set("confName", conf.Name)
|
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)
|
ctxt.SetFrameTitle("Import Messages: " + conf.Name)
|
||||||
return "framed", "conf_import.jet"
|
return "framed", "conf_import.jet"
|
||||||
}
|
}
|
||||||
@@ -784,6 +785,7 @@ func ConferenceImport(ctxt ui.AmContext) (string, any) {
|
|||||||
default:
|
default:
|
||||||
ctxt.VarMap().Set("errorMessage", "Invalid matching parameter.")
|
ctxt.VarMap().Set("errorMessage", "Invalid matching parameter.")
|
||||||
ctxt.VarMap().Set("confName", conf.Name)
|
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)
|
ctxt.SetFrameTitle("Import Messages: " + conf.Name)
|
||||||
return "framed", "conf_import.jet"
|
return "framed", "conf_import.jet"
|
||||||
}
|
}
|
||||||
@@ -792,6 +794,7 @@ func ConferenceImport(ctxt ui.AmContext) (string, any) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
ctxt.VarMap().Set("errorMessage", err.Error())
|
ctxt.VarMap().Set("errorMessage", err.Error())
|
||||||
ctxt.VarMap().Set("confName", conf.Name)
|
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)
|
ctxt.SetFrameTitle("Import Messages: " + conf.Name)
|
||||||
return "framed", "conf_import.jet"
|
return "framed", "conf_import.jet"
|
||||||
}
|
}
|
||||||
@@ -799,6 +802,7 @@ func ConferenceImport(ctxt ui.AmContext) (string, any) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
ctxt.VarMap().Set("errorMessage", err.Error())
|
ctxt.VarMap().Set("errorMessage", err.Error())
|
||||||
ctxt.VarMap().Set("confName", conf.Name)
|
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)
|
ctxt.SetFrameTitle("Import Messages: " + conf.Name)
|
||||||
return "framed", "conf_import.jet"
|
return "framed", "conf_import.jet"
|
||||||
}
|
}
|
||||||
@@ -807,11 +811,12 @@ func ConferenceImport(ctxt ui.AmContext) (string, any) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
ctxt.VarMap().Set("errorMessage", err.Error())
|
ctxt.VarMap().Set("errorMessage", err.Error())
|
||||||
ctxt.VarMap().Set("confName", conf.Name)
|
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)
|
ctxt.SetFrameTitle("Import Messages: " + conf.Name)
|
||||||
return "framed", "conf_import.jet"
|
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("headline", fmt.Sprintf("Processed %d topic(s) and added %d new post(s).", topics, posts))
|
||||||
ctxt.VarMap().Set("scroll", scroll)
|
ctxt.VarMap().Set("scroll", scroll)
|
||||||
ctxt.SetFrameTitle("Import Results")
|
ctxt.SetFrameTitle("Import Results")
|
||||||
|
|||||||
+19
-3
@@ -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.
|
// 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) {
|
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
|
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 = ?
|
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)
|
WHERE t.confid = ? AND t.archived = 0 AND (s.hidden IS NULL OR s.hidden = 0)`, u.Uid, c.ConfId)
|
||||||
return rc, err
|
return rc, err
|
||||||
@@ -1284,10 +1293,17 @@ func AmCreateConference(ctx context.Context, comm *Community, name, alias, descr
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the current "last" sequence number.
|
// Get the current "last" sequence number.
|
||||||
var seq int
|
seq := 0
|
||||||
if err = tx.GetContext(ctx, &seq, "SELECT MAX(sequence) FROM commtoconf WHERE commid = ?", comm.Id); err != nil {
|
count := 0
|
||||||
|
if err = tx.GetContext(ctx, &count, "SELECT COUNT(*) FROM commtoconf WHERE commid = ?", comm.Id); err != nil {
|
||||||
return nil, err
|
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.
|
// 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,
|
if _, err = tx.ExecContext(ctx, "INSERT INTO commtoconf (commid, confid, sequence, hide_list) VALUES (?, ?, ?, ?)", comm.Id, rc.ConfId,
|
||||||
|
|||||||
+3
-1
@@ -757,9 +757,11 @@ func AmCreateNewUser(ctx context.Context, username string, password string, remi
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Insert the user record.
|
// 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,
|
_, 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(), ?, '', ?)`,
|
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)
|
reminder, dob)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ CREATE TABLE users (
|
|||||||
verify_email TINYINT DEFAULT 0,
|
verify_email TINYINT DEFAULT 0,
|
||||||
lockout TINYINT DEFAULT 0,
|
lockout TINYINT DEFAULT 0,
|
||||||
access_tries SMALLINT DEFAULT 0,
|
access_tries SMALLINT DEFAULT 0,
|
||||||
email_confnum MEDIUMINT DEFAULT 0,
|
email_confnum INT DEFAULT 0,
|
||||||
base_lvl SMALLINT UNSIGNED NOT NULL,
|
base_lvl SMALLINT UNSIGNED NOT NULL,
|
||||||
created DATETIME NOT NULL,
|
created DATETIME NOT NULL,
|
||||||
lastaccess DATETIME,
|
lastaccess DATETIME,
|
||||||
|
|||||||
+1
-1
@@ -69,7 +69,7 @@ CREATE TABLE users (
|
|||||||
verify_email TINYINT DEFAULT 0,
|
verify_email TINYINT DEFAULT 0,
|
||||||
lockout TINYINT DEFAULT 0,
|
lockout TINYINT DEFAULT 0,
|
||||||
access_tries SMALLINT DEFAULT 0,
|
access_tries SMALLINT DEFAULT 0,
|
||||||
email_confnum MEDIUMINT DEFAULT 0,
|
email_confnum INT DEFAULT 0,
|
||||||
base_lvl SMALLINT UNSIGNED NOT NULL,
|
base_lvl SMALLINT UNSIGNED NOT NULL,
|
||||||
created DATETIME NOT NULL,
|
created DATETIME NOT NULL,
|
||||||
lastaccess DATETIME,
|
lastaccess DATETIME,
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
<!-- Upload Form -->
|
<!-- 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="bg-gray-50 p-6 rounded-lg">
|
||||||
<div class="mb-6 flex gap-2">
|
<div class="mb-6 flex gap-2">
|
||||||
<label for="idata" class="block text-black text-sm font-medium mb-2">
|
<label for="idata" class="block text-black text-sm font-medium mb-2">
|
||||||
|
|||||||
+31
-27
@@ -18,36 +18,40 @@
|
|||||||
<div class="max-w-4xl">
|
<div class="max-w-4xl">
|
||||||
<div class="bg-gray-50 p-6 rounded-lg mb-6">
|
<div class="bg-gray-50 p-6 rounded-lg mb-6">
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
{{ range i, c := conferences }}
|
{{ if len(conferences) > 0 }}
|
||||||
<div class="flex items-start gap-3">
|
{{ range i, c := conferences }}
|
||||||
<span class="text-lg pt-0.5 flex-shrink-0">🟣</span>
|
<div class="flex items-start gap-3">
|
||||||
<div class="flex-1">
|
<span class="text-lg pt-0.5 flex-shrink-0">🟣</span>
|
||||||
<div class="mb-2">
|
<div class="flex-1">
|
||||||
<a href="/comm/{{ commAlias }}/conf/{{ c.Alias }}"
|
<div class="mb-2">
|
||||||
class="text-blue-700 hover:text-blue-900 font-bold text-lg">{{ c.Name }}</a>
|
<a href="/comm/{{ commAlias }}/conf/{{ c.Alias }}"
|
||||||
<span class="text-gray-600 text-sm ml-2">- Latest activity: {{ DisplayActivity(c.LastUpdate, .) }}</span>
|
class="text-blue-700 hover:text-blue-900 font-bold text-lg">{{ c.Name }}</a>
|
||||||
{{ if newflag[i] }}
|
<span class="text-gray-600 text-sm ml-2">- Latest activity: {{ DisplayActivity(c.LastUpdate, .) }}</span>
|
||||||
<span class="ml-2" title="There are new messages in this conference">🔔</span>
|
{{ if newflag[i] }}
|
||||||
{{ end }}
|
<span class="ml-2" title="There are new messages in this conference">🔔</span>
|
||||||
</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 }}
|
{{ end }}
|
||||||
{{ else }}
|
</div>
|
||||||
None
|
<div class="text-sm text-gray-700 mb-1">
|
||||||
{{ end }}
|
{{ 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>
|
||||||
<div class="italic text-gray-600 text-sm">{{ c.Description }}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{{ end }}
|
||||||
|
{{ else }}
|
||||||
|
<div class="italic text-gray-600 text-lg">No conferences in this community.</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+23
-5
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Amsterdam Web Communities System
|
* 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
|
* 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
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@@ -12,8 +12,9 @@ package util
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
crand "crypto/rand"
|
crand "crypto/rand"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
mrand "math/rand"
|
"math/big"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
@@ -49,6 +50,15 @@ var syllabary = [...]string{
|
|||||||
"za", "ze", "zi", "zo", "zu",
|
"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.
|
// GenerateRandomAuthString generates a random authentication string.
|
||||||
func GenerateRandomAuthString() string {
|
func GenerateRandomAuthString() string {
|
||||||
b := make([]byte, authStringLen)
|
b := make([]byte, authStringLen)
|
||||||
@@ -64,10 +74,18 @@ func GenerateRandomAuthString() string {
|
|||||||
|
|
||||||
// GenerateRandomConfirmationNumber generates a random 7-digit confirmation number.
|
// GenerateRandomConfirmationNumber generates a random 7-digit confirmation number.
|
||||||
func GenerateRandomConfirmationNumber() int32 {
|
func GenerateRandomConfirmationNumber() int32 {
|
||||||
rc := mrand.Int31n(9000000) + 1000000
|
v1, err := crand.Int(crand.Reader, RCN_BASE)
|
||||||
for rc < 1000000 || rc > 9999999 {
|
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)
|
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
|
return rc
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user