@extends('layouts.app')
@section('title') Two-Factor Authentication @endsection
@section('content')


<!-- Modal Background -->
<div x-data="{ password_modal_open:false, status:{{ Auth::user()->twoFactorStatus() }}, password_confirmed:false}">
 <div x-show="password_modal_open" class="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 z-50 ">
  <div x-cloak
   @keydown.window.escape="password_modal_open = false"
   x-show="password_modal_open"
   class="relative z-10"
   aria-labelledby="modal-title"
   x-ref="dialog"
   aria-modal="true">
  <!-- Modal Content -->
   <div x-on:click.away="password_modal_open = false" class="flex flex-col gap-2 bg-white dark:bg-slate-900  rounded-lg drop-shadow-md p-4 hover:shadow-lg hover:transition-all animate-slide-up-fade-in">
    <div class="">
     <p class="text-2xl font-bold">Password confirmation</p>
    </div>
    <div class="">
     Password required before changing settings for 2FA.
    </div>
    <div id="password_message">

    </div>
    <div class="">
     <input type="password"
      class="bg-gray-50 border border-gray-300 text-gray-900 w-full rounded-lg block py-2 px-4 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white"
      placeholder="Login password"
      id="password" name="password"
      x-on:keyup.enter="$refs.password_verify.click()"
     >
    </div>
    <div class="flex justify-center">
     <button x-ref="password_verify" x-on:click=" async () => { if(await password_confirm()){ password_modal_open = false; password_confirmed = true;} else { password_confirmed = false; password_modal_open = true; }}" class="px-4 py-2 text-m font-medium text-gray-900 bg-white border border-gray-200 rounded-lg hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-700 dark:text-white dark:hover:text-white dark:hover:bg-gray-700">Verify</button>
    </div>
   </div>
  </div>
 </div>


 <div class="flex-1 justify-between border-s-2 border-indigo-400 flex-col bg-white dark:bg-slate-900  rounded-lg drop-shadow-md p-4 hover:shadow-lg hover:transition-all animate-slide-up-fade-in">
  <div x-show="status==0">
    <div class="flex flex-col gap-2">
     <div>
       <span class="text-xl">2FA is not enabled for your account</span>
     </div>
     <div>
      <button x-on:click="async () => { if ( password_confirmed ) { if(await enable_2fa()) { status=1; load_qr(); } } else { password_modal_open=true; } }" class="px-4 py-2 text-m font-medium text-gray-900 bg-white border border-gray-200 rounded-lg hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-700 dark:text-white dark:hover:text-white dark:hover:bg-gray-700">Enable 2FA</button>
     </div>
    </div>
   </div>
   <div x-show="status==1">
    <div class="flex flex-col gap-2">
     <div>
      <p><span class="text-xl">2FA is enabled for your account but not confirmed yet.</span></p>
      <p>Please finish configuring two factor authentication.<br>Scan the QR code with your authenticator app and fill in the TOTP code.</p>
     </div>
     <span class="p-4 bg-white w-fit" id="qr_code" x-init="if(status==1) {load_qr()}">
     </span>
     <div class="w-fit">
      <input type="text"
       class="bg-gray-50 border border-gray-300 text-gray-900 w-full rounded-lg block py-2 px-4 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white"
       placeholder="TOTP Password"
       id="totp" name="totp" autofocus
       x-on:keyup.enter="$refs.totp_verify.click()"
      >
     </div>
     <div class="w-fit">
      <button x-ref="totp_verify" x-on:click="async () => { if ( await(verify_totp()) ) { status=2; load_recovery_codes(); } }" class="px-4 py-2 text-m font-medium text-gray-900 bg-white border border-gray-200 rounded-lg hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-700 dark:text-white dark:hover:text-white dark:hover:bg-gray-700">Verify</button>
     </div>
    </div>
   </div>
   <div x-show="status==2">
    <div class="flex flex-col gap-2">
     <div>
      <span class="text-xl">2FA is enabled for your account</span>
     </div>
     <div id="recovery_codes" class="flex flex-col gap-2">
     </div>
     <div>
      <button x-on:click="async () => {if ( password_confirmed ) { if(await disable_2fa()) { status=0 } } else { password_modal_open=true; } }" class="px-4 py-2 text-m font-medium text-gray-900 bg-white border border-red-200 rounded-lg hover:bg-gray-100 dark:bg-gray-800 dark:border-red-700 dark:text-white dark:hover:text-white dark:hover:bg-gray-700">Disable 2FA</button>
     </div>
    </div>
   </div>

 </div>
