forked from
tangled.org/core
Monorepo for Tangled — https://tangled.org
1package db
2
3import (
4 "strings"
5 "time"
6
7 "tangled.org/core/appview/models"
8)
9
10func GetPrimaryEmail(e Execer, did string) (models.Email, error) {
11 query := `
12 select id, did, email, verified, is_primary, verification_code, last_sent, created
13 from emails
14 where did = ? and is_primary = true
15 `
16 var email models.Email
17 var createdStr string
18 var lastSent string
19 err := e.QueryRow(query, did).Scan(&email.ID, &email.Did, &email.Address, &email.Verified, &email.Primary, &email.VerificationCode, &lastSent, &createdStr)
20 if err != nil {
21 return models.Email{}, err
22 }
23 email.CreatedAt, err = time.Parse(time.RFC3339, createdStr)
24 if err != nil {
25 return models.Email{}, err
26 }
27 parsedTime, err := time.Parse(time.RFC3339, lastSent)
28 if err != nil {
29 return models.Email{}, err
30 }
31 email.LastSent = &parsedTime
32 return email, nil
33}
34
35func GetEmail(e Execer, did string, em string) (models.Email, error) {
36 query := `
37 select id, did, email, verified, is_primary, verification_code, last_sent, created
38 from emails
39 where did = ? and email = ?
40 `
41 var email models.Email
42 var createdStr string
43 var lastSent string
44 err := e.QueryRow(query, did, em).Scan(&email.ID, &email.Did, &email.Address, &email.Verified, &email.Primary, &email.VerificationCode, &lastSent, &createdStr)
45 if err != nil {
46 return models.Email{}, err
47 }
48 email.CreatedAt, err = time.Parse(time.RFC3339, createdStr)
49 if err != nil {
50 return models.Email{}, err
51 }
52 parsedTime, err := time.Parse(time.RFC3339, lastSent)
53 if err != nil {
54 return models.Email{}, err
55 }
56 email.LastSent = &parsedTime
57 return email, nil
58}
59
60func GetDidForEmail(e Execer, em string) (string, error) {
61 query := `
62 select did
63 from emails
64 where email = ?
65 `
66 var did string
67 err := e.QueryRow(query, em).Scan(&did)
68 if err != nil {
69 return "", err
70 }
71 return did, nil
72}
73
74func GetEmailToDid(e Execer, emails []string, isVerifiedFilter bool) (map[string]string, error) {
75 if len(emails) == 0 {
76 return make(map[string]string), nil
77 }
78
79 verifiedFilter := 0
80 if isVerifiedFilter {
81 verifiedFilter = 1
82 }
83
84 assoc := make(map[string]string)
85
86 // Create placeholders for the IN clause
87 placeholders := make([]string, 0, len(emails))
88 args := make([]any, 1, len(emails)+1)
89
90 args[0] = verifiedFilter
91 for _, email := range emails {
92 if strings.HasPrefix(email, "did:") {
93 assoc[email] = email
94 continue
95 }
96 placeholders = append(placeholders, "?")
97 args = append(args, email)
98 }
99
100 query := `
101 select email, did
102 from emails
103 where
104 verified = ?
105 and email in (` + strings.Join(placeholders, ",") + `)
106 `
107
108 rows, err := e.Query(query, args...)
109 if err != nil {
110 return nil, err
111 }
112 defer rows.Close()
113
114 for rows.Next() {
115 var email, did string
116 if err := rows.Scan(&email, &did); err != nil {
117 return nil, err
118 }
119 assoc[email] = did
120 }
121
122 if err := rows.Err(); err != nil {
123 return nil, err
124 }
125
126 return assoc, nil
127}
128
129func GetVerificationCodeForEmail(e Execer, did string, email string) (string, error) {
130 query := `
131 select verification_code
132 from emails
133 where did = ? and email = ?
134 `
135 var code string
136 err := e.QueryRow(query, did, email).Scan(&code)
137 if err != nil {
138 return "", err
139 }
140 return code, nil
141}
142
143func CheckEmailExists(e Execer, did string, email string) (bool, error) {
144 query := `
145 select count(*)
146 from emails
147 where did = ? and email = ?
148 `
149 var count int
150 err := e.QueryRow(query, did, email).Scan(&count)
151 if err != nil {
152 return false, err
153 }
154 return count > 0, nil
155}
156
157func CheckEmailExistsAtAll(e Execer, email string) (bool, error) {
158 query := `
159 select count(*)
160 from emails
161 where email = ?
162 `
163 var count int
164 err := e.QueryRow(query, email).Scan(&count)
165 if err != nil {
166 return false, err
167 }
168 return count > 0, nil
169}
170
171func CheckValidVerificationCode(e Execer, did string, email string, code string) (bool, error) {
172 query := `
173 select count(*)
174 from emails
175 where did = ? and email = ? and verification_code = ?
176 `
177 var count int
178 err := e.QueryRow(query, did, email, code).Scan(&count)
179 if err != nil {
180 return false, err
181 }
182 return count > 0, nil
183}
184
185func AddEmail(e Execer, email models.Email) error {
186 // Check if this is the first email for this DID
187 countQuery := `
188 select count(*)
189 from emails
190 where did = ?
191 `
192 var count int
193 err := e.QueryRow(countQuery, email.Did).Scan(&count)
194 if err != nil {
195 return err
196 }
197
198 // If this is the first email, mark it as primary
199 if count == 0 {
200 email.Primary = true
201 }
202
203 query := `
204 insert into emails (did, email, verified, is_primary, verification_code)
205 values (?, ?, ?, ?, ?)
206 `
207 _, err = e.Exec(query, email.Did, email.Address, email.Verified, email.Primary, email.VerificationCode)
208 return err
209}
210
211func DeleteEmail(e Execer, did string, email string) error {
212 query := `
213 delete from emails
214 where did = ? and email = ?
215 `
216 _, err := e.Exec(query, did, email)
217 return err
218}
219
220func MarkEmailVerified(e Execer, did string, email string) error {
221 query := `
222 update emails
223 set verified = true
224 where did = ? and email = ?
225 `
226 _, err := e.Exec(query, did, email)
227 return err
228}
229
230func MakeEmailPrimary(e Execer, did string, email string) error {
231 // First, unset all primary emails for this DID
232 query1 := `
233 update emails
234 set is_primary = false
235 where did = ?
236 `
237 _, err := e.Exec(query1, did)
238 if err != nil {
239 return err
240 }
241
242 // Then, set the specified email as primary
243 query2 := `
244 update emails
245 set is_primary = true
246 where did = ? and email = ?
247 `
248 _, err = e.Exec(query2, did, email)
249 return err
250}
251
252func GetAllEmails(e Execer, did string) ([]models.Email, error) {
253 query := `
254 select did, email, verified, is_primary, verification_code, last_sent, created
255 from emails
256 where did = ?
257 `
258 rows, err := e.Query(query, did)
259 if err != nil {
260 return nil, err
261 }
262 defer rows.Close()
263
264 var emails []models.Email
265 for rows.Next() {
266 var email models.Email
267 var createdStr string
268 var lastSent string
269 err := rows.Scan(&email.Did, &email.Address, &email.Verified, &email.Primary, &email.VerificationCode, &lastSent, &createdStr)
270 if err != nil {
271 return nil, err
272 }
273 email.CreatedAt, err = time.Parse(time.RFC3339, createdStr)
274 if err != nil {
275 return nil, err
276 }
277 parsedTime, err := time.Parse(time.RFC3339, lastSent)
278 if err != nil {
279 return nil, err
280 }
281 email.LastSent = &parsedTime
282 emails = append(emails, email)
283 }
284 return emails, nil
285}
286
287func UpdateVerificationCode(e Execer, did string, email string, code string) error {
288 query := `
289 update emails
290 set verification_code = ?,
291 last_sent = strftime('%Y-%m-%dT%H:%M:%SZ', 'now')
292 where did = ? and email = ?
293 `
294 _, err := e.Exec(query, code, did, email)
295 return err
296}