2023-01-18 20:05:10 +01:00
package store
import (
2023-01-20 17:00:46 +01:00
"fmt"
"strings"
"time"
2023-01-18 20:05:10 +01:00
"github.com/jmoiron/sqlx"
"github.com/pkg/errors"
2024-02-14 20:06:04 +01:00
"github.com/sirupsen/logrus"
2023-01-18 20:05:10 +01:00
)
type PasswordResetRequest struct {
Model
Token string
AccountId int
2023-03-09 21:08:59 +01:00
Deleted bool
2023-01-18 20:05:10 +01:00
}
2023-03-22 20:17:27 +01:00
func ( str * Store ) CreatePasswordResetRequest ( prr * PasswordResetRequest , tx * sqlx . Tx ) ( int , error ) {
2024-02-14 20:06:04 +01:00
if err := str . DeletePasswordResetRequestsByAccountId ( prr . AccountId , tx ) ; err != nil {
logrus . Errorf ( "unable to delete old password reset requests for account '%v', but continuing: %v" , prr . AccountId , err )
}
2024-01-18 18:14:32 +01:00
stmt , err := tx . Prepare ( "insert into password_reset_requests (account_id, token) values ($1, $2) returning id" )
2023-01-18 20:05:10 +01:00
if err != nil {
return 0 , errors . Wrap ( err , "error preparing password_reset_requests insert statement" )
}
var id int
if err := stmt . QueryRow ( prr . AccountId , prr . Token ) . Scan ( & id ) ; err != nil {
return 0 , errors . Wrap ( err , "error executing password_reset_requests insert statement" )
}
return id , nil
}
2023-03-22 20:17:27 +01:00
func ( str * Store ) FindPasswordResetRequestWithToken ( token string , tx * sqlx . Tx ) ( * PasswordResetRequest , error ) {
2023-01-18 20:05:10 +01:00
prr := & PasswordResetRequest { }
2023-03-10 17:14:01 +01:00
if err := tx . QueryRowx ( "select * from password_reset_requests where token = $1 and not deleted" , token ) . StructScan ( prr ) ; err != nil {
2023-01-18 20:05:10 +01:00
return nil , errors . Wrap ( err , "error selecting password_reset_requests by token" )
}
return prr , nil
}
2023-03-22 20:17:27 +01:00
func ( str * Store ) FindExpiredPasswordResetRequests ( before time . Time , limit int , tx * sqlx . Tx ) ( [ ] * PasswordResetRequest , error ) {
2023-01-20 17:00:46 +01:00
var sql string
2023-03-22 20:17:27 +01:00
switch str . cfg . Type {
2023-01-20 17:00:46 +01:00
case "postgres" :
2023-03-10 17:14:01 +01:00
sql = "select * from password_reset_requests where created_at < $1 and not deleted limit %d for update"
2023-01-20 17:00:46 +01:00
case "sqlite3" :
2023-03-10 17:14:01 +01:00
sql = "select * from password_reset_requests where created_at < $1 and not deleted limit %d"
2023-01-20 17:00:46 +01:00
default :
2023-03-22 20:17:27 +01:00
return nil , errors . Errorf ( "unknown database type '%v'" , str . cfg . Type )
2023-01-20 17:00:46 +01:00
}
rows , err := tx . Queryx ( fmt . Sprintf ( sql , limit ) , before )
if err != nil {
return nil , errors . Wrap ( err , "error selecting expired password_reset_requests" )
}
var prrs [ ] * PasswordResetRequest
for rows . Next ( ) {
prr := & PasswordResetRequest { }
if err := rows . StructScan ( prr ) ; err != nil {
return nil , errors . Wrap ( err , "error scanning password_reset_request" )
}
prrs = append ( prrs , prr )
}
return prrs , nil
}
2023-03-22 20:17:27 +01:00
func ( str * Store ) DeletePasswordResetRequest ( id int , tx * sqlx . Tx ) error {
2023-03-10 17:14:01 +01:00
stmt , err := tx . Prepare ( "update password_reset_requests set updated_at = current_timestamp, deleted = true where id = $1" )
2023-01-18 20:05:10 +01:00
if err != nil {
return errors . Wrap ( err , "error preparing password_reset_requests delete statement" )
}
_ , err = stmt . Exec ( id )
if err != nil {
return errors . Wrap ( err , "error executing password_reset_requests delete statement" )
}
return nil
}
2023-01-20 17:00:46 +01:00
2023-03-22 20:17:27 +01:00
func ( str * Store ) DeleteMultiplePasswordResetRequests ( ids [ ] int , tx * sqlx . Tx ) error {
2023-01-20 17:00:46 +01:00
if len ( ids ) == 0 {
return nil
}
anyIds := make ( [ ] any , len ( ids ) )
indexes := make ( [ ] string , len ( ids ) )
for i , id := range ids {
anyIds [ i ] = id
indexes [ i ] = fmt . Sprintf ( "$%d" , i + 1 )
}
2023-03-10 17:14:01 +01:00
stmt , err := tx . Prepare ( fmt . Sprintf ( "update password_reset_requests set updated_at = current_timestamp, deleted = true where id in (%s)" , strings . Join ( indexes , "," ) ) )
2023-01-20 17:00:46 +01:00
if err != nil {
return errors . Wrap ( err , "error preparing password_reset_requests delete multiple statement" )
}
_ , err = stmt . Exec ( anyIds ... )
if err != nil {
return errors . Wrap ( err , "error executing password_reset_requests delete multiple statement" )
}
return nil
}
2024-02-14 20:06:04 +01:00
func ( str * Store ) DeletePasswordResetRequestsByAccountId ( accountId int , tx * sqlx . Tx ) error {
stmt , err := tx . Prepare ( "update password_reset_requests set updated_at = current_timestamp, deleted = true where account_id = $1" )
if err != nil {
return errors . Wrap ( err , "error preparing password_reset_requests delete by account_id statement" )
}
_ , err = stmt . Exec ( accountId )
if err != nil {
return errors . Wrap ( err , "error executing password_reset_requests delete by account_id statement" )
}
return nil
}