Merge pull request 'feature/RVRNEXT-27-add-connect-with-google' (!50) from feature/RVRNEXT-27-add-connect-with-google into master
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				rvr-nextgen/pipeline/head This commit looks good
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	rvr-nextgen/pipeline/head This commit looks good
				
			Reviewed-on: #50
This commit is contained in:
		
						commit
						1a06326589
					
				@ -1,9 +0,0 @@
 | 
				
			|||||||
Hi,
 | 
					 | 
				
			||||||
<br><br>
 | 
					 | 
				
			||||||
You recently signed up on {{APP_NAME}} with this Google account ({{EMAIL}}).
 | 
					 | 
				
			||||||
<br><br>
 | 
					 | 
				
			||||||
Have fun on {{APP_NAME}}!
 | 
					 | 
				
			||||||
<br><br>
 | 
					 | 
				
			||||||
Regards,<br>
 | 
					 | 
				
			||||||
{{APP_NAME}}<br>
 | 
					 | 
				
			||||||
<a href="{{BASE_URL}}" title="{{APP_NAME}}">{{BASE_URL}}</a>
 | 
					 | 
				
			||||||
@ -1,18 +0,0 @@
 | 
				
			|||||||
Hi,
 | 
					 | 
				
			||||||
<br><br>
 | 
					 | 
				
			||||||
You recently signed up on {{APP_NAME}} with this email address ({{EMAIL}}).
 | 
					 | 
				
			||||||
To activate your account, please click on the following link:<br>
 | 
					 | 
				
			||||||
<a href="{{ACTIVATE_LINK}}" title="Account activation">{{ACTIVATE_LINK}}</a>
 | 
					 | 
				
			||||||
<br><br>
 | 
					 | 
				
			||||||
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.
 | 
					 | 
				
			||||||
<br><br>
 | 
					 | 
				
			||||||
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:<br>
 | 
					 | 
				
			||||||
<a href="{{CANCEL_LINK}}" title="Sign up cancellation">{{CANCEL_LINK}}</a>
 | 
					 | 
				
			||||||
<br><br>
 | 
					 | 
				
			||||||
Have fun on {{APP_NAME}}!
 | 
					 | 
				
			||||||
<br><br>
 | 
					 | 
				
			||||||
Regards,<br>
 | 
					 | 
				
			||||||
{{APP_NAME}}<br>
 | 
					 | 
				
			||||||
<a href="{{BASE_URL}}" title="{{APP_NAME}}">{{BASE_URL}}</a>
 | 
					 | 
				
			||||||
@ -37,6 +37,130 @@ class UserController implements IAuthenticationRequired
 | 
				
			|||||||
        return new HtmlContent('account/account', ['user' => $user->toArray()]);
 | 
					        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 <a href="' . \Container::$routeCollection->getRoute('account.googleConnect')->generateLink() . '" title="Connect with Google">try again</a>!';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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
 | 
					    public function getGoogleAuthenticateRedirect(): IRedirect
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
 | 
				
			|||||||
@ -44,6 +44,18 @@
 | 
				
			|||||||
            <div class="right marginTop">
 | 
					            <div class="right marginTop">
 | 
				
			||||||
                <button type="submit" name="submit_button" disabled>Save</button>
 | 
					                <button type="submit" name="submit_button" disabled>Save</button>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					            <hr>
 | 
				
			||||||
 | 
					            <div class="center">
 | 
				
			||||||
 | 
					                <?php if ($user['google_sub'] === null): ?>
 | 
				
			||||||
 | 
					                    <a class="button yellow" href="<?= Container::$routeCollection->getRoute('account.googleConnect')->generateLink() ?>" title="Connect with Google">Connect with Google</a>
 | 
				
			||||||
 | 
					                <?php else: ?>
 | 
				
			||||||
 | 
					                    <?php if ($user['password'] !== null): ?>
 | 
				
			||||||
 | 
					                        <a class="button yellow" href="<?= Container::$routeCollection->getRoute('account.googleDisconnect')->generateLink() ?>" title="Disconnect from Google">Disconnect from Google</a>
 | 
				
			||||||
 | 
					                    <?php else: ?>
 | 
				
			||||||
 | 
					                        <p class="bold small">Your account does not have a password. Please set a password if you want to disconnect your account from Google.</p>
 | 
				
			||||||
 | 
					                    <?php endif; ?>
 | 
				
			||||||
 | 
					                <?php endif; ?>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
        </form>
 | 
					        </form>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
