@@ -46,6 +46,7 @@ const (
46
46
userAuthLoggerName = "userauth"
47
47
OAuthConvertCookieValue = "coder_oauth_convert_jwt"
48
48
mergeStateStringPrefix = "convert-"
49
+ oneTimePasscodeDuration = 20 * time .Minute
49
50
)
50
51
51
52
type OAuthConvertStateClaims struct {
@@ -202,13 +203,13 @@ func (api *API) postConvertLoginType(rw http.ResponseWriter, r *http.Request) {
202
203
})
203
204
}
204
205
205
- // Requests a one-time- passcode for a user.
206
+ // Requests a one-time passcode for a user.
206
207
//
207
- // @Summary Request one-time- passcode.
208
+ // @Summary Request one-time passcode.
208
209
// @ID request-one-time-passcode
209
210
// @Accept json
210
211
// @Tags Authorization
211
- // @Param request body codersdk.RequestOneTimePasscodeRequest true "Request one time passcode request"
212
+ // @Param request body codersdk.RequestOneTimePasscodeRequest true "Request one- time passcode request"
212
213
// @Success 200
213
214
// @Router /users/request-one-time-passcode [post]
214
215
func (api * API )postRequestOneTimePasscode (rw http.ResponseWriter ,r * http.Request ) {
@@ -243,7 +244,7 @@ func (api *API) postRequestOneTimePasscode(rw http.ResponseWriter, r *http.Reque
243
244
rw .WriteHeader (http .StatusOK )
244
245
}()
245
246
246
- //nolint:gocritic // In order to request a one-time- passcode, we need to get the user first!
247
+ //nolint:gocritic // In order to request a one-time passcode, we need to get the user first - and can only do that in the system auth context.
247
248
user ,err := api .Database .GetUserByEmailOrUsername (dbauthz .AsSystemRestricted (ctx ), database.GetUserByEmailOrUsernameParams {
248
249
Email :req .Email ,
249
250
})
@@ -254,22 +255,22 @@ func (api *API) postRequestOneTimePasscode(rw http.ResponseWriter, r *http.Reque
254
255
aReq .Old = user
255
256
256
257
passcode := uuid .New ()
257
- passcodeExpiresAt := dbtime .Now ().Add (20 * time . Minute )
258
+ passcodeExpiresAt := dbtime .Now ().Add (oneTimePasscodeDuration )
258
259
259
260
hashedPasscode ,err := userpassword .Hash (passcode .String ())
260
261
if err != nil {
261
262
logger .Error (ctx ,"unable to hash passcode" ,slog .Error (err ))
262
263
return
263
264
}
264
265
265
- //nolint:gocritic // We need to be able to save the one-time- passcode.
266
+ //nolint:gocritic // We needthe system auth context to be able to save the one-time passcode.
266
267
err = api .Database .UpdateUserHashedOneTimePasscode (dbauthz .AsSystemRestricted (ctx ), database.UpdateUserHashedOneTimePasscodeParams {
267
268
ID :user .ID ,
268
269
HashedOneTimePasscode : []byte (hashedPasscode ),
269
270
OneTimePasscodeExpiresAt : sql.NullTime {Time :passcodeExpiresAt ,Valid :true },
270
271
})
271
272
if err != nil {
272
- logger .Error (ctx ,"unable to set user hashed one time passcode" ,slog .Error (err ))
273
+ logger .Error (ctx ,"unable to set user hashed one- time passcode" ,slog .Error (err ))
273
274
return
274
275
}
275
276
@@ -278,16 +279,16 @@ func (api *API) postRequestOneTimePasscode(rw http.ResponseWriter, r *http.Reque
278
279
newUser .OneTimePasscodeExpiresAt = sql.NullTime {Time :passcodeExpiresAt ,Valid :true }
279
280
aReq .New = newUser
280
281
281
- // Send the one-time- passcode to the user.
282
+ // Send the one-time passcode to the user.
282
283
err = api .notifyUserRequestedOneTimePasscode (ctx ,user ,passcode .String ())
283
284
if err != nil {
284
- logger .Error (ctx ,"unable to notify user about one time passcode request" ,slog .Error (err ))
285
+ logger .Error (ctx ,"unable to notify user about one- time passcode request" ,slog .Error (err ))
285
286
}
286
287
}
287
288
288
289
func (api * API )notifyUserRequestedOneTimePasscode (ctx context.Context ,user database.User ,passcode string )error {
289
290
_ ,err := api .NotificationsEnqueuer .Enqueue (
290
- //nolint:gocritic // We need to be able to send the user their one time passcode.
291
+ //nolint:gocritic // We needthe system auth context to be able to send the user their one- time passcode.
291
292
dbauthz .AsSystemRestricted (ctx ),
292
293
user .ID ,
293
294
notifications .TemplateUserRequestedOneTimePasscode ,
@@ -302,9 +303,9 @@ func (api *API) notifyUserRequestedOneTimePasscode(ctx context.Context, user dat
302
303
return nil
303
304
}
304
305
305
- // Change a users password with a one-time- passcode.
306
+ // Change a users password with a one-time passcode.
306
307
//
307
- // @Summary Change password with a one-time- passcode.
308
+ // @Summary Change password with a one-time passcode.
308
309
// @ID change-password-with-a-one-time-passcode
309
310
// @Accept json
310
311
// @Tags Authorization
@@ -338,7 +339,7 @@ func (api *API) postChangePasswordWithOneTimePasscode(rw http.ResponseWriter, r
338
339
return
339
340
}
340
341
341
- //nolint:gocritic // In order to change a user's password, we need to get the user first!
342
+ //nolint:gocritic // In order to change a user's password, we need to get the user first - and can only do that in the system auth context.
342
343
user ,err := api .Database .GetUserByEmailOrUsername (dbauthz .AsSystemRestricted (ctx ), database.GetUserByEmailOrUsernameParams {
343
344
Email :req .Email ,
344
345
})
@@ -361,7 +362,7 @@ func (api *API) postChangePasswordWithOneTimePasscode(rw http.ResponseWriter, r
361
362
}
362
363
363
364
if ! equal {
364
- httpapi .Write (ctx ,rw ,http .StatusUnauthorized , codersdk.Response {
365
+ httpapi .Write (ctx ,rw ,http .StatusBadRequest , codersdk.Response {
365
366
Message :"Incorrect email or one-time-passcode." ,
366
367
})
367
368
return
@@ -398,7 +399,7 @@ func (api *API) postChangePasswordWithOneTimePasscode(rw http.ResponseWriter, r
398
399
}
399
400
400
401
err = api .Database .InTx (func (tx database.Store )error {
401
- //nolint:gocritic // We need to update the user's password.
402
+ //nolint:gocritic // We needthe system auth context to be able to update the user's password.
402
403
err = tx .UpdateUserHashedPassword (dbauthz .AsSystemRestricted (ctx ), database.UpdateUserHashedPasswordParams {
403
404
ID :user .ID ,
404
405
HashedPassword : []byte (newHashedPassword ),
@@ -407,7 +408,7 @@ func (api *API) postChangePasswordWithOneTimePasscode(rw http.ResponseWriter, r
407
408
return xerrors .Errorf ("update user hashed password: %w" ,err )
408
409
}
409
410
410
- //nolint:gocritic // We need to delete all API keys for the user.
411
+ //nolint:gocritic // We needthe system auth context to be able to delete all API keys for the user.
411
412
err = tx .DeleteAPIKeysByUserID (dbauthz .AsSystemRestricted (ctx ),user .ID )
412
413
if err != nil {
413
414
return xerrors .Errorf ("delete api keys for user: %w" ,err )
@@ -430,7 +431,7 @@ func (api *API) postChangePasswordWithOneTimePasscode(rw http.ResponseWriter, r
430
431
newUser .HashedOneTimePasscode = nil
431
432
aReq .New = newUser
432
433
433
- rw .WriteHeader (http .StatusNoContent )
434
+ rw .WriteHeader (http .StatusOK )
434
435
}
435
436
436
437
// Authenticates the user with an email and password.