-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Expand file tree
/
Copy pathrecord_tokens.go
More file actions
165 lines (141 loc) · 4.28 KB
/
record_tokens.go
File metadata and controls
165 lines (141 loc) · 4.28 KB
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package core
import (
"errors"
"time"
"github.com/golang-jwt/jwt/v5"
"github.com/pocketbase/pocketbase/tools/security"
)
// Supported record token types
const (
TokenTypeAuth = "auth"
TokenTypeFile = "file"
TokenTypeVerification = "verification"
TokenTypePasswordReset = "passwordReset"
TokenTypeEmailChange = "emailChange"
)
// List with commonly used record token claims
const (
TokenClaimId = "id"
TokenClaimType = "type"
TokenClaimCollectionId = "collectionId"
TokenClaimEmail = "email"
TokenClaimNewEmail = "newEmail"
TokenClaimRefreshable = "refreshable"
)
// Common token related errors
var (
ErrNotAuthRecord = errors.New("not an auth collection record")
ErrMissingSigningKey = errors.New("missing or invalid signing key")
)
// NewStaticAuthToken generates and returns a new static record authentication token.
//
// Static auth tokens are similar to the regular auth tokens, but are
// non-refreshable and support custom duration.
//
// Zero or negative duration will fallback to the duration from the auth collection settings.
func (m *Record) NewStaticAuthToken(duration time.Duration) (string, error) {
return m.newAuthToken(duration, false)
}
// NewAuthToken generates and returns a new record authentication token.
func (m *Record) NewAuthToken() (string, error) {
return m.newAuthToken(0, true)
}
func (m *Record) newAuthToken(duration time.Duration, refreshable bool) (string, error) {
if !m.Collection().IsAuth() {
return "", ErrNotAuthRecord
}
key := (m.TokenKey() + m.Collection().AuthToken.Secret)
if key == "" {
return "", ErrMissingSigningKey
}
claims := jwt.MapClaims{
TokenClaimType: TokenTypeAuth,
TokenClaimId: m.Id,
TokenClaimCollectionId: m.Collection().Id,
TokenClaimRefreshable: refreshable,
}
if duration <= 0 {
duration = m.Collection().AuthToken.DurationTime()
}
return security.NewJWT(claims, key, duration)
}
// NewVerificationToken generates and returns a new record verification token.
func (m *Record) NewVerificationToken() (string, error) {
if !m.Collection().IsAuth() {
return "", ErrNotAuthRecord
}
key := (m.TokenKey() + m.Collection().VerificationToken.Secret)
if key == "" {
return "", ErrMissingSigningKey
}
return security.NewJWT(
jwt.MapClaims{
TokenClaimType: TokenTypeVerification,
TokenClaimId: m.Id,
TokenClaimCollectionId: m.Collection().Id,
TokenClaimEmail: m.Email(),
},
key,
m.Collection().VerificationToken.DurationTime(),
)
}
// NewPasswordResetToken generates and returns a new auth record password reset request token.
func (m *Record) NewPasswordResetToken() (string, error) {
if !m.Collection().IsAuth() {
return "", ErrNotAuthRecord
}
key := (m.TokenKey() + m.Collection().PasswordResetToken.Secret)
if key == "" {
return "", ErrMissingSigningKey
}
return security.NewJWT(
jwt.MapClaims{
TokenClaimType: TokenTypePasswordReset,
TokenClaimId: m.Id,
TokenClaimCollectionId: m.Collection().Id,
TokenClaimEmail: m.Email(),
},
key,
m.Collection().PasswordResetToken.DurationTime(),
)
}
// NewEmailChangeToken generates and returns a new auth record change email request token.
func (m *Record) NewEmailChangeToken(newEmail string) (string, error) {
if !m.Collection().IsAuth() {
return "", ErrNotAuthRecord
}
key := (m.TokenKey() + m.Collection().EmailChangeToken.Secret)
if key == "" {
return "", ErrMissingSigningKey
}
return security.NewJWT(
jwt.MapClaims{
TokenClaimType: TokenTypeEmailChange,
TokenClaimId: m.Id,
TokenClaimCollectionId: m.Collection().Id,
TokenClaimEmail: m.Email(),
TokenClaimNewEmail: newEmail,
},
key,
m.Collection().EmailChangeToken.DurationTime(),
)
}
// NewFileToken generates and returns a new record private file access token.
func (m *Record) NewFileToken() (string, error) {
if !m.Collection().IsAuth() {
return "", ErrNotAuthRecord
}
key := (m.TokenKey() + m.Collection().FileToken.Secret)
if key == "" {
return "", ErrMissingSigningKey
}
return security.NewJWT(
jwt.MapClaims{
TokenClaimType: TokenTypeFile,
TokenClaimId: m.Id,
TokenClaimCollectionId: m.Collection().Id,
},
key,
m.Collection().FileToken.DurationTime(),
)
}