@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,76 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\RegistryBridge\Models;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\Casts\Json;
|
|
6
|
+
use Fleetbase\Models\Company;
|
|
7
|
+
use Fleetbase\Models\Model;
|
|
8
|
+
use Fleetbase\Traits\HasMetaAttributes;
|
|
9
|
+
use Fleetbase\Traits\HasUuid;
|
|
10
|
+
|
|
11
|
+
class RegistryExtensionInstall extends Model
|
|
12
|
+
{
|
|
13
|
+
use HasUuid;
|
|
14
|
+
use HasMetaAttributes;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The database table used by the model.
|
|
18
|
+
*
|
|
19
|
+
* @var string
|
|
20
|
+
*/
|
|
21
|
+
protected $table = 'registry_extension_installs';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The attributes that are mass assignable.
|
|
25
|
+
*/
|
|
26
|
+
protected $fillable = [
|
|
27
|
+
'uuid',
|
|
28
|
+
'company_uuid',
|
|
29
|
+
'extension_uuid',
|
|
30
|
+
'meta',
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The attributes that should be cast to native types.
|
|
35
|
+
*/
|
|
36
|
+
protected $casts = [
|
|
37
|
+
'meta' => Json::class,
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Dynamic attributes that are appended to object.
|
|
42
|
+
*
|
|
43
|
+
* @var array
|
|
44
|
+
*/
|
|
45
|
+
protected $appends = [];
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Relations that should be loaded with model.
|
|
49
|
+
*
|
|
50
|
+
* @var array
|
|
51
|
+
*/
|
|
52
|
+
protected $with = [];
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Relations that should not be loaded.
|
|
56
|
+
*
|
|
57
|
+
* @var array
|
|
58
|
+
*/
|
|
59
|
+
protected $without = ['company', 'extension'];
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
|
63
|
+
*/
|
|
64
|
+
public function company()
|
|
65
|
+
{
|
|
66
|
+
return $this->belongsTo(Company::class, 'company_uuid', 'uuid');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
|
71
|
+
*/
|
|
72
|
+
public function extension()
|
|
73
|
+
{
|
|
74
|
+
return $this->belongsTo(RegistryExtension::class, 'extension_uuid', 'uuid');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\RegistryBridge\Models;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\Casts\Json;
|
|
6
|
+
use Fleetbase\Casts\Money;
|
|
7
|
+
use Fleetbase\Models\Company;
|
|
8
|
+
use Fleetbase\Models\Model;
|
|
9
|
+
use Fleetbase\Traits\HasApiModelBehavior;
|
|
10
|
+
use Fleetbase\Traits\HasMetaAttributes;
|
|
11
|
+
use Fleetbase\Traits\HasUuid;
|
|
12
|
+
|
|
13
|
+
class RegistryExtensionPurchase extends Model
|
|
14
|
+
{
|
|
15
|
+
use HasUuid;
|
|
16
|
+
use HasMetaAttributes;
|
|
17
|
+
use HasApiModelBehavior;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The database table used by the model.
|
|
21
|
+
*
|
|
22
|
+
* @var string
|
|
23
|
+
*/
|
|
24
|
+
protected $table = 'registry_extension_purchases';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The attributes that are mass assignable.
|
|
28
|
+
*/
|
|
29
|
+
protected $fillable = [
|
|
30
|
+
'uuid',
|
|
31
|
+
'company_uuid',
|
|
32
|
+
'extension_uuid',
|
|
33
|
+
'stripe_checkout_session_id',
|
|
34
|
+
'stripe_payment_intent_id',
|
|
35
|
+
'is_subcription',
|
|
36
|
+
'locked_price',
|
|
37
|
+
'subscription_billing_period',
|
|
38
|
+
'subscription_model',
|
|
39
|
+
'meta',
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The attributes that should be cast to native types.
|
|
44
|
+
*/
|
|
45
|
+
protected $casts = [
|
|
46
|
+
'meta' => Json::class,
|
|
47
|
+
'locked_price' => Money::class,
|
|
48
|
+
'is_subcription' => 'boolean',
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Dynamic attributes that are appended to object.
|
|
53
|
+
*
|
|
54
|
+
* @var array
|
|
55
|
+
*/
|
|
56
|
+
protected $appends = [];
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Relations that should be loaded with model.
|
|
60
|
+
*
|
|
61
|
+
* @var array
|
|
62
|
+
*/
|
|
63
|
+
protected $with = [];
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Relations that should not be loaded.
|
|
67
|
+
*
|
|
68
|
+
* @var array
|
|
69
|
+
*/
|
|
70
|
+
protected $without = ['company', 'extension'];
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
|
74
|
+
*/
|
|
75
|
+
public function company()
|
|
76
|
+
{
|
|
77
|
+
return $this->belongsTo(Company::class, 'company_uuid', 'uuid');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
|
82
|
+
*/
|
|
83
|
+
public function extension()
|
|
84
|
+
{
|
|
85
|
+
return $this->belongsTo(RegistryExtension::class, 'extension_uuid', 'uuid');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\RegistryBridge\Models;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\Casts\Json;
|
|
6
|
+
use Fleetbase\Models\Company;
|
|
7
|
+
use Fleetbase\Models\Model;
|
|
8
|
+
use Fleetbase\Models\User;
|
|
9
|
+
use Fleetbase\Traits\Expirable;
|
|
10
|
+
use Fleetbase\Traits\HasMetaAttributes;
|
|
11
|
+
use Fleetbase\Traits\HasPublicId;
|
|
12
|
+
use Fleetbase\Traits\HasUuid;
|
|
13
|
+
|
|
14
|
+
class RegistryUser extends Model
|
|
15
|
+
{
|
|
16
|
+
use HasUuid;
|
|
17
|
+
use HasMetaAttributes;
|
|
18
|
+
use HasPublicId;
|
|
19
|
+
use Expirable;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The database table used by the model.
|
|
23
|
+
*
|
|
24
|
+
* @var string
|
|
25
|
+
*/
|
|
26
|
+
protected $table = 'registry_users';
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The type of public Id to generate.
|
|
30
|
+
*
|
|
31
|
+
* @var string
|
|
32
|
+
*/
|
|
33
|
+
protected $publicIdType = 'registry_user';
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The attributes that are mass assignable.
|
|
37
|
+
*
|
|
38
|
+
* @var array
|
|
39
|
+
*/
|
|
40
|
+
protected $fillable = [
|
|
41
|
+
'company_uuid',
|
|
42
|
+
'user_uuid',
|
|
43
|
+
'token',
|
|
44
|
+
'scope',
|
|
45
|
+
'expires_at',
|
|
46
|
+
'last_used_at',
|
|
47
|
+
'name',
|
|
48
|
+
'metadata',
|
|
49
|
+
'revoked',
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The attributes that should be cast to native types.
|
|
54
|
+
*
|
|
55
|
+
* @var array
|
|
56
|
+
*/
|
|
57
|
+
protected $casts = [
|
|
58
|
+
'meta' => Json::class,
|
|
59
|
+
'last_used_at' => 'datetime',
|
|
60
|
+
'expires_at' => 'datetime',
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Dynamic attributes that are appended to object.
|
|
65
|
+
*
|
|
66
|
+
* @var array
|
|
67
|
+
*/
|
|
68
|
+
protected $appends = [];
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* The attributes excluded from the model's JSON form.
|
|
72
|
+
*
|
|
73
|
+
* @var array
|
|
74
|
+
*/
|
|
75
|
+
protected $hidden = [];
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The "booting" method of the model.
|
|
79
|
+
*
|
|
80
|
+
* This method is called when the model is being booted and is used to define
|
|
81
|
+
* model event hooks. In this model, it is used to automatically generate and
|
|
82
|
+
* assign a unique token to the `token` field when creating a new RegistryUser
|
|
83
|
+
* instance. The token is generated only if it hasn't been set already, ensuring
|
|
84
|
+
* that manually specified tokens are respected.
|
|
85
|
+
*
|
|
86
|
+
* @return void
|
|
87
|
+
*/
|
|
88
|
+
protected static function boot()
|
|
89
|
+
{
|
|
90
|
+
parent::boot();
|
|
91
|
+
|
|
92
|
+
// Hook into the 'creating' event to set the token for new models
|
|
93
|
+
static::creating(function ($model) {
|
|
94
|
+
// Set the token only if it's not already set
|
|
95
|
+
if (empty($model->token)) {
|
|
96
|
+
$model->token = self::generateToken();
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
|
103
|
+
*/
|
|
104
|
+
public function company()
|
|
105
|
+
{
|
|
106
|
+
return $this->belongsTo(Company::class);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
|
111
|
+
*/
|
|
112
|
+
public function user()
|
|
113
|
+
{
|
|
114
|
+
return $this->belongsTo(User::class);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Generates a unique token for authenticating with the registry.
|
|
119
|
+
*
|
|
120
|
+
* This method creates a token prefixed with 'flb_' and ensures its uniqueness
|
|
121
|
+
* within the `registry_users` table. The token is generated using secure random
|
|
122
|
+
* bytes, converted to a hexadecimal string.
|
|
123
|
+
*
|
|
124
|
+
* @param int the length of the unique token string
|
|
125
|
+
*
|
|
126
|
+
* @return string the unique, generated token
|
|
127
|
+
*/
|
|
128
|
+
public static function generateToken(int $length = 18): string
|
|
129
|
+
{
|
|
130
|
+
do {
|
|
131
|
+
// Generate a random string and prepend with 'flb_'
|
|
132
|
+
$token = 'flb_' . bin2hex(random_bytes($length));
|
|
133
|
+
|
|
134
|
+
// Check if the token is unique in the database
|
|
135
|
+
$tokenExists = self::where('token', $token)->exists();
|
|
136
|
+
} while ($tokenExists);
|
|
137
|
+
|
|
138
|
+
return $token;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\RegistryBridge\Providers;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\Providers\CoreServiceProvider;
|
|
6
|
+
|
|
7
|
+
if (!class_exists(CoreServiceProvider::class)) {
|
|
8
|
+
throw new \Exception('Registry Bridge cannot be loaded without `fleetbase/core-api` installed!');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Registry Bridge service provider.
|
|
13
|
+
*/
|
|
14
|
+
class RegistryBridgeServiceProvider extends CoreServiceProvider
|
|
15
|
+
{
|
|
16
|
+
/**
|
|
17
|
+
* The observers registered with the service provider.
|
|
18
|
+
*
|
|
19
|
+
* @var array
|
|
20
|
+
*/
|
|
21
|
+
public $observers = [];
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The console commands registered with the service provider.
|
|
25
|
+
*
|
|
26
|
+
* @var array
|
|
27
|
+
*/
|
|
28
|
+
public $commands = [
|
|
29
|
+
\Fleetbase\RegistryBridge\Console\Commands\PostInstallExtension::class,
|
|
30
|
+
\Fleetbase\RegistryBridge\Console\Commands\Initialize::class,
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The middleware groups registered with the service provider.
|
|
35
|
+
*
|
|
36
|
+
* @var array
|
|
37
|
+
*/
|
|
38
|
+
public $middleware = [
|
|
39
|
+
'fleetbase.registry' => [
|
|
40
|
+
'throttle:60,1',
|
|
41
|
+
\Illuminate\Session\Middleware\StartSession::class,
|
|
42
|
+
\Fleetbase\Http\Middleware\AuthenticateOnceWithBasicAuth::class,
|
|
43
|
+
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
|
44
|
+
],
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Register any application services.
|
|
49
|
+
*
|
|
50
|
+
* Within the register method, you should only bind things into the
|
|
51
|
+
* service container. You should never attempt to register any event
|
|
52
|
+
* listeners, routes, or any other piece of functionality within the
|
|
53
|
+
* register method.
|
|
54
|
+
*
|
|
55
|
+
* More information on this can be found in the Laravel documentation:
|
|
56
|
+
* https://laravel.com/docs/8.x/providers
|
|
57
|
+
*
|
|
58
|
+
* @return void
|
|
59
|
+
*/
|
|
60
|
+
public function register()
|
|
61
|
+
{
|
|
62
|
+
$this->app->register(CoreServiceProvider::class);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Bootstrap any package services.
|
|
67
|
+
*
|
|
68
|
+
* @return void
|
|
69
|
+
*
|
|
70
|
+
* @throws \Exception if the `fleetbase/core-api` package is not installed
|
|
71
|
+
*/
|
|
72
|
+
public function boot()
|
|
73
|
+
{
|
|
74
|
+
static::bootRegistryAuth();
|
|
75
|
+
$this->registerCommands();
|
|
76
|
+
$this->registerMiddleware();
|
|
77
|
+
$this->registerExpansionsFrom(__DIR__ . '/../Expansions');
|
|
78
|
+
$this->loadRoutesFrom(__DIR__ . '/../routes.php');
|
|
79
|
+
$this->loadMigrationsFrom(__DIR__ . '/../../migrations');
|
|
80
|
+
$this->mergeConfigFrom(__DIR__ . '/../../config/registry-bridge.php', 'registry-bridge');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Initializes and sets up the npm registry authentication configuration.
|
|
85
|
+
*
|
|
86
|
+
* This method constructs the registry authentication string from configuration settings,
|
|
87
|
+
* checks for the existence of an npmrc file in the user's home directory, and creates it
|
|
88
|
+
* with the registry authentication string if it doesn't already exist.
|
|
89
|
+
*
|
|
90
|
+
* The registry configuration and token are pulled from the application's configuration files.
|
|
91
|
+
* It ensures the path to the .npmrc file is correctly formed regardless of trailing slashes
|
|
92
|
+
* in the HOME directory path or the registry host configuration.
|
|
93
|
+
*
|
|
94
|
+
* @param bool $reset - Overwrites existing file, "resetting" the .npmrc
|
|
95
|
+
*
|
|
96
|
+
* @return void
|
|
97
|
+
*/
|
|
98
|
+
public static function bootRegistryAuth(bool $reset = false)
|
|
99
|
+
{
|
|
100
|
+
$homeDirectory = rtrim(getenv('HOME'), '/');
|
|
101
|
+
$authPath = $homeDirectory . '/.npmrc';
|
|
102
|
+
$authString = '//' . str_replace(['http://', 'https://'], '', rtrim(config('registry-bridge.registry.host'), '/')) . '/:_authToken="' . config('registry-bridge.registry.token') . '"' . PHP_EOL;
|
|
103
|
+
if (!file_exists($authPath) || $reset === true) {
|
|
104
|
+
file_put_contents($authPath, $authString);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
$consolePath = rtrim(config('fleetbase.console.path'), '/');
|
|
108
|
+
$registryPath = $consolePath . '/.npmrc';
|
|
109
|
+
$registryString = implode(PHP_EOL, [
|
|
110
|
+
'registry=https://registry.npmjs.org/',
|
|
111
|
+
'@fleetbase:registry=' . rtrim(config('registry-bridge.registry.host'), '/') . '/',
|
|
112
|
+
]) . PHP_EOL;
|
|
113
|
+
if (!file_exists($registryPath) || $reset === true) {
|
|
114
|
+
file_put_contents($registryPath, $registryString);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\RegistryBridge\Support;
|
|
4
|
+
|
|
5
|
+
use Illuminate\Support\Facades\Http;
|
|
6
|
+
|
|
7
|
+
class Bridge
|
|
8
|
+
{
|
|
9
|
+
/**
|
|
10
|
+
* Creates a complete URL by concatenating the base URL from the configuration with the provided URI.
|
|
11
|
+
*
|
|
12
|
+
* This method ensures that the base URL from the configuration has a trailing slash before
|
|
13
|
+
* concatenating it with the provided URI. It handles URL formation for making HTTP requests.
|
|
14
|
+
*
|
|
15
|
+
* @param string $uri the specific URI to append to the base URL
|
|
16
|
+
*
|
|
17
|
+
* @return string the complete URL formed by concatenating the base URL and the provided URI
|
|
18
|
+
*/
|
|
19
|
+
private static function createUrl(string $uri = ''): string
|
|
20
|
+
{
|
|
21
|
+
$url = config('registry-bridge.registry.host');
|
|
22
|
+
|
|
23
|
+
return rtrim($url, '/') . '/' . $uri;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Sends a GET request to the specified URI.
|
|
28
|
+
*
|
|
29
|
+
* @param string $uri URI to send the GET request to
|
|
30
|
+
* @param array $parameters parameters to include in the request
|
|
31
|
+
* @param array $options additional options for the HTTP client
|
|
32
|
+
*
|
|
33
|
+
* @return \Illuminate\Http\Client\Response
|
|
34
|
+
*/
|
|
35
|
+
public static function get($uri, $parameters = [], $options = [])
|
|
36
|
+
{
|
|
37
|
+
return Http::withOptions($options)->get(static::createUrl($uri), $parameters);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Sends a POST request to the specified URI.
|
|
42
|
+
*
|
|
43
|
+
* @param string $uri URI to send the GET request to
|
|
44
|
+
* @param array $parameters parameters to include in the request
|
|
45
|
+
* @param array $options additional options for the HTTP client
|
|
46
|
+
*
|
|
47
|
+
* @return \Illuminate\Http\Client\Response
|
|
48
|
+
*/
|
|
49
|
+
public static function post($uri, $parameters = [], $options = [])
|
|
50
|
+
{
|
|
51
|
+
return Http::withOptions($options)->post(static::createUrl($uri), $parameters);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\RegistryBridge\Support;
|
|
4
|
+
|
|
5
|
+
use Stripe\StripeClient;
|
|
6
|
+
|
|
7
|
+
class Utils
|
|
8
|
+
{
|
|
9
|
+
/**
|
|
10
|
+
* Get the StripeClient instance.
|
|
11
|
+
*/
|
|
12
|
+
public static function getStripeClient(array $options = []): ?StripeClient
|
|
13
|
+
{
|
|
14
|
+
return new StripeClient([
|
|
15
|
+
'api_key' => config('registry-bridge.stripe.secret'),
|
|
16
|
+
...$options,
|
|
17
|
+
]);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
use Illuminate\Support\Facades\Route;
|
|
4
|
+
|
|
5
|
+
/*
|
|
6
|
+
|--------------------------------------------------------------------------
|
|
7
|
+
| API Routes
|
|
8
|
+
|--------------------------------------------------------------------------
|
|
9
|
+
|
|
|
10
|
+
| Here is where you can register API routes for your application. These
|
|
11
|
+
| routes are loaded by the RouteServiceProvider within a group which
|
|
12
|
+
| is assigned the "api" middleware group. Enjoy building your API!
|
|
13
|
+
|
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
Route::get('~registry/test', 'Fleetbase\RegistryBridge\Http\Controllers\Internal\v1\RegistryAuthController@test');
|
|
17
|
+
|
|
18
|
+
Route::prefix(config('internals.api.routing.prefix', '~registry'))->middleware(['fleetbase.registry'])->namespace('Fleetbase\RegistryBridge\Http\Controllers')->group(
|
|
19
|
+
function ($router) {
|
|
20
|
+
/*
|
|
21
|
+
* Internal Routes v1
|
|
22
|
+
*/
|
|
23
|
+
$router->group(['prefix' => config('internals.api.routing.internal_prefix', 'v1'), 'namespace' => 'Internal\v1'], function ($router) {
|
|
24
|
+
$router->get('categories', 'RegistryController@categories');
|
|
25
|
+
$router->get('engines', 'RegistryController@getInstalledEngines');
|
|
26
|
+
$router->group(['prefix' => 'installer'], function ($router) {
|
|
27
|
+
$router->post('install', 'ExtensionInstallerController@install');
|
|
28
|
+
$router->post('uninstall', 'ExtensionInstallerController@uninstall');
|
|
29
|
+
});
|
|
30
|
+
$router->group(['prefix' => 'auth'], function ($router) {
|
|
31
|
+
$router->post('authenticate', 'RegistryAuthController@authenticate');
|
|
32
|
+
$router->post('add-user', 'RegistryAuthController@addUser');
|
|
33
|
+
$router->post('check-access', 'RegistryAuthController@checkAccess');
|
|
34
|
+
$router->post('check-publish', 'RegistryAuthController@checkPublishAllowed');
|
|
35
|
+
});
|
|
36
|
+
$router->group(['prefix' => 'payments'], function ($router) {
|
|
37
|
+
$router->post('account', 'RegistryPaymentsController@getStripeAccount');
|
|
38
|
+
$router->post('account-session', 'RegistryPaymentsController@getStripeAccountSession');
|
|
39
|
+
$router->get('has-stripe-connect-account', 'RegistryPaymentsController@hasStripeConnectAccount');
|
|
40
|
+
$router->post('create-checkout-session', 'RegistryPaymentsController@createStripeCheckoutSession');
|
|
41
|
+
$router->post('get-checkout-session', 'RegistryPaymentsController@getStripeCheckoutSessionStatus');
|
|
42
|
+
$router->get('author-received', 'RegistryPaymentsController@getAuthorReceivedPayments');
|
|
43
|
+
});
|
|
44
|
+
$router->fleetbaseRoutes('registry-extensions', function ($router, $controller) {
|
|
45
|
+
$router->post('{id}/submit', $controller('submit'));
|
|
46
|
+
$router->post('approve', $controller('approve'));
|
|
47
|
+
$router->post('reject', $controller('reject'));
|
|
48
|
+
$router->get('download-bundle', $controller('downloadBundle'));
|
|
49
|
+
$router->get('analytics', $controller('analytics'));
|
|
50
|
+
$router->get('installed', $controller('installed'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
|
|
51
|
+
$router->get('purchased', $controller('purchased'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
|
|
52
|
+
});
|
|
53
|
+
$router->fleetbaseRoutes('registry-extension-bundles', function ($router, $controller) {
|
|
54
|
+
$router->get('download', $controller('download'));
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
);
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
registry-bridge:
|
|
2
|
+
extension-name: Registry Bridge
|
|
3
|
+
common:
|
|
4
|
+
install: Install
|
|
5
|
+
uninstall: Uninstall
|
|
6
|
+
approve: Approve
|
|
7
|
+
reject: Reject
|
|
8
|
+
details: Details
|
|
9
|
+
about: About
|
|
10
|
+
about-extension: About {extensionName}
|
|
11
|
+
component:
|
|
12
|
+
extension-pending-publish-viewer:
|
|
13
|
+
content-panel-title: Extensions Pending Publish
|
|
14
|
+
focused-extension-title: >
|
|
15
|
+
{extensionName} Details
|
|
16
|
+
download-bundle: Download Bundle
|
|
17
|
+
view-details: View Details
|
|
18
|
+
no-extensions-awaiting-publish: No extensions awaiting publish
|
|
19
|
+
extension-reviewer-control:
|
|
20
|
+
content-panel-title: Extensions Awaiting Review
|
|
21
|
+
focused-extension-title: >
|
|
22
|
+
{extensionName} Details
|
|
23
|
+
approve-confirm-title: Are you sure you want to approve this extension?
|
|
24
|
+
approve-confirm-body: This extension should be thoroughly tested in both a development and test environment and tested for compliance as well as security issues. Once approved the extension will need to be manually published to the registry.
|
|
25
|
+
decline-confirm-title: Are you sure you want to reject this extension?
|
|
26
|
+
decline-confirm-body: This extension will be rejected, but the author will be given a chance to make corrections and re-submit for review.
|
|
27
|
+
download-bundle: Download Bundle
|
|
28
|
+
view-details: View Details
|
|
29
|
+
approve: Approve
|
|
30
|
+
reject: Reject
|
|
31
|
+
no-extensions-awaiting-review: No extensions awaiting review
|
|
32
|
+
installed:
|
|
33
|
+
title: Installed Extensions
|
|
34
|
+
purchased:
|
|
35
|
+
title: Purchased Extensions
|
|
36
|
+
developers:
|
|
37
|
+
extensions:
|
|
38
|
+
extensions: Extensions
|
|
39
|
+
create-new-extension: Create new Extension
|
|
40
|
+
new-extension: New Extension
|
|
41
|
+
extension: Extension
|
|
42
|
+
submission: Submission
|
|
43
|
+
details: Details
|
|
44
|
+
bundles: Bundles
|
|
45
|
+
monetize: Monetize
|
|
46
|
+
explore:
|
|
47
|
+
explore-extensions: Explore Extensions
|
|
48
|
+
explore-category-extensions: >
|
|
49
|
+
{categoryName} Extensions
|
|
50
|
+
extension-form:
|
|
51
|
+
package-name: Package Name
|
|
52
|
+
package-json-name: package.json name
|
|
53
|
+
composer-json-name: composer.json name
|
|
54
|
+
submission-success-message: Extension submitted and is awaiting review.
|
|
55
|
+
extension-category: Category
|
|
56
|
+
extension-category-help-text: Select the category in which users will be able to find your extension.
|
|
57
|
+
extension-select-category: Select Category
|
|
58
|
+
extension-name: Extension Name
|
|
59
|
+
extension-icon: Extension Icon
|
|
60
|
+
upload-extension-icon: Upload Icon
|
|
61
|
+
extension-description: Description
|
|
62
|
+
extension-tags: Tags
|
|
63
|
+
extension-add-tags: Add keywords and tags
|
|
64
|
+
extension-promotional-text: Promotional Text
|
|
65
|
+
details-content-block: Extension Details
|
|
66
|
+
extension-listing-details: Listing Details
|
|
67
|
+
extension-subtitle: Subtitle
|
|
68
|
+
extension-website-url: Website URL
|
|
69
|
+
extension-repo-url: Repository URL
|
|
70
|
+
extension-support-url: Support URL
|
|
71
|
+
extension-privacy-policy-url: Privacy Policy URL
|
|
72
|
+
extension-tos-url: Terms of Service URL
|
|
73
|
+
extension-primary-language: Primary Language
|
|
74
|
+
extension-version: Version
|
|
75
|
+
extension-copyright: Copyright
|
|
76
|
+
extension-copyright-help-text: Enter the copyright notice for your extension. This typically includes the year and the name of the copyright owner or company.
|
|
77
|
+
extension-payment-required: Payment Required
|
|
78
|
+
extension-payment-required-help-text: Determines if payment or subscription is required for users to install this extension.
|
|
79
|
+
extension-price: Price
|
|
80
|
+
extension-price-help-text: Specify the regular price of the extension. This is the standard cost for users to purchase or access the extension.
|
|
81
|
+
extension-sale-price: Sale Price
|
|
82
|
+
extension-sale-price-help-text: If the extension is currently offered at a discounted rate, enter the sale price here. This should be less than the regular price.
|
|
83
|
+
extension-subscription-required: Subscription Required
|
|
84
|
+
extension-subscription-required-help-text: Determines if user must have a subscription to install and use this extension.
|
|
85
|
+
extension-subscription-billing-period: Subscription Billing Period
|
|
86
|
+
extension-subscription-billing-period-placeholder: Select Billing Period
|
|
87
|
+
extension-subscription-billing-period-help-text: Specify the billing period for the subscription. Examples include monthly, quarterly, annually, or other custom intervals.
|
|
88
|
+
extension-subscription-amount: Subscription Amount
|
|
89
|
+
extension-subscription-amount-help-text: Enter the standard amount to be charged for the subscription. This should reflect the regular price before any discounts or tiered pricing adjustments.
|
|
90
|
+
extension-subscription-model: Subscription Model
|
|
91
|
+
extension-subscription-model-help-text: Determines the type of subscription pricing model to follow. Options include flate rate, tiered, and usage based subscription.
|
|
92
|
+
extension-subscription-tiers: Subscription Tiers
|
|
93
|
+
extension-subscription-tiers-help-text: Define the different pricing tiers for the subscription, if applicable. Include details like the tier levels, pricing for each tier, and any specific features or limitations of each tier.
|
|
94
|
+
extension-name-help-text: Enter the official name of the extension. This will be displayed as the primary identifier for users.
|
|
95
|
+
extension-icon-help-text: Upload an icon representing the extension. This icon will be used in listings and search results.
|
|
96
|
+
extension-description-help-text: Provide a detailed description of what the extension does and its key features. This information helps users understand the extension's functionality.
|
|
97
|
+
extension-tags-help-text: Add relevant keywords and tags that describe the extension, helping users find it through search.
|
|
98
|
+
extension-promotional-text-help-text: Write promotional text to highlight the extension's unique selling points. This text will be used in marketing or featured sections.
|
|
99
|
+
extension-subtitle-help-text: Provide a brief subtitle that offers additional context or information about the extension.
|
|
100
|
+
extension-website-url-help-text: Enter the URL to the extension's official website or product page for more information.
|
|
101
|
+
extension-repo-url-help-text: Provide the URL to the extension's code repository (e.g., GitHub, GitLab), if applicable.
|
|
102
|
+
extension-support-url-help-text: Specify the URL where users can obtain support, ask questions, or report issues with the extension.
|
|
103
|
+
extension-privacy-policy-url-help-text: Link to the privacy policy document that details how user data is handled and protected.
|
|
104
|
+
extension-tos-url-help-text: Link to the Terms of Service document that users must agree to before using the extension.
|
|
105
|
+
extension-primary-language-help-text: Specify the primary language the extension is developed or available in.
|
|
106
|
+
extension-version-help-text: Indicate the current version of the extension. This is important for tracking updates and compatibility.
|
|
107
|
+
extension-payment-details: Payment Details
|
|
108
|
+
extension-screenshots: Screenshots
|
|
109
|
+
upload-screenshots: Upload Screenshots
|
|
110
|
+
submit-for-review: Submit for Review
|
|
111
|
+
extension-bundle: Extension Bundle
|
|
112
|
+
extension-upload-bundle: Upload Extension Bundle
|
|
113
|
+
details: Details
|
|
114
|
+
bundle-id: Bundle ID
|
|
115
|
+
bundle-id-help-text: The identifier of the currently published bundle.
|
|
116
|
+
extension-id: Extension ID
|
|
117
|
+
extension-id-help-text: The unique identifier for this extension.
|
|
118
|
+
bundles: Bundles
|
|
119
|
+
upload-new-bundle: Upload new Bundle
|