-
Notifications
You must be signed in to change notification settings - Fork 1
/
config.go
304 lines (261 loc) · 9.93 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
// Copyright (c) 2024 H0llyW00dz All rights reserved.
//
// License: BSD 3-Clause License
package twofa
import (
"encoding/json"
"image"
"time"
otp "github.com/H0llyW00dzZ/fiber2fa/internal/otpverifier"
"github.com/gofiber/fiber/v2"
"github.com/skip2/go-qrcode"
"github.com/xlzd/gotp"
)
// Config defines the configuration options for the 2FA middleware.
type Config struct {
// Secret is the shared secret used for generating and verifying TOTP tokens.
//
// Optional. Default: "gotp.RandomSecret(16)" (Recommended).
Secret string
// Issuer is the name of the issuer to be displayed in the authenticator app.
//
// Optional. Default: "MyApp"
Issuer string
// AccountName is the name of the account to be displayed in the authenticator app.
//
// Deprecated: Use "ContextKey" Instead.
AccountName string
// DigitsCount is the number of digits in the generated TOTP token.
//
// Optional. Default: 6
DigitsCount int
// Period is the time step size in seconds for generating TOTP tokens.
//
// Optional. Default: 30
Period int
// Hash is the hashing algorithm used for generating TOTP tokens.
//
// Optional. Default: otp.SHA512
Hash string
// TimeSource is the time source used for generating TOTP tokens.
//
// Optional. Default: otp.DefaultConfig.TOTPTime()
TimeSource otp.TimeSource
// SyncWindow is the number of time steps to check before and after the current time step when verifying TOTP tokens.
//
// Optional. Default: otp.DefaultConfig.SyncWindow
SyncWindow int
// SkipCookies is a list of paths that should skip the 2FA middleware.
//
// Optional. Default: nil
SkipCookies []string
// CookieName is the name of the cookie used to store the 2FA validation status.
//
// Optional. Default: "twofa_cookie"
CookieName string
// CookieMaxAge is the maximum age of the 2FA cookie in seconds.
//
// Optional. Default: 86400 (24 hours)
CookieMaxAge int
// CookiePath is the path scope of the 2FA cookie.
//
// Optional. Default: "/"
CookiePath string
// CookieDomain is the domain scope of the 2FA cookie.
//
// If set to "auto", it will automatically set the cookie domain based on the request's domain if HTTPS is used.
//
// Optional. Default: ""
CookieDomain string
// CookieSecure determines whether the 2FA cookie should be sent only over HTTPS.
//
// Optional. Default: false
CookieSecure bool
// RedirectURL is the URL to redirect the user to when 2FA is required.
//
// Optional. Default: "/2fa"
RedirectURL string
// Storage is the storage provider for storing 2FA information.
//
// Optional. Default: nil (in-memory storage)
Storage fiber.Storage
// StorageExpiration is the duration for which the 2FA information should be stored in the storage.
//
// Optional. Default: 0 (no expiration)
StorageExpiration time.Duration
// TokenLookup is a string in the form of "<source>:<name>" that is used to extract the token from the request.
//
// Optional. Default value "query:token".
//
// Possible values:
//
// - "header:<name>"
// - "query:<name>"
// - "form:<name>"
// - "param:<name>"
// - "cookie:<name>"
TokenLookup string
// ContextKey is the key used to store the 2FA information in the context.
//
// Required.
ContextKey string
// JSONMarshal is a custom JSON marshaling function.
//
// Optional. Default: json.Marshal
JSONMarshal JSONMarshal
// JSONUnmarshal is a custom JSON unmarshaling function.
//
// Optional. Default: json.Unmarshal
JSONUnmarshal JSONUnmarshal
// Next defines a function to skip this middleware when returned true.
//
// Optional. Default: nil
Next func(c *fiber.Ctx) bool
// QRcodeImage is the custom barcode image to be used instead of the default QR code.
//
// Deprecated: replaced by "QRCode"
QRcodeImage image.Image
// QRCode is the configuration for the QR code generation.
// It allows customizing the QR code path template, image, and content.
//
// Optional. Default: see DefaultQRCodeConfig
QRCode QRCodeConfig
// Encode is the configuration for the QR code encoding.
//
// Optional. Default: see DefaultEncodeConfig
Encode EncodeConfig
// ResponseMIME is the MIME type for the response format.
//
// This field is used to set the default response format for the middleware.
// When custom error handlers (UnauthorizedHandler and InternalErrorHandler) are not provided,
// the middleware will use the ResponseMIME value to determine the response format.
//
// Optional. Default: fiber.MIMETextPlainCharsetUTF8
//
// Possible values:
// - fiber.MIMETextPlainCharsetUTF8 (default)
// - fiber.MIMEApplicationJSON
// - fiber.MIMEApplicationJSONCharsetUTF8
// - fiber.MIMEApplicationXML
// - fiber.MIMEApplicationXMLCharsetUTF8
// - fiber.MIMETextPlain
// - fiber.MIMETextHTML (custom handler required)
// - fiber.MIMETextHTMLCharsetUTF8 (custom handler required)
// - fiber.MIMETextJavaScript (custom handler required)
// - fiber.MIMETextJavaScriptCharsetUTF8 (custom handler required)
// - fiber.MIMEApplicationForm (custom handler required)
// - fiber.MIMEMultipartForm (custom handler required)
// - fiber.MIMEOctetStream (custom handler required)
//
// When using custom error handlers, you can set the response format within the handler functions
// using the appropriate methods provided by the Fiber context (c.JSON(), c.XML(), c.SendString(), etc.).
// The custom error handlers allow you to use any valid MIME type supported by Fiber for the response format.
//
// Examples of possible response formats for custom error handlers:
// - Plain text: c.SendString() with content type fiber.MIMETextPlain or fiber.MIMETextPlainCharsetUTF8
// - HTML: c.SendString() with content type fiber.MIMETextHTML or fiber.MIMETextHTMLCharsetUTF8
// - XML: c.XML() with content type fiber.MIMEApplicationXML or fiber.MIMEApplicationXMLCharsetUTF8
// - JSON: c.JSON() with content type fiber.MIMEApplicationJSON or fiber.MIMEApplicationJSONCharsetUTF8
// - JavaScript: c.SendString() with content type fiber.MIMETextJavaScript or fiber.MIMETextJavaScriptCharsetUTF8
// - Form data: c.SendString() with content type fiber.MIMEApplicationForm
// - Custom MIME type: c.Send() with the desired MIME type
//
// Note: When custom error handlers are provided, the ResponseMIME value is not used for the response format.
// The response format is determined by the methods used within the custom error handlers.
ResponseMIME string
// UnauthorizedHandler is a custom handler for unauthorized responses.
//
// Optional. Default: nil
UnauthorizedHandler fiber.ErrorHandler
// InternalErrorHandler is a custom handler for internal server error responses.
//
// Optional. Default: nil
InternalErrorHandler fiber.ErrorHandler
// IdentifierGenerator is a function that generates a unique identifier for the 2FA registration.
//
// The function takes a *fiber.Ctx as a parameter and returns a string identifier.
// It allows customizing the identifier generation based on the request context.
//
// If not provided, the default identifier generator will be used, which generates a UUID.
//
// Optional. Default: nil (uses fiber utils.UUIDv4 generator)
IdentifierGenerator func(*fiber.Ctx) string
}
// DefaultConfig holds the default configuration values.
var DefaultConfig = Config{
Secret: gotp.RandomSecret(16),
Issuer: "MyApp",
DigitsCount: otp.DefaultConfig.Digits,
Period: otp.DefaultConfig.Period,
Hash: otp.SHA512,
TimeSource: otp.DefaultConfig.TOTPTime,
SyncWindow: otp.DefaultConfig.SyncWindow,
SkipCookies: nil,
CookieName: "twofa_cookie",
CookieMaxAge: 86400,
CookiePath: "/",
CookieDomain: "",
CookieSecure: false,
RedirectURL: "/2fa",
Storage: nil,
StorageExpiration: 0,
TokenLookup: "query:token",
ContextKey: "",
JSONMarshal: json.Marshal,
JSONUnmarshal: json.Unmarshal,
Next: nil,
QRCode: DefaultQRCodeConfig,
Encode: DefaultEncodeConfig,
ResponseMIME: fiber.MIMETextPlainCharsetUTF8,
UnauthorizedHandler: nil,
InternalErrorHandler: nil,
IdentifierGenerator: nil,
}
// JSONMarshal defines the function signature for a JSON marshal.
type JSONMarshal func(v any) ([]byte, error)
// JSONUnmarshal defines the function signature for a JSON unmarshal.
type JSONUnmarshal func(data []byte, v any) error
// QRCodeConfig defines the configuration options for the QR code generation.
type QRCodeConfig struct {
// PathTemplate is the template for the QR code path.
//
// Optional. Default: "/2fa/register?account=%s"
PathTemplate string
// Image is the custom QR code image to be used instead of the default QR code.
//
// Optional. Default: nil
Image image.Image
// Content is the template for the QR code content.
//
// Optional. Default: "otpauth://totp/%s:%s?secret=%s&issuer=%s"
Content string
}
// DefaultQRCodeConfig holds the default configuration values for the QR code generation.
var DefaultQRCodeConfig = QRCodeConfig{
Image: nil,
Content: "otpauth://totp/%s:%s?secret=%s&issuer=%s",
// TODO: Implement a page for generating a QR code that can be scanned by mobile apps to register and store the one-time password.
// Implementation will be done later as I currently don't have a clear idea during a break.
PathTemplate: "/2fa/register?account=%s",
}
// EncodeConfig defines the configuration options for the QR code encoding.
type EncodeConfig struct {
// Level is the QR code recovery level.
//
// Optional. Default: qrcode.Medium
Level qrcode.RecoveryLevel
// Size is the size of the QR code image.
//
// Optional. Default: 256
Size int
// VersionNumber is the QR code version number.
//
// Optional. Default: 0 (automatically determined)
VersionNumber int
}
// DefaultEncodeConfig holds the default configuration values for the QR code encoding.
var DefaultEncodeConfig = EncodeConfig{
Level: qrcode.Medium,
Size: 256,
VersionNumber: 0,
}