public function verify()
{
if (!Configure::read('Users.GoogleAuthenticator.login')) {
$message = __d('CakeDC/Users', 'Please enable Google Authenticator first.');
$this->Flash->error($message, 'default', [], 'auth');
$this->redirect(Configure::read('Auth.loginAction'));
}
// storing user's session in the temporary one
// until the GA verification is checked
$temporarySession = $this->Auth->user();
$this->request->session()->delete('Auth.User');
if (!empty($temporarySession)) {
$this->request->session()->write('temporarySession', $temporarySession);
}
if (array_key_exists('secret', $temporarySession)) {
$secret = $temporarySession['secret'];
}
$secretVerified = $temporarySession['secret_verified'];
// showing QR-code until shared secret is verified
if (!$secretVerified) {
if (empty($secret)) {
$secret = $this->GoogleAuthenticator->createSecret();
// catching sql exception in case of any sql inconsistencies
try {
$query = $this->getUsersTable()->query();
$query->update()->set(['secret' => $secret])->where(['id' => $temporarySession['id']]);
$executed = $query->execute();
} catch (\Exception $e) {
$this->request->session()->destroy();
$message = __d('CakeDC/Users', $e->getMessage());
$this->Flash->error($message, 'default', [], 'auth');
return $this->redirect(Configure::read('Auth.loginAction'));
}
}
$this->set('secretDataUri', $this->GoogleAuthenticator->getQRCodeImageAsDataUri($temporarySession['email'], $secret));
}
if ($this->request->is('post')) {
$verificationCode = $this->request->data('code');
$user = $this->request->session()->read('temporarySession');
if (array_key_exists('secret', $user)) {
$codeVerified = $this->GoogleAuthenticator->verifyCode($user['secret'], $verificationCode);
}
if ($codeVerified) {
unset($user['secret']);
if (!$user['secret_verified']) {
$this->getUsersTable()->query()->update()->set(['secret_verified' => true])->where(['id' => $user['id']])->execute();
}
$this->request->session()->delete('temporarySession');
$this->request->session()->write('Auth.User', $user);
$url = $this->Auth->redirectUrl();
return $this->redirect($url);
} else {
$this->request->session()->destroy();
$message = __d('CakeDC/Users', 'Verification code is invalid. Try again');
$this->Flash->error($message, 'default', [], 'auth');
return $this->redirect(Configure::read('Auth.loginAction'));
}
}
}