1
1
package shieldpassword
2
2
3
3
import (
4
+ "cmp"
4
5
"context"
5
6
"fmt"
6
7
"log/slog"
24
25
25
26
// Config is the configuration for the password handler.
26
27
type Config [T any ] struct {
27
- Logger * slog.Logger
28
- PasswordHasher PasswordHasher
29
- Hijacker Hijacker [T ]
28
+ Logger * slog.Logger
29
+ PasswordHasher PasswordHasher
30
+ PasswordVerifier shieldpasswordverifier.PasswordVerifier
31
+ Hijacker Hijacker [T ]
32
+ }
33
+
34
+ func (c * Config [T ]) defaults () {
35
+ c .Logger = cmp .Or (c .Logger , shield .DefaultLogger )
36
+ c .PasswordHasher = cmp .Or (c .PasswordHasher , DefaultPasswordHasher )
37
+ }
38
+
39
+ func (c * Config [T ]) assert () {
40
+ debug .Assert (c .PasswordHasher != nil , "PasswordHasher must be set" )
41
+ debug .Assert (c .Logger != nil , "Logger must be set" )
30
42
}
31
43
32
44
// Hijacker also to hijack into the user registration and logging in sessions
@@ -46,42 +58,49 @@ type Hijacker[T any] interface {
46
58
// NewConfig creates a new config.
47
59
//
48
60
// If no password hasher is configured, the DefaultPasswordHasher will be used.
49
- func NewConfig [T any ](config ... func (* Config [T ])) * Config [T ] {
50
- cfg := Config [T ]{}
51
-
52
- for _ , c := range config {
53
- c (& cfg )
54
- }
55
-
56
- if cfg .PasswordHasher == nil {
57
- cfg .PasswordHasher = DefaultPasswordHasher
61
+ func NewConfig [T any ](opts ... func (* Config [T ])) * Config [T ] {
62
+ config := Config [T ]{}
63
+ for _ , opt := range opts {
64
+ opt (& config )
58
65
}
59
66
60
- debug .Assert (cfg .PasswordHasher != nil , "PasswordHasher must be set" )
67
+ config .defaults ()
68
+ config .assert ()
61
69
62
- return & cfg
70
+ return & config
63
71
}
64
72
65
73
// WithPasswordHasher configures the password hasher.
66
74
//
67
75
// When setting a password hasher make sure to set it across all modules,
68
- // such as user registration, password reset and password verification.
76
+ // i.e., user registration, password reset and password verification.
69
77
func WithPasswordHasher [T any ](hasher PasswordHasher ) func (* Config [T ]) {
70
78
return func (cfg * Config [T ]) { cfg .PasswordHasher = hasher }
71
79
}
72
80
73
- func WithLogger [T any ](logger * slog.Logger ) func (* Config [T ]) {
74
- return func (cfg * Config [T ]) { cfg .Logger = logger }
75
- }
76
-
77
81
func WithHijacker [T any ](hijacker Hijacker [T ]) func (* Config [T ]) {
78
82
return func (cfg * Config [T ]) { cfg .Hijacker = hijacker }
79
83
}
80
84
81
85
type Handler [T any ] struct {
82
- config * Config [T ]
83
- pool * pgxpool.Pool
84
- PasswordVerifier shieldpasswordverifier.PasswordVerifier
86
+ pool * pgxpool.Pool
87
+ config * Config [T ]
88
+ }
89
+
90
+ func NewHandler [T any ](pool * pgxpool.Pool , config * Config [T ]) * Handler [T ] {
91
+ if config == nil {
92
+ config = NewConfig [T ]()
93
+ }
94
+ config .assert ()
95
+
96
+ h := Handler [T ]{pool , config }
97
+ h .assert ()
98
+
99
+ return & h
100
+ }
101
+
102
+ func (h * Handler [T ]) assert () {
103
+ debug .Assert (h .pool != nil , "Logger must be set" )
85
104
}
86
105
87
106
func (h * Handler [T ]) HandleUserRegistration (
@@ -147,6 +166,7 @@ func (h *Handler[T]) handleUserRegistrationTx(
147
166
Email : email ,
148
167
}); err != nil {
149
168
if sqldb .IsUniqueViolationError (err ) {
169
+ d ("unique error violation" )
150
170
return uid , ErrEmailAlreadyTaken
151
171
}
152
172
0 commit comments