@fleetbase/registry-bridge-engine 0.0.1 → 0.0.3

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.
Files changed (31) hide show
  1. package/addon/components/modals/create-registry-credentials.hbs +5 -0
  2. package/addon/components/registry-admin-config.hbs +16 -0
  3. package/addon/components/registry-admin-config.js +36 -0
  4. package/addon/controllers/developers/credentials.js +106 -0
  5. package/addon/engine.js +8 -2
  6. package/addon/routes/developers/credentials.js +8 -1
  7. package/addon/templates/application.hbs +1 -0
  8. package/addon/templates/developers/credentials.hbs +13 -1
  9. package/addon/templates/developers/payments/index.hbs +14 -13
  10. package/addon/templates/installed.hbs +3 -3
  11. package/app/components/modals/create-registry-credentials.js +1 -0
  12. package/app/components/registry-admin-config.js +1 -0
  13. package/app/controllers/developers/credentials.js +1 -0
  14. package/composer.json +2 -2
  15. package/extension.json +1 -1
  16. package/package.json +5 -5
  17. package/server/config/registry-bridge.php +2 -1
  18. package/server/migrations/2024_07_18_151000_add_auth_token_column_to_registry_users_table.php +28 -0
  19. package/server/src/Http/Controllers/Internal/v1/RegistryAuthController.php +163 -24
  20. package/server/src/Http/Controllers/Internal/v1/RegistryExtensionBundleController.php +1 -1
  21. package/server/src/Http/Controllers/Internal/v1/RegistryExtensionController.php +59 -1
  22. package/server/src/Http/Filter/RegistryExtensionFilter.php +1 -1
  23. package/server/src/Http/Requests/RegistryAuthRequest.php +3 -1
  24. package/server/src/Http/Resources/RegistryUser.php +0 -12
  25. package/server/src/Models/RegistryExtension.php +42 -3
  26. package/server/src/Models/RegistryExtensionBundle.php +1 -1
  27. package/server/src/Models/RegistryUser.php +111 -1
  28. package/server/src/Providers/RegistryBridgeServiceProvider.php +16 -31
  29. package/server/src/Support/Bridge.php +123 -0
  30. package/server/src/Support/Utils.php +136 -1
  31. package/server/src/routes.php +45 -31
@@ -2,9 +2,10 @@
2
2
 
3
3
  namespace Fleetbase\RegistryBridge\Support;
4
4
 
5
+ use Fleetbase\Support\Utils as SupportUtils;
5
6
  use Stripe\StripeClient;
6
7
 
