Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c1d43461ef | |||
| 6605b4ca8b | |||
| a25569d6f2 |
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
|||||||
namespace KTXM\AuthenticationProviderTotp\Controllers;
|
namespace KTXM\AuthenticationProviderTotp\Controllers;
|
||||||
|
|
||||||
use KTXC\Http\Response\JsonResponse;
|
use KTXC\Http\Response\JsonResponse;
|
||||||
use KTXC\SessionIdentity;
|
use KTXC\Context\IdentityContextInterface;
|
||||||
use KTXF\Controller\ControllerAbstract;
|
use KTXF\Controller\ControllerAbstract;
|
||||||
use KTXF\Routing\Attributes\AuthenticatedRoute;
|
use KTXF\Routing\Attributes\AuthenticatedRoute;
|
||||||
use KTXM\AuthenticationProviderTotp\Services\EnrollmentService;
|
use KTXM\AuthenticationProviderTotp\Services\EnrollmentService;
|
||||||
@@ -23,7 +23,7 @@ use KTXM\AuthenticationProviderTotp\Services\EnrollmentService;
|
|||||||
class EnrollmentController extends ControllerAbstract
|
class EnrollmentController extends ControllerAbstract
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly SessionIdentity $userIdentity,
|
private readonly IdentityContextInterface $identityContext,
|
||||||
private readonly EnrollmentService $enrollmentService,
|
private readonly EnrollmentService $enrollmentService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ class EnrollmentController extends ControllerAbstract
|
|||||||
#[AuthenticatedRoute('/totp/status', name: 'totp.status', methods: ['GET'])]
|
#[AuthenticatedRoute('/totp/status', name: 'totp.status', methods: ['GET'])]
|
||||||
public function status(): JsonResponse
|
public function status(): JsonResponse
|
||||||
{
|
{
|
||||||
$userId = $this->userIdentity->identifier();
|
$userId = $this->identityContext->identifier();
|
||||||
if (!$userId) {
|
if (!$userId) {
|
||||||
return new JsonResponse(
|
return new JsonResponse(
|
||||||
['error' => 'User not authenticated', 'error_code' => 'unauthorized'],
|
['error' => 'User not authenticated', 'error_code' => 'unauthorized'],
|
||||||
@@ -56,7 +56,7 @@ class EnrollmentController extends ControllerAbstract
|
|||||||
#[AuthenticatedRoute('/totp/enroll', name: 'totp.enroll.begin', methods: ['POST'])]
|
#[AuthenticatedRoute('/totp/enroll', name: 'totp.enroll.begin', methods: ['POST'])]
|
||||||
public function beginEnrollment(string $accountName = ''): JsonResponse
|
public function beginEnrollment(string $accountName = ''): JsonResponse
|
||||||
{
|
{
|
||||||
$userId = $this->userIdentity->identifier();
|
$userId = $this->identityContext->identifier();
|
||||||
if (!$userId) {
|
if (!$userId) {
|
||||||
return new JsonResponse(
|
return new JsonResponse(
|
||||||
['error' => 'User not authenticated', 'error_code' => 'unauthorized'],
|
['error' => 'User not authenticated', 'error_code' => 'unauthorized'],
|
||||||
@@ -95,7 +95,7 @@ class EnrollmentController extends ControllerAbstract
|
|||||||
#[AuthenticatedRoute('/totp/enroll/verify', name: 'totp.enroll.verify', methods: ['POST'])]
|
#[AuthenticatedRoute('/totp/enroll/verify', name: 'totp.enroll.verify', methods: ['POST'])]
|
||||||
public function completeEnrollment(string $code): JsonResponse
|
public function completeEnrollment(string $code): JsonResponse
|
||||||
{
|
{
|
||||||
$userId = $this->userIdentity->identifier();
|
$userId = $this->identityContext->identifier();
|
||||||
if (!$userId) {
|
if (!$userId) {
|
||||||
return new JsonResponse(
|
return new JsonResponse(
|
||||||
['error' => 'User not authenticated', 'error_code' => 'unauthorized'],
|
['error' => 'User not authenticated', 'error_code' => 'unauthorized'],
|
||||||
@@ -131,7 +131,7 @@ class EnrollmentController extends ControllerAbstract
|
|||||||
#[AuthenticatedRoute('/totp/enroll/remove', name: 'totp.enroll.remove', methods: ['POST'])]
|
#[AuthenticatedRoute('/totp/enroll/remove', name: 'totp.enroll.remove', methods: ['POST'])]
|
||||||
public function removeEnrollment(string $code): JsonResponse
|
public function removeEnrollment(string $code): JsonResponse
|
||||||
{
|
{
|
||||||
$userId = $this->userIdentity->identifier();
|
$userId = $this->identityContext->identifier();
|
||||||
if (!$userId) {
|
if (!$userId) {
|
||||||
return new JsonResponse(
|
return new JsonResponse(
|
||||||
['error' => 'User not authenticated', 'error_code' => 'unauthorized'],
|
['error' => 'User not authenticated', 'error_code' => 'unauthorized'],
|
||||||
|
|||||||
+7
-12
@@ -5,13 +5,14 @@ declare(strict_types=1);
|
|||||||
namespace KTXM\AuthenticationProviderTotp;
|
namespace KTXM\AuthenticationProviderTotp;
|
||||||
|
|
||||||
use KTXC\Resource\ProviderManager;
|
use KTXC\Resource\ProviderManager;
|
||||||
use KTXF\Module\ModuleBrowserInterface;
|
use KTXF\Module\Configuration\BrowserModuleContextInterface;
|
||||||
|
use KTXF\Module\Configuration\ModuleContextInterface;
|
||||||
use KTXF\Module\ModuleInstanceAbstract;
|
use KTXF\Module\ModuleInstanceAbstract;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TOTP Identity Provider Module
|
* TOTP Identity Provider Module
|
||||||
*/
|
*/
|
||||||
class Module extends ModuleInstanceAbstract implements ModuleBrowserInterface
|
class Module extends ModuleInstanceAbstract
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly ProviderManager $providerManager,
|
private readonly ProviderManager $providerManager,
|
||||||
@@ -58,16 +59,10 @@ class Module extends ModuleInstanceAbstract implements ModuleBrowserInterface
|
|||||||
$this->providerManager->register('authentication', 'totp', Provider::class);
|
$this->providerManager->register('authentication', 'totp', Provider::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function registerBI(): array
|
public function configure(ModuleContextInterface $context): void
|
||||||
{
|
{
|
||||||
return [
|
if ($context instanceof BrowserModuleContextInterface) {
|
||||||
'handle' => $this->handle(),
|
$context->registerModule($this, 'AuthenticationProviderTotp', 'static/module.mjs');
|
||||||
'namespace' => 'AuthenticationProviderTotp',
|
}
|
||||||
'version' => $this->version(),
|
|
||||||
'label' => $this->label(),
|
|
||||||
'author' => $this->author(),
|
|
||||||
'description' => $this->description(),
|
|
||||||
'boot' => 'static/module.mjs',
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace KTXM\AuthenticationProviderTotp\Services;
|
namespace KTXM\AuthenticationProviderTotp\Services;
|
||||||
|
|
||||||
use KTXC\SessionTenant;
|
use KTXC\Context\TenantContextInterface;
|
||||||
use KTXM\AuthenticationProviderTotp\Stores\EnrollmentStore;
|
use KTXM\AuthenticationProviderTotp\Stores\EnrollmentStore;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -26,7 +26,7 @@ class EnrollmentService
|
|||||||
private const SECRET_LENGTH = 20; // 160 bits as recommended by RFC 4226
|
private const SECRET_LENGTH = 20; // 160 bits as recommended by RFC 4226
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly SessionTenant $tenant,
|
private readonly TenantContextInterface $tenantContext,
|
||||||
private readonly EnrollmentStore $enrollmentStore,
|
private readonly EnrollmentStore $enrollmentStore,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ class EnrollmentService
|
|||||||
*/
|
*/
|
||||||
public function isEnrolled(string $userId): bool
|
public function isEnrolled(string $userId): bool
|
||||||
{
|
{
|
||||||
$tenantId = $this->tenant->identifier();
|
$tenantId = $this->tenantContext->identifier();
|
||||||
if (!$tenantId) {
|
if (!$tenantId) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,7 @@ class EnrollmentService
|
|||||||
*/
|
*/
|
||||||
public function beginEnrollment(string $userId, array $config = []): array
|
public function beginEnrollment(string $userId, array $config = []): array
|
||||||
{
|
{
|
||||||
$tenantId = $this->tenant->identifier();
|
$tenantId = $this->tenantContext->identifier();
|
||||||
if (!$tenantId) {
|
if (!$tenantId) {
|
||||||
return [
|
return [
|
||||||
'success' => false,
|
'success' => false,
|
||||||
@@ -108,7 +108,7 @@ class EnrollmentService
|
|||||||
*/
|
*/
|
||||||
public function completeEnrollment(string $userId, string $code): array
|
public function completeEnrollment(string $userId, string $code): array
|
||||||
{
|
{
|
||||||
$tenantId = $this->tenant->identifier();
|
$tenantId = $this->tenantContext->identifier();
|
||||||
if (!$tenantId) {
|
if (!$tenantId) {
|
||||||
return [
|
return [
|
||||||
'success' => false,
|
'success' => false,
|
||||||
@@ -150,7 +150,7 @@ class EnrollmentService
|
|||||||
*/
|
*/
|
||||||
public function removeEnrollment(string $userId): array
|
public function removeEnrollment(string $userId): array
|
||||||
{
|
{
|
||||||
$tenantId = $this->tenant->identifier();
|
$tenantId = $this->tenantContext->identifier();
|
||||||
if (!$tenantId) {
|
if (!$tenantId) {
|
||||||
return [
|
return [
|
||||||
'success' => false,
|
'success' => false,
|
||||||
@@ -181,7 +181,7 @@ class EnrollmentService
|
|||||||
*/
|
*/
|
||||||
public function verifyCode(string $userId, string $code): array
|
public function verifyCode(string $userId, string $code): array
|
||||||
{
|
{
|
||||||
$tenantId = $this->tenant->identifier();
|
$tenantId = $this->tenantContext->identifier();
|
||||||
if (!$tenantId) {
|
if (!$tenantId) {
|
||||||
return [
|
return [
|
||||||
'success' => false,
|
'success' => false,
|
||||||
@@ -225,7 +225,7 @@ class EnrollmentService
|
|||||||
*/
|
*/
|
||||||
public function getEnrollmentSecret(string $userId): ?string
|
public function getEnrollmentSecret(string $userId): ?string
|
||||||
{
|
{
|
||||||
$tenantId = $this->tenant->identifier();
|
$tenantId = $this->tenantContext->identifier();
|
||||||
if (!$tenantId) {
|
if (!$tenantId) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+64
-4
@@ -1176,6 +1176,63 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@vuetify/v0": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vuetify/v0/-/v0-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-lFBUeMmQiKbFR7JXC1Z74Z2dvvGLCqt/Wd9JQqg4falICTvHtlkulYqaHbtmByGV9eR7cbG1ohN1+7OQLLSPfg==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/johnleider"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/vuetify"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@adobe/leonardo-contrast-colors": ">=1.0.0",
|
||||||
|
"@ant-design/colors": ">=7.0.0",
|
||||||
|
"@flagsmith/flagsmith": ">=11.0.0",
|
||||||
|
"@floating-ui/dom": ">=1.8.0",
|
||||||
|
"@js-temporal/polyfill": ">=0.5.0",
|
||||||
|
"@material/material-color-utilities": ">=0.3.0",
|
||||||
|
"launchdarkly-js-client-sdk": "^3.0.0",
|
||||||
|
"posthog-js": "^1.0.0",
|
||||||
|
"vue": ">=3.5.0 || >=3.6.0-0",
|
||||||
|
"vue-i18n": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@adobe/leonardo-contrast-colors": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@ant-design/colors": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@flagsmith/flagsmith": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@floating-ui/dom": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@js-temporal/polyfill": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@material/material-color-utilities": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"launchdarkly-js-client-sdk": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"posthog-js": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"vue-i18n": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/abbrev": {
|
"node_modules/abbrev": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -3053,10 +3110,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vuetify": {
|
"node_modules/vuetify": {
|
||||||
"version": "4.1.6",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-4.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-4.2.0.tgz",
|
||||||
"integrity": "sha512-VOsRTsNfs+FE4JXMONZkqX2yznSqC/FXG9/pgVVjsoqIjUvJg+CfFTuOlgyWVFrZYY+crk7LV9uaiN8bZREV/g==",
|
"integrity": "sha512-KaMbAl57GG/zdLdL9dcMqEZligIK3jYvkPkpx+RS9DufD/TOfWKnlDTOUzoYlvmhT/3LfJ/usAt1bSoWfYX4JA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@vuetify/v0": "^1.2.1"
|
||||||
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "github",
|
"type": "github",
|
||||||
"url": "https://github.com/sponsors/johnleider"
|
"url": "https://github.com/sponsors/johnleider"
|
||||||
@@ -3064,7 +3124,7 @@
|
|||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": ">=4.7",
|
"typescript": ">=4.7",
|
||||||
"vite-plugin-vuetify": ">=2.1.0",
|
"vite-plugin-vuetify": ">=2.1.0",
|
||||||
"vue": "^3.5.0",
|
"vue": "^3.5.0 || ^3.6.0-0",
|
||||||
"webpack-plugin-vuetify": ">=3.1.0"
|
"webpack-plugin-vuetify": ">=3.1.0"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
|
|||||||
Reference in New Issue
Block a user