Skip to content

Commit 26a1ceb

Browse files
committed
Merge branch 'b-7.4.x-finalize-oauth-OXDEV-10037' into b-7.4.x-2fa-OXDEV-9078
2 parents 3bde242 + 5cb4fca commit 26a1ceb

56 files changed

Lines changed: 1112 additions & 262 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

assets/out/src/js/module/resend-otp.js

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,22 @@ export class ResendOtp {
1010
submitButtonId = 'auth_submit',
1111
attemptsDisplayId = 'remaining-attempts',
1212
codeInputId = 'auth_code',
13-
maxAttempts = 5
13+
maxAttempts = 5,
1414
} = options;
1515

1616
this.btn = button;
1717
this.hint = document.getElementById(hintId);
1818
this.submitBtn = document.getElementById(submitButtonId);
1919
this.attemptsDisplay = document.getElementById(attemptsDisplayId);
2020
this.codeInput = document.getElementById(codeInputId);
21-
this.maxAttempts = maxAttempts;
2221

2322
this.cooldownSeconds = Number(button.dataset.cooldown || 60);
23+
this.maxAttempts = maxAttempts;
2424
this.url = button.dataset.url;
25+
this.textDefault = button.dataset.textDefault;
26+
this.textSending = button.dataset.textSending;
27+
this.textError = button.dataset.textError;
28+
this.textCountdown = button.dataset.textCountdown;
2529
this.storageKey = `otp_resend_until_${this.url}`;
2630

2731
this.timer = null;
@@ -39,17 +43,21 @@ export class ResendOtp {
3943
}
4044

