@fleetbase/registry-bridge-engine 0.0.11 → 0.0.13
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/addon/components/extension-card.hbs +5 -0
- package/addon/components/extension-card.js +54 -3
- package/addon/components/extension-form.hbs +20 -2
- package/addon/components/extension-form.js +57 -0
- package/addon/components/modals/extension-details.hbs +40 -18
- package/addon/components/modals/self-managed-install-instructions.hbs +40 -0
- package/addon/controllers/installed.js +2 -0
- package/addon/engine.js +1 -1
- package/addon/models/registry-extension.js +2 -0
- package/addon/routes/application.js +11 -0
- package/addon/routes/developers/analytics.js +11 -0
- package/addon/routes/developers/credentials.js +11 -0
- package/addon/routes/developers/extensions/edit.js +11 -0
- package/addon/routes/developers/extensions/index.js +11 -0
- package/addon/routes/developers/extensions/new.js +14 -1
- package/addon/routes/developers/extensions.js +14 -1
- package/addon/routes/developers/payments/index.js +11 -0
- package/addon/routes/developers/payments/onboard.js +8 -1
- package/addon/routes/developers/payments.js +14 -1
- package/addon/routes/explore/category.js +11 -0
- package/addon/routes/explore/index.js +11 -0
- package/addon/routes/installed.js +11 -0
- package/addon/routes/purchased.js +11 -0
- package/addon/styles/registry-bridge-engine.css +137 -0
- package/addon/templates/application.hbs +9 -15
- package/addon/templates/developers/analytics.hbs +2 -0
- package/addon/templates/developers/credentials.hbs +1 -1
- package/addon/templates/developers/extensions/edit.hbs +2 -1
- package/addon/templates/developers/extensions/index.hbs +1 -1
- package/addon/templates/developers/extensions/new.hbs +1 -1
- package/addon/templates/developers/payments/index.hbs +1 -1
- package/app/components/modals/self-managed-install-instructions.js +1 -0
- package/composer.json +2 -2
- package/extension.json +1 -1
- package/package.json +4 -3
- package/server/migrations/2024_08_02_072214_add_self_managed_column_to_registry_extensions_table.php +28 -0
- package/server/src/Auth/Schemas/RegistryBridge.php +215 -0
- package/server/src/Http/Controllers/Internal/v1/RegistryController.php +46 -0
- package/server/src/Models/RegistryExtension.php +45 -0
- package/server/src/Models/RegistryExtensionBundle.php +2 -2
- package/server/src/routes.php +2 -1
- package/translations/en-us.yaml +14 -1
|
@@ -3,6 +3,17 @@ import { inject as service } from '@ember/service';
|
|
|
3
3
|
|
|
4
4
|
export default class InstalledRoute extends Route {
|
|
5
5
|
@service fetch;
|
|
6
|
+
@service notifications;
|
|
7
|
+
@service hostRouter;
|
|
8
|
+
@service abilities;
|
|
9
|
+
@service intl;
|
|
10
|
+
|
|
11
|
+
beforeModel() {
|
|
12
|
+
if (this.abilities.cannot('registry-bridge list extension-install')) {
|
|
13
|
+
this.notifications.warning(this.intl.t('common.unauthorized-access'));
|
|
14
|
+
return this.hostRouter.transitionTo('console');
|
|
15
|
+
}
|
|
16
|
+
}
|
|
6
17
|
|
|
7
18
|
model(params = {}) {
|
|
8
19
|
return this.fetch.get('registry-extensions/installed', params, { namespace: '~registry/v1', normalizeToEmberData: true, modelType: 'registry-extension' });
|
|
@@ -3,6 +3,17 @@ import { inject as service } from '@ember/service';
|
|
|
3
3
|
|
|
4
4
|
export default class PurchasedRoute extends Route {
|
|
5
5
|
@service fetch;
|
|
6
|
+
@service notifications;
|
|
7
|
+
@service hostRouter;
|
|
8
|
+
@service abilities;
|
|
9
|
+
@service intl;
|
|
10
|
+
|
|
11
|
+
beforeModel() {
|
|
12
|
+
if (this.abilities.cannot('registry-bridge list extension-purchase')) {
|
|
13
|
+
this.notifications.warning(this.intl.t('common.unauthorized-access'));
|
|
14
|
+
return this.hostRouter.transitionTo('console');
|
|
15
|
+
}
|
|
16
|
+
}
|
|
6
17
|
|
|
7
18
|
model(params = {}) {
|
|
8
19
|
return this.fetch.get('registry-extensions/purchased', params, { namespace: '~registry/v1', normalizeToEmberData: true, modelType: 'registry-extension' });
|
|
@@ -140,3 +140,140 @@ body[data-theme='dark'] .extension-card-container > .extension-card-body-contain
|
|
|
140
140
|
margin-left: 2rem;
|
|
141
141
|
margin-bottom: 2rem;
|
|
142
142
|
}
|
|
143
|
+
|
|
144
|
+
.self-managed-install-instructions {
|
|
145
|
+
list-style: decimal;
|
|
146
|
+
color: #000;
|
|
147
|
+
padding-left: 30px;
|
|
148
|
+
font-size: 0.85rem;
|
|
149
|
+
line-height: 1rem;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.self-managed-install-instructions > li {
|
|
153
|
+
padding-bottom: 1.5rem;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
body[data-theme='dark'] .self-managed-install-instructions {
|
|
157
|
+
list-style: decimal;
|
|
158
|
+
color: #fff;
|
|
159
|
+
padding-left: 30px;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.self-managed-install-instructions code {
|
|
163
|
+
display: flex;
|
|
164
|
+
font-family: monospace;
|
|
165
|
+
padding: 0.25rem 0.75rem;
|
|
166
|
+
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 5%);
|
|
167
|
+
background-color: #1f2937;
|
|
168
|
+
border: 1px #374151 solid;
|
|
169
|
+
color: #86efac;
|
|
170
|
+
border-radius: 0.5rem;
|
|
171
|
+
font-size: 0.75rem;
|
|
172
|
+
line-height: 1rem;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.extension-details-promo-content {
|
|
176
|
+
padding: 0.5rem;
|
|
177
|
+
background-color: #f9fafb;
|
|
178
|
+
color: #000;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
body[data-theme='dark'] .extension-details-promo-content {
|
|
182
|
+
padding: 0.5rem;
|
|
183
|
+
background-color: #111827;
|
|
184
|
+
color: #f9fafb;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.extension-details-promo-content hr {
|
|
188
|
+
border: none;
|
|
189
|
+
border-top: 1px solid #e5e7eb;
|
|
190
|
+
margin: 0.5rem 0;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
body[data-theme='dark'] .extension-details-promo-content hr {
|
|
194
|
+
border-top: 1px solid #374151;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.extension-details-promo-content ol,
|
|
198
|
+
.extension-details-promo-content ul {
|
|
199
|
+
padding-left: 25px;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.extension-details-promo-content ol {
|
|
203
|
+
list-style: decimal;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.extension-details-promo-content ul {
|
|
207
|
+
list-style: disc;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.extension-details-promo-content blockquote {
|
|
211
|
+
border-left: 3px #e2e8f0 solid;
|
|
212
|
+
padding-left: 0.5rem;
|
|
213
|
+
margin-left: 0.25rem;
|
|
214
|
+
font-style: italic;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
body[data-theme='dark'] .extension-details-promo-content blockquote {
|
|
218
|
+
border-left: 3px #4b5563 solid;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.extension-details-promo-content pre {
|
|
222
|
+
white-space: pre;
|
|
223
|
+
font-family: monospace;
|
|
224
|
+
padding: 0.25rem 0.75rem;
|
|
225
|
+
border-radius: 0.25rem;
|
|
226
|
+
background-color: #f3f4f6;
|
|
227
|
+
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 5%);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
body[data-theme='dark'] .extension-details-promo-content pre {
|
|
231
|
+
background-color: #1f2937;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.extension-details-promo-content pre > code {
|
|
235
|
+
font-family: monospace;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.extension-details-promo-content table {
|
|
239
|
+
border-collapse: collapse;
|
|
240
|
+
margin: 0;
|
|
241
|
+
overflow: hidden;
|
|
242
|
+
table-layout: fixed;
|
|
243
|
+
width: 100%;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.extension-details-promo-content table td,
|
|
247
|
+
.extension-details-promo-content table th {
|
|
248
|
+
border: 1px solid #d1d5db;
|
|
249
|
+
box-sizing: border-box;
|
|
250
|
+
min-width: 1em;
|
|
251
|
+
padding: 6px 8px;
|
|
252
|
+
position: relative;
|
|
253
|
+
vertical-align: top;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
body[data-theme='dark'] .extension-details-promo-content table td,
|
|
257
|
+
body[data-theme='dark'] .extension-details-promo-content table th {
|
|
258
|
+
border: 1px solid #374151;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
.extension-details-promo-content table td > *,
|
|
262
|
+
.extension-details-promo-content table th > * {
|
|
263
|
+
margin-bottom: 0;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.extension-details-promo-content table th {
|
|
267
|
+
background-color: #e5e7eb;
|
|
268
|
+
font-weight: bold;
|
|
269
|
+
text-align: left;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
body[data-theme='dark'] .extension-details-promo-content table th {
|
|
273
|
+
background-color: #1f2937;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.extension-details-promo-content .tableWrapper {
|
|
277
|
+
margin: 1.5rem 0;
|
|
278
|
+
overflow-x: auto;
|
|
279
|
+
}
|
|
@@ -1,23 +1,17 @@
|
|
|
1
1
|
<EmberWormhole @to="sidebar-menu-items">
|
|
2
|
-
<Layout::Sidebar::Item @route="console.extensions.installed" @icon="inbox">Installed</Layout::Sidebar::Item>
|
|
3
|
-
<Layout::Sidebar::Item @route="console.extensions.purchased" @icon="bag-shopping">Purchased</Layout::Sidebar::Item>
|
|
4
|
-
<Layout::Sidebar::Panel @open={{true}} @title="Explore">
|
|
5
|
-
<Layout::Sidebar::Item @route="console.extensions.explore.index" @icon="shapes">Explore All</Layout::Sidebar::Item>
|
|
2
|
+
<Layout::Sidebar::Item @route="console.extensions.installed" @icon="inbox" @permission="registry-bridge list extension-install" @visible={{can "registry-bridge see extension-install"}}>Installed</Layout::Sidebar::Item>
|
|
3
|
+
<Layout::Sidebar::Item @route="console.extensions.purchased" @icon="bag-shopping" @permission="registry-bridge list extension-purchase" @visible={{can "registry-bridge see extension-purchase"}}>Purchased</Layout::Sidebar::Item>
|
|
4
|
+
<Layout::Sidebar::Panel @open={{true}} @title="Explore" @visible={{can "registry-bridge see extension"}}>
|
|
5
|
+
<Layout::Sidebar::Item @route="console.extensions.explore.index" @icon="shapes" @permission="registry-bridge list extension">Explore All</Layout::Sidebar::Item>
|
|
6
6
|
{{#each this.categories as |category|}}
|
|
7
|
-
<
|
|
8
|
-
<div class="next-nav-item-icon-container">
|
|
9
|
-
<FaIcon @icon={{category.icon}} @size="sm" />
|
|
10
|
-
</div>
|
|
11
|
-
<div class="truncate w-10/12">{{category.name}}</div>
|
|
12
|
-
<div class="next-nav-item-right-side"></div>
|
|
13
|
-
</LinkTo>
|
|
7
|
+
<Layout::Sidebar::Item @route="console.extensions.explore.category" @model={{category}} @icon={{category.icon}} @permission="registry-bridge list extension">{{category.name}}</Layout::Sidebar::Item>
|
|
14
8
|
{{/each}}
|
|
15
9
|
</Layout::Sidebar::Panel>
|
|
16
10
|
<Layout::Sidebar::Panel @open={{true}} @title="Developers">
|
|
17
|
-
<Layout::Sidebar::Item @route="console.extensions.developers.extensions" @icon="box-archive">Extensions</Layout::Sidebar::Item>
|
|
18
|
-
<Layout::Sidebar::Item @route="console.extensions.developers.analytics" @icon="chart-simple">Analytics</Layout::Sidebar::Item>
|
|
19
|
-
<Layout::Sidebar::Item @route="console.extensions.developers.payments" @icon="cash-register">Payments</Layout::Sidebar::Item>
|
|
20
|
-
<Layout::Sidebar::Item @route="console.extensions.developers.credentials" @icon="key">Credentials</Layout::Sidebar::Item>
|
|
11
|
+
<Layout::Sidebar::Item @route="console.extensions.developers.extensions" @icon="box-archive" @permission="registry-bridge list extension-bundle" @visible={{can "registry-bridge see extension-bundle"}}>Extensions</Layout::Sidebar::Item>
|
|
12
|
+
<Layout::Sidebar::Item @route="console.extensions.developers.analytics" @icon="chart-simple" @permission="registry-bridge list extension-analytic" @visible={{can "registry-bridge see extension-analytic"}}>Analytics</Layout::Sidebar::Item>
|
|
13
|
+
<Layout::Sidebar::Item @route="console.extensions.developers.payments" @icon="cash-register" @permission="registry-bridge list extension-payment" @visible={{can "registry-bridge see extension-payment"}}>Payments</Layout::Sidebar::Item>
|
|
14
|
+
<Layout::Sidebar::Item @route="console.extensions.developers.credentials" @icon="key" @permission="registry-bridge list registry-token" @visible={{can "registry-bridge see registry-token"}}>Credentials</Layout::Sidebar::Item>
|
|
21
15
|
</Layout::Sidebar::Panel>
|
|
22
16
|
<Spacer @height="200px" />
|
|
23
17
|
</EmberWormhole>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<Layout::Section::Header @title="Credentials">
|
|
2
|
-
<Button @type="primary" @icon="plus" @iconPrefix="fas" @text="Create new credentials" class="mr-2" @onClick={{this.createCredentials}} />
|
|
2
|
+
<Button @type="primary" @icon="plus" @iconPrefix="fas" @text="Create new credentials" class="mr-2" @onClick={{this.createCredentials}} @permission="registry-bridge create registry-token" />
|
|
3
3
|
</Layout::Section::Header>
|
|
4
4
|
|
|
5
5
|
<Layout::Section::Body class="overflow-y-scroll h-full">
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<Badge @status={{@model.status}} />
|
|
4
4
|
</div>
|
|
5
5
|
<Button @type="default" @size="sm" @icon="arrow-left" @text={{t "common.back"}} @onClick={{transition-to "developers.extensions"}} @wrapperClass="mr-2" />
|
|
6
|
-
<Button @type="primary" @size="sm" @icon="save" @text={{t "common.save"}} @onClick={{perform this.save}} @isLoading={{not this.save.isIdle}} @wrapperClass="mr-2" />
|
|
6
|
+
<Button @type="primary" @size="sm" @icon="save" @text={{t "common.save"}} @onClick={{perform this.save}} @isLoading={{not this.save.isIdle}} @wrapperClass="mr-2" @permission="registry-bridge update registry-bundle" />
|
|
7
7
|
<Button
|
|
8
8
|
@type="magic"
|
|
9
9
|
@size="sm"
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
@onClick={{this.submitForReview}}
|
|
14
14
|
@disabled={{not this.isReady}}
|
|
15
15
|
@isLoading={{not this.startReview.isIdle}}
|
|
16
|
+
@permission="registry-bridge submit registry-bundle"
|
|
16
17
|
/>
|
|
17
18
|
</Layout::Section::Header>
|
|
18
19
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<Layout::Section::Header @title={{t "registry-bridge.developers.extensions.extensions"}}>
|
|
2
|
-
<Button @type="primary" @size="sm" @icon="circle-plus" @text={{t "registry-bridge.developers.extensions.create-new-extension"}} @onClick={{transition-to "developers.extensions.new"}} />
|
|
2
|
+
<Button @type="primary" @size="sm" @icon="circle-plus" @text={{t "registry-bridge.developers.extensions.create-new-extension"}} @onClick={{transition-to "developers.extensions.new"}} @permission="registry-bridge create registry-bundle" />
|
|
3
3
|
</Layout::Section::Header>
|
|
4
4
|
|
|
5
5
|
<Layout::Section::Body class="overflow-y-scroll h-full">
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
</InputGroup>
|
|
30
30
|
</ContentPanel>
|
|
31
31
|
<div class="mt-4 flex items-center space-x-4">
|
|
32
|
-
<Button @size="lg" @type="primary" @text="Continue" @icon="check" @onClick={{perform this.save}} @isLoading={{not this.save.isIdle}} />
|
|
32
|
+
<Button @size="lg" @type="primary" @text="Continue" @icon="check" @onClick={{perform this.save}} @isLoading={{not this.save.isIdle}} @permission="registry-bridge create registry-bundle" />
|
|
33
33
|
<Button @size="lg" @type="default" @text="Cancel" @icon="times" @onClick={{this.cancel}} />
|
|
34
34
|
</div>
|
|
35
35
|
</div>
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
<div class="flex flex-col items-center justify-center">
|
|
33
33
|
<h1 class="text-lg font-semibold mb-1">Your account is not setup to accept payments yet.</h1>
|
|
34
34
|
<p class="text-sm mb-2">To accept payments for extensions, you must complete the onboard process via Stripe.</p>
|
|
35
|
-
<Button @type="primary" @size="lg" @text="Start payments onboard" @onClick={{transition-to "developers.payments.onboard"}} />
|
|
35
|
+
<Button @type="primary" @size="lg" @text="Start payments onboard" @onClick={{transition-to "developers.payments.onboard"}} @permission="registry-bridge onboard extension-payment" />
|
|
36
36
|
</div>
|
|
37
37
|
</div>
|
|
38
38
|
</div>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/registry-bridge-engine/components/modals/self-managed-install-instructions';
|
package/composer.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fleetbase/registry-bridge",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.13",
|
|
4
4
|
"description": "Internal Bridge between Fleetbase API and Extensions Registry",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fleetbase-extension",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
],
|
|
21
21
|
"require": {
|
|
22
22
|
"php": "^8.0",
|
|
23
|
-
"fleetbase/core-api": "^1.5.
|
|
23
|
+
"fleetbase/core-api": "^1.5.3",
|
|
24
24
|
"laravel/cashier": "^15.2.1",
|
|
25
25
|
"php-http/guzzle7-adapter": "^1.0",
|
|
26
26
|
"psr/http-factory-implementation": "*",
|
package/extension.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fleetbase/registry-bridge-engine",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.13",
|
|
4
4
|
"description": "Internal Bridge between Fleetbase API and Extensions Registry",
|
|
5
5
|
"fleetbase": {
|
|
6
6
|
"route": "extensions"
|
|
@@ -39,11 +39,12 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@babel/core": "^7.23.2",
|
|
42
|
-
"@fleetbase/ember-core": "^0.2.
|
|
43
|
-
"@fleetbase/ember-ui": "^0.2.
|
|
42
|
+
"@fleetbase/ember-core": "^0.2.17",
|
|
43
|
+
"@fleetbase/ember-ui": "^0.2.24",
|
|
44
44
|
"@fortawesome/ember-fontawesome": "^2.0.0",
|
|
45
45
|
"@fortawesome/fontawesome-svg-core": "6.4.0",
|
|
46
46
|
"@fortawesome/free-solid-svg-icons": "6.4.0",
|
|
47
|
+
"@fortawesome/free-brands-svg-icons": "6.4.0",
|
|
47
48
|
"@stripe/connect-js": "^3.3.10",
|
|
48
49
|
"ember-auto-import": "^2.6.3",
|
|
49
50
|
"ember-cli-babel": "^8.2.0",
|
package/server/migrations/2024_08_02_072214_add_self_managed_column_to_registry_extensions_table.php
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
use Illuminate\Database\Migrations\Migration;
|
|
4
|
+
use Illuminate\Database\Schema\Blueprint;
|
|
5
|
+
use Illuminate\Support\Facades\Schema;
|
|
6
|
+
|
|
7
|
+
return new class extends Migration
|
|
8
|
+
{
|
|
9
|
+
/**
|
|
10
|
+
* Run the migrations.
|
|
11
|
+
*/
|
|
12
|
+
public function up(): void
|
|
13
|
+
{
|
|
14
|
+
Schema::table('registry_extensions', function (Blueprint $table) {
|
|
15
|
+
$table->boolean('self_managed')->after('subtitle')->default(0);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Reverse the migrations.
|
|
21
|
+
*/
|
|
22
|
+
public function down(): void
|
|
23
|
+
{
|
|
24
|
+
Schema::table('registry_extensions', function (Blueprint $table) {
|
|
25
|
+
$table->dropColumn('self_managed');
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
};
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\RegistryBridge\Auth\Schemas;
|
|
4
|
+
|
|
5
|
+
class RegistryBridge
|
|
6
|
+
{
|
|
7
|
+
/**
|
|
8
|
+
* The permission schema Name.
|
|
9
|
+
*/
|
|
10
|
+
public string $name = 'registry-bridge';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The permission schema Polict Name.
|
|
14
|
+
*/
|
|
15
|
+
public string $policyName = 'RegistryBridge';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Guards these permissions should apply to.
|
|
19
|
+
*/
|
|
20
|
+
public array $guards = ['sanctum'];
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The permission schema resources.
|
|
24
|
+
*/
|
|
25
|
+
public array $resources = [
|
|
26
|
+
[
|
|
27
|
+
'name' => 'registry-token',
|
|
28
|
+
'actions' => ['export'],
|
|
29
|
+
],
|
|
30
|
+
[
|
|
31
|
+
'name' => 'extension',
|
|
32
|
+
'actions' => ['uninstall', 'install', 'purchase'],
|
|
33
|
+
],
|
|
34
|
+
[
|
|
35
|
+
'name' => 'extension-bundle',
|
|
36
|
+
'actions' => ['submit'],
|
|
37
|
+
'remove_actions' => [],
|
|
38
|
+
],
|
|
39
|
+
[
|
|
40
|
+
'name' => 'extension-purchase',
|
|
41
|
+
'actions' => [],
|
|
42
|
+
'remove_actions' => ['create', 'update', 'delete'],
|
|
43
|
+
],
|
|
44
|
+
[
|
|
45
|
+
'name' => 'extension-install',
|
|
46
|
+
'actions' => [],
|
|
47
|
+
'remove_actions' => ['create', 'update', 'delete'],
|
|
48
|
+
],
|
|
49
|
+
[
|
|
50
|
+
'name' => 'extension-analytic',
|
|
51
|
+
'actions' => [],
|
|
52
|
+
'remove_actions' => ['create', 'update', 'delete'],
|
|
53
|
+
],
|
|
54
|
+
[
|
|
55
|
+
'name' => 'extension-payment',
|
|
56
|
+
'actions' => ['onboard'],
|
|
57
|
+
'remove_actions' => ['create', 'update', 'delete'],
|
|
58
|
+
],
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Policies provided by this schema.
|
|
63
|
+
*/
|
|
64
|
+
public array $policies = [
|
|
65
|
+
[
|
|
66
|
+
'name' => 'ExtensionDeveloper',
|
|
67
|
+
'description' => 'Policy for developing and publishing extensions.',
|
|
68
|
+
'permissions' => [
|
|
69
|
+
'see extension',
|
|
70
|
+
'see registry-token',
|
|
71
|
+
'list registry-token',
|
|
72
|
+
'create registry-token',
|
|
73
|
+
'see extension-bundle',
|
|
74
|
+
'list extension-bundle',
|
|
75
|
+
'view extension-bundle',
|
|
76
|
+
'create extension-bundle',
|
|
77
|
+
'update extension-bundle',
|
|
78
|
+
'delete extension-bundle',
|
|
79
|
+
'submit extension-bundle',
|
|
80
|
+
'see extension-analytic',
|
|
81
|
+
'view extension-analytic',
|
|
82
|
+
'see extension-payment',
|
|
83
|
+
'view extension-payment',
|
|
84
|
+
'list extension',
|
|
85
|
+
],
|
|
86
|
+
],
|
|
87
|
+
[
|
|
88
|
+
'name' => 'ExtensionMarketing',
|
|
89
|
+
'description' => 'Policy to provide insight for marketing extensions.',
|
|
90
|
+
'permissions' => [
|
|
91
|
+
'see extension',
|
|
92
|
+
'see extension-bundle',
|
|
93
|
+
'list extension-bundle',
|
|
94
|
+
'update extension-bundle',
|
|
95
|
+
'see extension-analytic',
|
|
96
|
+
'view extension-analytic',
|
|
97
|
+
'list extension-analytic',
|
|
98
|
+
'list extension',
|
|
99
|
+
],
|
|
100
|
+
],
|
|
101
|
+
[
|
|
102
|
+
'name' => 'ExtensionFinance',
|
|
103
|
+
'description' => 'Policy for managing finance and accounting for extensions.',
|
|
104
|
+
'permissions' => [
|
|
105
|
+
'see extension',
|
|
106
|
+
'see extension-analytic',
|
|
107
|
+
'view extension-analytic',
|
|
108
|
+
'list extension-analytic',
|
|
109
|
+
'see extension-payment',
|
|
110
|
+
'view extension-payment',
|
|
111
|
+
'list extension-payment',
|
|
112
|
+
'onboard extension-payment',
|
|
113
|
+
'list extension',
|
|
114
|
+
],
|
|
115
|
+
],
|
|
116
|
+
[
|
|
117
|
+
'name' => 'ExtensionSales',
|
|
118
|
+
'description' => 'Policy for managing sales reports of extensions.',
|
|
119
|
+
'permissions' => [
|
|
120
|
+
'see extension',
|
|
121
|
+
'see extension-analytic',
|
|
122
|
+
'view extension-analytic',
|
|
123
|
+
'list extension-analytic',
|
|
124
|
+
'see extension-payment',
|
|
125
|
+
'view extension-payment',
|
|
126
|
+
'list extension-payment',
|
|
127
|
+
'see extension-purchase',
|
|
128
|
+
'view extension-purchase',
|
|
129
|
+
'list extension-purchase',
|
|
130
|
+
'list extension',
|
|
131
|
+
],
|
|
132
|
+
],
|
|
133
|
+
[
|
|
134
|
+
'name' => 'ExtensionManager',
|
|
135
|
+
'description' => 'Policy for complete management of extensions.',
|
|
136
|
+
'permissions' => [
|
|
137
|
+
'see extension',
|
|
138
|
+
'see extension-bundle',
|
|
139
|
+
'list extension-bundle',
|
|
140
|
+
'view extension-bundle',
|
|
141
|
+
'create extension-bundle',
|
|
142
|
+
'update extension-bundle',
|
|
143
|
+
'delete extension-bundle',
|
|
144
|
+
'submit extension-bundle',
|
|
145
|
+
'see extension-analytic',
|
|
146
|
+
'view extension-analytic',
|
|
147
|
+
'list extension-analytic',
|
|
148
|
+
'see extension-payment',
|
|
149
|
+
'view extension-payment',
|
|
150
|
+
'list extension-payment',
|
|
151
|
+
'list extension',
|
|
152
|
+
],
|
|
153
|
+
],
|
|
154
|
+
];
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Roles provided by this schema.
|
|
158
|
+
*/
|
|
159
|
+
public array $roles = [
|
|
160
|
+
[
|
|
161
|
+
'name' => 'Extension Developer',
|
|
162
|
+
'description' => 'Role for developing and publishing extensions.',
|
|
163
|
+
'policies' => [
|
|
164
|
+
'ExtensionDeveloper',
|
|
165
|
+
],
|
|
166
|
+
],
|
|
167
|
+
[
|
|
168
|
+
'name' => 'Quality Assurance',
|
|
169
|
+
'description' => 'Role for testing extensions.',
|
|
170
|
+
'permissions' => [
|
|
171
|
+
'see extension',
|
|
172
|
+
'list extension',
|
|
173
|
+
'view extension',
|
|
174
|
+
'see extension-bundle',
|
|
175
|
+
'list extension-bundle',
|
|
176
|
+
'view extension-bundle',
|
|
177
|
+
'create extension-bundle',
|
|
178
|
+
'update extension-bundle',
|
|
179
|
+
'delete extension-bundle',
|
|
180
|
+
'submit extension-bundle',
|
|
181
|
+
],
|
|
182
|
+
],
|
|
183
|
+
[
|
|
184
|
+
'name' => 'Extension Auditor',
|
|
185
|
+
'description' => 'Role for auditing and creating reports for extensions.',
|
|
186
|
+
'permissions' => [
|
|
187
|
+
'see extension',
|
|
188
|
+
'list extension',
|
|
189
|
+
'view extension',
|
|
190
|
+
'see extension-bundle',
|
|
191
|
+
'list extension-bundle',
|
|
192
|
+
'view extension-bundle',
|
|
193
|
+
'see extension-analytic',
|
|
194
|
+
'list extension-analytic',
|
|
195
|
+
'view extension-analytic',
|
|
196
|
+
'see extension-payment',
|
|
197
|
+
'list extension-payment',
|
|
198
|
+
'view extension-payment',
|
|
199
|
+
],
|
|
200
|
+
],
|
|
201
|
+
[
|
|
202
|
+
'name' => 'Extension Admin',
|
|
203
|
+
'description' => 'Role for full control of extensions.',
|
|
204
|
+
'permissions' => [
|
|
205
|
+
'* extension',
|
|
206
|
+
'* extension-bundle',
|
|
207
|
+
'* extension-analytic',
|
|
208
|
+
'* extension-payment',
|
|
209
|
+
'* extension-purchase',
|
|
210
|
+
'* extension-install',
|
|
211
|
+
'* registry-token',
|
|
212
|
+
],
|
|
213
|
+
],
|
|
214
|
+
];
|
|
215
|
+
}
|
|
@@ -6,6 +6,7 @@ use Fleetbase\Http\Controllers\Controller;
|
|
|
6
6
|
use Fleetbase\Http\Resources\Category as CategoryResource;
|
|
7
7
|
use Fleetbase\Models\Category;
|
|
8
8
|
use Fleetbase\RegistryBridge\Models\RegistryExtension;
|
|
9
|
+
use Illuminate\Http\Request;
|
|
9
10
|
|
|
10
11
|
class RegistryController extends Controller
|
|
11
12
|
{
|
|
@@ -51,4 +52,49 @@ class RegistryController extends Controller
|
|
|
51
52
|
|
|
52
53
|
return response()->json($installedExtensions);
|
|
53
54
|
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Lookup and retrieve package information based on the provided package name.
|
|
58
|
+
*
|
|
59
|
+
* This method handles a request to lookup a package by its name. It utilizes the `RegistryExtension::lookup` method to find the
|
|
60
|
+
* corresponding registry extension. If no extension is found or if the extension does not have valid package or composer data,
|
|
61
|
+
* an error response is returned.
|
|
62
|
+
*
|
|
63
|
+
* If a valid extension and its associated bundle are found, the function extracts the package and composer names from the
|
|
64
|
+
* `package.json` and `composer.json` metadata. These names are then returned in a JSON response.
|
|
65
|
+
*
|
|
66
|
+
* @param Request $request the incoming HTTP request containing the 'package' input parameter
|
|
67
|
+
*
|
|
68
|
+
* @return \Illuminate\Http\JsonResponse a JSON response containing the package and composer names if found, or an error message otherwise
|
|
69
|
+
*/
|
|
70
|
+
public function lookupPackage(Request $request)
|
|
71
|
+
{
|
|
72
|
+
$packageName = $request->input('package');
|
|
73
|
+
$registryExtension = RegistryExtension::lookup($packageName);
|
|
74
|
+
if (!$registryExtension) {
|
|
75
|
+
return response()->error('No extension found by this name for install');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (!$registryExtension->currentBundle) {
|
|
79
|
+
return response()->error('No valid package data found for this extension install');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
$packageJson = $registryExtension->currentBundle->meta['package.json'];
|
|
83
|
+
if (!$packageJson) {
|
|
84
|
+
return response()->error('No valid package data found for this extension install');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
$composerJson = $registryExtension->currentBundle->meta['composer.json'];
|
|
88
|
+
if (!$composerJson) {
|
|
89
|
+
return response()->error('No valid package data found for this extension install');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
$packageJsonName = data_get($packageJson, 'name');
|
|
93
|
+
$composerJsonName = data_get($composerJson, 'name');
|
|
94
|
+
|
|
95
|
+
return response()->json([
|
|
96
|
+
'npm' => $packageJsonName,
|
|
97
|
+
'composer' => $composerJsonName,
|
|
98
|
+
]);
|
|
99
|
+
}
|
|
54
100
|
}
|