diff --git a/mail/signup-noconfirm.html b/mail/signup-noconfirm.html
deleted file mode 100644
index dba50fa..0000000
--- a/mail/signup-noconfirm.html
+++ /dev/null
@@ -1,9 +0,0 @@
-Hi,
-
-You recently signed up on {{APP_NAME}} with this Google account ({{EMAIL}}).
-
-Have fun on {{APP_NAME}}!
-
-Regards,
-{{APP_NAME}}
-{{BASE_URL}}
diff --git a/mail/signup.html b/mail/signup.html
deleted file mode 100644
index ebdec4f..0000000
--- a/mail/signup.html
+++ /dev/null
@@ -1,18 +0,0 @@
-Hi,
-
-You recently signed up on {{APP_NAME}} with this email address ({{EMAIL}}).
-To activate your account, please click on the following link:
-{{ACTIVATE_LINK}}
-
-You can activate your account until {{ACTIVATABLE_UNTIL}}.
-If you don't activate your account, your email address will be permanently deleted after this point of time.
-
-If you did not sign up on {{APP_NAME}} or changed your mind, no further action is required.
-However if you want to immediately delete your email address, please click on the following link:
-{{CANCEL_LINK}}
-
-Have fun on {{APP_NAME}}!
-
-Regards,
-{{APP_NAME}}
-{{BASE_URL}}
diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php
index 8ae40a6..021c1b7 100644
--- a/src/Controller/UserController.php
+++ b/src/Controller/UserController.php
@@ -37,6 +37,130 @@ class UserController implements IAuthenticationRequired
return new HtmlContent('account/account', ['user' => $user->toArray()]);
}
+ public function getGoogleConnectRedirect(): IRedirect
+ {
+ /**
+ * @var User $user
+ */
+ $user = \Container::$request->user();
+
+ $state = bin2hex(random_bytes(16));
+ $nonce = bin2hex(random_bytes(16));
+
+ \Container::$request->session()->set('oauth_state', $state);
+ \Container::$request->session()->set('oauth_nonce', $nonce);
+
+ $oAuth = new GoogleOAuth(new Request());
+
+ $url = $oAuth->getDialogUrl(
+ $state,
+ \Container::$request->getBase() . \Container::$routeCollection->getRoute('account.googleConnect-confirm')->generateLink(),
+ $nonce,
+ $user->getEmail()
+ );
+
+ return new Redirect($url, IRedirect::TEMPORARY);
+ }
+
+ public function getGoogleConnectConfirm(): IContent
+ {
+ $defaultError = 'Authentication with Google failed. Please try again!';
+
+ if (\Container::$request->query('state') !== \Container::$request->session()->get('oauth_state')) {
+ return new HtmlContent('account/google_connect', ['success' => false, 'error' => $defaultError]);
+ }
+
+ $oAuth = new GoogleOAuth(new Request());
+ $tokenData = $oAuth->getToken(
+ \Container::$request->query('code'),
+ \Container::$request->getBase() . \Container::$routeCollection->getRoute('account.googleConnect-confirm')->generateLink()
+ );
+ if (!isset($tokenData['id_token'])) {
+ return new HtmlContent('account/google_connect', ['success' => false, 'error' => $defaultError]);
+ }
+
+ $jwtParser = new JwtParser($tokenData['id_token']);
+ $idToken = $jwtParser->getPayload();
+ if ($idToken['nonce'] !== \Container::$request->session()->get('oauth_nonce')) {
+ return new HtmlContent('account/google_connect', ['success' => false, 'error' => $defaultError]);
+ }
+
+ $anotherUser = $this->userRepository->getByGoogleSub($idToken['sub']);
+ if ($anotherUser !== null) {
+ return new HtmlContent('account/google_connect', [
+ 'success' => false,
+ 'error' => 'This Google account is linked to another account.'
+ ]);
+ }
+
+ \Container::$request->session()->set('google_user_data', $idToken);
+
+ /**
+ * @var User $user
+ */
+ $user = \Container::$request->user();
+
+ return new HtmlContent('account/google_connect', [
+ 'success' => true,
+ 'googleAccount' => $idToken['email'],
+ 'userEmail' => $user->getEmail()
+ ]);
+ }
+
+ public function connectGoogle(): IContent
+ {
+ /**
+ * @var User $user
+ */
+ $user = \Container::$request->user();
+ if (!$user->checkPassword(\Container::$request->post('password'))) {
+ return new JsonContent([
+ 'error' => [
+ 'errorText' => 'The given password is wrong.'
+ ]
+ ]);
+ }
+
+ $googleUserData = \Container::$request->session()->get('google_user_data');
+ $user->setGoogleSub($googleUserData['sub']);
+ \Container::$persistentDataManager->saveToDb($user);
+
+ return new JsonContent(['success' => true]);
+ }
+
+ public function getGoogleDisconnectConfirm(): IContent
+ {
+ /**
+ * @var User $user
+ */
+ $user = \Container::$request->user();
+
+ return new HtmlContent('account/google_disconnect', [
+ 'success' => true,
+ 'userEmail' => $user->getEmail()
+ ]);
+ }
+
+ public function disconnectGoogle(): IContent
+ {
+ /**
+ * @var User $user
+ */
+ $user = \Container::$request->user();
+ if (!$user->checkPassword(\Container::$request->post('password'))) {
+ return new JsonContent([
+ 'error' => [
+ 'errorText' => 'The given password is wrong.'
+ ]
+ ]);
+ }
+
+ $user->setGoogleSub(null);
+ \Container::$persistentDataManager->saveToDb($user);
+
+ return new JsonContent(['success' => true]);
+ }
+
public function getGoogleAuthenticateRedirect(): IRedirect
{
/**
diff --git a/views/account/account.php b/views/account/account.php
index fac3eac..6c95542 100644
--- a/views/account/account.php
+++ b/views/account/account.php
@@ -44,6 +44,18 @@
Your account does not have a password. Please set a password if you want to disconnect your account from Google.
+ + += $error ?>
+ + + += $error ?>