MCPcopy Create free account
hub / github.com/supabase/auth / enrollTOTPFactor

Method enrollTOTPFactor

internal/api/mfa.go:232–304  ·  view source on GitHub ↗
(w http.ResponseWriter, r *http.Request, params *EnrollFactorParams)

Source from the content-addressed store, hash-verified

230}
231
232func (a *API) enrollTOTPFactor(w http.ResponseWriter, r *http.Request, params *EnrollFactorParams) error {
233 ctx := r.Context()
234 user := getUser(ctx)
235 db := a.db.WithContext(ctx)
236 config := a.config
237 session := getSession(ctx)
238 issuer := ""
239 if params.Issuer == "" {
240 u, err := url.ParseRequestURI(config.SiteURL)
241 if err != nil {
242 return apierrors.NewInternalServerError("site url is improperly formatted")
243 }
244 issuer = u.Host
245 } else {
246 issuer = params.Issuer
247 }
248
249 if err := validateFactors(db, user, params.FriendlyName, config, session); err != nil {
250 return err
251 }
252
253 var factor *models.Factor
254 var buf bytes.Buffer
255 var key *otp.Key
256 key, err := totp.Generate(totp.GenerateOpts{
257 Issuer: issuer,
258 AccountName: user.GetEmail(),
259 })
260 if err != nil {
261 return apierrors.NewInternalServerError(QRCodeGenerationErrorMessage).WithInternalError(err)
262 }
263
264 svgData := svg.New(&buf)
265 qrCode, _ := qr.Encode(key.String(), qr.H, qr.Auto)
266 qs := goqrsvg.NewQrSVG(qrCode, DefaultQRSize)
267 qs.StartQrSVG(svgData)
268 if err = qs.WriteQrSVG(svgData); err != nil {
269 return apierrors.NewInternalServerError(QRCodeGenerationErrorMessage).WithInternalError(err)
270 }
271 svgData.End()
272
273 factor = models.NewTOTPFactor(user, params.FriendlyName)
274 if err := factor.SetSecret(key.Secret(), config.Security.DBEncryption.Encrypt, config.Security.DBEncryption.EncryptionKeyID, config.Security.DBEncryption.EncryptionKey); err != nil {
275 return err
276 }
277
278 err = db.Transaction(func(tx *storage.Connection) error {
279 if terr := tx.Create(factor); terr != nil {
280 return terr
281 }
282
283 if terr := models.NewAuditLogEntry(config.AuditLog, r, tx, user, models.EnrollFactorAction, utilities.GetIPAddress(r), map[string]interface{}{
284 "factor_id": factor.ID,
285 }); terr != nil {
286 return terr
287 }
288 return nil
289 })

Callers 1

EnrollFactorMethod · 0.95

Calls 15

SetSecretMethod · 0.95
NewInternalServerErrorFunction · 0.92
NewTOTPFactorFunction · 0.92
NewAuditLogEntryFunction · 0.92
GetIPAddressFunction · 0.92
getUserFunction · 0.85
getSessionFunction · 0.85
validateFactorsFunction · 0.85
sendJSONFunction · 0.85
WithContextMethod · 0.80
EncodeMethod · 0.80
TransactionMethod · 0.80

Tested by

no test coverage detected