4145
async resend() {
42-
console.log('Resend OTP code requested');
4346
if (this.btn.disabled) return;
4447

45-
this.lock('Sending…');
48+
this.lock(this.textSending);
4649

4750
try {
48-
await fetch(this.url, {
51+
const response = await fetch(this.url, {
4952
method: 'POST',
5053
headers: { 'Content-Type': 'application/json' }
5154
});
5255

56+
if (!response.ok) {
57+
this.unlock();
58+
return;
59+
}
60+
5361
const until = Date.now() + this.cooldownSeconds * 1000;
5462
this.storeUntil(until);
5563
this.startCooldown(until);
@@ -59,7 +67,7 @@ export class ResendOtp {
5967
} catch (e) {
6068
console.error(e);
6169
this.unlock();
62-
this.setHint('Could not resend code.');
70+
this.setHint(this.textError);
6371
}
6472
}
6573

@@ -90,7 +98,6 @@ export class ResendOtp {
9098

9199
startCooldown(until) {
92100
clearInterval(this.timer);
93-
console.log(`Starting OTP resend cooldown until ${new Date(until).toISOString()}`);
94101
const tick = () => {
95102
const remaining = Math.ceil((until - Date.now()) / 1000);
96103

@@ -99,7 +106,7 @@ export class ResendOtp {
99106
this.unlock();
100107
clearInterval(this.timer);
101108
} else {
102-
this.lock(`Resend in ${remaining}s`);
109+
this.lock(this.textCountdown.replace('%d', remaining));
103110
}
104111
};
105112

@@ -114,7 +121,7 @@ export class ResendOtp {
114121

115122
unlock() {
116123
this.btn.disabled = false;
117-
this.btn.textContent = 'Resend code';
124+
this.btn.textContent = this.textDefault;
118125
}
119126

120127
setHint(text) {
@@ -134,7 +141,6 @@ export class ResendOtp {
134141
}
135142

136143
restoreOnRefresh() {
137-
console.log('Restoring OTP resend cooldown if needed');
138144
const until = this.getStoredUntil();
139145
if (until && until > Date.now()) {
140146
this.startCooldown(until);

metadata.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
* Metadata version
1010
*/
1111

12-
use OxidEsales\SecurityModule\Authentication\OAuth2\Service\ModuleSettingsService;
1312
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Service\ModuleSettingsService as TwoFactorAuthModuleSettings;
1413
use OxidEsales\SecurityModule\PasswordPolicy\Service\ModuleSettingsService as PasswordPolicyModuleSettings;
1514
use OxidEsales\SecurityModule\Captcha\Service\ModuleSettingsService as CaptchaModuleSettings;
@@ -43,7 +42,6 @@
4342
'controllers' => [
4443
'captcha' => \OxidEsales\SecurityModule\Captcha\Controller\CaptchaController::class,
4544
'password' => \OxidEsales\SecurityModule\PasswordPolicy\Controller\PasswordAjaxController::class,
46-
'oauth' => \OxidEsales\SecurityModule\Authentication\OAuth2\Controller\OAuthController::class,
4745
],
4846
'templates' => [
4947
],

src/Authentication/OAuth2/Controller/OAuthController.php

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,36 +8,43 @@
88
namespace OxidEsales\SecurityModule\Authentication\OAuth2\Controller;
99

1010
use OxidEsales\Eshop\Application\Controller\FrontendController;
11-
use OxidEsales\Eshop\Core\Registry;
12-
use OxidEsales\SecurityModule\Authentication\OAuth2\Service\ProviderCollectorInterface;
13-
use OxidEsales\SecurityModule\Authentication\OAuth2\Service\UserServiceInterface;
11+
use OxidEsales\Eshop\Core\Utils;
12+
use OxidEsales\SecurityModule\Authentication\OAuth2\Service\AuthenticationServiceInterface;
13+
use OxidEsales\SecurityModule\Authentication\OAuth2\Transput\OAuthRequestInterface;
14+
use OxidEsales\SecurityModule\Authentication\Service\InternalRedirectServiceInterface;
1415

1516
class OAuthController extends FrontendController
1617
{
18+
public function __construct(
19+
private readonly AuthenticationServiceInterface $authService,
20+
private readonly OAuthRequestInterface $oauthRequest,
21+
private readonly InternalRedirectServiceInterface $redirectService,
22+
private readonly Utils $utils,
23+
) {
24+
parent::__construct();
25+
}
26+
1727
public function login(): void
1828
{
19-
$providerCollector = $this->getService(ProviderCollectorInterface::class);
20-
21-
$provider = $providerCollector->getProvider($_GET['provider']);
29+
$authorizationUrl = $this->authService->getAuthorizationUrl(
30+
$this->oauthRequest->getProvider()
31+
);
2232

23-
Registry::getUtils()->redirect($provider->getAuthorizationUrl());
33+
$this->utils->redirect($authorizationUrl);
2434
}
2535

2636
public function redirect(): void
2737
{
28-
//todo: get provider dynamically
29-
$provider = $this
30-
->getService(ProviderCollectorInterface::class)
31-
->getProvider('google');
32-
33-
$accessToken = $provider->getAccessToken($_GET['code']);
34-
35-
$userDTO = $provider->getUserInfo($accessToken);
38+
if ($this->oauthRequest->hasError()) {
39+
$this->utils->redirect($this->redirectService->getRedirectUrl(), false);
40+
return;
41+
}
3642

37-
$this
38-
->getService(UserServiceInterface::class)
39-
->login($userDTO);
43+
$this->authService->handleCallback(
44+
$this->oauthRequest->getProvider(),
45+
$this->oauthRequest->getCode()
46+
);
4047

41-
Registry::getUtils()->redirect('');
48+
$this->utils->redirect($this->redirectService->getRedirectUrl(), false);
4249
}
4350
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
services:
2+
_defaults:
3+
autowire: true
4+
public: false
5+
bind:
6+
OxidEsales\Eshop\Core\Utils: '@=service("OxidEsales\\SecurityModule\\Core\\Registry").getUtils()'
7+
8+
OxidEsales\SecurityModule\Authentication\OAuth2\Controller\OAuthController:
9+
public: true
10+
tags:
11+
- { name: 'oxid.view_controller', controller_key: 'oauth' }

src/Authentication/OAuth2/Infrastructure/Provider/Facebook/FacebookAdapter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public function getAuthorizationUrl(array $options = []): string
4646
return $this->provider->getAuthorizationUrl($options);
4747
}
4848

49-
public function getAccessToken(string $code): AccessTokenInterface
49+
public function getAccessToken(#[\SensitiveParameter] string $code): AccessTokenInterface
5050
{
5151
return $this->provider->getAccessToken('authorization_code', ['code' => $code]);
5252
}

src/Authentication/OAuth2/Infrastructure/Provider/Google/GoogleAdapter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public function getAuthorizationUrl(array $options = []): string
4747
return $this->provider->getAuthorizationUrl($options);
4848
}
4949

50-
public function getAccessToken(string $code): AccessTokenInterface
50+
public function getAccessToken(#[\SensitiveParameter] string $code): AccessTokenInterface
5151
{
5252
return $this->provider->getAccessToken('authorization_code', [
5353
'code' => $code,

src/Authentication/OAuth2/Infrastructure/Provider/Google/GoogleProviderFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public function create(): GoogleProvider
2626
{
2727
return new GoogleProvider([
2828
'clientId' => $this->moduleSettings->getGoogleClientId(),
29-
'clientSecret' => $this->moduleSettings->getFacebookClientSecret(),
29+
'clientSecret' => $this->moduleSettings->getGoogleClientSecret(),
3030
'redirectUri' => $this->moduleSettings->getGoogleRedirectUrl(),
3131
]);
3232
}

src/Authentication/OAuth2/Infrastructure/Provider/ProviderAdapterInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public function getAuthorizationUrl(array $options = []): string;
3131
/**
3232
* Exchange the authorization code for an access token.
3333
*/
34-
public function getAccessToken(string $code): AccessTokenInterface;
34+
public function getAccessToken(#[\SensitiveParameter] string $code): AccessTokenInterface;
3535

3636
/**
3737
* Fetch user information (claims) from the provider using the access token.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
/**
4+
* Copyright © OXID eSales AG. All rights reserved.
5+
* See LICENSE file for license details.
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
namespace OxidEsales\SecurityModule\Authentication\OAuth2\Service;
11+
12+
readonly class AuthenticationService implements AuthenticationServiceInterface
13+
{
14+
public function __construct(
15+
private ProviderCollectorInterface $providerCollector,
16+
private UserServiceInterface $userService,
17+
) {
18+
}
19+
20+
public function getAuthorizationUrl(string $providerName): string
21+
{
22+
$provider = $this->providerCollector->getProvider($providerName);
23+
24+
return $provider->getAuthorizationUrl();
25+
}
26+
27+
public function handleCallback(string $providerName, #[\SensitiveParameter] string $code): void
28+
{
29+
$provider = $this->providerCollector->getProvider($providerName);
30+
31+
$accessToken = $provider->getAccessToken($code);
32+
$userDTO = $provider->getUserInfo($accessToken);
33+
34+
$this->userService->login($userDTO);
35+
}
36+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
/**
4+
* Copyright © OXID eSales AG. All rights reserved.
5+
* See LICENSE file for license details.
6+
*/
7+
8+
namespace OxidEsales\SecurityModule\Authentication\OAuth2\Service;
9+
10+
interface AuthenticationServiceInterface
11+
{
12+
public function getAuthorizationUrl(string $providerName): string;
13+
14+
public function handleCallback(string $providerName, #[\SensitiveParameter] string $code): void;
15+
}

0 commit comments

Comments
 (0)