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}