arche / internal/archesrv/invites.go

commit 154431fd
  1package archesrv
  2
  3import (
  4	"database/sql"
  5	"time"
  6)
  7
  8type InviteToken struct {
  9	ID        int64
 10	Token     string
 11	CreatedBy int64
 12	UsedBy    *int64
 13	CreatedAt time.Time
 14	UsedAt    *time.Time
 15}
 16
 17func (d *DB) CreateInvite(createdBy int64) (*InviteToken, error) {
 18	tok, err := generateToken()
 19	if err != nil {
 20		return nil, err
 21	}
 22	res, err := d.db.Exec(
 23		"INSERT INTO invite_tokens(token,created_by,created_at) VALUES(?,?,?)",
 24		tok, createdBy, time.Now().Unix(),
 25	)
 26	if err != nil {
 27		return nil, err
 28	}
 29	id, _ := res.LastInsertId()
 30	return &InviteToken{ID: id, Token: tok, CreatedBy: createdBy, CreatedAt: time.Now()}, nil
 31}
 32
 33func (d *DB) GetInvite(token string) (*InviteToken, error) {
 34	var inv InviteToken
 35	var usedBy sql.NullInt64
 36	var usedAt sql.NullInt64
 37	var createdAt int64
 38	err := d.db.QueryRow(
 39		"SELECT id, token, created_by, used_by, created_at, used_at FROM invite_tokens WHERE token=?",
 40		token,
 41	).Scan(&inv.ID, &inv.Token, &inv.CreatedBy, &usedBy, &createdAt, &usedAt)
 42	if err == sql.ErrNoRows {
 43		return nil, nil
 44	}
 45	if err != nil {
 46		return nil, err
 47	}
 48	inv.CreatedAt = time.Unix(createdAt, 0)
 49	if usedBy.Valid {
 50		v := usedBy.Int64
 51		inv.UsedBy = &v
 52	}
 53	if usedAt.Valid {
 54		t := time.Unix(usedAt.Int64, 0)
 55		inv.UsedAt = &t
 56	}
 57	return &inv, nil
 58}
 59
 60func (d *DB) UseInvite(token string, userID int64) error {
 61	now := time.Now().Unix()
 62	res, err := d.db.Exec(
 63		"UPDATE invite_tokens SET used_by=?, used_at=? WHERE token=? AND used_by IS NULL",
 64		userID, now, token,
 65	)
 66	if err != nil {
 67		return err
 68	}
 69	n, _ := res.RowsAffected()
 70	if n == 0 {
 71		return sql.ErrNoRows
 72	}
 73	return nil
 74}
 75
 76func (d *DB) ListInvites(createdBy int64) ([]InviteToken, error) {
 77	rows, err := d.db.Query(
 78		`SELECT id, token, created_by, used_by, created_at, used_at
 79		 FROM invite_tokens WHERE created_by=? ORDER BY id DESC`,
 80		createdBy,
 81	)
 82	if err != nil {
 83		return nil, err
 84	}
 85	defer rows.Close()
 86	var out []InviteToken
 87	for rows.Next() {
 88		var inv InviteToken
 89		var usedBy sql.NullInt64
 90		var usedAt sql.NullInt64
 91		var createdAt int64
 92		if err := rows.Scan(&inv.ID, &inv.Token, &inv.CreatedBy, &usedBy, &createdAt, &usedAt); err != nil {
 93			return nil, err
 94		}
 95		inv.CreatedAt = time.Unix(createdAt, 0)
 96		if usedBy.Valid {
 97			v := usedBy.Int64
 98			inv.UsedBy = &v
 99		}
100		if usedAt.Valid {
101			t := time.Unix(usedAt.Int64, 0)
102			inv.UsedAt = &t
103		}
104		out = append(out, inv)
105	}
106	return out, rows.Err()
107}
108
109func (d *DB) DeleteInvite(id, adminID int64) error {
110	_, err := d.db.Exec("DELETE FROM invite_tokens WHERE id=? AND used_by IS NULL", id)
111	return err
112}