generate invites on acceptance

trunk
vilmibm 2023-02-26 23:02:51 +00:00
parent c0d205b447
commit d5aff6fc83
2 changed files with 75 additions and 13 deletions

View File

@ -10,6 +10,7 @@ import (
"strings"
"time"
"git.tilde.town/tildetown/town/invites"
"git.tilde.town/tildetown/town/models"
"git.tilde.town/tildetown/town/signup"
tuser "git.tilde.town/tildetown/town/user"
@ -88,13 +89,10 @@ func renderNotes(s models.TownSignup) string {
}
func _main() error {
/*
TODO will use this for invites
userDB, err := review.ConnectDB()
if err != nil {
return fmt.Errorf("could not connect to user database: %w", err)
}
*/
inviteDB, err := invites.ConnectDB()
if err != nil {
return fmt.Errorf("could not connect to invites database: %w", err)
}
signupDB, err := signup.ConnectDB()
if err != nil {
@ -145,11 +143,10 @@ func _main() error {
count := tview.NewTextView()
count.SetDynamicColors(true)
updateCount := func() {
plural := "s"
if len(signups) == 1 {
plural = ""
count.SetText(fmt.Sprintf("[-:-:b]%d of %d[-:-:-]", signupIx+1, len(signups)))
if len(signups) == 0 {
count.SetText("")
}
count.SetText(fmt.Sprintf("[-:-:b]%d of %d %s[-:-:-]", signupIx+1, len(signups), plural))
}
updateCount()
@ -266,7 +263,12 @@ func _main() error {
updateCount()
render()
if decision == models.SignupAccepted {
// TODO generate invite token
err = invites.InsertInvite(inviteDB, currSignup.CleanEmail)
if err != nil {
errorModal.SetText(fmt.Sprintf("error! failed to create invite: %s", err.Error()))
pages.SwitchToPage("error")
}
// TODO send invite email
}
pages.SwitchToPage("main")

View File

@ -2,10 +2,18 @@ package invites
import (
"database/sql"
"encoding/base64"
"math/rand"
"strings"
"time"
_ "github.com/mattn/go-sqlite3"
)
const dsn = "/town/var/invites/invites.db?mode=rw"
const (
dsn = "/town/var/invites/invites.db?mode=rw"
codeLen = 32
)
func ConnectDB() (*sql.DB, error) {
db, err := sql.Open("sqlite3", dsn)
@ -15,3 +23,55 @@ func ConnectDB() (*sql.DB, error) {
return db, nil
}
func generateCode(email string) string {
rand.Seed(time.Now().Unix())
charset := "abcdefghijklmnopqrztuvwxyz"
charset += strings.ToUpper(charset)
charset += "0123456789"
charset += "`~!@#$%^&*()-=_+[]{}|;:,./<>?"
code := []byte{}
for len(code) < codeLen {
code = append(code, charset[rand.Intn(len(charset))])
}
code = append(code, ' ')
eb := []byte(email)
for x := 0; x < len(eb); x++ {
code = append(code, eb[x])
}
return base64.StdEncoding.EncodeToString(code)
}
func Decode(code string) ([]string, error) {
decoded, err := base64.StdEncoding.DecodeString(code)
if err != nil {
return nil, err
}
return strings.Split(string(decoded), " "), nil
}
func InsertInvite(db *sql.DB, email string) error {
stmt, err := db.Prepare(`
INSERT INTO invites (code, email) VALUES (?, ?)
`)
if err != nil {
return err
}
_, err = stmt.Exec(generateCode(email), email)
if err != nil {
return err
}
defer stmt.Close()
return nil
}
// TODO decide on rest of API (eg Validate, Use, Get, etc)