+ {{/if}}
\ No newline at end of file
diff --git a/addon/templates/installed.hbs b/addon/templates/installed.hbs
index 571c3d0..ed2991c 100644
--- a/addon/templates/installed.hbs
+++ b/addon/templates/installed.hbs
@@ -13,15 +13,15 @@
{{extension.name}}
{{n-a extension.description}}
-
+
-
+
diff --git a/app/components/registry-admin-config.js b/app/components/registry-admin-config.js
new file mode 100644
index 0000000..c108556
--- /dev/null
+++ b/app/components/registry-admin-config.js
@@ -0,0 +1 @@
+export { default } from '@fleetbase/registry-bridge-engine/components/registry-admin-config';
diff --git a/composer.json b/composer.json
index 2f0c777..9e323cc 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,6 @@
{
"name": "fleetbase/registry-bridge",
- "version": "0.0.2",
+ "version": "0.0.3",
"description": "Internal Bridge between Fleetbase API and Extensions Registry",
"keywords": [
"fleetbase-extension",
@@ -20,7 +20,7 @@
],
"require": {
"php": "^8.0",
- "fleetbase/core-api": "^1.4.28",
+ "fleetbase/core-api": "^1.4.30",
"laravel/cashier": "^15.2.1",
"php-http/guzzle7-adapter": "^1.0",
"psr/http-factory-implementation": "*",
diff --git a/extension.json b/extension.json
index 1d89d77..5d3ba89 100644
--- a/extension.json
+++ b/extension.json
@@ -1,6 +1,6 @@
{
"name": "Registry Bridge",
- "version": "0.0.2",
+ "version": "0.0.3",
"description": "Internal Bridge between Fleetbase API and Extensions Registry",
"repository": "https://github.com/fleetbase/registry-bridge",
"license": "AGPL-3.0-or-later",
diff --git a/package.json b/package.json
index 73fedaf..e1e0ea7 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@fleetbase/registry-bridge-engine",
- "version": "0.0.2",
+ "version": "0.0.3",
"description": "Internal Bridge between Fleetbase API and Extensions Registry",
"fleetbase": {
"route": "extensions"
@@ -40,10 +40,10 @@
"dependencies": {
"@babel/core": "^7.23.2",
"@fleetbase/ember-core": "^0.2.13",
- "@fleetbase/ember-ui": "^0.2.18",
- "@fortawesome/ember-fontawesome": "^0.4.1",
- "@fortawesome/fontawesome-svg-core": "^6.5.2",
- "@fortawesome/free-solid-svg-icons": "^6.5.2",
+ "@fleetbase/ember-ui": "^0.2.19",
+ "@fortawesome/ember-fontawesome": "^2.0.0",
+ "@fortawesome/fontawesome-svg-core": "6.4.0",
+ "@fortawesome/free-solid-svg-icons": "6.4.0",
"@stripe/connect-js": "^3.3.10",
"ember-auto-import": "^2.6.3",
"ember-cli-babel": "^8.2.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 90eab96..6c7df09 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -8,17 +8,17 @@ dependencies:
specifier: ^0.2.13
version: 0.2.13(@ember/test-helpers@3.2.0)(ember-source@5.4.0)(webpack@5.89.0)
'@fleetbase/ember-ui':
- specifier: ^0.2.18
- version: 0.2.18(@ember/test-helpers@3.2.0)(@glimmer/component@1.1.2)(@glimmer/tracking@1.1.2)(ember-source@5.4.0)(postcss@8.4.39)(rollup@4.18.1)(tracked-built-ins@3.3.0)(webpack@5.89.0)
+ specifier: ^0.2.19
+ version: 0.2.19(@ember/test-helpers@3.2.0)(@glimmer/component@1.1.2)(@glimmer/tracking@1.1.2)(ember-source@5.4.0)(postcss@8.4.39)(tracked-built-ins@3.3.0)(webpack@5.89.0)
'@fortawesome/ember-fontawesome':
- specifier: ^0.4.1
- version: 0.4.1(rollup@4.18.1)
+ specifier: ^2.0.0
+ version: 2.0.0(ember-source@5.4.0)(webpack@5.89.0)
'@fortawesome/fontawesome-svg-core':
- specifier: ^6.5.2
- version: 6.5.2
+ specifier: 6.4.0
+ version: 6.4.0
'@fortawesome/free-solid-svg-icons':
- specifier: ^6.5.2
- version: 6.5.2
+ specifier: 6.4.0
+ version: 6.4.0
'@stripe/connect-js':
specifier: ^3.3.10
version: 3.3.10
@@ -2523,8 +2523,8 @@ packages:
- webpack
dev: false
- /@fleetbase/ember-ui@0.2.18(@ember/test-helpers@3.2.0)(@glimmer/component@1.1.2)(@glimmer/tracking@1.1.2)(ember-source@5.4.0)(postcss@8.4.39)(rollup@4.18.1)(tracked-built-ins@3.3.0)(webpack@5.89.0):
- resolution: {integrity: sha512-lOwUmwstfM/o1NdlB1jv6mPdyGfmcZuJGFdYdITfayMCW7CwAZBY84czwV5w53AQbFCt4A5nkGXxV6EGUDjA4A==}
+ /@fleetbase/ember-ui@0.2.19(@ember/test-helpers@3.2.0)(@glimmer/component@1.1.2)(@glimmer/tracking@1.1.2)(ember-source@5.4.0)(postcss@8.4.39)(tracked-built-ins@3.3.0)(webpack@5.89.0):
+ resolution: {integrity: sha512-VxWjr56T7CpkjTBNquGSyZIQz+cpIzJW26UY0DVnPYgczRXq/h0XgBzyxSc5Ubr6IeLKxhK0r1+lcKvdSLCw+w==}
engines: {node: '>= 18'}
dependencies:
'@babel/core': 7.23.2
@@ -2534,10 +2534,10 @@ packages:
'@embroider/macros': 1.16.5
'@fleetbase/ember-accounting': 0.0.1(ember-source@5.4.0)
'@floating-ui/dom': 1.6.7
- '@fortawesome/ember-fontawesome': 1.0.3(rollup@4.18.1)(webpack@5.89.0)
- '@fortawesome/fontawesome-svg-core': 6.5.2
- '@fortawesome/free-brands-svg-icons': 6.5.2
- '@fortawesome/free-solid-svg-icons': 6.5.2
+ '@fortawesome/ember-fontawesome': 2.0.0(ember-source@5.4.0)(webpack@5.89.0)
+ '@fortawesome/fontawesome-svg-core': 6.4.0
+ '@fortawesome/free-brands-svg-icons': 6.4.0
+ '@fortawesome/free-solid-svg-icons': 6.4.0
'@fullcalendar/core': 6.1.15
'@fullcalendar/daygrid': 6.1.15(@fullcalendar/core@6.1.15)
'@fullcalendar/interaction': 6.1.15(@fullcalendar/core@6.1.15)
@@ -2552,7 +2552,7 @@ packages:
chartjs-adapter-date-fns: 3.0.0(chart.js@4.4.3)(date-fns@2.30.0)
date-fns: 2.30.0
ember-animated: 1.1.4(@ember/test-helpers@3.2.0)(ember-source@5.4.0)
- ember-auto-import: 2.6.3(webpack@5.89.0)
+ ember-auto-import: 2.7.4(webpack@5.89.0)
ember-basic-dropdown: 7.3.0(@babel/core@7.23.2)(@ember/string@3.1.1)(ember-source@5.4.0)(webpack@5.89.0)
ember-cli-babel: 8.2.0(@babel/core@7.23.2)
ember-cli-htmlbars: 6.3.0
@@ -2690,49 +2690,29 @@ packages:
tslib: 2.6.3
dev: false
- /@fortawesome/ember-fontawesome@0.4.1(rollup@4.18.1):
- resolution: {integrity: sha512-drBupV++kJP2rmyfxg55e4NeaezGEk1Ng9QMTFvEURIkFQfd3QPAxBdC9CLuAWKtzgF6zACGyv/9D2AzF45juQ==}
- engines: {node: 12.* || 14.* || >= 16}
- dependencies:
- '@fortawesome/fontawesome-svg-core': 6.5.2
- broccoli-file-creator: 2.1.1
- broccoli-merge-trees: 4.2.0
- broccoli-plugin: 4.0.7
- broccoli-rollup: 4.1.1
- broccoli-source: 3.0.1
- camel-case: 4.1.2
- ember-ast-helpers: 0.3.5
- ember-cli-babel: 7.26.11
- ember-cli-htmlbars: 5.7.2
- ember-get-config: 2.1.1
- find-yarn-workspace-root: 2.0.0
- glob: 7.2.3
- rollup-plugin-node-resolve: 5.2.0(rollup@4.18.1)
- transitivePeerDependencies:
- - '@glint/template'
- - rollup
- - supports-color
- dev: false
-
- /@fortawesome/ember-fontawesome@1.0.3(rollup@4.18.1)(webpack@5.89.0):
- resolution: {integrity: sha512-KGw4a4moLo9wcGwFU05Y7yV2/va2R/lN7rO3cw6ZBrnMigyAReYH9XcK4zkiAXGaLAbzc/mOyP19ofr2rc7HBg==}
- engines: {node: 12.* || 14.* || >= 16}
+ /@fortawesome/ember-fontawesome@2.0.0(ember-source@5.4.0)(webpack@5.89.0):
+ resolution: {integrity: sha512-lUyMvocZZzMuCwr8pkKhejXKBj5RGnIs8YUHc/tCNSEyHSx7/E5xAhtE4fa5B1c9+UO789Kng8z6DQ9E/agVGA==}
+ engines: {node: 14.* || 16.* || >= 18}
+ peerDependencies:
+ ember-source: ^4.0.0 || >=5.0.0
dependencies:
- '@fortawesome/fontawesome-svg-core': 6.5.2
- '@rollup/plugin-node-resolve': 15.2.3(rollup@4.18.1)
+ '@fortawesome/fontawesome-svg-core': 6.4.0
+ '@rollup/plugin-node-resolve': 15.2.3
+ array-unique: 0.3.2
broccoli-file-creator: 2.1.1
broccoli-merge-trees: 4.2.0
broccoli-plugin: 4.0.7
broccoli-rollup: 5.0.0
broccoli-source: 3.0.1
camel-case: 4.1.2
- ember-ast-helpers: 0.3.5
+ ember-ast-helpers: 0.4.0
ember-auto-import: 2.7.4(webpack@5.89.0)
ember-cli-babel: 7.26.11
- ember-cli-htmlbars: 5.7.2
+ ember-cli-htmlbars: 6.3.0
ember-get-config: 2.1.1
+ ember-source: 5.4.0(@babel/core@7.23.2)(@glimmer/component@1.1.2)(rsvp@4.8.5)(webpack@5.89.0)
find-yarn-workspace-root: 2.0.0
- glob: 7.2.3
+ glob: 10.4.5
transitivePeerDependencies:
- '@glint/template'
- rollup
@@ -2740,34 +2720,34 @@ packages:
- webpack
dev: false
- /@fortawesome/fontawesome-common-types@6.5.2:
- resolution: {integrity: sha512-gBxPg3aVO6J0kpfHNILc+NMhXnqHumFxOmjYCFfOiLZfwhnnfhtsdA2hfJlDnj+8PjAs6kKQPenOTKj3Rf7zHw==}
+ /@fortawesome/fontawesome-common-types@6.4.0:
+ resolution: {integrity: sha512-HNii132xfomg5QVZw0HwXXpN22s7VBHQBv9CeOu9tfJnhsWQNd2lmTNi8CSrnw5B+5YOmzu1UoPAyxaXsJ6RgQ==}
engines: {node: '>=6'}
requiresBuild: true
dev: false
- /@fortawesome/fontawesome-svg-core@6.5.2:
- resolution: {integrity: sha512-5CdaCBGl8Rh9ohNdxeeTMxIj8oc3KNBgIeLMvJosBMdslK/UnEB8rzyDRrbKdL1kDweqBPo4GT9wvnakHWucZw==}
+ /@fortawesome/fontawesome-svg-core@6.4.0:
+ resolution: {integrity: sha512-Bertv8xOiVELz5raB2FlXDPKt+m94MQ3JgDfsVbrqNpLU9+UE2E18GKjLKw+d3XbeYPqg1pzyQKGsrzbw+pPaw==}
engines: {node: '>=6'}
requiresBuild: true
dependencies:
- '@fortawesome/fontawesome-common-types': 6.5.2
+ '@fortawesome/fontawesome-common-types': 6.4.0
dev: false
- /@fortawesome/free-brands-svg-icons@6.5.2:
- resolution: {integrity: sha512-zi5FNYdmKLnEc0jc0uuHH17kz/hfYTg4Uei0wMGzcoCL/4d3WM3u1VMc0iGGa31HuhV5i7ZK8ZlTCQrHqRHSGQ==}
+ /@fortawesome/free-brands-svg-icons@6.4.0:
+ resolution: {integrity: sha512-qvxTCo0FQ5k2N+VCXb/PZQ+QMhqRVM4OORiO6MXdG6bKolIojGU/srQ1ptvKk0JTbRgaJOfL2qMqGvBEZG7Z6g==}
engines: {node: '>=6'}
requiresBuild: true
dependencies:
- '@fortawesome/fontawesome-common-types': 6.5.2
+ '@fortawesome/fontawesome-common-types': 6.4.0
dev: false
- /@fortawesome/free-solid-svg-icons@6.5.2:
- resolution: {integrity: sha512-QWFZYXFE7O1Gr1dTIp+D6UcFUF0qElOnZptpi7PBUMylJh+vFmIedVe1Ir6RM1t2tEQLLSV1k7bR4o92M+uqlw==}
+ /@fortawesome/free-solid-svg-icons@6.4.0:
+ resolution: {integrity: sha512-kutPeRGWm8V5dltFP1zGjQOEAzaLZj4StdQhWVZnfGFCvAPVvHh8qk5bRrU4KXnRRRNni5tKQI9PBAdI6MP8nQ==}
engines: {node: '>=6'}
requiresBuild: true
dependencies:
- '@fortawesome/fontawesome-common-types': 6.5.2
+ '@fortawesome/fontawesome-common-types': 6.4.0
dev: false
/@fullcalendar/core@6.1.15:
@@ -2792,16 +2772,6 @@ packages:
'@fullcalendar/core': 6.1.15
dev: false
- /@glimmer/compiler@0.27.0:
- resolution: {integrity: sha512-SJUUEpkFCL+GTpEK6c2EhZQJant67ahGLF6M1xRmIsq6E+AtbHgu+y8mWvFbtpb7lx4gqNKpXSEwlHUTTuxVGw==}
- dependencies:
- '@glimmer/interfaces': 0.27.0
- '@glimmer/syntax': 0.27.0
- '@glimmer/util': 0.27.0
- '@glimmer/wire-format': 0.27.0
- simple-html-tokenizer: 0.3.0
- dev: false
-
/@glimmer/compiler@0.84.3:
resolution: {integrity: sha512-cj9sGlnvExP9httxY6ZMivJRGulyaZ31DddCYB5h6LxupR4Nk2d1nAJCWPLsvuQJ8qR+eYw0y9aiY/VeT0krpQ==}
dependencies:
@@ -2859,12 +2829,6 @@ packages:
dependencies:
'@glimmer/env': 0.1.7
- /@glimmer/interfaces@0.27.0:
- resolution: {integrity: sha512-Uz9txXB0Agnac6vUOAk6uZIB7SeS/fFrdjyNsNJnge5XeojvOQs1YyIFqOhky3G7NHO/mcx3Tdt8PXggFakVtQ==}
- dependencies:
- '@glimmer/wire-format': 0.27.0
- dev: false
-
/@glimmer/interfaces@0.84.3:
resolution: {integrity: sha512-dk32ykoNojt0mvEaIW6Vli5MGTbQo58uy3Epj7ahCgTHmWOKuw/0G83f2UmFprRwFx689YTXG38I/vbpltEjzg==}
dependencies:
@@ -2945,15 +2909,6 @@ packages:
'@glimmer/wire-format': 0.84.3
'@simple-dom/interface': 1.4.0
- /@glimmer/syntax@0.27.0:
- resolution: {integrity: sha512-IC+JaGkfF+J3e5jUXrW4SkVAAgI6WyN4kzfJKqWEnjMAa6pB8XGEDkaaMhoMrxjfK+R0Us2PO45CWhGB3FqsKg==}
- dependencies:
- '@glimmer/interfaces': 0.27.0
- '@glimmer/util': 0.27.0
- handlebars: 4.7.8
- simple-html-tokenizer: 0.3.0
- dev: false
-
/@glimmer/syntax@0.84.3:
resolution: {integrity: sha512-ioVbTic6ZisLxqTgRBL2PCjYZTFIwobifCustrozRU2xGDiYvVIL0vt25h2c1ioDsX59UgVlDkIK4YTAQQSd2A==}
dependencies:
@@ -2968,10 +2923,6 @@ packages:
'@glimmer/env': 0.1.7
'@glimmer/validator': 0.44.0
- /@glimmer/util@0.27.0:
- resolution: {integrity: sha512-GxER83ZuyEyZ5Phn86VkHcjjN/3MagK0MMr91S5t62IVSW/zyFevpaVV26YKmisDqOe4918nvwGqn543O5gGXw==}
- dev: false
-
/@glimmer/util@0.44.0:
resolution: {integrity: sha512-duAsm30uVK9jSysElCbLyU6QQYO2X9iLDLBIBUcCqck9qN1o3tK2qWiHbGK5d6g8E2AJ4H88UrfElkyaJlGrwg==}
@@ -3004,12 +2955,6 @@ packages:
'@glimmer/interfaces': 0.84.3
'@glimmer/util': 0.84.3
- /@glimmer/wire-format@0.27.0:
- resolution: {integrity: sha512-gNhityUr9HODYH9GydHVk7C6NZ57MqSbdGzC5TM8VdPibtd72N3+3Zggrm12Faw4E4zTvTM1692Sz/bNwMxLNw==}
- dependencies:
- '@glimmer/util': 0.27.0
- dev: false
-
/@glimmer/wire-format@0.84.3:
resolution: {integrity: sha512-aZVfQhqv4k7tTo2vwjy+b4mAxKt7cHH75JR3zAeCilimApa+yYTYUyY73NDNSUVbelgAlQ5s6vTiMSQ55WwVow==}
dependencies:
@@ -3191,7 +3136,7 @@ packages:
find-up: 5.0.0
dev: true
- /@rollup/plugin-node-resolve@15.2.3(rollup@4.18.1):
+ /@rollup/plugin-node-resolve@15.2.3:
resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==}
engines: {node: '>=14.0.0'}
peerDependencies:
@@ -3200,16 +3145,15 @@ packages:
rollup:
optional: true
dependencies:
- '@rollup/pluginutils': 5.1.0(rollup@4.18.1)
+ '@rollup/pluginutils': 5.1.0
'@types/resolve': 1.20.2
deepmerge: 4.3.1
is-builtin-module: 3.2.1
is-module: 1.0.0
resolve: 1.22.8
- rollup: 4.18.1
dev: false
- /@rollup/pluginutils@5.1.0(rollup@4.18.1):
+ /@rollup/pluginutils@5.1.0:
resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==}
engines: {node: '>=14.0.0'}
peerDependencies:
@@ -3221,136 +3165,7 @@ packages:
'@types/estree': 1.0.5
estree-walker: 2.0.2
picomatch: 2.3.1
- rollup: 4.18.1
- dev: false
-
- /@rollup/rollup-android-arm-eabi@4.18.1:
- resolution: {integrity: sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==}
- cpu: [arm]
- os: [android]
- requiresBuild: true
- dev: false
- optional: true
-
- /@rollup/rollup-android-arm64@4.18.1:
- resolution: {integrity: sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==}
- cpu: [arm64]
- os: [android]
- requiresBuild: true
- dev: false
- optional: true
-
- /@rollup/rollup-darwin-arm64@4.18.1:
- resolution: {integrity: sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==}
- cpu: [arm64]
- os: [darwin]
- requiresBuild: true
- dev: false
- optional: true
-
- /@rollup/rollup-darwin-x64@4.18.1:
- resolution: {integrity: sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==}
- cpu: [x64]
- os: [darwin]
- requiresBuild: true
- dev: false
- optional: true
-
- /@rollup/rollup-linux-arm-gnueabihf@4.18.1:
- resolution: {integrity: sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==}
- cpu: [arm]
- os: [linux]
- requiresBuild: true
- dev: false
- optional: true
-
- /@rollup/rollup-linux-arm-musleabihf@4.18.1:
- resolution: {integrity: sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==}
- cpu: [arm]
- os: [linux]
- requiresBuild: true
- dev: false
- optional: true
-
- /@rollup/rollup-linux-arm64-gnu@4.18.1:
- resolution: {integrity: sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==}
- cpu: [arm64]
- os: [linux]
- requiresBuild: true
- dev: false
- optional: true
-
- /@rollup/rollup-linux-arm64-musl@4.18.1:
- resolution: {integrity: sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==}
- cpu: [arm64]
- os: [linux]
- requiresBuild: true
- dev: false
- optional: true
-
- /@rollup/rollup-linux-powerpc64le-gnu@4.18.1:
- resolution: {integrity: sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==}
- cpu: [ppc64]
- os: [linux]
- requiresBuild: true
- dev: false
- optional: true
-
- /@rollup/rollup-linux-riscv64-gnu@4.18.1:
- resolution: {integrity: sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==}
- cpu: [riscv64]
- os: [linux]
- requiresBuild: true
- dev: false
- optional: true
-
- /@rollup/rollup-linux-s390x-gnu@4.18.1:
- resolution: {integrity: sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==}
- cpu: [s390x]
- os: [linux]
- requiresBuild: true
- dev: false
- optional: true
-
- /@rollup/rollup-linux-x64-gnu@4.18.1:
- resolution: {integrity: sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==}
- cpu: [x64]
- os: [linux]
- requiresBuild: true
- dev: false
- optional: true
-
- /@rollup/rollup-linux-x64-musl@4.18.1:
- resolution: {integrity: sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==}
- cpu: [x64]
- os: [linux]
- requiresBuild: true
- dev: false
- optional: true
-
- /@rollup/rollup-win32-arm64-msvc@4.18.1:
- resolution: {integrity: sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==}
- cpu: [arm64]
- os: [win32]
- requiresBuild: true
- dev: false
- optional: true
-
- /@rollup/rollup-win32-ia32-msvc@4.18.1:
- resolution: {integrity: sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==}
- cpu: [ia32]
- os: [win32]
- requiresBuild: true
- dev: false
- optional: true
-
- /@rollup/rollup-win32-x64-msvc@4.18.1:
- resolution: {integrity: sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==}
- cpu: [x64]
- os: [win32]
- requiresBuild: true
dev: false
- optional: true
/@simple-dom/document@1.4.0:
resolution: {integrity: sha512-/RUeVH4kuD3rzo5/91+h4Z1meLSLP66eXqpVAw/4aZmYozkeqUkMprq0znL4psX/adEed5cBgiNJcfMz/eKZLg==}
@@ -3396,10 +3211,6 @@ packages:
'@types/node': 20.14.10
dev: true
- /@types/broccoli-plugin@1.3.0:
- resolution: {integrity: sha512-SLk4/hFc2kGvgwNFrpn2O1juxFOllcHAywvlo7VwxfExLzoz1GGJ0oIZCwj5fwSpvHw4AWpZjJ1fUvb62PDayQ==}
- dev: false
-
/@types/broccoli-plugin@3.0.0:
resolution: {integrity: sha512-f+TcsARR2PovfFRKFdCX0kfH/QoM3ZVD2h1rl2mNvrKO0fq2uBNCBsTU3JanfU4COCt5cXpTfARyUsERlC8vIw==}
deprecated: This is a stub types definition. broccoli-plugin provides its own type definitions, so you do not need this installed.
@@ -3536,12 +3347,6 @@ packages:
resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==}
dev: true
- /@types/resolve@0.0.8:
- resolution: {integrity: sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==}
- dependencies:
- '@types/node': 20.14.10
- dev: false
-
/@types/resolve@1.20.2:
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
dev: false
@@ -3848,12 +3653,6 @@ packages:
hasBin: true
dev: false
- /acorn@7.4.1:
- resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==}
- engines: {node: '>=0.4.0'}
- hasBin: true
- dev: false
-
/acorn@8.12.1:
resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==}
engines: {node: '>=0.4.0'}
@@ -5195,23 +4994,6 @@ packages:
- supports-color
dev: false
- /broccoli-rollup@4.1.1:
- resolution: {integrity: sha512-hkp0dB5chiemi32t6hLe5bJvxuTOm1TU+SryFlZIs95KT9+94uj0C8w6k6CsZ2HuIdIZg6D252t4gwOlcTXrpA==}
- engines: {node: '>=8.0'}
- dependencies:
- '@types/broccoli-plugin': 1.3.0
- broccoli-plugin: 2.1.0
- fs-tree-diff: 2.0.1
- heimdalljs: 0.2.6
- node-modules-path: 1.0.2
- rollup: 1.32.1
- rollup-pluginutils: 2.8.2
- symlink-or-copy: 1.3.1
- walk-sync: 1.1.4
- transitivePeerDependencies:
- - supports-color
- dev: false
-
/broccoli-rollup@5.0.0:
resolution: {integrity: sha512-QdMuXHwsdz/LOS8zu4HP91Sfi4ofimrOXoYP/lrPdRh7lJYD87Lfq4WzzUhGHsxMfzANIEvl/7qVHKD3cFJ4tA==}
engines: {node: '>=12.0'}
@@ -6844,12 +6626,9 @@ packages:
- supports-color
dev: false
- /ember-ast-helpers@0.3.5:
- resolution: {integrity: sha512-ZtaGAUDvRX13G9D4t4WbTMhcUzqsw6KqhcHreIiZi3ZhRFlSZ3BumgyJ6buDZj+tCBLiQsxRv7l5AY6imqNR6Q==}
+ /ember-ast-helpers@0.4.0:
+ resolution: {integrity: sha512-3gBsatspW3AT2hwzD27aQbgyWA29RXeMxCnMYgFBYtmS/T1M6TxuatEgfpofKqai4OC/JijftmN4s6dydeXGzQ==}
engines: {node: '>= 6'}
- dependencies:
- '@glimmer/compiler': 0.27.0
- '@glimmer/syntax': 0.27.0
dev: false
/ember-auto-import@1.12.2:
@@ -13618,35 +13397,12 @@ packages:
inherits: 2.0.4
dev: false
- /rollup-plugin-node-resolve@5.2.0(rollup@4.18.1):
- resolution: {integrity: sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==}
- deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-node-resolve.
- peerDependencies:
- rollup: '>=1.11.0'
- dependencies:
- '@types/resolve': 0.0.8
- builtin-modules: 3.3.0
- is-module: 1.0.0
- resolve: 1.22.8
- rollup: 4.18.1
- rollup-pluginutils: 2.8.2
- dev: false
-
/rollup-pluginutils@2.8.2:
resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==}
dependencies:
estree-walker: 0.6.1
dev: false
- /rollup@1.32.1:
- resolution: {integrity: sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A==}
- hasBin: true
- dependencies:
- '@types/estree': 1.0.5
- '@types/node': 20.14.10
- acorn: 7.4.1
- dev: false
-
/rollup@2.79.1:
resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==}
engines: {node: '>=10.0.0'}
@@ -13655,32 +13411,6 @@ packages:
fsevents: 2.3.3
dev: false
- /rollup@4.18.1:
- resolution: {integrity: sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==}
- engines: {node: '>=18.0.0', npm: '>=8.0.0'}
- hasBin: true
- dependencies:
- '@types/estree': 1.0.5
- optionalDependencies:
- '@rollup/rollup-android-arm-eabi': 4.18.1
- '@rollup/rollup-android-arm64': 4.18.1
- '@rollup/rollup-darwin-arm64': 4.18.1
- '@rollup/rollup-darwin-x64': 4.18.1
- '@rollup/rollup-linux-arm-gnueabihf': 4.18.1
- '@rollup/rollup-linux-arm-musleabihf': 4.18.1
- '@rollup/rollup-linux-arm64-gnu': 4.18.1
- '@rollup/rollup-linux-arm64-musl': 4.18.1
- '@rollup/rollup-linux-powerpc64le-gnu': 4.18.1
- '@rollup/rollup-linux-riscv64-gnu': 4.18.1
- '@rollup/rollup-linux-s390x-gnu': 4.18.1
- '@rollup/rollup-linux-x64-gnu': 4.18.1
- '@rollup/rollup-linux-x64-musl': 4.18.1
- '@rollup/rollup-win32-arm64-msvc': 4.18.1
- '@rollup/rollup-win32-ia32-msvc': 4.18.1
- '@rollup/rollup-win32-x64-msvc': 4.18.1
- fsevents: 2.3.3
- dev: false
-
/route-recognizer@0.3.4:
resolution: {integrity: sha512-2+MhsfPhvauN1O8KaXpXAOfR/fwe8dnUXVM+xw7yt40lJRfPVQxV6yryZm0cgRvAj5fMF/mdRZbL2ptwbs5i2g==}
@@ -14032,10 +13762,6 @@ packages:
transitivePeerDependencies:
- supports-color
- /simple-html-tokenizer@0.3.0:
- resolution: {integrity: sha512-cuUWLyKJbCExtBmxJWhmIk/KIbMF1yOuNaansJiPEdxqitM7r7So3a1M4Sw2uqfNYWjBTiVVdJjb7vtYIaEjhw==}
- dev: false
-
/simple-html-tokenizer@0.5.11:
resolution: {integrity: sha512-C2WEK/Z3HoSFbYq8tI7ni3eOo/NneSPRoPpcM7WdLjFOArFuyXEjAoCdOC3DgMfRyziZQ1hCNR4mrNdWEvD0og==}
diff --git a/server/src/Http/Controllers/Internal/v1/RegistryAuthController.php b/server/src/Http/Controllers/Internal/v1/RegistryAuthController.php
index 92e2eac..0feaa50 100644
--- a/server/src/Http/Controllers/Internal/v1/RegistryAuthController.php
+++ b/server/src/Http/Controllers/Internal/v1/RegistryAuthController.php
@@ -17,6 +17,52 @@
class RegistryAuthController extends Controller
{
+ /**
+ * Handle Composer authentication and return a list of unauthorized packages.
+ *
+ * This function authenticates the user based on the provided registry token.
+ * If the token is valid, it returns a list of packages that the user is not authorized to access.
+ *
+ * @param Request $request the incoming HTTP request containing the registry token
+ *
+ * @return \Illuminate\Http\JsonResponse a JSON response containing the status and a list of unauthorized packages
+ */
+ public function composerAuthentication(Request $request)
+ {
+ $registryToken = $request->input('registryToken');
+ if (!$registryToken) {
+ return response()->error('No registry token provided for authentication.', 401);
+ }
+
+ // Get registry user via token
+ $registryUser = RegistryUser::where('registry_token', $registryToken)->first();
+ if (!$registryUser) {
+ return response()->error('Invalid registry token provided for authentication.', 401);
+ }
+
+ // Fetch unauthorized extensions
+ $unauthorizedExtensions = RegistryExtension::where('payment_required', true)
+ ->whereDoesntHave('purchases', function ($query) use ($registryUser) {
+ $query->where('company_uuid', $registryUser->company_uuid);
+ })
+ ->whereHas('currentBundle')
+ ->with('currentBundle')
+ ->get();
+
+ // Map to unathorized to package names
+ $unauthorizedExtensionNames = $unauthorizedExtensions->map(function ($registryExtension) {
+ $composerJson = $registryExtension->currentBundle->meta['composer.json'] ?? [];
+
+ return $composerJson['name'] ?? null;
+ })->filter()->values();
+
+ // Done
+ return response()->json([
+ 'status' => 'ok',
+ 'unauthorizedPackages' => $unauthorizedExtensionNames,
+ ]);
+ }
+
/**
* Authenticates a registry user based on provided credentials.
*
diff --git a/server/src/Http/Controllers/Internal/v1/RegistryExtensionBundleController.php b/server/src/Http/Controllers/Internal/v1/RegistryExtensionBundleController.php
index 75c43d3..6413df3 100644
--- a/server/src/Http/Controllers/Internal/v1/RegistryExtensionBundleController.php
+++ b/server/src/Http/Controllers/Internal/v1/RegistryExtensionBundleController.php
@@ -8,7 +8,7 @@
use Fleetbase\RegistryBridge\Http\Requests\CreateRegistryExtensionBundleRequest;
use Fleetbase\RegistryBridge\Http\Requests\RegistryExtensionActionRequest;
use Fleetbase\RegistryBridge\Models\RegistryExtensionBundle;
-use Fleetbase\Support\Utils;
+use Fleetbase\RegistryBridge\Support\Utils;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
diff --git a/server/src/Http/Controllers/Internal/v1/RegistryExtensionController.php b/server/src/Http/Controllers/Internal/v1/RegistryExtensionController.php
index e4d07fe..2b57937 100644
--- a/server/src/Http/Controllers/Internal/v1/RegistryExtensionController.php
+++ b/server/src/Http/Controllers/Internal/v1/RegistryExtensionController.php
@@ -3,11 +3,12 @@
namespace Fleetbase\RegistryBridge\Http\Controllers\Internal\v1;
use Fleetbase\Exceptions\FleetbaseRequestValidationException;
+use Fleetbase\Models\Setting;
use Fleetbase\RegistryBridge\Http\Controllers\RegistryBridgeController;
use Fleetbase\RegistryBridge\Http\Requests\CreateRegistryExtensionRequest;
use Fleetbase\RegistryBridge\Http\Requests\RegistryExtensionActionRequest;
use Fleetbase\RegistryBridge\Models\RegistryExtension;
-use Fleetbase\Support\Utils;
+use Fleetbase\RegistryBridge\Support\Utils;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
@@ -254,4 +255,61 @@ public function downloadBundle(RegistryExtensionActionRequest $request)
return response()->error('Failed to download extension bundle');
}
+
+ /**
+ * Retrieve the current registry configuration.
+ *
+ * This method fetches the current registry host and token from the configuration
+ * settings or environment variables and returns them in a JSON response.
+ *
+ * @return \Illuminate\Http\JsonResponse a JSON response containing the registry host and token
+ */
+ public function getConfig()
+ {
+ $registryHost = config('registry-bridge.registry.host', env('REGISTRY_HOST', 'https://registry.fleetbase.io'));
+ $registryToken = config('registry-bridge.registry.token', env('REGISTRY_TOKEN'));
+
+ return response()->json([
+ 'host' => $registryHost,
+ 'token' => $registryToken,
+ ]);
+ }
+
+ /**
+ * Save the registry configuration.
+ *
+ * This method updates the registry host and token based on the provided request input.
+ * If no input is provided, it uses the current configuration values or environment variables.
+ * The updated configuration is then saved in the settings and returned in a JSON response.
+ *
+ * @param Request $request the incoming HTTP request containing the new host and token
+ *
+ * @return \Illuminate\Http\JsonResponse a JSON response containing the updated registry host and token
+ */
+ public function saveConfig(Request $request)
+ {
+ $currentRegistryHost = config('registry-bridge.registry.host', env('REGISTRY_HOST', 'https://registry.fleetbase.io'));
+ $currentRegistryToken = config('registry-bridge.registry.token', env('REGISTRY_TOKEN'));
+ $registryHost = $request->input('host', $currentRegistryHost);
+ $registryToken = $request->input('token', $currentRegistryToken);
+
+ // Save values in settings and config
+ if ($registryHost) {
+ Setting::configure('registry-bridge.registry.host', $registryHost);
+ config(['registry-bridge.registry.host' => $registryHost]);
+ }
+
+ if ($registryToken) {
+ Setting::configure('registry-bridge.registry.token', $registryToken);
+ config(['registry-bridge.registry.token' => $registryToken]);
+ }
+
+ // Reboot registry auth
+ Utils::bootRegistryAuth(true);
+
+ return response()->json([
+ 'host' => $registryHost,
+ 'token' => $registryToken,
+ ]);
+ }
}
diff --git a/server/src/Http/Filter/RegistryExtensionFilter.php b/server/src/Http/Filter/RegistryExtensionFilter.php
index 30adca3..7b4f0d3 100644
--- a/server/src/Http/Filter/RegistryExtensionFilter.php
+++ b/server/src/Http/Filter/RegistryExtensionFilter.php
@@ -3,7 +3,7 @@
namespace Fleetbase\RegistryBridge\Http\Filter;
use Fleetbase\Http\Filter\Filter;
-use Fleetbase\Support\Utils;
+use Fleetbase\RegistryBridge\Support\Utils;
use Illuminate\Support\Str;
class RegistryExtensionFilter extends Filter
diff --git a/server/src/Models/RegistryExtension.php b/server/src/Models/RegistryExtension.php
index c8e1721..f8f7d09 100644
--- a/server/src/Models/RegistryExtension.php
+++ b/server/src/Models/RegistryExtension.php
@@ -10,7 +10,6 @@
use Fleetbase\Models\Model;
use Fleetbase\Models\User;
use Fleetbase\RegistryBridge\Support\Utils;
-use Fleetbase\Support\Utils as SupportUtils;
use Fleetbase\Traits\HasApiModelBehavior;
use Fleetbase\Traits\HasMetaAttributes;
use Fleetbase\Traits\HasPublicId;
@@ -627,7 +626,7 @@ public function createStripeCheckoutSession(string $returnUri): \Stripe\Checkout
// Calculate the fee fleetbase takes for faciliation of extension
$totalAmount = $price->unit_amount;
- $facilitatorFee = SupportUtils::calculatePercentage(config('registry-bridge.facilitator_fee', 10), $totalAmount);
+ $facilitatorFee = Utils::calculatePercentage(config('registry-bridge.facilitator_fee', 10), $totalAmount);
// Get the stripe client to create the checkout session
$stripe = Utils::getStripeClient();
@@ -642,7 +641,7 @@ public function createStripeCheckoutSession(string $returnUri): \Stripe\Checkout
],
],
'mode' => 'payment',
- 'return_url' => SupportUtils::consoleUrl($returnUri) . '?extension_id=' . $this->uuid . '&checkout_session_id={CHECKOUT_SESSION_ID}',
+ 'return_url' => Utils::consoleUrl($returnUri) . '?extension_id=' . $this->uuid . '&checkout_session_id={CHECKOUT_SESSION_ID}',
'payment_intent_data' => [
'application_fee_amount' => $facilitatorFee,
'transfer_data' => [
diff --git a/server/src/Models/RegistryExtensionBundle.php b/server/src/Models/RegistryExtensionBundle.php
index eba8287..8a4dcd9 100644
--- a/server/src/Models/RegistryExtensionBundle.php
+++ b/server/src/Models/RegistryExtensionBundle.php
@@ -8,8 +8,8 @@
use Fleetbase\Models\Model;
use Fleetbase\Models\User;
use Fleetbase\RegistryBridge\Exceptions\InstallFailedException;
+use Fleetbase\RegistryBridge\Support\Utils;
use Fleetbase\Support\SocketCluster\SocketClusterService;
-use Fleetbase\Support\Utils;
use Fleetbase\Traits\HasApiModelBehavior;
use Fleetbase\Traits\HasMetaAttributes;
use Fleetbase\Traits\HasPublicId;
diff --git a/server/src/Providers/RegistryBridgeServiceProvider.php b/server/src/Providers/RegistryBridgeServiceProvider.php
index 6402bf4..00324f6 100644
--- a/server/src/Providers/RegistryBridgeServiceProvider.php
+++ b/server/src/Providers/RegistryBridgeServiceProvider.php
@@ -2,7 +2,9 @@
namespace Fleetbase\RegistryBridge\Providers;
+use Fleetbase\Models\Setting;
use Fleetbase\Providers\CoreServiceProvider;
+use Fleetbase\RegistryBridge\Support\Utils;
if (!class_exists(CoreServiceProvider::class)) {
throw new \Exception('Registry Bridge cannot be loaded without `fleetbase/core-api` installed!');
@@ -70,47 +72,31 @@ public function register()
*/
public function boot()
{
- static::bootRegistryAuth();
+ Utils::bootRegistryAuth();
$this->registerCommands();
$this->registerMiddleware();
$this->registerExpansionsFrom(__DIR__ . '/../Expansions');
$this->loadRoutesFrom(__DIR__ . '/../routes.php');
$this->loadMigrationsFrom(__DIR__ . '/../../migrations');
$this->mergeConfigFrom(__DIR__ . '/../../config/registry-bridge.php', 'registry-bridge');
+ $this->mergeConfigFromSettings();
}
- /**
- * Initializes and sets up the npm registry authentication configuration.
- *
- * This method constructs the registry authentication string from configuration settings,
- * checks for the existence of an npmrc file in the user's home directory, and creates it
- * with the registry authentication string if it doesn't already exist.
- *
- * The registry configuration and token are pulled from the application's configuration files.
- * It ensures the path to the .npmrc file is correctly formed regardless of trailing slashes
- * in the HOME directory path or the registry host configuration.
- *
- * @param bool $reset - Overwrites existing file, "resetting" the .npmrc
- *
- * @return void
- */
- public static function bootRegistryAuth(bool $reset = false)
+ public function mergeConfigFromSettings()
{
- $homeDirectory = rtrim(getenv('HOME'), '/');
- $authPath = $homeDirectory . '/.npmrc';
- $authString = '//' . str_replace(['http://', 'https://'], '', rtrim(config('registry-bridge.registry.host'), '/')) . '/:_authToken="' . config('registry-bridge.registry.token') . '"' . PHP_EOL;
- if (!file_exists($authPath) || $reset === true) {
- file_put_contents($authPath, $authString);
+ if (Setting::doesntHaveConnection()) {
+ return;
+ }
+
+ $registryHost = Setting::getByKey('registry-bridge.registry.host');
+ $registryToken = Setting::getByKey('registry-bridge.registry.token');
+
+ if ($registryHost) {
+ config(['registry-bridge.registry.host' => $registryHost->value]);
}
- $consolePath = rtrim(config('fleetbase.console.path'), '/');
- $registryPath = $consolePath . '/.npmrc';
- $registryString = implode(PHP_EOL, [
- 'registry=https://registry.npmjs.org/',
- '@fleetbase:registry=' . rtrim(config('registry-bridge.registry.host'), '/') . '/',
- ]) . PHP_EOL;
- if (!file_exists($registryPath) || $reset === true) {
- file_put_contents($registryPath, $registryString);
+ if ($registryToken) {
+ config(['registry-bridge.registry.token' => $registryToken->value]);
}
}
}
diff --git a/server/src/Support/Utils.php b/server/src/Support/Utils.php
index ec8b33c..8643a4e 100644
--- a/server/src/Support/Utils.php
+++ b/server/src/Support/Utils.php
@@ -2,9 +2,10 @@
namespace Fleetbase\RegistryBridge\Support;
+use Fleetbase\Support\Utils as SupportUtils;
use Stripe\StripeClient;
-class Utils
+class Utils extends SupportUtils
{
/**
* Get the StripeClient instance.
@@ -16,4 +17,138 @@ public static function getStripeClient(array $options = []): ?StripeClient
...$options,
]);
}
+
+ /**
+ * Set the npm configuration for the console.
+ *
+ * This function sets the npm configuration in the .npmrc file located in the console path.
+ * It sets the registry for npm and the Fleetbase scope registry.
+ * If the .npmrc file does not exist or if the reset flag is set to true, it writes the configuration to the file.
+ *
+ * @param bool $reset whether to reset the configuration if the file already exists
+ *
+ * @return bool true if the configuration was set, false otherwise
+ */
+ public static function setConsoleNpmrcConfig(bool $reset = false): bool
+ {
+ $npmrcPath = static::consolePath('.npmrc');
+ $registryHost = config('registry-bridge.registry.host', env('REGISTRY_HOST', 'https://registry.fleetbase.io'));
+ $config = implode(PHP_EOL, [
+ 'registry=https://registry.npmjs.org/',
+ '@fleetbase:registry=' . rtrim($registryHost, '/') . '/',
+ ]) . PHP_EOL;
+
+ if (!file_exists($npmrcPath) || $reset === true) {
+ file_put_contents($npmrcPath, $config, LOCK_EX);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Set the global npm authentication token.
+ *
+ * This function sets the authentication token in the global .npmrc file located in the user's home directory.
+ * If the .npmrc file does not exist or if the reset flag is set to true, it writes the authentication token to the file.
+ *
+ * @param bool $reset whether to reset the configuration if the file already exists
+ *
+ * @return bool true if the authentication token was set, false otherwise
+ */
+ public static function setGlobalNpmrcAuthKey(bool $reset = false): bool
+ {
+ $homePath = rtrim(getenv('HOME'), DIRECTORY_SEPARATOR);
+ $npmrcPath = $homePath . DIRECTORY_SEPARATOR . '.npmrc';
+ $registryHost = config('registry-bridge.registry.host', env('REGISTRY_HOST', 'https://registry.fleetbase.io'));
+ $registryToken = config('registry-bridge.registry.token', env('REGISTRY_TOKEN'));
+ $authString = '//' . str_replace(['http://', 'https://'], '', rtrim($registryHost, '/')) . '/:_authToken="' . $registryToken . '"' . PHP_EOL;
+
+ if (!file_exists($npmrcPath) || $reset === true) {
+ file_put_contents($npmrcPath, $authString, LOCK_EX);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Set the Composer authentication configuration.
+ *
+ * This function sets or updates the auth.json file with the registry token for authentication.
+ * It ensures that no bearer tokens with null or empty values are set.
+ *
+ * @return bool true if the operation was successful, otherwise false
+ *
+ * @throws \RuntimeException if there is a JSON encoding/decoding error
+ */
+ public static function setComposerAuthConfig(): bool
+ {
+ $composerAuthPath = base_path('auth.json');
+ $registryHost = static::getDomainFromUrl(config('registry-bridge.registry.host', env('REGISTRY_HOST', 'https://registry.fleetbase.io')), true);
+ $registryToken = config('registry-bridge.registry.token', env('REGISTRY_TOKEN'));
+
+ // Ensure the registry token is not null or empty
+ if (empty($registryToken)) {
+ return false;
+ }
+
+ $newBearerConfig = [
+ 'bearer' => [
+ $registryHost => $registryToken,
+ ],
+ ];
+
+ $currentConfig = [];
+
+ if (file_exists($composerAuthPath)) {
+ $jsonContent = file_get_contents($composerAuthPath);
+ $currentConfig = json_decode($jsonContent, true);
+ if ($currentConfig === null && json_last_error() !== JSON_ERROR_NONE) {
+ throw new \RuntimeException('Failed to decode JSON: ' . json_last_error_msg());
+ }
+
+ // Merge existing config with the new bearer config
+ if (isset($currentConfig['bearer'])) {
+ $currentConfig['bearer'] = array_merge($currentConfig['bearer'], $newBearerConfig['bearer']);
+ } else {
+ $currentConfig['bearer'] = $newBearerConfig['bearer'];
+ }
+ } else {
+ $currentConfig = $newBearerConfig;
+ }
+
+ $jsonContent = json_encode($currentConfig, JSON_PRETTY_PRINT);
+ if ($jsonContent === false) {
+ throw new \RuntimeException('Failed to encode JSON: ' . json_last_error_msg());
+ }
+
+ file_put_contents($composerAuthPath, $jsonContent, LOCK_EX);
+
+ return true;
+ }
+
+ /**
+ * Initializes and sets up the npm registry authentication configuration.
+ *
+ * This method constructs the registry authentication string from configuration settings,
+ * checks for the existence of an npmrc file in the user's home directory, and creates it
+ * with the registry authentication string if it doesn't already exist.
+ *
+ * The registry configuration and token are pulled from the application's configuration files.
+ * It ensures the path to the .npmrc file is correctly formed regardless of trailing slashes
+ * in the HOME directory path or the registry host configuration.
+ *
+ * @param bool $reset - Overwrites existing file, "resetting" the .npmrc
+ *
+ * @return void
+ */
+ public static function bootRegistryAuth(bool $reset = false)
+ {
+ Utils::setConsoleNpmrcConfig($reset);
+ Utils::setGlobalNpmrcAuthKey($reset);
+ Utils::setComposerAuthConfig();
+ }
}
diff --git a/server/src/routes.php b/server/src/routes.php
index 87d4ecd..b475c5a 100644
--- a/server/src/routes.php
+++ b/server/src/routes.php
@@ -26,6 +26,7 @@ function ($router) {
$router->post('registry-tokens', 'RegistryAuthController@createRegistryUser');
});
+ $router->post('composer-auth', 'RegistryAuthController@composerAuthentication')->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
$router->post('authenticate', 'RegistryAuthController@authenticate')->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
$router->post('add-user', 'RegistryAuthController@addUser')->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
$router->post('check-access', 'RegistryAuthController@checkAccess')->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
@@ -58,6 +59,8 @@ function ($router) {
$router->get('analytics', $controller('analytics'));
$router->get('installed', $controller('installed'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
$router->get('purchased', $controller('purchased'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
+ $router->get('config', $controller('getConfig'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
+ $router->post('config', $controller('saveConfig'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
});
$router->fleetbaseRoutes('registry-extension-bundles', function ($router, $controller) {
diff --git a/tests/integration/components/registry-admin-config-test.js b/tests/integration/components/registry-admin-config-test.js
new file mode 100644
index 0000000..c3e5579
--- /dev/null
+++ b/tests/integration/components/registry-admin-config-test.js
@@ -0,0 +1,26 @@
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'dummy/tests/helpers';
+import { render } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
+
+module('Integration | Component | registry-admin-config', function (hooks) {
+ setupRenderingTest(hooks);
+
+ test('it renders', async function (assert) {
+ // Set any properties with this.set('myProperty', 'value');
+ // Handle any actions with this.set('myAction', function(val) { ... });
+
+ await render(hbs``);
+
+ assert.dom().hasText('');
+
+ // Template block usage:
+ await render(hbs`
+
+ template block text
+
+ `);
+
+ assert.dom().hasText('template block text');
+ });
+});