@endsection
 | 
					@endsection
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										22
									
								
								views/account/google_connect.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								views/account/google_connect.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					@extends(templates/layout_normal)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@section(main)
 | 
				
			||||||
 | 
					    <h2>Connect with Google</h2>
 | 
				
			||||||
 | 
					    <div class="box compactBox">
 | 
				
			||||||
 | 
					        <?php if (!$success): ?>
 | 
				
			||||||
 | 
					            <p class="error justify"><?= $error ?></p>
 | 
				
			||||||
 | 
					        <?php else: ?>
 | 
				
			||||||
 | 
					            <form id="connectGoogleForm" action="<?= Container::$routeCollection->getRoute('account.googleConnect-action')->generateLink() ?>" method="post" data-redirect-on-success="<?= Container::$routeCollection->getRoute('account')->generateLink() ?>">
 | 
				
			||||||
 | 
					                <p class="justify marginBottom">Your account will be connected with the following Google account: <b><?= $googleAccount ?></b></p>
 | 
				
			||||||
 | 
					                <input type="email" style="display: none;" name="email" autocomplete="username" value="<?= $userEmail ?>">
 | 
				
			||||||
 | 
					                <p class="formLabel marginTop">Password</p>
 | 
				
			||||||
 | 
					                <input type="password" class="text big fullWidth" name="password" autocomplete="current-password" required minlength="6" autofocus>
 | 
				
			||||||
 | 
					                <p class="formError justify marginTop"></p>
 | 
				
			||||||
 | 
					                <div class="right marginTop">
 | 
				
			||||||
 | 
					                    <button class="marginRight" type="submit" name="submit">Connect</button><!--
 | 
				
			||||||
 | 
					                 --><a class="button gray" href="<?= Container::$routeCollection->getRoute('account')->generateLink() ?>" title="Back to account">Cancel</a>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </form>
 | 
				
			||||||
 | 
					        <?php endif; ?>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					@endsection
 | 
				
			||||||
							
								
								
									
										18
									
								
								views/account/google_disconnect.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								views/account/google_disconnect.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					@extends(templates/layout_normal)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@section(main)
 | 
				
			||||||
 | 
					    <h2>Disconnect from Google</h2>
 | 
				
			||||||
 | 
					    <div class="box compactBox">
 | 
				
			||||||
 | 
					        <form id="connectGoogleForm" action="<?= Container::$routeCollection->getRoute('account.googleDisconnect-action')->generateLink() ?>" method="post" data-redirect-on-success="<?= Container::$routeCollection->getRoute('account')->generateLink() ?>">
 | 
				
			||||||
 | 
					            <p class="justify marginBottom">Your account will be disconnected from the currently set Google account.</p>
 | 
				
			||||||
 | 
					            <input type="email" style="display: none;" name="email" autocomplete="username" value="<?= $userEmail ?>">
 | 
				
			||||||
 | 
					            <p class="formLabel marginTop">Password</p>
 | 
				
			||||||
 | 
					            <input type="password" class="text big fullWidth" name="password" autocomplete="current-password" required minlength="6" autofocus>
 | 
				
			||||||
 | 
					            <p class="formError justify marginTop"></p>
 | 
				
			||||||
 | 
					            <div class="right marginTop">
 | 
				
			||||||
 | 
					                <button class="red marginRight" type="submit" name="submit">Disconnect</button><!--
 | 
				
			||||||
 | 
					             --><a class="button gray" href="<?= Container::$routeCollection->getRoute('account')->generateLink() ?>" title="Back to account">Cancel</a>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </form>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					@endsection
 | 
				
			||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
@extends(templates/layout_normal)
 | 
					@extends(templates/layout_normal)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@section(main)
 | 
					@section(main)
 | 
				
			||||||
    <h2>Login up with Google</h2>
 | 
					    <h2>Login with Google</h2>
 | 
				
			||||||
    <div class="box compactBox">
 | 
					    <div class="box compactBox">
 | 
				
			||||||
        <p class="error justify"><?= $error ?></p>
 | 
					        <p class="error justify"><?= $error ?></p>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										5
									
								
								web.php
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								web.php
									
									
									
									
									
								
							@ -52,6 +52,11 @@ Container::$routeCollection->get('logout', 'logout', [LoginController::class, 'l
 | 
				
			|||||||
Container::$routeCollection->group('account', function (RouteCollection $routeCollection) {
 | 
					Container::$routeCollection->group('account', function (RouteCollection $routeCollection) {
 | 
				
			||||||
    $routeCollection->get('account', '', [UserController::class, 'getAccount']);
 | 
					    $routeCollection->get('account', '', [UserController::class, 'getAccount']);
 | 
				
			||||||
    $routeCollection->post('account-action', '', [UserController::class, 'saveAccount']);
 | 
					    $routeCollection->post('account-action', '', [UserController::class, 'saveAccount']);
 | 
				
			||||||
 | 
					    $routeCollection->get('account.googleConnect', 'googleConnect', [UserController::class, 'getGoogleConnectRedirect']);
 | 
				
			||||||
 | 
					    $routeCollection->get('account.googleConnect-confirm', 'googleConnect/code', [UserController::class, 'getGoogleConnectConfirm']);
 | 
				
			||||||
 | 
					    $routeCollection->post('account.googleConnect-action', 'googleConnect', [UserController::class, 'connectGoogle']);
 | 
				
			||||||
 | 
					    $routeCollection->get('account.googleDisconnect', 'googleDisconnect', [UserController::class, 'getGoogleDisconnectConfirm']);
 | 
				
			||||||
 | 
					    $routeCollection->post('account.googleDisconnect-action', 'googleDisconnect', [UserController::class, 'disconnectGoogle']);
 | 
				
			||||||
    $routeCollection->get('account.googleAuthenticate', 'googleAuthenticate', [UserController::class, 'getGoogleAuthenticateRedirect']);
 | 
					    $routeCollection->get('account.googleAuthenticate', 'googleAuthenticate', [UserController::class, 'getGoogleAuthenticateRedirect']);
 | 
				
			||||||
    $routeCollection->get('account.googleAuthenticate-action', 'googleAuthenticate/code', [UserController::class, 'authenticateWithGoogle']);
 | 
					    $routeCollection->get('account.googleAuthenticate-action', 'googleAuthenticate/code', [UserController::class, 'authenticateWithGoogle']);
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user