generated from datumforge/go-template
-
Notifications
You must be signed in to change notification settings - Fork 7
/
users.go
117 lines (95 loc) · 3.01 KB
/
users.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package handlers
import (
"database/sql"
"time"
"github.com/oklog/ulid/v2"
"github.com/datumforge/datum/pkg/tokens"
)
// User holds data specific to the datum user for the REST handlers for
// login, registration, verification, etc
type User struct {
ID string
FirstName string
LastName string
Name string
Email string
Password *string
OTPSecret string `json:"-"`
EmailVerificationExpires sql.NullString
EmailVerificationToken sql.NullString
EmailVerificationSecret []byte
PasswordResetExpires sql.NullString
PasswordResetToken sql.NullString
PasswordResetSecret []byte
URLToken
}
// URLToken holds data specific to a future user of the system for invite logic
type URLToken struct {
Expires sql.NullString
Token sql.NullString
Secret []byte
}
// GetVerificationToken returns the verification token if its valid
func (u *User) GetVerificationToken() string {
if u.EmailVerificationToken.Valid {
return u.EmailVerificationToken.String
}
return ""
}
// GetVerificationExpires returns the expiration time of email verification token
func (u *User) GetVerificationExpires() (time.Time, error) {
if u.EmailVerificationExpires.Valid {
return time.Parse(time.RFC3339Nano, u.EmailVerificationExpires.String)
}
return time.Time{}, nil
}
// CreateVerificationToken creates a new email verification token for the user
func (u *User) CreateVerificationToken() error {
// Create a unique token from the user's email address
verify, err := tokens.NewVerificationToken(u.Email)
if err != nil {
return err
}
// Sign the token to ensure that we can verify it later
token, secret, err := verify.Sign()
if err != nil {
return err
}
u.EmailVerificationToken = sql.NullString{Valid: true, String: token}
u.EmailVerificationExpires = sql.NullString{Valid: true, String: verify.ExpiresAt.Format(time.RFC3339Nano)}
u.EmailVerificationSecret = secret
return nil
}
// GetPasswordResetToken returns the password reset token if its valid
func (u *User) GetPasswordResetToken() string {
if u.PasswordResetToken.Valid {
return u.PasswordResetToken.String
}
return ""
}
// GetPasswordResetExpires returns the expiration time of password verification token
func (u *User) GetPasswordResetExpires() (time.Time, error) {
if u.PasswordResetExpires.Valid {
return time.Parse(time.RFC3339Nano, u.PasswordResetExpires.String)
}
return time.Time{}, nil
}
// CreatePasswordResetToken creates a new reset token for the user
func (u *User) CreatePasswordResetToken() error {
uid, err := ulid.Parse(u.ID)
if err != nil {
return err
}
reset, err := tokens.NewResetToken(uid)
if err != nil {
return err
}
token, secret, err := reset.Sign()
if err != nil {
return err
}
u.PasswordResetToken = sql.NullString{Valid: true, String: token}
u.PasswordResetExpires = sql.NullString{Valid: true, String: reset.ExpiresAt.Format(time.RFC3339Nano)}
u.PasswordResetSecret = secret
return nil
}