@fleetbase/registry-bridge-engine 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.php-cs-fixer.php +29 -0
- package/LICENSE.md +651 -0
- package/README.md +122 -0
- package/addon/adapters/registry-bridge.js +5 -0
- package/addon/adapters/registry-extension-bundle.js +1 -0
- package/addon/adapters/registry-extension.js +1 -0
- package/addon/components/extension-card.hbs +12 -0
- package/addon/components/extension-card.js +235 -0
- package/addon/components/extension-form.hbs +237 -0
- package/addon/components/extension-form.js +123 -0
- package/addon/components/extension-modal-title.hbs +14 -0
- package/addon/components/extension-modal-title.js +20 -0
- package/addon/components/extension-monetize-form.hbs +56 -0
- package/addon/components/extension-monetize-form.js +7 -0
- package/addon/components/extension-pending-publish-viewer.hbs +52 -0
- package/addon/components/extension-pending-publish-viewer.js +37 -0
- package/addon/components/extension-reviewer-control.hbs +68 -0
- package/addon/components/extension-reviewer-control.js +68 -0
- package/addon/components/modals/confirm-extension-purchase.hbs +5 -0
- package/addon/components/modals/confirm-extension-purchase.js +3 -0
- package/addon/components/modals/extension-details.hbs +69 -0
- package/addon/components/modals/extension-details.js +33 -0
- package/addon/components/modals/extension-purchase-form.hbs +5 -0
- package/addon/components/modals/extension-purchase-form.js +3 -0
- package/addon/components/modals/extension-uninstall.hbs +25 -0
- package/addon/components/modals/extension-uninstall.js +11 -0
- package/addon/components/modals/select-extension-bundle.hbs +43 -0
- package/addon/components/modals/select-extension-bundle.js +31 -0
- package/addon/components/progress-bar.hbs +12 -0
- package/addon/components/progress-bar.js +8 -0
- package/addon/controllers/application.js +6 -0
- package/addon/controllers/developers/analytics.js +26 -0
- package/addon/controllers/developers/extensions/edit/bundles.js +70 -0
- package/addon/controllers/developers/extensions/edit/index.js +3 -0
- package/addon/controllers/developers/extensions/edit/monetize.js +7 -0
- package/addon/controllers/developers/extensions/edit.js +107 -0
- package/addon/controllers/developers/extensions/index.js +3 -0
- package/addon/controllers/developers/extensions/new.js +32 -0
- package/addon/controllers/developers/payments/index.js +39 -0
- package/addon/controllers/developers/payments/onboard.js +67 -0
- package/addon/controllers/explore/category.js +22 -0
- package/addon/controllers/explore/index.js +15 -0
- package/addon/controllers/installed.js +86 -0
- package/addon/controllers/purchased.js +18 -0
- package/addon/engine.js +44 -0
- package/addon/models/registry-extension-bundle.js +62 -0
- package/addon/models/registry-extension.js +215 -0
- package/addon/routes/application.js +12 -0
- package/addon/routes/developers/analytics.js +10 -0
- package/addon/routes/developers/credentials.js +3 -0
- package/addon/routes/developers/extensions/edit/bundles.js +21 -0
- package/addon/routes/developers/extensions/edit/details.js +3 -0
- package/addon/routes/developers/extensions/edit/index.js +3 -0
- package/addon/routes/developers/extensions/edit/monetize.js +3 -0
- package/addon/routes/developers/extensions/edit.js +18 -0
- package/addon/routes/developers/extensions/index.js +10 -0
- package/addon/routes/developers/extensions/new.js +3 -0
- package/addon/routes/developers/extensions.js +3 -0
- package/addon/routes/developers/payments/index.js +26 -0
- package/addon/routes/developers/payments/onboard.js +21 -0
- package/addon/routes/developers/payments.js +3 -0
- package/addon/routes/developers.js +3 -0
- package/addon/routes/explore/category.js +27 -0
- package/addon/routes/explore/index.js +17 -0
- package/addon/routes/explore.js +3 -0
- package/addon/routes/installed.js +10 -0
- package/addon/routes/purchased.js +10 -0
- package/addon/routes.js +28 -0
- package/addon/serializers/registry-extension-bundle.js +15 -0
- package/addon/serializers/registry-extension.js +21 -0
- package/addon/services/stripe.js +83 -0
- package/addon/styles/registry-bridge-engine.css +142 -0
- package/addon/templates/application.hbs +26 -0
- package/addon/templates/developers/analytics.hbs +83 -0
- package/addon/templates/developers/credentials.hbs +1 -0
- package/addon/templates/developers/extensions/edit/bundles.hbs +71 -0
- package/addon/templates/developers/extensions/edit/details.hbs +16 -0
- package/addon/templates/developers/extensions/edit/index.hbs +1 -0
- package/addon/templates/developers/extensions/edit/monetize.hbs +3 -0
- package/addon/templates/developers/extensions/edit.hbs +48 -0
- package/addon/templates/developers/extensions/index.hbs +27 -0
- package/addon/templates/developers/extensions/new.hbs +39 -0
- package/addon/templates/developers/extensions.hbs +1 -0
- package/addon/templates/developers/payments/index.hbs +33 -0
- package/addon/templates/developers/payments/onboard.hbs +48 -0
- package/addon/templates/developers/payments.hbs +1 -0
- package/addon/templates/developers.hbs +1 -0
- package/addon/templates/explore/category.hbs +12 -0
- package/addon/templates/explore/index.hbs +12 -0
- package/addon/templates/explore.hbs +1 -0
- package/addon/templates/installed.hbs +32 -0
- package/addon/templates/purchased.hbs +34 -0
- package/app/adapters/registry-bridge.js +1 -0
- package/app/adapters/registry-extension-bundle.js +1 -0
- package/app/adapters/registry-extension.js +1 -0
- package/app/components/extension-card.js +1 -0
- package/app/components/extension-form.js +1 -0
- package/app/components/extension-modal-title.js +1 -0
- package/app/components/extension-monetize-form.js +1 -0
- package/app/components/extension-pending-publish-viewer.js +1 -0
- package/app/components/extension-reviewer-control.js +1 -0
- package/app/components/modals/confirm-extension-purchase.js +1 -0
- package/app/components/modals/extension-details.js +1 -0
- package/app/components/modals/extension-purchase-form.js +1 -0
- package/app/components/modals/extension-uninstall.js +1 -0
- package/app/components/modals/select-extension-bundle.js +1 -0
- package/app/components/progress-bar.js +1 -0
- package/app/controllers/application.js +1 -0
- package/app/controllers/developers/analytics.js +1 -0
- package/app/controllers/developers/extensions/edit/bundles.js +1 -0
- package/app/controllers/developers/extensions/edit/index.js +1 -0
- package/app/controllers/developers/extensions/edit/monetize.js +1 -0
- package/app/controllers/developers/extensions/edit.js +1 -0
- package/app/controllers/developers/extensions/index.js +1 -0
- package/app/controllers/developers/extensions/new.js +1 -0
- package/app/controllers/developers/payments/index.js +1 -0
- package/app/controllers/developers/payments/onboard.js +1 -0
- package/app/controllers/explore/category.js +1 -0
- package/app/controllers/explore/index.js +1 -0
- package/app/controllers/installed.js +1 -0
- package/app/controllers/purchased.js +1 -0
- package/app/models/registry-extension-bundle.js +1 -0
- package/app/models/registry-extension.js +1 -0
- package/app/routes/developers/analytics.js +1 -0
- package/app/routes/developers/credentials.js +1 -0
- package/app/routes/developers/extensions/edit/bundles.js +1 -0
- package/app/routes/developers/extensions/edit/details.js +1 -0
- package/app/routes/developers/extensions/edit/index.js +1 -0
- package/app/routes/developers/extensions/edit/monetize.js +1 -0
- package/app/routes/developers/extensions/edit.js +1 -0
- package/app/routes/developers/extensions/index.js +1 -0
- package/app/routes/developers/extensions/new.js +1 -0
- package/app/routes/developers/extensions.js +1 -0
- package/app/routes/developers/payments/index.js +1 -0
- package/app/routes/developers/payments/onboard.js +1 -0
- package/app/routes/developers/payments.js +1 -0
- package/app/routes/developers.js +1 -0
- package/app/routes/explore/category.js +1 -0
- package/app/routes/explore/index.js +1 -0
- package/app/routes/explore.js +1 -0
- package/app/routes/installed.js +1 -0
- package/app/routes/purchased.js +1 -0
- package/app/serializers/registry-extension-bundle.js +1 -0
- package/app/serializers/registry-extension.js +1 -0
- package/app/services/stripe.js +1 -0
- package/app/templates/developers/analytics.js +1 -0
- package/app/templates/developers/credentials.js +1 -0
- package/app/templates/developers/extensions/edit/bundles.js +1 -0
- package/app/templates/developers/extensions/edit/details.js +1 -0
- package/app/templates/developers/extensions/edit/index.js +1 -0
- package/app/templates/developers/extensions/edit/monetize.js +1 -0
- package/app/templates/developers/extensions/edit.js +1 -0
- package/app/templates/developers/extensions/index.js +1 -0
- package/app/templates/developers/extensions/new.js +1 -0
- package/app/templates/developers/extensions.js +1 -0
- package/app/templates/developers/payments/index.js +1 -0
- package/app/templates/developers/payments/onboard.js +1 -0
- package/app/templates/developers/payments.js +1 -0
- package/app/templates/developers.js +1 -0
- package/app/templates/explore/category.js +1 -0
- package/app/templates/explore/index.js +1 -0
- package/app/templates/explore.js +1 -0
- package/app/templates/installed.js +1 -0
- package/app/templates/purchased.js +1 -0
- package/composer.json +95 -0
- package/config/environment.js +28 -0
- package/extension.json +10 -0
- package/index.js +26 -0
- package/package.json +129 -0
- package/phpstan.neon.dist +8 -0
- package/phpunit.xml.dist +16 -0
- package/server/.gitattributes +14 -0
- package/server/config/registry-bridge.php +32 -0
- package/server/migrations/2024_03_19_060627_create_registry_users_table.php +42 -0
- package/server/migrations/2024_03_21_051614_create_registry_extensions_table.php +76 -0
- package/server/migrations/2024_03_25_044537_create_registry_extension_bundles_table.php +54 -0
- package/server/migrations/2024_03_29_072101_registry_extension_installs.php +35 -0
- package/server/migrations/2024_07_16_155000_create_registry_extension_purchases.php +41 -0
- package/server/seeders/ExtensionsCategorySeeder.php +359 -0
- package/server/src/Console/Commands/Initialize.php +35 -0
- package/server/src/Console/Commands/PostInstallExtension.php +84 -0
- package/server/src/Exceptions/InstallFailedException.php +21 -0
- package/server/src/Expansions/CategoryExpansion.php +30 -0
- package/server/src/Http/Controllers/Internal/v1/ExtensionInstallerController.php +153 -0
- package/server/src/Http/Controllers/Internal/v1/RegistryAuthController.php +230 -0
- package/server/src/Http/Controllers/Internal/v1/RegistryController.php +54 -0
- package/server/src/Http/Controllers/Internal/v1/RegistryExtensionBundleController.php +112 -0
- package/server/src/Http/Controllers/Internal/v1/RegistryExtensionController.php +257 -0
- package/server/src/Http/Controllers/Internal/v1/RegistryPaymentsController.php +227 -0
- package/server/src/Http/Controllers/RegistryBridgeController.php +13 -0
- package/server/src/Http/Filter/RegistryExtensionFilter.php +80 -0
- package/server/src/Http/Requests/AddRegistryUserRequest.php +47 -0
- package/server/src/Http/Requests/AuthenticateRegistryUserRequest.php +47 -0
- package/server/src/Http/Requests/CreateRegistryExtensionBundleRequest.php +42 -0
- package/server/src/Http/Requests/CreateRegistryExtensionRequest.php +31 -0
- package/server/src/Http/Requests/InstallExtensionRequest.php +30 -0
- package/server/src/Http/Requests/RegistryAuthRequest.php +46 -0
- package/server/src/Http/Requests/RegistryExtensionActionRequest.php +30 -0
- package/server/src/Http/Resources/RegistryUser.php +40 -0
- package/server/src/Models/RegistryExtension.php +656 -0
- package/server/src/Models/RegistryExtensionBundle.php +1015 -0
- package/server/src/Models/RegistryExtensionInstall.php +76 -0
- package/server/src/Models/RegistryExtensionPurchase.php +87 -0
- package/server/src/Models/RegistryUser.php +140 -0
- package/server/src/Providers/RegistryBridgeServiceProvider.php +117 -0
- package/server/src/Support/Bridge.php +53 -0
- package/server/src/Support/Utils.php +19 -0
- package/server/src/routes.php +58 -0
- package/server/tests/Feature.php +5 -0
- package/translations/en-us.yaml +119 -0
- package/tsconfig.declarations.json +10 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\RegistryBridge\Console\Commands;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\RegistryBridge\Providers\RegistryBridgeServiceProvider;
|
|
6
|
+
use Illuminate\Console\Command;
|
|
7
|
+
|
|
8
|
+
class Initialize extends Command
|
|
9
|
+
{
|
|
10
|
+
/**
|
|
11
|
+
* The name and signature of the console command.
|
|
12
|
+
*
|
|
13
|
+
* @var string
|
|
14
|
+
*/
|
|
15
|
+
protected $signature = 'registry:init';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The console command description.
|
|
19
|
+
*
|
|
20
|
+
* @var string
|
|
21
|
+
*/
|
|
22
|
+
protected $description = 'Runs initialization for registry bridge.';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Execute the console command.
|
|
26
|
+
*
|
|
27
|
+
* @return int
|
|
28
|
+
*/
|
|
29
|
+
public function handle()
|
|
30
|
+
{
|
|
31
|
+
RegistryBridgeServiceProvider::bootRegistryAuth(true);
|
|
32
|
+
|
|
33
|
+
return 0;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\RegistryBridge\Console\Commands;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\RegistryBridge\Models\RegistryExtension;
|
|
6
|
+
use Illuminate\Console\Command;
|
|
7
|
+
use Symfony\Component\Process\Exception\ProcessFailedException;
|
|
8
|
+
use Symfony\Component\Process\Process;
|
|
9
|
+
|
|
10
|
+
class PostInstallExtension extends Command
|
|
11
|
+
{
|
|
12
|
+
/**
|
|
13
|
+
* The name and signature of the console command.
|
|
14
|
+
*
|
|
15
|
+
* @var string
|
|
16
|
+
*/
|
|
17
|
+
protected $signature = 'registry:post-install {extensionId}';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The console command description.
|
|
21
|
+
*
|
|
22
|
+
* @var string
|
|
23
|
+
*/
|
|
24
|
+
protected $description = 'Post install an extension by running necessary commands';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Execute the console command.
|
|
28
|
+
*
|
|
29
|
+
* @return int
|
|
30
|
+
*/
|
|
31
|
+
public function handle()
|
|
32
|
+
{
|
|
33
|
+
$extensionId = $this->argument('extensionId');
|
|
34
|
+
$extension = RegistryExtension::disableCache()->where('public_id', $extensionId)->first();
|
|
35
|
+
|
|
36
|
+
if ($extension) {
|
|
37
|
+
$this->postInstallExtension($extension);
|
|
38
|
+
$this->info('Post install commands executed successfully.');
|
|
39
|
+
} else {
|
|
40
|
+
$this->error('Extension not found.');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Post install extension commands.
|
|
48
|
+
*/
|
|
49
|
+
public function postInstallExtension(RegistryExtension $extension): void
|
|
50
|
+
{
|
|
51
|
+
if (isset($extension->currentBundle)) {
|
|
52
|
+
$composerJson = $extension->currentBundle->meta['composer.json'];
|
|
53
|
+
if ($composerJson) {
|
|
54
|
+
$extensionPath = base_path('vendor/' . $composerJson['name']);
|
|
55
|
+
|
|
56
|
+
$commands = [
|
|
57
|
+
'rm -rf /fleetbase/.pnpm-store',
|
|
58
|
+
'rm -rf node_modules',
|
|
59
|
+
'pnpm install',
|
|
60
|
+
'pnpm build',
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
$this->info('Running post install for: ' . $extension->name);
|
|
64
|
+
$this->info('Extension install path: ' . $extensionPath);
|
|
65
|
+
foreach ($commands as $command) {
|
|
66
|
+
$this->info('Running extension post install command: `' . $command . '`');
|
|
67
|
+
$process = Process::fromShellCommandline($command, $extensionPath);
|
|
68
|
+
$process->run(function ($type, $buffer) {
|
|
69
|
+
if (Process::ERR === $type) {
|
|
70
|
+
$this->error($buffer);
|
|
71
|
+
} else {
|
|
72
|
+
$this->info($buffer);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Check if the process was successful
|
|
77
|
+
if (!$process->isSuccessful()) {
|
|
78
|
+
throw new ProcessFailedException($process);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\RegistryBridge\Exceptions;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Represents an exception thrown when a package installation fails.
|
|
7
|
+
*/
|
|
8
|
+
class InstallFailedException extends \Exception
|
|
9
|
+
{
|
|
10
|
+
/**
|
|
11
|
+
* Constructs the InstallFailedException.
|
|
12
|
+
*
|
|
13
|
+
* @param string $message the Exception message to throw
|
|
14
|
+
* @param int $code the Exception code
|
|
15
|
+
* @param \Throwable|null $previous the previous throwable used for the exception chaining
|
|
16
|
+
*/
|
|
17
|
+
public function __construct($message = '', $code = 0, ?\Throwable $previous = null)
|
|
18
|
+
{
|
|
19
|
+
parent::__construct($message, $code, $previous);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\RegistryBridge\Expansions;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\Build\Expansion;
|
|
6
|
+
use Fleetbase\RegistryBridge\Models\RegistryExtension;
|
|
7
|
+
|
|
8
|
+
class CategoryExpansion implements Expansion
|
|
9
|
+
{
|
|
10
|
+
/**
|
|
11
|
+
* Get the target class to expand.
|
|
12
|
+
*
|
|
13
|
+
* @return string|Class
|
|
14
|
+
*/
|
|
15
|
+
public static function target()
|
|
16
|
+
{
|
|
17
|
+
return \Fleetbase\Models\Category::class;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
|
22
|
+
*/
|
|
23
|
+
public static function registryExtensions()
|
|
24
|
+
{
|
|
25
|
+
return function () {
|
|
26
|
+
/* @var \Illuminate\Database\Eloquent\Model $this */
|
|
27
|
+
return $this->hasMany(RegistryExtension::class, 'category_uuid', 'uuid')->where('status', 'published');
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\RegistryBridge\Http\Controllers\Internal\v1;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\Http\Controllers\Controller;
|
|
6
|
+
use Fleetbase\RegistryBridge\Http\Requests\InstallExtensionRequest;
|
|
7
|
+
use Fleetbase\RegistryBridge\Models\RegistryExtension;
|
|
8
|
+
use Fleetbase\RegistryBridge\Models\RegistryExtensionInstall;
|
|
9
|
+
|
|
10
|
+
class ExtensionInstallerController extends Controller
|
|
11
|
+
{
|
|
12
|
+
/**
|
|
13
|
+
* Installs a specified extension for a company.
|
|
14
|
+
*
|
|
15
|
+
* This method handles the installation process of an extension. It first looks up
|
|
16
|
+
* the extension in the `RegistryExtension` model using its public identifier provided
|
|
17
|
+
* in the request. Then, it ensures that the installation is recorded in the
|
|
18
|
+
* `RegistryExtensionInstall` model, linking the extension to the current company.
|
|
19
|
+
* If the installation record already exists, it does not create a duplicate.
|
|
20
|
+
*
|
|
21
|
+
* @param InstallExtensionRequest $request The request object containing the extension
|
|
22
|
+
* identifier. Expected to have an 'extension'
|
|
23
|
+
* field with the public ID of the extension.
|
|
24
|
+
*
|
|
25
|
+
* @return \Illuminate\Http\JsonResponse Returns a JSON response indicating the status.
|
|
26
|
+
* The response contains a 'status' key with the
|
|
27
|
+
* value 'ok' if the process is successful.
|
|
28
|
+
*
|
|
29
|
+
* @throws \Exception throws an exception if the specified extension is not found in the
|
|
30
|
+
* `RegistryExtension` model, leading to a potential error when
|
|
31
|
+
* trying to access properties of a non-object (`$extension->uuid`)
|
|
32
|
+
*/
|
|
33
|
+
public function install(InstallExtensionRequest $request)
|
|
34
|
+
{
|
|
35
|
+
set_time_limit(120 * 6);
|
|
36
|
+
$extension = RegistryExtension::where('public_id', $request->input('extension'))->first();
|
|
37
|
+
|
|
38
|
+
// Check if already installed
|
|
39
|
+
$installed = RegistryExtensionInstall::disableCache()->where(['company_uuid' => session('company'), 'extension_uuid' => $extension->uuid])->exists();
|
|
40
|
+
if ($installed) {
|
|
41
|
+
return response()->error('This extension is already installed.');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Check if extensions are pre-installed to system
|
|
45
|
+
$PREINSTALLED_EXTENSIONS = config('registry-bridge.extensions.preinstalled') === true;
|
|
46
|
+
|
|
47
|
+
// Run installers if extension needs to be installed
|
|
48
|
+
if ($PREINSTALLED_EXTENSIONS === false) {
|
|
49
|
+
// Install for Composer
|
|
50
|
+
try {
|
|
51
|
+
$extension->currentBundle->installComposerPackage();
|
|
52
|
+
} catch (\Throwable $e) {
|
|
53
|
+
return response()->error($e->getMessage());
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Install for Console
|
|
57
|
+
try {
|
|
58
|
+
$extension->currentBundle->installEnginePackage();
|
|
59
|
+
} catch (\Throwable $e) {
|
|
60
|
+
return response()->error($e->getMessage());
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Rebuild Console
|
|
64
|
+
try {
|
|
65
|
+
$extension->currentBundle->buildConsole();
|
|
66
|
+
} catch (\Throwable $e) {
|
|
67
|
+
return response()->error($e->getMessage());
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Run installer progress if preinstalled
|
|
72
|
+
if ($PREINSTALLED_EXTENSIONS === true) {
|
|
73
|
+
$extension->currentBundle->runInstallerProgress();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Create install record
|
|
77
|
+
$install = RegistryExtensionInstall::create([
|
|
78
|
+
'company_uuid' => session('company'),
|
|
79
|
+
'extension_uuid' => $extension->uuid,
|
|
80
|
+
]);
|
|
81
|
+
|
|
82
|
+
return response()->json(['status' => 'ok', 'install' => $install]);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Uninstall a specific extension for the current company.
|
|
87
|
+
*
|
|
88
|
+
* This function handles the uninstallation of an extension specified by the public ID
|
|
89
|
+
* provided in the request. It first checks if the extension is already uninstalled for
|
|
90
|
+
* the company identified by the `company_uuid` stored in the session. If the extension
|
|
91
|
+
* is not installed, an error response is returned.
|
|
92
|
+
*
|
|
93
|
+
* If the extension is installed, it proceeds to uninstall the extension using Composer
|
|
94
|
+
* and removes the corresponding installation records from the database. If any errors
|
|
95
|
+
* occur during the Composer uninstallation process, an error response is returned.
|
|
96
|
+
*
|
|
97
|
+
* @param InstallExtensionRequest $request the request containing the public ID of the extension to be uninstalled
|
|
98
|
+
*
|
|
99
|
+
* @return \Illuminate\Http\JsonResponse a JSON response indicating the status of the uninstallation process
|
|
100
|
+
*/
|
|
101
|
+
public function uninstall(InstallExtensionRequest $request)
|
|
102
|
+
{
|
|
103
|
+
set_time_limit(120 * 6);
|
|
104
|
+
$extension = RegistryExtension::where('public_id', $request->input('extension'))->first();
|
|
105
|
+
$uninstalled = false;
|
|
106
|
+
|
|
107
|
+
// Check if already uninstalled
|
|
108
|
+
$uninstalled = RegistryExtensionInstall::disableCache()->where(['company_uuid' => session('company'), 'extension_uuid' => $extension->uuid])->doesntExist();
|
|
109
|
+
if ($uninstalled) {
|
|
110
|
+
return response()->error('This extension is not installed.');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Check if extensions are pre-installed to system
|
|
114
|
+
$PREINSTALLED_EXTENSIONS = config('registry-bridge.extensions.preinstalled') === true;
|
|
115
|
+
|
|
116
|
+
// Run installers if extension needs to be installed
|
|
117
|
+
if ($PREINSTALLED_EXTENSIONS === false) {
|
|
118
|
+
// Uninstall for Composer
|
|
119
|
+
try {
|
|
120
|
+
$extension->currentBundle->uninstallComposerPackage();
|
|
121
|
+
} catch (\Throwable $e) {
|
|
122
|
+
return response()->error($e->getMessage());
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Unnstall for Console
|
|
126
|
+
try {
|
|
127
|
+
$extension->currentBundle->uninstallEnginePackage();
|
|
128
|
+
} catch (\Throwable $e) {
|
|
129
|
+
return response()->error($e->getMessage());
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Rebuild Console
|
|
133
|
+
try {
|
|
134
|
+
$extension->currentBundle->buildConsole();
|
|
135
|
+
} catch (\Throwable $e) {
|
|
136
|
+
return response()->error($e->getMessage());
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Run installer progress if preinstalled
|
|
141
|
+
if ($PREINSTALLED_EXTENSIONS === true) {
|
|
142
|
+
$extension->currentBundle->runUninstallerProgress();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Remove install records
|
|
146
|
+
$uninstalled = RegistryExtensionInstall::where([
|
|
147
|
+
'company_uuid' => session('company'),
|
|
148
|
+
'extension_uuid' => $extension->uuid,
|
|
149
|
+
])->delete();
|
|
150
|
+
|
|
151
|
+
return response()->json(['status' => 'ok', 'uninstalled' => $uninstalled]);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\RegistryBridge\Http\Controllers\Internal\v1;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\Http\Controllers\Controller;
|
|
6
|
+
use Fleetbase\Models\User;
|
|
7
|
+
use Fleetbase\RegistryBridge\Http\Requests\AddRegistryUserRequest;
|
|
8
|
+
use Fleetbase\RegistryBridge\Http\Requests\AuthenticateRegistryUserRequest;
|
|
9
|
+
use Fleetbase\RegistryBridge\Http\Requests\RegistryAuthRequest;
|
|
10
|
+
use Fleetbase\RegistryBridge\Http\Resources\RegistryUser as RegistryUserResource;
|
|
11
|
+
use Fleetbase\RegistryBridge\Models\RegistryExtension;
|
|
12
|
+
use Fleetbase\RegistryBridge\Models\RegistryUser;
|
|
13
|
+
use Fleetbase\RegistryBridge\Support\Bridge;
|
|
14
|
+
use Fleetbase\Support\Auth;
|
|
15
|
+
|
|
16
|
+
class RegistryAuthController extends Controller
|
|
17
|
+
{
|
|
18
|
+
public function test()
|
|
19
|
+
{
|
|
20
|
+
dd(Bridge::get('~/flb/extensions'));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Authenticates a registry user based on provided credentials.
|
|
25
|
+
*
|
|
26
|
+
* This method attempts to authenticate a user using an identity (which can be either an email or username)
|
|
27
|
+
* and a password. Upon successful authentication, it either retrieves an existing token associated with
|
|
28
|
+
* the user or generates a new one. The method returns the token and user information in JSON format.
|
|
29
|
+
*
|
|
30
|
+
* If authentication fails or a token cannot be generated or retrieved, an error response is returned.
|
|
31
|
+
*
|
|
32
|
+
* @param AuthenticateRegistryUserRequest $request the request object containing identity and password
|
|
33
|
+
*
|
|
34
|
+
* @return RegistryUserResource Returns a JSON resource representing the registry user along with groups and containing the auth token and additional user data.
|
|
35
|
+
* Returns an error response if authentication fails or token generation is unsuccessful.
|
|
36
|
+
*/
|
|
37
|
+
public function authenticate(AuthenticateRegistryUserRequest $request)
|
|
38
|
+
{
|
|
39
|
+
$identity = $request->input('identity');
|
|
40
|
+
$password = $request->input('password');
|
|
41
|
+
|
|
42
|
+
// Find user by email or username
|
|
43
|
+
$user = User::where(function ($query) use ($identity) {
|
|
44
|
+
$query->where('email', $identity)->orWhere('phone', $identity)->orWhere('username', $identity);
|
|
45
|
+
})->first();
|
|
46
|
+
|
|
47
|
+
// Authenticate user with password
|
|
48
|
+
if (Auth::isInvalidPassword($password, $user->password)) {
|
|
49
|
+
return response()->error('Invalid credentials.', 401);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Get existing token for current user
|
|
53
|
+
$registryUser = RegistryUser::where(['company_uuid' => $user->company_uuid, 'user_uuid' => $user->uuid])->first();
|
|
54
|
+
if (!$registryUser) {
|
|
55
|
+
// Create registry user
|
|
56
|
+
$registryUser = RegistryUser::create([
|
|
57
|
+
'company_uuid' => $user->company_uuid,
|
|
58
|
+
'user_uuid' => $user->uuid,
|
|
59
|
+
'scope' => '*',
|
|
60
|
+
'expires_at' => now()->addYear(),
|
|
61
|
+
'name' => $user->public_id . ' developer token',
|
|
62
|
+
]);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// If no token response with error
|
|
66
|
+
if (!$registryUser) {
|
|
67
|
+
return response()->error('Unable to authenticate.');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return new RegistryUserResource($registryUser);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Adds a new user to the registry with authentication credentials.
|
|
75
|
+
*
|
|
76
|
+
* This method creates a registry user linked to the currently active company
|
|
77
|
+
* of the user. It requires an identity (email or username) and password for
|
|
78
|
+
* authentication. After successful authentication, it generates a developer
|
|
79
|
+
* key for the user with a scope and expiration date.
|
|
80
|
+
*
|
|
81
|
+
* @param AddRegistryUserRequest $request the request object containing identity and password
|
|
82
|
+
*
|
|
83
|
+
* @return \Illuminate\Http\JsonResponse returns the newly created registry user data in JSON format
|
|
84
|
+
*/
|
|
85
|
+
public function addUser(AddRegistryUserRequest $request)
|
|
86
|
+
{
|
|
87
|
+
$identity = $request->input('identity');
|
|
88
|
+
$password = $request->input('password');
|
|
89
|
+
|
|
90
|
+
// Find user by email or username
|
|
91
|
+
$user = User::where(function ($query) use ($identity) {
|
|
92
|
+
$query->where('email', $identity)->orWhere('phone', $identity)->orWhere('username', $identity);
|
|
93
|
+
})->first();
|
|
94
|
+
|
|
95
|
+
// Authenticate user with password
|
|
96
|
+
if (Auth::isInvalidPassword($password, $user->password)) {
|
|
97
|
+
return response()->error('Invalid credentials.', 401);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Check if registry user already exists first
|
|
101
|
+
$registryUser = RegistryUser::where(['company_uuid' => $user->company_uuid, 'user_uuid' => $user->uuid])->first();
|
|
102
|
+
if (!$registryUser) {
|
|
103
|
+
// Create registry user
|
|
104
|
+
$registryUser = RegistryUser::create([
|
|
105
|
+
'company_uuid' => $user->company_uuid,
|
|
106
|
+
'user_uuid' => $user->uuid,
|
|
107
|
+
'scope' => '*',
|
|
108
|
+
'expires_at' => now()->addYear(),
|
|
109
|
+
'name' => $user->public_id . ' developer token',
|
|
110
|
+
]);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return response()->json($registryUser);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Checks if a user has access to the registry based on their identity.
|
|
118
|
+
*
|
|
119
|
+
* This function receives a request containing an 'identity' (which could be an email or username) and
|
|
120
|
+
* attempts to find a corresponding user. If the user is found and they have admin privileges, it grants access
|
|
121
|
+
* to the registry by returning a JSON response indicating that access is allowed. If the user doesn't have
|
|
122
|
+
* admin privileges or the user can't be found based on the provided identity, it returns an error response.
|
|
123
|
+
*
|
|
124
|
+
* @param RegistryAuthRequest $request the request containing the user's identity information
|
|
125
|
+
*
|
|
126
|
+
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
|
127
|
+
* Returns a JSON response indicating access is allowed if the user is an admin,
|
|
128
|
+
* or an error response if the user is not an admin or can't be found
|
|
129
|
+
*/
|
|
130
|
+
public function checkAccess(RegistryAuthRequest $request)
|
|
131
|
+
{
|
|
132
|
+
// Get identity
|
|
133
|
+
$identity = $request->input('identity');
|
|
134
|
+
|
|
135
|
+
// Find user by email or username
|
|
136
|
+
$user = User::where('email', $identity)->orWhere('username', $identity)->first();
|
|
137
|
+
|
|
138
|
+
// If user is not admin respond with error
|
|
139
|
+
if (!$user->isAdmin()) {
|
|
140
|
+
return response()->error('User is not allowed access to the registry.', 401);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// For now only admin users can access registry
|
|
144
|
+
return response()->json(['allowed' => true]);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Validates whether a user is allowed to publish or unpublish a specified package in the registry.
|
|
149
|
+
*
|
|
150
|
+
* This function extracts the user's identity, the package name, and the desired action ('publish' or 'unpublish')
|
|
151
|
+
* from the request. It then performs several checks:
|
|
152
|
+
* 1. Verifies that the specified package (extension) exists in the registry.
|
|
153
|
+
* 2. Confirms the existence of the user associated with the provided identity.
|
|
154
|
+
* 3. Checks if the user has administrative privileges.
|
|
155
|
+
* 4. Ensures that the extension's status allows the desired action (either 'approved' or 'published' for publishing,
|
|
156
|
+
* 'published' for unpublishing).
|
|
157
|
+
* If these conditions are met, the function updates the extension's status based on the action and returns a
|
|
158
|
+
* JSON response indicating the action is allowed. If any of these checks fail, it returns an error response.
|
|
159
|
+
*
|
|
160
|
+
* @param RegistryAuthRequest $request the request containing the user's identity, package information, and action
|
|
161
|
+
*
|
|
162
|
+
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
|
163
|
+
* Returns a JSON response indicating the action is allowed if all checks pass, or
|
|
164
|
+
* an error response if any check fails
|
|
165
|
+
*/
|
|
166
|
+
public function checkPublishAllowed(RegistryAuthRequest $request)
|
|
167
|
+
{
|
|
168
|
+
$identity = $request->input('identity');
|
|
169
|
+
$package = $request->input('package');
|
|
170
|
+
$action = $request->input('action', 'publish');
|
|
171
|
+
$force = $request->boolean('force');
|
|
172
|
+
$password = $request->input('password');
|
|
173
|
+
|
|
174
|
+
// If force publish bypass checks, authenticate by user login
|
|
175
|
+
if ($force === true) {
|
|
176
|
+
// Find user by email or username
|
|
177
|
+
$user = User::where(function ($query) use ($identity) {
|
|
178
|
+
$query->where('email', $identity)->orWhere('phone', $identity)->orWhere('username', $identity);
|
|
179
|
+
})->first();
|
|
180
|
+
|
|
181
|
+
// Authenticate user with password
|
|
182
|
+
if (Auth::isInvalidPassword($password, $user->password)) {
|
|
183
|
+
return response()->error('Invalid credentials, unable to force publish.', 401);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return response()->json(['allowed' => true]);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Make sure package is provided
|
|
190
|
+
if (!$package) {
|
|
191
|
+
return response()->error('No package specified for publish.', 401);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Find package
|
|
195
|
+
$extension = RegistryExtension::findByPackageName($package);
|
|
196
|
+
if (!$extension) {
|
|
197
|
+
return response()->error('Attempting to publish extension which has no record.', 401);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Find user by email or username
|
|
201
|
+
$user = User::where(function ($query) use ($identity) {
|
|
202
|
+
$query->where('email', $identity)->orWhere('phone', $identity)->orWhere('username', $identity);
|
|
203
|
+
})->first();
|
|
204
|
+
if (!$user) {
|
|
205
|
+
return response()->error('Attempting to publish extension with invalid user.', 401);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// If user is not admin respond with error
|
|
209
|
+
if (!$user->isAdmin()) {
|
|
210
|
+
return response()->error('User is not allowed publish to the registry.', 401);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Extension should be approved
|
|
214
|
+
if (!in_array($extension->status, ['approved', 'published'])) {
|
|
215
|
+
return response()->error('Attempting to publish extension which is not approved.', 401);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Change status to published
|
|
219
|
+
if ($action === 'publish') {
|
|
220
|
+
$extension->update(['status' => 'published']);
|
|
221
|
+
$extension->currentBundle()->update(['status' => 'published']);
|
|
222
|
+
} elseif ($action === 'unpublish') {
|
|
223
|
+
$extension->update(['status' => 'unpublished']);
|
|
224
|
+
$extension->currentBundle()->update(['status' => 'unpublished']);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Passed all checks
|
|
228
|
+
return response()->json(['allowed' => true]);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\RegistryBridge\Http\Controllers\Internal\v1;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\Http\Controllers\Controller;
|
|
6
|
+
use Fleetbase\Http\Resources\Category as CategoryResource;
|
|
7
|
+
use Fleetbase\Models\Category;
|
|
8
|
+
use Fleetbase\RegistryBridge\Models\RegistryExtension;
|
|
9
|
+
|
|
10
|
+
class RegistryController extends Controller
|
|
11
|
+
{
|
|
12
|
+
/**
|
|
13
|
+
* Retrieve a collection of categories that have registry extensions.
|
|
14
|
+
*
|
|
15
|
+
* This method fetches categories that have associated registry extensions
|
|
16
|
+
* and meet the specified criteria (core_category equals 1 and 'for' equals
|
|
17
|
+
* 'extension_category'). The retrieved categories are then wrapped using
|
|
18
|
+
* the CategoryResource and returned as a collection of CategoryResource.
|
|
19
|
+
*
|
|
20
|
+
* @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection
|
|
21
|
+
* A collection of CategoryResource objects representing the categories
|
|
22
|
+
*/
|
|
23
|
+
public function categories()
|
|
24
|
+
{
|
|
25
|
+
$categories = Category::whereHas('registryExtensions')->where(['core_category' => 1, 'for' => 'extension_category'])->get();
|
|
26
|
+
|
|
27
|
+
CategoryResource::wrap('categories');
|
|
28
|
+
|
|
29
|
+
return CategoryResource::collection($categories);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Retrieve a list of installed engines for the current company session.
|
|
34
|
+
*
|
|
35
|
+
* This method fetches registry extensions that have been installed by the
|
|
36
|
+
* company identified in the current session. It disables caching for the
|
|
37
|
+
* query, filters the results based on the company's UUID stored in the session,
|
|
38
|
+
* and maps the retrieved extensions to extract the 'package.json' metadata.
|
|
39
|
+
* The result is returned as a JSON response.
|
|
40
|
+
*
|
|
41
|
+
* @return \Illuminate\Http\JsonResponse
|
|
42
|
+
* A JSON response containing a list of installed engines with their metadata
|
|
43
|
+
*/
|
|
44
|
+
public function getInstalledEngines()
|
|
45
|
+
{
|
|
46
|
+
$installedExtensions = RegistryExtension::disableCache()->whereHas('installs', function ($query) {
|
|
47
|
+
$query->where('company_uuid', session('company'));
|
|
48
|
+
})->get()->map(function ($extension) {
|
|
49
|
+
return $extension->currentBundle->meta['package.json'] ?? [];
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
return response()->json($installedExtensions);
|
|
53
|
+
}
|
|
54
|
+
}
|