Merged in feature/MAPG-181-handle-the-case-when-user-has-no-password (pull request #163)
Feature/MAPG-181 handle the case when user has no password
This commit is contained in:
commit
d03a3934c6
@ -153,13 +153,27 @@ button, a.button {
|
|||||||
line-height: 35px;
|
line-height: 35px;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.small {
|
button.small, div.inputWithButton>button {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button.small {
|
||||||
|
height: 32px;
|
||||||
|
line-height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.inputWithButton>button {
|
||||||
|
border-radius: 2px;
|
||||||
|
height: 27px;
|
||||||
|
line-height: 27px;
|
||||||
|
width: 75px;
|
||||||
|
margin-left: -79px;
|
||||||
|
vertical-align: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
button:enabled:hover, button:enabled:focus, a.button:hover, a.button:focus {
|
button:enabled:hover, button:enabled:focus, a.button:hover, a.button:focus {
|
||||||
background-color: #29457f;
|
background-color: #29457f;
|
||||||
outline: none;
|
outline: none;
|
||||||
@ -191,7 +205,7 @@ button.gray, a.button.gray {
|
|||||||
background-color: #808080;
|
background-color: #808080;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.gray:hover, button.gray:focus, a.button.gray:hover, a.button.gray:focus {
|
button.gray:enabled:hover, button.gray:enabled:focus, a.button.gray:hover, a.button.gray:focus {
|
||||||
background-color: #555555;
|
background-color: #555555;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +213,7 @@ button.red, a.button.red {
|
|||||||
background-color: #aa5e5e;
|
background-color: #aa5e5e;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.red:hover, button.red:focus, a.button.red:hover, a.button.red:focus {
|
button.red:enabled:hover, button.red:enabled:focus, a.button.red:hover, a.button.red:focus {
|
||||||
background-color: #7f2929;
|
background-color: #7f2929;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,7 +221,7 @@ button.yellow, a.button.yellow {
|
|||||||
background-color: #e8a349;
|
background-color: #e8a349;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.yellow:hover, button.yellow:focus, a.button.yellow:hover, a.button.yellow:focus {
|
button.yellow:enabled:hover, button.yellow:enabled:focus, a.button.yellow:hover, a.button.yellow:focus {
|
||||||
background-color: #c37713;
|
background-color: #c37713;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,7 +229,7 @@ button.green, a.button.green {
|
|||||||
background-color: #28a745;
|
background-color: #28a745;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.green:hover, button.green:focus, a.button.green:hover, a.button.green:focus {
|
button.green:enabled:hover, button.green:enabled:focus, a.button.green:hover, a.button.green:focus {
|
||||||
background-color: #1b7d31;
|
background-color: #1b7d31;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,22 +237,36 @@ input, select, textarea {
|
|||||||
background-color: #f9fafb;
|
background-color: #f9fafb;
|
||||||
border: solid #c8d2e1 1px;
|
border: solid #c8d2e1 1px;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
padding: 4px;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input, select {
|
||||||
|
height: 30px;
|
||||||
|
line-height: 30px;
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
font-size: 13px;
|
padding: 5px;
|
||||||
resize: none;
|
resize: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
input.big, select.big, textarea.big {
|
input.big, select.big, textarea.big, div.inputWithButton>input {
|
||||||
padding: 5px;
|
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input.big, select.big, div.inputWithButton>input {
|
||||||
|
height: 35px;
|
||||||
|
line-height: 35px;
|
||||||
|
padding: 0 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea.big {
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
input.fullWidth, select.fullWidth, textarea.fullWidth {
|
input.fullWidth, select.fullWidth, textarea.fullWidth {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -253,14 +281,30 @@ input:disabled, select:disabled, textarea:disabled {
|
|||||||
input:focus, select:focus, textarea:focus {
|
input:focus, select:focus, textarea:focus {
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
border: solid #29457f 2px;
|
border: solid #29457f 2px;
|
||||||
padding: 3px;
|
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
input.big:focus, select.big:focus, textarea.big:focus {
|
input:focus, select:focus {
|
||||||
|
padding: 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea:focus {
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input.big:focus, select.big:focus {
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.inputWithButton>input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 83px 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea.big:focus {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
div.modal {
|
div.modal {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
|
69
public/static/js/account/account.js
Normal file
69
public/static/js/account/account.js
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
var Account = {
|
||||||
|
original: null,
|
||||||
|
countdown: null,
|
||||||
|
|
||||||
|
openGoogleAuthenticate: function () {
|
||||||
|
window.open('/account/googleAuthenticate', 'googleAuthenticate', 'height=600,width=600')
|
||||||
|
},
|
||||||
|
|
||||||
|
authenticatedWithGoogleCallback: function (authenticatedWithGoogleUntil) {
|
||||||
|
var password = document.getElementsByTagName('form')[0].elements.password;
|
||||||
|
var button = document.getElementById('authenticateWithGoogleButton');
|
||||||
|
|
||||||
|
Account.original = {
|
||||||
|
type: password.type,
|
||||||
|
placeholder: password.placeholder,
|
||||||
|
required: password.required,
|
||||||
|
disabled: password.disabled
|
||||||
|
};
|
||||||
|
|
||||||
|
password.type = 'text';
|
||||||
|
password.placeholder = 'Authenticated!'
|
||||||
|
password.value = '';
|
||||||
|
password.required = false;
|
||||||
|
password.disabled = true;
|
||||||
|
|
||||||
|
button.disabled = true;
|
||||||
|
|
||||||
|
Account.countdown = setInterval(function () {
|
||||||
|
var timeLeft = Math.ceil((authenticatedWithGoogleUntil.getTime() - new Date().getTime()) / 1000);
|
||||||
|
|
||||||
|
if (timeLeft > 30) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeLeft <= 0) {
|
||||||
|
Account.resetGoogleAuthentication();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
password.placeholder = 'Authenticated! ' + timeLeft + ' seconds left...';
|
||||||
|
}, 1000);
|
||||||
|
},
|
||||||
|
|
||||||
|
resetGoogleAuthentication: function () {
|
||||||
|
if (Account.countdown !== null) {
|
||||||
|
clearInterval(Account.countdown);
|
||||||
|
}
|
||||||
|
|
||||||
|
var password = document.getElementsByTagName('form')[0].elements.password;
|
||||||
|
var button = document.getElementById('authenticateWithGoogleButton');
|
||||||
|
|
||||||
|
password.type = Account.original.type;
|
||||||
|
password.placeholder = Account.original.placeholder
|
||||||
|
password.required = Account.original.required;
|
||||||
|
password.disabled = Account.original.disabled;
|
||||||
|
|
||||||
|
button.disabled = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
document.getElementById('authenticateWithGoogleButton').onclick = function () {
|
||||||
|
Account.openGoogleAuthenticate();
|
||||||
|
};
|
||||||
|
|
||||||
|
document.getElementsByTagName('form')[0].onreset = function () {
|
||||||
|
Account.resetGoogleAuthentication();
|
||||||
|
};
|
||||||
|
})();
|
10
public/static/js/account/google_authenticate.js
Normal file
10
public/static/js/account/google_authenticate.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
(function () {
|
||||||
|
if (success) {
|
||||||
|
window.opener.Account.authenticatedWithGoogleCallback(authenticatedWithGoogleUntil);
|
||||||
|
window.close();
|
||||||
|
} else {
|
||||||
|
document.getElementById('closeWindowButton').onclick = function () {
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
@ -23,6 +23,7 @@ class AddUserCommand extends Command
|
|||||||
$user = new User();
|
$user = new User();
|
||||||
$user->setEmail($input->getArgument('email'));
|
$user->setEmail($input->getArgument('email'));
|
||||||
$user->setPlainPassword($input->getArgument('password'));
|
$user->setPlainPassword($input->getArgument('password'));
|
||||||
|
$user->setActive(true);
|
||||||
|
|
||||||
if ($input->hasArgument('type')) {
|
if ($input->hasArgument('type')) {
|
||||||
$user->setType($input->getArgument('type'));
|
$user->setType($input->getArgument('type'));
|
||||||
|
@ -1,16 +1,22 @@
|
|||||||
<?php namespace MapGuesser\Controller;
|
<?php namespace MapGuesser\Controller;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
use MapGuesser\Database\Query\Select;
|
use MapGuesser\Database\Query\Select;
|
||||||
|
use MapGuesser\Http\Request;
|
||||||
use MapGuesser\Interfaces\Authorization\ISecured;
|
use MapGuesser\Interfaces\Authorization\ISecured;
|
||||||
use MapGuesser\Interfaces\Database\IResultSet;
|
use MapGuesser\Interfaces\Database\IResultSet;
|
||||||
use MapGuesser\Interfaces\Request\IRequest;
|
use MapGuesser\Interfaces\Request\IRequest;
|
||||||
use MapGuesser\Interfaces\Response\IContent;
|
use MapGuesser\Interfaces\Response\IContent;
|
||||||
|
use MapGuesser\Interfaces\Response\IRedirect;
|
||||||
|
use MapGuesser\OAuth\GoogleOAuth;
|
||||||
use MapGuesser\PersistentData\PersistentDataManager;
|
use MapGuesser\PersistentData\PersistentDataManager;
|
||||||
use MapGuesser\PersistentData\Model\User;
|
use MapGuesser\PersistentData\Model\User;
|
||||||
use MapGuesser\PersistentData\Model\UserConfirmation;
|
use MapGuesser\PersistentData\Model\UserConfirmation;
|
||||||
use MapGuesser\Repository\UserConfirmationRepository;
|
use MapGuesser\Repository\UserConfirmationRepository;
|
||||||
use MapGuesser\Response\HtmlContent;
|
use MapGuesser\Response\HtmlContent;
|
||||||
use MapGuesser\Response\JsonContent;
|
use MapGuesser\Response\JsonContent;
|
||||||
|
use MapGuesser\Response\Redirect;
|
||||||
|
use MapGuesser\Util\JwtParser;
|
||||||
|
|
||||||
class UserController implements ISecured
|
class UserController implements ISecured
|
||||||
{
|
{
|
||||||
@ -45,6 +51,63 @@ class UserController implements ISecured
|
|||||||
return new HtmlContent('account/account', $data);
|
return new HtmlContent('account/account', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getGoogleAuthenticateRedirect(): IRedirect
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var User $user
|
||||||
|
*/
|
||||||
|
$user = $this->request->user();
|
||||||
|
|
||||||
|
$state = bin2hex(random_bytes(16));
|
||||||
|
|
||||||
|
$this->request->session()->set('oauth_state', $state);
|
||||||
|
|
||||||
|
$oAuth = new GoogleOAuth(new Request());
|
||||||
|
|
||||||
|
$url = $oAuth->getDialogUrl(
|
||||||
|
$state,
|
||||||
|
$this->request->getBase() . '/' . \Container::$routeCollection->getRoute('account.googleAuthenticate-action')->generateLink(),
|
||||||
|
$user->getEmail()
|
||||||
|
);
|
||||||
|
|
||||||
|
return new Redirect($url, IRedirect::TEMPORARY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function authenticateWithGoogle(): IContent
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var User $user
|
||||||
|
*/
|
||||||
|
$user = $this->request->user();
|
||||||
|
|
||||||
|
if ($this->request->query('state') !== $this->request->session()->get('oauth_state')) {
|
||||||
|
$data = ['success' => false];
|
||||||
|
return new HtmlContent('account/google_authenticate', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
$oAuth = new GoogleOAuth(new Request());
|
||||||
|
$tokenData = $oAuth->getToken($this->request->query('code'), $this->request->getBase() . '/' . \Container::$routeCollection->getRoute('account.googleAuthenticate-action')->generateLink());
|
||||||
|
|
||||||
|
if (!isset($tokenData['id_token'])) {
|
||||||
|
$data = ['success' => false];
|
||||||
|
return new HtmlContent('account/google_authenticate', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
$jwtParser = new JwtParser($tokenData['id_token']);
|
||||||
|
$userData = $jwtParser->getPayload();
|
||||||
|
|
||||||
|
if ($userData['sub'] !== $user->getGoogleSub()) {
|
||||||
|
$data = ['success' => false, 'errorText' => 'This Google account is not linked to your account.'];
|
||||||
|
return new HtmlContent('account/google_authenticate', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
$authenticatedWithGoogleUntil = new DateTime('+45 seconds');
|
||||||
|
$this->request->session()->set('authenticated_with_google_until', $authenticatedWithGoogleUntil);
|
||||||
|
|
||||||
|
$data = ['success' => true, 'authenticatedWithGoogleUntil' => $authenticatedWithGoogleUntil];
|
||||||
|
return new HtmlContent('account/google_authenticate', $data);
|
||||||
|
}
|
||||||
|
|
||||||
public function getDeleteAccount(): IContent
|
public function getDeleteAccount(): IContent
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -63,8 +126,13 @@ class UserController implements ISecured
|
|||||||
*/
|
*/
|
||||||
$user = $this->request->user();
|
$user = $this->request->user();
|
||||||
|
|
||||||
if (!$user->checkPassword($this->request->post('password'))) {
|
if (!$this->confirmUserIdentity(
|
||||||
$data = ['error' => ['errorText' => 'The given current password is wrong.']];
|
$user,
|
||||||
|
$this->request->session()->get('authenticated_with_google_until'),
|
||||||
|
$this->request->post('password'),
|
||||||
|
$error
|
||||||
|
)) {
|
||||||
|
$data = ['error' => ['errorText' => $error]];
|
||||||
return new JsonContent($data);
|
return new JsonContent($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,6 +152,8 @@ class UserController implements ISecured
|
|||||||
|
|
||||||
$this->pdm->saveToDb($user);
|
$this->pdm->saveToDb($user);
|
||||||
|
|
||||||
|
$this->request->session()->delete('authenticated_with_google_until');
|
||||||
|
|
||||||
$data = ['success' => true];
|
$data = ['success' => true];
|
||||||
return new JsonContent($data);
|
return new JsonContent($data);
|
||||||
}
|
}
|
||||||
@ -95,8 +165,13 @@ class UserController implements ISecured
|
|||||||
*/
|
*/
|
||||||
$user = $this->request->user();
|
$user = $this->request->user();
|
||||||
|
|
||||||
if (!$user->checkPassword($this->request->post('password'))) {
|
if (!$this->confirmUserIdentity(
|
||||||
$data = ['error' => ['errorText' => 'The given current password is wrong.']];
|
$user,
|
||||||
|
$this->request->session()->get('authenticated_with_google_until'),
|
||||||
|
$this->request->post('password'),
|
||||||
|
$error
|
||||||
|
)) {
|
||||||
|
$data = ['error' => ['errorText' => $error]];
|
||||||
return new JsonContent($data);
|
return new JsonContent($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +185,28 @@ class UserController implements ISecured
|
|||||||
|
|
||||||
\Container::$dbConnection->commit();
|
\Container::$dbConnection->commit();
|
||||||
|
|
||||||
|
$this->request->session()->delete('authenticated_with_google_until');
|
||||||
|
|
||||||
$data = ['success' => true];
|
$data = ['success' => true];
|
||||||
return new JsonContent($data);
|
return new JsonContent($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function confirmUserIdentity(User $user, ?DateTime $authenticatedWithGoogleUntil, ?string $password, &$error): bool
|
||||||
|
{
|
||||||
|
if ($authenticatedWithGoogleUntil !== null && $authenticatedWithGoogleUntil > new DateTime()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($password !== null) {
|
||||||
|
if ($user->checkPassword($password)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$error = 'The given current password is wrong.';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$error = 'Could not confirm your identity. Please try again!';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ class GoogleOAuth
|
|||||||
$this->request = $request;
|
$this->request = $request;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDialogUrl(string $state, string $redirectUrl): string
|
public function getDialogUrl(string $state, string $redirectUrl, ?string $loginHint = null): string
|
||||||
{
|
{
|
||||||
$oauthParams = [
|
$oauthParams = [
|
||||||
'response_type' => 'code',
|
'response_type' => 'code',
|
||||||
@ -26,6 +26,10 @@ class GoogleOAuth
|
|||||||
'nonce' => hash('sha256', random_bytes(10) . microtime()),
|
'nonce' => hash('sha256', random_bytes(10) . microtime()),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if ($loginHint !== null) {
|
||||||
|
$oauthParams['login_hint'] = $loginHint;
|
||||||
|
}
|
||||||
|
|
||||||
return self::$dialogUrlBase . '?' . http_build_query($oauthParams);
|
return self::$dialogUrlBase . '?' . http_build_query($oauthParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,27 @@
|
|||||||
|
@js('js/account/account.js')
|
||||||
|
|
||||||
@extends('templates/layout_normal')
|
@extends('templates/layout_normal')
|
||||||
|
|
||||||
@section('main')
|
@section('main')
|
||||||
<h2>Account</h2>
|
<h2>Account</h2>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<form id="accountForm" action="/account" method="post" data-observe-inputs="password_new,password_new_confirm">
|
<form id="accountForm" action="/account" method="post" data-observe-inputs="password_new,password_new_confirm">
|
||||||
|
<?php if ($user['password'] !== null && $user['google_sub'] !== null): ?>
|
||||||
|
<p class="justify small">Please confirm your identity with your password or with Google to modify your account.</p>
|
||||||
|
<div class="inputWithButton">
|
||||||
|
<input type="password" name="password" placeholder="Current password" required minlength="6" autofocus><!--
|
||||||
|
--><button id="authenticateWithGoogleButton" class="yellow" type="button">Google</button>
|
||||||
|
</div>
|
||||||
|
<?php elseif ($user['password'] !== null): ?>
|
||||||
|
<p class="justify small">Please confirm your identity with your password to modify your account.</p>
|
||||||
<input class="big fullWidth" type="password" name="password" placeholder="Current password" required minlength="6" autofocus>
|
<input class="big fullWidth" type="password" name="password" placeholder="Current password" required minlength="6" autofocus>
|
||||||
|
<?php elseif ($user['google_sub'] !== null): ?>
|
||||||
|
<p class="justify small">Please confirm your identity with Google to modify your account.</p>
|
||||||
|
<div class="inputWithButton">
|
||||||
|
<input type="text" name="password" placeholder="Authenticate with Google..." disabled><!--
|
||||||
|
--><button id="authenticateWithGoogleButton" class="yellow" type="button">Google</button>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
<hr>
|
<hr>
|
||||||
<?php /* TODO: disabled for the time being, email modification should be implemented */ ?>
|
<?php /* TODO: disabled for the time being, email modification should be implemented */ ?>
|
||||||
<input class="big fullWidth" type="email" name="email" placeholder="Email address" value="<?= $user['email'] ?>" disabled>
|
<input class="big fullWidth" type="email" name="email" placeholder="Email address" value="<?= $user['email'] ?>" disabled>
|
||||||
|
@ -1,14 +1,32 @@
|
|||||||
|
@js('js/account/account.js')
|
||||||
|
|
||||||
@extends('templates/layout_normal')
|
@extends('templates/layout_normal')
|
||||||
|
|
||||||
@section('main')
|
@section('main')
|
||||||
<h2>Delete account</h2>
|
<h2>Delete account</h2>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<form id="deleteAccountForm" action="/account/delete" method="post" data-redirect-on-success="/">
|
<form id="deleteAccountForm" action="/account/delete" method="post" data-redirect-on-success="/">
|
||||||
<p class="justify">Are you sure you want to delete your account? This cannot be undone!</p>
|
<p class="justify marginBottom">Are you sure you want to delete your account? This cannot be undone!</p>
|
||||||
<input class="big fullWidth marginTop" type="password" name="password" placeholder="Current password" required minlength="6" autofocus>
|
<?php if ($user['password'] !== null && $user['google_sub'] !== null): ?>
|
||||||
|
<p class="justify small">Please confirm your identity with your password or with Google to delete your account.</p>
|
||||||
|
<div class="inputWithButton">
|
||||||
|
<input type="password" name="password" placeholder="Current password" required minlength="6" autofocus><!--
|
||||||
|
--><button id="authenticateWithGoogleButton" class="yellow" type="button">Google</button>
|
||||||
|
</div>
|
||||||
|
<?php elseif ($user['password'] !== null): ?>
|
||||||
|
<p class="justify small">Please confirm your identity with your password to delete your account.</p>
|
||||||
|
<input class="big fullWidth" type="password" name="password" placeholder="Current password" required minlength="6" autofocus>
|
||||||
|
<?php elseif ($user['google_sub'] !== null): ?>
|
||||||
|
<p class="justify small">Please confirm your identity with Google to delete your account.</p>
|
||||||
|
<div class="inputWithButton">
|
||||||
|
<input type="text" name="password" placeholder="Authenticate with Google..." disabled><!--
|
||||||
|
--><button id="authenticateWithGoogleButton" class="yellow" type="button">Google</button>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
<p id="deleteAccountFormError" class="formError justify marginTop"></p>
|
<p id="deleteAccountFormError" class="formError justify marginTop"></p>
|
||||||
<div class="right marginTop">
|
<div class="right marginTop">
|
||||||
<button class="red" type="submit" name="submit">Delete account</button>
|
<button class="red marginRight" type="submit" name="submit">Delete account</button><!--
|
||||||
|
--><a class="button gray marginTop" href="/account" title="Back to account">Cancel</a>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
28
views/account/google_authenticate.php
Normal file
28
views/account/google_authenticate.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
@js('js/account/google_authenticate.js')
|
||||||
|
|
||||||
|
@extends('templates/layout_minimal')
|
||||||
|
|
||||||
|
@section('main')
|
||||||
|
<h2>Authenticate with Google</h2>
|
||||||
|
<?php if (!$success): ?>
|
||||||
|
<div class="box">
|
||||||
|
<p class="error justify">
|
||||||
|
<?php if (isset($errorText)): ?>
|
||||||
|
<?= $errorText ?>
|
||||||
|
<?php else: ?>
|
||||||
|
Authentication with Google failed.
|
||||||
|
<?php endif; ?>
|
||||||
|
Please <a id="closeWindowButton" href="javascript:;" title="Close">close this window/tab</a> and try again!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('pageScript')
|
||||||
|
<script>
|
||||||
|
var success = <?= $success ? 'true' : 'false' ?>;
|
||||||
|
<?php if (isset($authenticatedWithGoogleUntil)): ?>
|
||||||
|
var authenticatedWithGoogleUntil = new Date('<?= $authenticatedWithGoogleUntil->format('c') ?>');
|
||||||
|
<?php endif; ?>
|
||||||
|
</script>
|
||||||
|
@endsection
|
@ -3,6 +3,6 @@
|
|||||||
@section('main')
|
@section('main')
|
||||||
<h2>Login up with Google</h2>
|
<h2>Login up with Google</h2>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<p class="error justify">Authenticating with Google failed. Please <a href="/login/google" title="Login with Google">retry</a>!</p>
|
<p class="error justify">Authentication with Google failed. Please <a href="/login/google" title="Login with Google">try again</a>!</p>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
13
views/templates/layout_minimal.php
Normal file
13
views/templates/layout_minimal.php
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
@extends('templates/mapguesser')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<header>
|
||||||
|
<h1>
|
||||||
|
<img class="inline" width="1em" height="1em" src="<?= $_ENV['STATIC_ROOT'] ?>/img/icon.svg?rev=<?= REVISION ?>"><!--
|
||||||
|
--><?= $_ENV['APP_NAME'] ?>
|
||||||
|
</h1>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
@yields('main')
|
||||||
|
</main>
|
||||||
|
@endsection
|
2
web.php
2
web.php
@ -37,6 +37,8 @@ Container::$routeCollection->group('account', function (MapGuesser\Routing\Route
|
|||||||
$routeCollection->post('account-action', '', [MapGuesser\Controller\UserController::class, 'saveAccount']);
|
$routeCollection->post('account-action', '', [MapGuesser\Controller\UserController::class, 'saveAccount']);
|
||||||
$routeCollection->get('account.delete', 'delete', [MapGuesser\Controller\UserController::class, 'getDeleteAccount']);
|
$routeCollection->get('account.delete', 'delete', [MapGuesser\Controller\UserController::class, 'getDeleteAccount']);
|
||||||
$routeCollection->post('account.delete-action', 'delete', [MapGuesser\Controller\UserController::class, 'deleteAccount']);
|
$routeCollection->post('account.delete-action', 'delete', [MapGuesser\Controller\UserController::class, 'deleteAccount']);
|
||||||
|
$routeCollection->get('account.googleAuthenticate', 'googleAuthenticate', [MapGuesser\Controller\UserController::class, 'getGoogleAuthenticateRedirect']);
|
||||||
|
$routeCollection->get('account.googleAuthenticate-action', 'googleAuthenticate/code', [MapGuesser\Controller\UserController::class, 'authenticateWithGoogle']);
|
||||||
});
|
});
|
||||||
//Container::$routeCollection->get('maps', 'maps', [MapGuesser\Controller\MapsController::class, 'getMaps']);
|
//Container::$routeCollection->get('maps', 'maps', [MapGuesser\Controller\MapsController::class, 'getMaps']);
|
||||||
Container::$routeCollection->group('game', function (MapGuesser\Routing\RouteCollection $routeCollection) {
|
Container::$routeCollection->group('game', function (MapGuesser\Routing\RouteCollection $routeCollection) {
|
||||||
|
Loading…
Reference in New Issue
Block a user