SecuritySettings.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <?php
  2. namespace App\Http\Controllers\Settings;
  3. use App\AccountLog;
  4. use App\EmailVerification;
  5. use App\Media;
  6. use App\Profile;
  7. use App\User;
  8. use App\UserFilter;
  9. use App\UserDevice;
  10. use App\Util\Lexer\PrettyNumber;
  11. use Auth;
  12. use DB;
  13. use Carbon\Carbon;
  14. use Illuminate\Http\Request;
  15. use PragmaRX\Google2FA\Google2FA;
  16. use BaconQrCode\Renderer\ImageRenderer;
  17. use BaconQrCode\Renderer\Image\ImagickImageBackEnd;
  18. use BaconQrCode\Renderer\RendererStyle\RendererStyle;
  19. use BaconQrCode\Writer;
  20. trait SecuritySettings
  21. {
  22. public function security()
  23. {
  24. $user = Auth::user();
  25. $activity = AccountLog::whereUserId($user->id)
  26. ->orderBy('created_at', 'desc')
  27. ->limit(20)
  28. ->get();
  29. $devices = UserDevice::whereUserId($user->id)
  30. ->orderBy('created_at', 'desc')
  31. ->limit(5)
  32. ->get();
  33. return view('settings.security', compact('activity', 'user', 'devices'));
  34. }
  35. public function securityTwoFactorSetup(Request $request)
  36. {
  37. $user = Auth::user();
  38. if($user->{'2fa_enabled'} && $user->{'2fa_secret'}) {
  39. return redirect(route('account.security'));
  40. }
  41. $backups = $this->generateBackupCodes();
  42. //$google2fa = new Google2FA();
  43. $google2fa = app(Google2FA::class);
  44. $key = $google2fa->generateSecretKey(32);
  45. $qrcode = $google2fa->getQRCodeUrl(
  46. config('pixelfed.domain.app'),
  47. $user->email,
  48. $key,
  49. 500
  50. );
  51. $writer = new Writer(
  52. new ImageRenderer(
  53. new RendererStyle(400),
  54. new ImagickImageBackEnd()
  55. )
  56. );
  57. $qrcode = base64_encode($writer->writeString($qrcode));
  58. $user->{'2fa_secret'} = $key;
  59. $user->{'2fa_backup_codes'} = json_encode($backups);
  60. $user->save();
  61. return view('settings.security.2fa.setup', compact('user', 'qrcode', 'backups'));
  62. }
  63. protected function generateBackupCodes()
  64. {
  65. $keys = [];
  66. for ($i=0; $i < 11; $i++) {
  67. $key = str_random(24);
  68. $keys[] = $key;
  69. }
  70. return $keys;
  71. }
  72. public function securityTwoFactorSetupStore(Request $request)
  73. {
  74. $user = Auth::user();
  75. if($user->{'2fa_enabled'} && $user->{'2fa_secret'}) {
  76. abort(403, 'Two factor auth is already setup.');
  77. }
  78. $this->validate($request, [
  79. 'code' => 'required|integer'
  80. ]);
  81. $code = $request->input('code');
  82. $google2fa = new Google2FA();
  83. $verify = $google2fa->verifyKey($user->{'2fa_secret'}, $code);
  84. if($verify) {
  85. $user->{'2fa_enabled'} = true;
  86. $user->{'2fa_setup_at'} = Carbon::now();
  87. $user->save();
  88. return response()->json(['msg'=>'success']);
  89. } else {
  90. return response()->json(['msg'=>'fail'], 403);
  91. }
  92. }
  93. public function securityTwoFactorEdit(Request $request)
  94. {
  95. $user = Auth::user();
  96. if(!$user->{'2fa_enabled'} || !$user->{'2fa_secret'}) {
  97. abort(403);
  98. }
  99. return view('settings.security.2fa.edit', compact('user'));
  100. }
  101. public function securityTwoFactorRecoveryCodes(Request $request)
  102. {
  103. $user = Auth::user();
  104. if(!$user->{'2fa_enabled'} || !$user->{'2fa_secret'} || !$user->{'2fa_backup_codes'}) {
  105. abort(403);
  106. }
  107. $codes = json_decode($user->{'2fa_backup_codes'}, true);
  108. return view('settings.security.2fa.recovery-codes', compact('user', 'codes'));
  109. }
  110. public function securityTwoFactorRecoveryCodesRegenerate(Request $request)
  111. {
  112. $user = Auth::user();
  113. if(!$user->{'2fa_enabled'} || !$user->{'2fa_secret'}) {
  114. abort(403);
  115. }
  116. $backups = $this->generateBackupCodes();
  117. $user->{'2fa_backup_codes'} = json_encode($backups);
  118. $user->save();
  119. return redirect(route('settings.security.2fa.recovery'));
  120. }
  121. public function securityTwoFactorUpdate(Request $request)
  122. {
  123. $user = Auth::user();
  124. if(!$user->{'2fa_enabled'} || !$user->{'2fa_secret'} || !$user->{'2fa_backup_codes'}) {
  125. abort(403);
  126. }
  127. $this->validate($request, [
  128. 'action' => 'required|string|max:12'
  129. ]);
  130. if($request->action !== 'remove') {
  131. abort(403);
  132. }
  133. $user->{'2fa_enabled'} = false;
  134. $user->{'2fa_secret'} = null;
  135. $user->{'2fa_backup_codes'} = null;
  136. $user->{'2fa_setup_at'} = null;
  137. $user->save();
  138. return response()->json([
  139. 'msg' => 'Successfully removed 2fa device'
  140. ], 200);
  141. }
  142. }