| 402 | } |
| 403 | |
| 404 | func SettingsTwoFactorEnable(c *context.Context) { |
| 405 | if database.Handle.TwoFactors().IsEnabled(c.Req.Context(), c.User.ID) { |
| 406 | c.NotFound() |
| 407 | return |
| 408 | } |
| 409 | |
| 410 | c.Title("settings.two_factor_enable_title") |
| 411 | c.PageIs("SettingsSecurity") |
| 412 | |
| 413 | var key *otp.Key |
| 414 | var err error |
| 415 | keyURL := c.Session.Get("twoFactorURL") |
| 416 | if keyURL != nil { |
| 417 | key, _ = otp.NewKeyFromURL(keyURL.(string)) |
| 418 | } |
| 419 | if key == nil { |
| 420 | key, err = totp.Generate(totp.GenerateOpts{ |
| 421 | Issuer: conf.App.BrandName, |
| 422 | AccountName: c.User.Email, |
| 423 | }) |
| 424 | if err != nil { |
| 425 | c.Errorf(err, "generate TOTP") |
| 426 | return |
| 427 | } |
| 428 | } |
| 429 | c.Data["TwoFactorSecret"] = key.Secret() |
| 430 | |
| 431 | img, err := key.Image(240, 240) |
| 432 | if err != nil { |
| 433 | c.Errorf(err, "generate image") |
| 434 | return |
| 435 | } |
| 436 | |
| 437 | var buf bytes.Buffer |
| 438 | if err = png.Encode(&buf, img); err != nil { |
| 439 | c.Errorf(err, "encode image") |
| 440 | return |
| 441 | } |
| 442 | c.Data["QRCode"] = template.URL("data:image/png;base64," + base64.StdEncoding.EncodeToString(buf.Bytes())) |
| 443 | |
| 444 | _ = c.Session.Set("twoFactorSecret", c.Data["TwoFactorSecret"]) |
| 445 | _ = c.Session.Set("twoFactorURL", key.String()) |
| 446 | c.Success(tmplUserSettingsTwoFactorEnable) |
| 447 | } |
| 448 | |
| 449 | func SettingsTwoFactorEnablePost(c *context.Context) { |
| 450 | secret, ok := c.Session.Get("twoFactorSecret").(string) |