@@ -11,7 +11,6 @@ import (
11
11
"time"
12
12
13
13
"staticbackend/cache"
14
- "staticbackend/email"
15
14
"staticbackend/internal"
16
15
"staticbackend/middleware"
17
16
@@ -246,165 +245,134 @@ func (m *membership) createUser(db *mongo.Database, accountID primitive.ObjectID
246
245
return jwtBytes , tok , nil
247
246
}
248
247
249
- func (m * membership ) setRole (w http.ResponseWriter , r * http.Request ) {
250
- conf , a , err := middleware . Extract ( r , true )
251
- if err != nil || a . Role < 100 {
252
- http .Error (w , "insufficient priviledges " , http .StatusUnauthorized )
248
+ func (m * membership ) setResetCode (w http.ResponseWriter , r * http.Request ) {
249
+ email := strings . ToLower ( r . URL . Query (). Get ( "e" ) )
250
+ if len ( email ) == 0 || strings . Index ( email , "@" ) <= 0 {
251
+ http .Error (w , "invalid email " , http .StatusBadRequest )
253
252
return
254
253
}
255
254
256
- var data = new (struct {
257
- Email string `json:"email"`
258
- Role int `json:"role"`
259
- })
260
- if err := parseBody (r .Body , & data ); err != nil {
261
- http .Error (w , err .Error (), http .StatusBadRequest )
255
+ code := randStringRunes (10 )
256
+
257
+ conf , _ , err := middleware .Extract (r , false )
258
+ if err != nil {
259
+ http .Error (w , err .Error (), http .StatusUnauthorized )
262
260
return
263
261
}
264
262
265
- db := client .Database (conf .Name )
263
+ curDB := client .Database (conf .Name )
266
264
267
- ctx , _ := context .WithTimeout (context .Background (), 2 * time .Second )
268
- filter := bson.M {"email" : data .Email }
269
- update := bson.M {"$set" : bson.M {"role" : data .Role }}
270
- if _ , err := db .Collection ("sb_tokens" ).UpdateOne (ctx , filter , update ); err != nil {
265
+ tok , err := internal .FindTokenByEmail (curDB , email )
266
+ if err != nil {
267
+ http .Error (w , "email not found" , http .StatusNotFound )
268
+ return
269
+ }
270
+
271
+ if err := internal .SetPasswordResetCode (curDB , tok .ID , code ); err != nil {
271
272
http .Error (w , err .Error (), http .StatusInternalServerError )
272
273
return
273
274
}
274
275
275
- respond (w , http .StatusOK , true )
276
+ respond (w , http .StatusOK , code )
276
277
}
277
278
278
- func (m * membership ) setPassword (w http.ResponseWriter , r * http.Request ) {
279
- conf , a , err := middleware .Extract (r , true )
280
- if err != nil || a . Role < 100 {
281
- http .Error (w , "insufficient priviledges" , http .StatusUnauthorized )
279
+ func (m * membership ) resetPassword (w http.ResponseWriter , r * http.Request ) {
280
+ conf , _ , err := middleware .Extract (r , false )
281
+ if err != nil {
282
+ http .Error (w , err . Error () , http .StatusUnauthorized )
282
283
return
283
284
}
284
285
286
+ curDB := client .Database (conf .Name )
287
+
285
288
var data = new (struct {
286
- Email string `json:"email"`
287
- OldPassword string `json:"oldPassword "`
288
- NewPassword string `json:"newPassword "`
289
+ Email string `json:"email"`
290
+ Code string `json:"code "`
291
+ Password string `json:"password "`
289
292
})
290
293
if err := parseBody (r .Body , & data ); err != nil {
291
294
http .Error (w , err .Error (), http .StatusBadRequest )
292
295
return
293
296
}
294
297
295
- db := client . Database ( conf . Name )
298
+ data . Email = strings . ToLower ( data . Email )
296
299
297
- tok , err := m .validateUserPassword (db , data .Email , data .OldPassword )
298
- if err != nil {
299
- http .Error (w , err .Error (), http .StatusUnauthorized )
300
- return
301
- }
302
-
303
- newpw , err := bcrypt .GenerateFromPassword ([]byte (data .NewPassword ), bcrypt .DefaultCost )
300
+ b , err := bcrypt .GenerateFromPassword ([]byte (data .Password ), bcrypt .DefaultCost )
304
301
if err != nil {
305
302
http .Error (w , err .Error (), http .StatusInternalServerError )
306
303
return
307
304
}
308
305
309
- ctx := context .Background ()
310
- filter := bson.M {"_id" : tok .ID }
311
- update := bson.M {"$set" : bson.M {"pw" : string (newpw )}}
312
- if _ , err := db .Collection ("sb_tokens" ).UpdateOne (ctx , filter , update ); err != nil {
306
+ if err := internal .ResetPassword (curDB , data .Email , data .Code , string (b )); err != nil {
313
307
http .Error (w , err .Error (), http .StatusInternalServerError )
314
308
return
315
309
}
316
310
317
311
respond (w , http .StatusOK , true )
318
312
}
319
313
320
- func (m * membership ) resetPassword (w http.ResponseWriter , r * http.Request ) {
321
- conf , _ , err := middleware .Extract (r , false )
322
- if err != nil {
323
- http .Error (w , "invalid StaticBackend key " , http .StatusUnauthorized )
314
+ func (m * membership ) setRole (w http.ResponseWriter , r * http.Request ) {
315
+ conf , a , err := middleware .Extract (r , true )
316
+ if err != nil || a . Role < 100 {
317
+ http .Error (w , "insufficient priviledges " , http .StatusUnauthorized )
324
318
return
325
319
}
326
320
327
- db := client .Database (conf .Name )
328
-
329
321
var data = new (struct {
330
322
Email string `json:"email"`
323
+ Role int `json:"role"`
331
324
})
332
325
if err := parseBody (r .Body , & data ); err != nil {
333
326
http .Error (w , err .Error (), http .StatusBadRequest )
334
327
return
335
328
}
336
329
337
- filter := bson.M {"email" : strings .ToLower (data .Email )}
338
- count , err := db .Collection ("sb_tokens" ).CountDocuments (context .Background (), filter )
339
- if err != nil {
340
- http .Error (w , err .Error (), http .StatusInternalServerError )
341
- return
342
- } else if count == 0 {
343
- http .Error (w , "not found" , http .StatusNotFound )
344
- return
345
- }
346
-
347
- code := randStringRunes (6 )
348
- update := bson.M {"%set" : bson.M {"sb_reset_code" : code }}
349
- if _ , err := db .Collection ("sb_tokens" ).UpdateOne (context .Background (), filter , update ); err != nil {
350
- http .Error (w , err .Error (), http .StatusInternalServerError )
351
- return
352
- }
353
-
354
- //TODO: have HTML template for those
355
- body := fmt .Sprintf (`Your reset code is: %s` , code )
330
+ db := client .Database (conf .Name )
356
331
357
- ed := internal.SendMailData {
358
- From : FromEmail ,
359
- FromName : FromName ,
360
- To : data .Email ,
361
- Subject : "Your password reset code" ,
362
- HTMLBody : body ,
363
- TextBody : email .StripHTML (body ),
364
- }
365
- if err := emailer .Send (ed ); err != nil {
332
+ ctx , _ := context .WithTimeout (context .Background (), 2 * time .Second )
333
+ filter := bson.M {"email" : data .Email }
334
+ update := bson.M {"$set" : bson.M {"role" : data .Role }}
335
+ if _ , err := db .Collection ("sb_tokens" ).UpdateOne (ctx , filter , update ); err != nil {
366
336
http .Error (w , err .Error (), http .StatusInternalServerError )
367
337
return
368
338
}
369
339
370
340
respond (w , http .StatusOK , true )
371
341
}
372
342
373
- func (m * membership ) changePassword (w http.ResponseWriter , r * http.Request ) {
374
- conf , _ , err := middleware .Extract (r , false )
375
- if err != nil {
376
- http .Error (w , "invalid StaticBackend key " , http .StatusUnauthorized )
343
+ func (m * membership ) setPassword (w http.ResponseWriter , r * http.Request ) {
344
+ conf , a , err := middleware .Extract (r , true )
345
+ if err != nil || a . Role < 100 {
346
+ http .Error (w , "insufficient priviledges " , http .StatusUnauthorized )
377
347
return
378
348
}
379
349
380
- db := client .Database (conf .Name )
381
-
382
350
var data = new (struct {
383
- Email string `json:"email"`
384
- Code string `json:"code "`
385
- Password string `json:"password "`
351
+ Email string `json:"email"`
352
+ OldPassword string `json:"oldPassword "`
353
+ NewPassword string `json:"newPassword "`
386
354
})
387
355
if err := parseBody (r .Body , & data ); err != nil {
388
356
http .Error (w , err .Error (), http .StatusBadRequest )
389
357
return
390
358
}
391
359
392
- filter := bson. M { "email" : strings . ToLower ( data . Email ), "sb_reset_code" : data . Code }
393
- var tok internal. Token
394
- sr := db . Collection ( "sb_tokens" ). FindOne ( context . Background (), filter )
395
- if err := sr . Decode ( & tok ); err != nil {
396
- http .Error (w , err .Error (), http .StatusInternalServerError )
360
+ db := client . Database ( conf . Name )
361
+
362
+ tok , err := m . validateUserPassword ( db , data . Email , data . OldPassword )
363
+ if err != nil {
364
+ http .Error (w , err .Error (), http .StatusUnauthorized )
397
365
return
398
366
}
399
367
400
- newpw , err := bcrypt .GenerateFromPassword ([]byte (data .Password ), bcrypt .DefaultCost )
368
+ newpw , err := bcrypt .GenerateFromPassword ([]byte (data .NewPassword ), bcrypt .DefaultCost )
401
369
if err != nil {
402
370
http .Error (w , err .Error (), http .StatusInternalServerError )
403
371
return
404
372
}
405
373
406
374
ctx := context .Background ()
407
- filter = bson.M {internal . FieldID : tok .ID }
375
+ filter : = bson.M {"_id" : tok .ID }
408
376
update := bson.M {"$set" : bson.M {"pw" : string (newpw )}}
409
377
if _ , err := db .Collection ("sb_tokens" ).UpdateOne (ctx , filter , update ); err != nil {
410
378
http .Error (w , err .Error (), http .StatusInternalServerError )
0 commit comments