87 lines
2.2 KiB
Go
87 lines
2.2 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"crypto/rand"
|
|
"database/sql"
|
|
"encoding/base64"
|
|
"fmt"
|
|
"log"
|
|
"time"
|
|
)
|
|
|
|
type Address struct {
|
|
Id int64 `json:"-"`
|
|
Street1 string `json:"street1" form:"street1"`
|
|
Street2 *string `json:"street2,omitempty" form:"street2,omitempty"`
|
|
City string `json:"city" form:"city"`
|
|
State *string `json:"state,omitempty" form:"state,omitempty"`
|
|
PostalCode string `json:"postal_code" form:"postal-code"`
|
|
Country string `json:"country" form:"country"`
|
|
CreatedAt time.Time `json:"-"`
|
|
UpdatedAt time.Time `json:"-"`
|
|
}
|
|
|
|
type User struct {
|
|
Status int32 `json:"status"`
|
|
Id int64 `json:"-"`
|
|
UserName string `json:"user_name" form:"user-id"`
|
|
ContactName string `json:"contact_name" form:"name"`
|
|
SecretCodes string `json:"-"`
|
|
CurrentToken *string `json:"-"`
|
|
ContactNumber string `json:"contact_number" form:"phone-number"`
|
|
EmailAddress string `json:"email_address" form:"email"`
|
|
MailingAddress Address `json:"mailing_address"`
|
|
RegistrationCode string `json:"-" form:"registration_code"`
|
|
}
|
|
|
|
func GenerateToken(n int) (string, error) {
|
|
b := make([]byte, n)
|
|
if _, err := rand.Read(b); err != nil {
|
|
return "", fmt.Errorf("reading random bytes: %w\n", err)
|
|
}
|
|
return base64.RawURLEncoding.EncodeToString(b), nil
|
|
}
|
|
|
|
func startCleanupLoop(ctx context.Context, db *sql.DB, interval, ttl time.Duration) {
|
|
ticker := time.NewTicker(interval)
|
|
defer ticker.Stop()
|
|
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
|
|
case <-ticker.C:
|
|
if err := cleanupExpired(db, ttl); err != nil {
|
|
log.Printf("token cleanup error: %v\n", err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func cleanupExpired(db *sql.DB, ttl time.Duration) error {
|
|
sqlStmt := `
|
|
UPDATE users
|
|
SET current_token=null,token_creation=null
|
|
WHERE token_creation < DATE_SUB(NOW(), INTERVAL ? SECOND);
|
|
`
|
|
res, err := db.Exec(sqlStmt, int(ttl.Seconds()))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
n, _ := res.RowsAffected()
|
|
log.Printf("Token Cleanup: updated %d rows\n", n)
|
|
return nil
|
|
}
|
|
|
|
func generateAESKey(keySize int) ([]byte, error) {
|
|
key := make([]byte, keySize)
|
|
_, err := rand.Read(key)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return key, nil
|
|
}
|