7
- class Utils
8
+ class Utils extends SupportUtils
8
9
  {
9
10
  /**
10
11
  * Get the StripeClient instance.
@@ -16,4 +17,138 @@ class Utils
16
17
  ...$options,
17
18
  ]);
18
19
  }
20
+
21
+ /**
22
+ * Set the npm configuration for the console.
23
+ *
24
+ * This function sets the npm configuration in the .npmrc file located in the console path.
25
+ * It sets the registry for npm and the Fleetbase scope registry.
26
+ * If the .npmrc file does not exist or if the reset flag is set to true, it writes the configuration to the file.
27
+ *
28
+ * @param bool $reset whether to reset the configuration if the file already exists
29
+ *
30
+ * @return bool true if the configuration was set, false otherwise
31
+ */
32
+ public static function setConsoleNpmrcConfig(bool $reset = false): bool
33
+ {
34
+ $npmrcPath = static::consolePath('.npmrc');
35
+ $registryHost = config('registry-bridge.registry.host', env('REGISTRY_HOST', 'https://registry.fleetbase.io'));
36
+ $config = implode(PHP_EOL, [
37
+ 'registry=https://registry.npmjs.org/',
38
+ '@fleetbase:registry=' . rtrim($registryHost, '/') . '/',
39
+ ]) . PHP_EOL;
40
+
41
+ if (!file_exists($npmrcPath) || $reset === true) {
42
+ file_put_contents($npmrcPath, $config, LOCK_EX);
43
+
44
+ return true;
45
+ }
46
+
47
+ return false;
48
+ }
49
+
50
+ /**
51
+ * Set the global npm authentication token.
52
+ *
53
+ * This function sets the authentication token in the global .npmrc file located in the user's home directory.
54
+ * If the .npmrc file does not exist or if the reset flag is set to true, it writes the authentication token to the file.
55
+ *
56
+ * @param bool $reset whether to reset the configuration if the file already exists
57
+ *
58
+ * @return bool true if the authentication token was set, false otherwise
59
+ */
60
+ public static function setGlobalNpmrcAuthKey(bool $reset = false): bool
61
+ {
62
+ $homePath = rtrim(getenv('HOME'), DIRECTORY_SEPARATOR);
63
+ $npmrcPath = $homePath . DIRECTORY_SEPARATOR . '.npmrc';
64
+ $registryHost = config('registry-bridge.registry.host', env('REGISTRY_HOST', 'https://registry.fleetbase.io'));
65
+ $registryToken = config('registry-bridge.registry.token', env('REGISTRY_TOKEN'));
66
+ $authString = '//' . str_replace(['http://', 'https://'], '', rtrim($registryHost, '/')) . '/:_authToken="' . $registryToken . '"' . PHP_EOL;
67
+
68
+ if (!file_exists($npmrcPath) || $reset === true) {
69
+ file_put_contents($npmrcPath, $authString, LOCK_EX);
70
+
71
+ return true;
72
+ }
73
+
74
+ return false;
75
+ }
76
+
77
+ /**
78
+ * Set the Composer authentication configuration.
79
+ *
80
+ * This function sets or updates the auth.json file with the registry token for authentication.
81
+ * It ensures that no bearer tokens with null or empty values are set.
82
+ *
83
+ * @return bool true if the operation was successful, otherwise false
84
+ *
85
+ * @throws \RuntimeException if there is a JSON encoding/decoding error
86
+ */
87
+ public static function setComposerAuthConfig(): bool
88
+ {
89
+ $composerAuthPath = base_path('auth.json');
90
+ $registryHost = static::getDomainFromUrl(config('registry-bridge.registry.host', env('REGISTRY_HOST', 'https://registry.fleetbase.io')), true);
91
+ $registryToken = config('registry-bridge.registry.token', env('REGISTRY_TOKEN'));
92
+
93
+ // Ensure the registry token is not null or empty
94
+ if (empty($registryToken)) {
95
+ return false;
96
+ }
97
+
98
+ $newBearerConfig = [
99
+ 'bearer' => [
100
+ $registryHost => $registryToken,
101
+ ],
102
+ ];
103
+
104
+ $currentConfig = [];
105
+
106
+ if (file_exists($composerAuthPath)) {
107
+ $jsonContent = file_get_contents($composerAuthPath);
108
+ $currentConfig = json_decode($jsonContent, true);
109
+ if ($currentConfig === null && json_last_error() !== JSON_ERROR_NONE) {
110
+ throw new \RuntimeException('Failed to decode JSON: ' . json_last_error_msg());
111
+ }
112
+
113
+ // Merge existing config with the new bearer config
114
+ if (isset($currentConfig['bearer'])) {
115
+ $currentConfig['bearer'] = array_merge($currentConfig['bearer'], $newBearerConfig['bearer']);
116
+ } else {
117
+ $currentConfig['bearer'] = $newBearerConfig['bearer'];
118
+ }
119
+ } else {
120
+ $currentConfig = $newBearerConfig;
121
+ }
122
+
123
+ $jsonContent = json_encode($currentConfig, JSON_PRETTY_PRINT);
124
+ if ($jsonContent === false) {
125
+ throw new \RuntimeException('Failed to encode JSON: ' . json_last_error_msg());
126
+ }
127
+
128
+ file_put_contents($composerAuthPath, $jsonContent, LOCK_EX);
129
+
130
+ return true;
131
+ }
132
+
133
+ /**
134
+ * Initializes and sets up the npm registry authentication configuration.
135
+ *
136
+ * This method constructs the registry authentication string from configuration settings,
137
+ * checks for the existence of an npmrc file in the user's home directory, and creates it
138
+ * with the registry authentication string if it doesn't already exist.
139
+ *
140
+ * The registry configuration and token are pulled from the application's configuration files.
141
+ * It ensures the path to the .npmrc file is correctly formed regardless of trailing slashes
142
+ * in the HOME directory path or the registry host configuration.
143
+ *
144
+ * @param bool $reset - Overwrites existing file, "resetting" the .npmrc
145
+ *
146
+ * @return void
147
+ */
148
+ public static function bootRegistryAuth(bool $reset = false)
149
+ {
150
+ Utils::setConsoleNpmrcConfig($reset);
151
+ Utils::setGlobalNpmrcAuthKey($reset);
152
+ Utils::setComposerAuthConfig();
153
+ }
19
154
  }
