add google connect and disconnect to account
This commit is contained in:
		
							parent
							
								
									ea8b46ab91
								
							
						
					
					
						commit
						e18ed3a034
					
				@ -57,6 +57,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 <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
 | 
			
		||||
    {
 | 
			
		||||
        /**
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,14 @@
 | 
			
		||||
                <button type="submit" name="submit_button" disabled>Save</button>
 | 
			
		||||
            </div>
 | 
			
		||||
            <hr>
 | 
			
		||||
            <div class="center">
 | 
			
		||||
            <div class="center" style="font-size: 0;">
 | 
			
		||||
                <?php if ($user['google_sub'] === null): ?>
 | 
			
		||||
                    <a class="button yellow marginRight" 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 marginRight" href="<?= Container::$routeCollection->getRoute('account.googleDisconnect')->generateLink() ?>" title="Disconnect from Google">Disconnect from Google</a>
 | 
			
		||||
                    <?php endif; ?>
 | 
			
		||||
                <?php endif; ?>
 | 
			
		||||
                <a class="button red" href="/account/delete" title="Delete account">Delete account</a>
 | 
			
		||||
            </div>
 | 
			
		||||
        </form>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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"><i class="fa-solid fa-link"></i> 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"><i class="fa-solid fa-link-slash"></i> Disconnect</button><!--
 | 
			
		||||
             --><a class="button gray" href="<?= Container::$routeCollection->getRoute('account')->generateLink() ?>" title="Back to account">Cancel</a>
 | 
			
		||||
            </div>
 | 
			
		||||
        </form>
 | 
			
		||||
    </div>
 | 
			
		||||
@endsection
 | 
			
		||||
							
								
								
									
										5
									
								
								web.php
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								web.php
									
									
									
									
									
								
							@ -57,6 +57,11 @@ Container::$routeCollection->group('account', function (RouteCollection $routeCo
 | 
			
		||||
    $routeCollection->post('account-action', '', [UserController::class, 'saveAccount']);
 | 
			
		||||
    $routeCollection->get('account.delete', 'delete', [UserController::class, 'getDeleteAccount']);
 | 
			
		||||
    $routeCollection->post('account.delete-action', 'delete', [UserController::class, 'deleteAccount']);
 | 
			
		||||
    $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-action', 'googleAuthenticate/code', [UserController::class, 'authenticateWithGoogle']);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user