</div>
<script type="text/javascript">
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
document.addEventListener('DOMContentLoaded', function () {
 document.getElementById('menu_twofactor').classList.remove('text-gray-500');
 document.getElementById('menu_twofactor').classList.remove('hover:bg-gray-700');
 document.getElementById('menu_twofactor').classList.remove('hover:bg-opacity-25');
 document.getElementById('menu_twofactor').classList.remove('hover:text-gray-100');
 document.getElementById('menu_twofactor').classList.add('text-gray-100');
 document.getElementById('menu_twofactor').classList.add('bg-opacity-25');
 document.getElementById('menu_twofactor').classList.add('bg-gray-700');
 document.getElementById('menu_twofactor').classList.add('border-e-2');
 document.getElementById('menu_twofactor').classList.add('border-indigo-400');
});
function password_confirm()
{
 var password = document.getElementById('password').value;
 var msg = document.getElementById('password_message');
 var ret = false;
 return fetch('{{ route("password.confirm.store") }}', {
  method: 'POST',
  headers: {
    'X-CSRF-TOKEN': csrfToken,
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  },
  credentials: 'same-origin',
  body: JSON.stringify({ password: password })
 })
 .then(response => {
  if (response.ok) {
   msg.innerHTML = '';
   return true;
  } else {

   msg.innerHTML = '<span>Wrong password</span>';
   return false;
 }
 });
}

function enable_2fa()
{
 return fetch('{{ route("two-factor.enable") }}', {
  method: 'POST',
  headers: {
    'X-CSRF-TOKEN': csrfToken,
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  },
  credentials: 'same-origin',
  body: JSON.stringify({})
 })
 .then(response => {
  if (response.ok) {
   return true;
  } else {
   return false;
 }
 });
}
function load_qr()
{
 return fetch('{{ route("two-factor.qr-code") }}', {
  method: 'GET',
  headers: {
    'X-CSRF-TOKEN': csrfToken,
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  },
  credentials: 'same-origin'
 })
 .then(response => response.json())
 .then(response => {
  qr_img = document.getElementById('qr_code');
  qr_img.innerHTML = response.svg;
 });
}

function load_recovery_codes()
{
 return fetch('{{ route("two-factor.recovery-codes") }}', {
  method: 'GET',
  headers: {
    'X-CSRF-TOKEN': csrfToken,
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  },
  credentials: 'same-origin'
 })
 .then(response => response.json())
 .then(response => {
  recovery_codes_element = document.getElementById('recovery_codes');
  var output = '<span>Here are your recovery codes. You may login with any of them if you lose access to your authenticator app.</br>\
   These won\'t be shown again.</br>\
  Keep them safe.</span>';
  response.forEach( (code) => {
   output += `<span>${code}</span>`;
  });
  recovery_codes_element.innerHTML = output;
 });
}

function verify_totp()
{
 var otp = document.getElementById('totp').value;
 return fetch('{{ route("two-factor.confirm") }}', {
  method: 'POST',
  headers: {
    'X-CSRF-TOKEN': csrfToken,
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  },
  credentials: 'same-origin',
  body: JSON.stringify({ code: otp })
 })
 .then(response => {
  if (response.ok) {
   return true;
  } else {
   return false;
 }
 });
}

function disable_2fa()
{
 return fetch('{{ route("two-factor.disable") }}', {
  method: 'DELETE',
  headers: {
    'X-CSRF-TOKEN': csrfToken,
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  },
  credentials: 'same-origin',
 })
 .then(response => {
  if (response.ok) {
   return true;
  } else {
   return false;
 }
 });
}
</script>
@endsection
