@qodalis/cli-core 2.0.0-beta.13 → 2.0.0-beta.15

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/public-api.js CHANGED
@@ -667,7 +667,7 @@ var require_compare_build = __commonJS({
667
667
  var require_sort = __commonJS({
668
668
  "../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/sort.js"(exports$1, module) {
669
669
  var compareBuild = require_compare_build();
670
- var sort = (list, loose) => list.sort((a, b) => compareBuild(a, b, loose));
670
+ var sort = (list2, loose) => list2.sort((a, b) => compareBuild(a, b, loose));
671
671
  module.exports = sort;
672
672
  }
673
673
  });
@@ -676,7 +676,7 @@ var require_sort = __commonJS({
676
676
  var require_rsort = __commonJS({
677
677
  "../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/functions/rsort.js"(exports$1, module) {
678
678
  var compareBuild = require_compare_build();
679
- var rsort = (list, loose) => list.sort((a, b) => compareBuild(b, a, loose));
679
+ var rsort = (list2, loose) => list2.sort((a, b) => compareBuild(b, a, loose));
680
680
  module.exports = rsort;
681
681
  }
682
682
  });
@@ -2067,10 +2067,17 @@ var ICliTranslationService_TOKEN = "cli-translation-service";
2067
2067
  var ICliPermissionService_TOKEN = "cli-permission-service";
2068
2068
  var ICliFilePickerProvider_TOKEN = "cli-file-picker-provider";
2069
2069
  var ICliHttpClient_TOKEN = "cli-http-client";
2070
+ var ICliUserEventService_TOKEN = "cli-user-event-service";
2071
+ var ICliAuditService_TOKEN = "cli-audit-service";
2072
+ var ICliAuthorizationService_TOKEN = "cli-authorization-service";
2073
+ var ICliPermissionRegistry_TOKEN = "cli-permission-registry";
2074
+ var ICliSessionsService_TOKEN = "cli-sessions-service";
2075
+ var ICliKeyValueStore_TOKEN = "cli-key-value-store";
2070
2076
 
2071
2077
  // src/lib/interfaces/services.ts
2072
2078
  var ICliServerAuthTokenProvider_TOKEN = "cli-server-auth-token-provider";
2073
2079
  var ICliServerAuthService_TOKEN = "cli-server-auth-service";
2080
+ var ICliServerManager_TOKEN = "cli-server-manager";
2074
2081
 
2075
2082
  // src/lib/models/server.ts
2076
2083
  function resolveHeaders(provider) {
@@ -2112,6 +2119,113 @@ var enums = {
2112
2119
  CliLogLevel
2113
2120
  };
2114
2121
 
2122
+ // src/lib/interfaces/command-guards.ts
2123
+ var ICliCommandGuard_TOKEN = "cli-command-guard";
2124
+
2125
+ // src/lib/utils/permissions.ts
2126
+ function cliPermissionMatches(granted, required) {
2127
+ const g = granted.trim().toLowerCase().split(":");
2128
+ const r = required.trim().toLowerCase().split(":");
2129
+ for (let i = 0; i < g.length; i++) {
2130
+ if (g[i] === "*" && i === g.length - 1) return true;
2131
+ if (i >= r.length || g[i] !== "*" && g[i] !== r[i]) return false;
2132
+ }
2133
+ return g.length === r.length;
2134
+ }
2135
+ function cliHasPermission(granted, required) {
2136
+ return !!granted?.some((p) => cliPermissionMatches(p, required));
2137
+ }
2138
+ function cliMissingPermissions(granted, required) {
2139
+ return required.filter((r) => !cliHasPermission(granted, r));
2140
+ }
2141
+ function cliMergePermissions(...lists) {
2142
+ const seen = /* @__PURE__ */ new Set();
2143
+ const out = [];
2144
+ for (const list2 of lists) {
2145
+ for (const p of list2 ?? []) {
2146
+ const key = p.trim();
2147
+ if (key && !seen.has(key.toLowerCase())) {
2148
+ seen.add(key.toLowerCase());
2149
+ out.push(key);
2150
+ }
2151
+ }
2152
+ }
2153
+ return out;
2154
+ }
2155
+ var CliServerPermissions = {
2156
+ /** Open a remote shell on a server (`ssh`) */
2157
+ ShellExecute: "shell:execute"
2158
+ };
2159
+ var CliUsersPermissions = {
2160
+ UsersRead: "users:read",
2161
+ UsersCreate: "users:create",
2162
+ UsersUpdate: "users:update",
2163
+ UsersDelete: "users:delete",
2164
+ GroupsRead: "groups:read",
2165
+ GroupsCreate: "groups:create",
2166
+ GroupsUpdate: "groups:update",
2167
+ GroupsDelete: "groups:delete",
2168
+ SessionsRead: "sessions:read",
2169
+ SessionsRevoke: "sessions:revoke",
2170
+ AuditRead: "audit:read",
2171
+ AuditClear: "audit:clear"
2172
+ };
2173
+
2174
+ // src/lib/interfaces/authorization.ts
2175
+ var CliAccessDeniedError = class _CliAccessDeniedError extends Error {
2176
+ constructor(message = "permission denied") {
2177
+ super(message);
2178
+ this.code = "EACCES";
2179
+ this.name = "CliAccessDeniedError";
2180
+ Object.setPrototypeOf(this, _CliAccessDeniedError.prototype);
2181
+ }
2182
+ };
2183
+ function isCliAccessDeniedError(error) {
2184
+ return error instanceof CliAccessDeniedError || !!error && typeof error === "object" && error.name === "CliAccessDeniedError";
2185
+ }
2186
+ function authorizationService(context) {
2187
+ try {
2188
+ return context.services.get(ICliAuthorizationService_TOKEN);
2189
+ } catch {
2190
+ return void 0;
2191
+ }
2192
+ }
2193
+ function cliAuthorize(context, permission) {
2194
+ const auth = authorizationService(context);
2195
+ return auth ? auth.can(permission) : true;
2196
+ }
2197
+ function cliCanAccess(context, resource, action, bypassPermissions) {
2198
+ const auth = authorizationService(context);
2199
+ return auth ? auth.canAccess(resource, action, bypassPermissions) : true;
2200
+ }
2201
+ function cliEvaluateAccess(principal, resource, action, bypassPermissions = []) {
2202
+ const mode = resource.permissions;
2203
+ const owner = resource.ownership;
2204
+ if (!mode || mode.length < 9 || !owner) return true;
2205
+ if (principal && (cliHasPermission(principal.permissions, "*") || bypassPermissions.some((p) => cliHasPermission(principal.permissions, p)))) {
2206
+ return true;
2207
+ }
2208
+ let offset = 6;
2209
+ if (principal) {
2210
+ if (owner.uid === principal.name || owner.uid === principal.id) offset = 0;
2211
+ else if (principal.groups.some((g) => g.toLowerCase() === owner.gid.toLowerCase())) offset = 3;
2212
+ }
2213
+ const index = offset + (action === "read" ? 0 : action === "write" ? 1 : 2);
2214
+ return mode.charAt(index) !== "-";
2215
+ }
2216
+
2217
+ // src/lib/interfaces/http-client.ts
2218
+ var CliHttpError = class _CliHttpError extends Error {
2219
+ constructor(message, status, statusText = "", body) {
2220
+ super(message);
2221
+ this.status = status;
2222
+ this.statusText = statusText;
2223
+ this.body = body;
2224
+ this.name = "CliHttpError";
2225
+ Object.setPrototypeOf(this, _CliHttpError.prototype);
2226
+ }
2227
+ };
2228
+
2115
2229
  // src/lib/constants/index.ts
2116
2230
  var DefaultLibraryAuthor = {
2117
2231
  name: "Nicolae Lupei",
@@ -2339,7 +2453,7 @@ function satisfiesVersionRange(installed, range) {
2339
2453
  }
2340
2454
 
2341
2455
  // src/lib/version.ts
2342
- var LIBRARY_VERSION = "2.0.0-beta.13";
2456
+ var LIBRARY_VERSION = "2.0.0-beta.15";
2343
2457
  var API_VERSION = 2;
2344
2458
 
2345
2459
  // src/lib/utils/server-version-negotiator.ts
@@ -2395,6 +2509,20 @@ function buildAuthenticatedWebSocketUrl(wsUrl, headers) {
2395
2509
  ).join("&");
2396
2510
  return `${wsUrl}${separator}${params}`;
2397
2511
  }
2512
+ async function resolveServerWebSocketUrl(services, serverName, wsUrl, configHeaders) {
2513
+ const authService = services?.get(ICliServerAuthService_TOKEN);
2514
+ const params = await authService?.getWebSocketParams?.(serverName);
2515
+ if (params) {
2516
+ return appendQueryParams(wsUrl, params);
2517
+ }
2518
+ return buildAuthenticatedWebSocketUrl(wsUrl, () => resolveServerHeaders(services, serverName, configHeaders));
2519
+ }
2520
+ function appendQueryParams(url, params) {
2521
+ const entries = Object.entries(params);
2522
+ if (!entries.length) return url;
2523
+ const query = entries.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join("&");
2524
+ return `${url}${url.includes("?") ? "&" : "?"}${query}`;
2525
+ }
2398
2526
 
2399
2527
  // src/lib/utils/panel-theme-sync.ts
2400
2528
  function hexToRgb(hex) {
@@ -2496,6 +2624,74 @@ function isWideCharacter(cp) {
2496
2624
  return false;
2497
2625
  }
2498
2626
 
2627
+ // src/lib/utils/access-guards.ts
2628
+ var list = (value) => Array.isArray(value) ? value.filter((v) => typeof v === "string" && v.trim()) : [];
2629
+ var authorization = (context) => {
2630
+ try {
2631
+ return context.services.get(ICliAuthorizationService_TOKEN);
2632
+ } catch {
2633
+ return void 0;
2634
+ }
2635
+ };
2636
+ function chain(processor) {
2637
+ const out = [];
2638
+ let current = processor;
2639
+ while (current && out.length < 32 && !out.includes(current)) {
2640
+ out.push(current);
2641
+ current = current.parent;
2642
+ }
2643
+ return out;
2644
+ }
2645
+ var requiredPermissionsOf = (p) => [...new Set(chain(p).flatMap((x) => list(x.metadata?.requiredPermissions)))];
2646
+ var requiredGroupLevels = (p) => chain(p).map((x) => list(x.metadata?.requiredGroups)).filter((g) => g.length > 0);
2647
+ var needsAuth = (p) => chain(p).some((x) => x.metadata?.requireAuth === true) || requiredGroupLevels(p).length > 0 || requiredPermissionsOf(p).length > 0;
2648
+ var cliRequireAuthGuard = {
2649
+ name: "access:require-auth",
2650
+ priority: -100,
2651
+ appliesTo: (processor, _command, context) => needsAuth(processor) && !!authorization(context),
2652
+ canActivate: (_command, processor, context) => authorization(context).getPrincipal() ? true : `${processor.command}: login required`
2653
+ };
2654
+ var cliRequiredGroupsGuard = {
2655
+ name: "access:required-groups",
2656
+ priority: -90,
2657
+ appliesTo: (processor, _command, context) => requiredGroupLevels(processor).length > 0 && !!authorization(context),
2658
+ canActivate: (_command, processor, context) => {
2659
+ const auth = authorization(context);
2660
+ const principal = auth.getPrincipal();
2661
+ if (!principal) return `${processor.command}: login required`;
2662
+ if (auth.can("*")) return true;
2663
+ for (const required of requiredGroupLevels(processor)) {
2664
+ const member = required.some((g) => principal.groups.some((pg) => pg.toLowerCase() === g.toLowerCase()));
2665
+ if (!member) return `${processor.command}: permission denied (requires group: ${required.join(" or ")})`;
2666
+ }
2667
+ return true;
2668
+ }
2669
+ };
2670
+ var cliRequiredPermissionsGuard = {
2671
+ name: "access:required-permissions",
2672
+ priority: -80,
2673
+ appliesTo: (processor, _command, context) => requiredPermissionsOf(processor).length > 0 && !!authorization(context),
2674
+ canActivate: (_command, processor, context) => {
2675
+ const principal = authorization(context).getPrincipal();
2676
+ if (!principal) return `${processor.command}: login required`;
2677
+ const missing = cliMissingPermissions(principal.permissions, requiredPermissionsOf(processor));
2678
+ return missing.length === 0 ? true : `${processor.command}: permission denied (requires ${missing.join(", ")})`;
2679
+ }
2680
+ };
2681
+ var cliAccessMetadataGuards = [
2682
+ cliRequireAuthGuard,
2683
+ cliRequiredGroupsGuard,
2684
+ cliRequiredPermissionsGuard
2685
+ ];
2686
+
2687
+ // src/lib/utils/server-target.ts
2688
+ function cliDefaultServer(context) {
2689
+ const servers = context.options?.servers ?? [];
2690
+ const manager = context.services?.get(ICliServerManager_TOKEN);
2691
+ const preferred = manager?.preferredServer?.();
2692
+ return (preferred ? servers.find((s) => s.name === preferred) : void 0) ?? servers[0];
2693
+ }
2694
+
2499
2695
  // src/lib/utils/index.ts
2500
2696
  var getParameterValue = (p, args) => {
2501
2697
  if (args[p.name] !== void 0) {
@@ -3700,36 +3896,61 @@ exports.BrowserFileTransferService = BrowserFileTransferService;
3700
3896
  exports.CANCELLATION_ERROR_MESSAGE = CANCELLATION_ERROR_MESSAGE;
3701
3897
  exports.CLI_CONFIGURE_STORE_NAME = CLI_CONFIGURE_STORE_NAME;
3702
3898
  exports.CancellablePromise = CancellablePromise;
3899
+ exports.CliAccessDeniedError = CliAccessDeniedError;
3703
3900
  exports.CliBackgroundColor = CliBackgroundColor;
3704
3901
  exports.CliForegroundColor = CliForegroundColor;
3902
+ exports.CliHttpError = CliHttpError;
3705
3903
  exports.CliIcon = CliIcon;
3706
3904
  exports.CliLogLevel = CliLogLevel;
3707
3905
  exports.CliModuleRegistry = CliModuleRegistry;
3906
+ exports.CliServerPermissions = CliServerPermissions;
3907
+ exports.CliUsersPermissions = CliUsersPermissions;
3708
3908
  exports.DEFAULT_DIR_PERMISSIONS = DEFAULT_DIR_PERMISSIONS;
3709
3909
  exports.DEFAULT_FILE_PERMISSIONS = DEFAULT_FILE_PERMISSIONS;
3710
3910
  exports.DefaultLibraryAuthor = DefaultLibraryAuthor;
3711
3911
  exports.DefaultThemeInfos = DefaultThemeInfos;
3712
3912
  exports.DefaultThemes = DefaultThemes;
3913
+ exports.ICliAuditService_TOKEN = ICliAuditService_TOKEN;
3713
3914
  exports.ICliAuthService_TOKEN = ICliAuthService_TOKEN;
3915
+ exports.ICliAuthorizationService_TOKEN = ICliAuthorizationService_TOKEN;
3916
+ exports.ICliCommandGuard_TOKEN = ICliCommandGuard_TOKEN;
3714
3917
  exports.ICliCompletionProvider_TOKEN = ICliCompletionProvider_TOKEN;
3715
3918
  exports.ICliDragDropService_TOKEN = ICliDragDropService_TOKEN;
3716
3919
  exports.ICliFilePickerProvider_TOKEN = ICliFilePickerProvider_TOKEN;
3717
3920
  exports.ICliFileTransferService_TOKEN = ICliFileTransferService_TOKEN;
3718
3921
  exports.ICliGroupsStoreService_TOKEN = ICliGroupsStoreService_TOKEN;
3719
3922
  exports.ICliHttpClient_TOKEN = ICliHttpClient_TOKEN;
3923
+ exports.ICliKeyValueStore_TOKEN = ICliKeyValueStore_TOKEN;
3924
+ exports.ICliPermissionRegistry_TOKEN = ICliPermissionRegistry_TOKEN;
3720
3925
  exports.ICliPermissionService_TOKEN = ICliPermissionService_TOKEN;
3721
3926
  exports.ICliServerAuthService_TOKEN = ICliServerAuthService_TOKEN;
3722
3927
  exports.ICliServerAuthTokenProvider_TOKEN = ICliServerAuthTokenProvider_TOKEN;
3928
+ exports.ICliServerManager_TOKEN = ICliServerManager_TOKEN;
3929
+ exports.ICliSessionsService_TOKEN = ICliSessionsService_TOKEN;
3723
3930
  exports.ICliTranslationService_TOKEN = ICliTranslationService_TOKEN;
3931
+ exports.ICliUserEventService_TOKEN = ICliUserEventService_TOKEN;
3724
3932
  exports.ICliUserSessionService_TOKEN = ICliUserSessionService_TOKEN;
3725
3933
  exports.ICliUsersStoreService_TOKEN = ICliUsersStoreService_TOKEN;
3726
3934
  exports.LIBRARY_VERSION = LIBRARY_VERSION;
3727
3935
  exports.ObjectDescriber = ObjectDescriber;
3728
3936
  exports.ServerVersionNegotiator = ServerVersionNegotiator;
3937
+ exports.appendQueryParams = appendQueryParams;
3729
3938
  exports.bootCliModule = bootCliModule;
3730
3939
  exports.bootUmdModule = bootUmdModule;
3731
3940
  exports.buildAuthenticatedWebSocketUrl = buildAuthenticatedWebSocketUrl;
3732
3941
  exports.clearTerminalLine = clearTerminalLine;
3942
+ exports.cliAccessMetadataGuards = cliAccessMetadataGuards;
3943
+ exports.cliAuthorize = cliAuthorize;
3944
+ exports.cliCanAccess = cliCanAccess;
3945
+ exports.cliDefaultServer = cliDefaultServer;
3946
+ exports.cliEvaluateAccess = cliEvaluateAccess;
3947
+ exports.cliHasPermission = cliHasPermission;
3948
+ exports.cliMergePermissions = cliMergePermissions;
3949
+ exports.cliMissingPermissions = cliMissingPermissions;
3950
+ exports.cliPermissionMatches = cliPermissionMatches;
3951
+ exports.cliRequireAuthGuard = cliRequireAuthGuard;
3952
+ exports.cliRequiredGroupsGuard = cliRequiredGroupsGuard;
3953
+ exports.cliRequiredPermissionsGuard = cliRequiredPermissionsGuard;
3733
3954
  exports.colorFirstWord = colorFirstWord;
3734
3955
  exports.colorizeJson = colorizeJson;
3735
3956
  exports.compareVersions = compareVersions;
@@ -3745,11 +3966,13 @@ exports.getPluginConfigValue = getPluginConfigValue;
3745
3966
  exports.getRightOfWord = getRightOfWord;
3746
3967
  exports.highlightTextWithBg = highlightTextWithBg;
3747
3968
  exports.initializeBrowserEnvironment = initializeBrowserEnvironment;
3969
+ exports.isCliAccessDeniedError = isCliAccessDeniedError;
3748
3970
  exports.loadPanelPosition = loadPanelPosition;
3749
3971
  exports.nextPanelPosition = nextPanelPosition;
3750
3972
  exports.resolveConfigurationCategories = resolveConfigurationCategories;
3751
3973
  exports.resolveHeaders = resolveHeaders;
3752
3974
  exports.resolveServerHeaders = resolveServerHeaders;
3975
+ exports.resolveServerWebSocketUrl = resolveServerWebSocketUrl;
3753
3976
  exports.satisfiesMinVersion = satisfiesMinVersion;
3754
3977
  exports.satisfiesVersionRange = satisfiesVersionRange;
3755
3978
  exports.savePanelPosition = savePanelPosition;