@@ -13,45 +13,59 @@ use Illuminate\Support\Facades\Route;
13
13
  |
14
14
  */
15
15
 
16
- Route::get('~registry/test', 'Fleetbase\RegistryBridge\Http\Controllers\Internal\v1\RegistryAuthController@test');
17
-
18
16
  Route::prefix(config('internals.api.routing.prefix', '~registry'))->middleware(['fleetbase.registry'])->namespace('Fleetbase\RegistryBridge\Http\Controllers')->group(
19
17
  function ($router) {
20
18
  /*
21
19
  * Internal Routes v1
22
20
  */
23
21
  $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
22
  $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]);
23
+ $router->group(['middleware' => ['fleetbase.protected', 'throttle:60,1']], function ($router) {
24
+ $router->get('registry-tokens', 'RegistryAuthController@getRegistryTokens');
25
+ $router->delete('registry-tokens/{id}', 'RegistryAuthController@deleteRegistryToken');
26
+ $router->post('registry-tokens', 'RegistryAuthController@createRegistryUser');
27
+ });
28
+
29
+ $router->post('composer-auth', 'RegistryAuthController@composerAuthentication')->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
30
+ $router->post('authenticate', 'RegistryAuthController@authenticate')->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
31
+ $router->post('add-user', 'RegistryAuthController@addUser')->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
32
+ $router->post('check-access', 'RegistryAuthController@checkAccess')->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
33
+ $router->post('check-publish', 'RegistryAuthController@checkPublishAllowed')->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
52
34
  });
53
- $router->fleetbaseRoutes('registry-extension-bundles', function ($router, $controller) {
54
- $router->get('download', $controller('download'));
35
+
36
+ $router->group(['middleware' => ['fleetbase.protected', 'throttle:60,1']], function ($router) {
37
+ $router->get('categories', 'RegistryController@categories');
38
+ $router->get('engines', 'RegistryController@getInstalledEngines');
39
+
40
+ $router->group(['prefix' => 'installer'], function ($router) {
41
+ $router->post('install', 'ExtensionInstallerController@install');
42
+ $router->post('uninstall', 'ExtensionInstallerController@uninstall');
43
+ });
44
+
45
+ $router->group(['prefix' => 'payments'], function ($router) {
46
+ $router->post('account', 'RegistryPaymentsController@getStripeAccount');
47
+ $router->post('account-session', 'RegistryPaymentsController@getStripeAccountSession');
48
+ $router->get('has-stripe-connect-account', 'RegistryPaymentsController@hasStripeConnectAccount');
49
+ $router->post('create-checkout-session', 'RegistryPaymentsController@createStripeCheckoutSession');
50
+ $router->post('get-checkout-session', 'RegistryPaymentsController@getStripeCheckoutSessionStatus');
51
+ $router->get('author-received', 'RegistryPaymentsController@getAuthorReceivedPayments');
52
+ });
53
+
54
+ $router->fleetbaseRoutes('registry-extensions', function ($router, $controller) {
55
+ $router->post('{id}/submit', $controller('submit'));
56
+ $router->post('approve', $controller('approve'));
57
+ $router->post('reject', $controller('reject'));
58
+ $router->get('download-bundle', $controller('downloadBundle'));
59
+ $router->get('analytics', $controller('analytics'));
60
+ $router->get('installed', $controller('installed'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
61
+ $router->get('purchased', $controller('purchased'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
62
+ $router->get('config', $controller('getConfig'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
63
+ $router->post('config', $controller('saveConfig'))->middleware([Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class]);
64
+ });
65
+
66
+ $router->fleetbaseRoutes('registry-extension-bundles', function ($router, $controller) {
67
+ $router->get('download', $controller('download'));
68
+ });
55
69
  });
56
70
  });
57
71
  }