@aderis-erp/cli 1.0.15 → 1.1.0
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/README.md +30 -8
- package/dist/commands/access-groups.d.ts +0 -1
- package/dist/commands/access-groups.js +54 -78
- package/dist/commands/account-transaction-allocations.d.ts +0 -1
- package/dist/commands/account-transaction-allocations.js +51 -75
- package/dist/commands/account-transactions.d.ts +0 -1
- package/dist/commands/account-transactions.js +80 -94
- package/dist/commands/accounts.d.ts +0 -1
- package/dist/commands/accounts.js +59 -83
- package/dist/commands/agent-platform.d.ts +0 -1
- package/dist/commands/agent-platform.js +58 -82
- package/dist/commands/agent-runs.d.ts +39 -0
- package/dist/commands/agent-runs.js +1155 -0
- package/dist/commands/analytics.d.ts +0 -1
- package/dist/commands/analytics.js +52 -76
- package/dist/commands/{text-templates.d.ts → api-keys.d.ts} +1 -2
- package/dist/commands/api-keys.js +1150 -0
- package/dist/commands/async-jobs.d.ts +39 -0
- package/dist/commands/async-jobs.js +1158 -0
- package/dist/commands/audit-log.d.ts +0 -1
- package/dist/commands/audit-log.js +51 -75
- package/dist/commands/auth/login.d.ts +9 -0
- package/dist/commands/auth/login.js +73 -20
- package/dist/commands/auth/logout.d.ts +4 -0
- package/dist/commands/auth/logout.js +4 -0
- package/dist/commands/auth/status.js +26 -17
- package/dist/commands/auth/tenant.js +3 -6
- package/dist/commands/auth.d.ts +0 -1
- package/dist/commands/auth.js +5 -34
- package/dist/commands/bank-accounts.d.ts +0 -1
- package/dist/commands/bank-accounts.js +68 -91
- package/dist/commands/bank-integrations.d.ts +1 -1
- package/dist/commands/bank-integrations.js +71 -92
- package/dist/commands/business-partners.d.ts +1 -1
- package/dist/commands/business-partners.js +84 -100
- package/dist/commands/chat.d.ts +0 -1
- package/dist/commands/chat.js +57 -80
- package/dist/commands/config/add.d.ts +3 -0
- package/dist/commands/config/add.js +34 -16
- package/dist/commands/config/current.js +3 -0
- package/dist/commands/config/list.js +3 -0
- package/dist/commands/credit-card-accounts.d.ts +1 -1
- package/dist/commands/credit-card-accounts.js +72 -90
- package/dist/commands/delivery-notes.d.ts +0 -1
- package/dist/commands/delivery-notes.js +83 -105
- package/dist/commands/dunning-configs.d.ts +0 -1
- package/dist/commands/dunning-configs.js +54 -78
- package/dist/commands/dunning-reminders.d.ts +0 -1
- package/dist/commands/dunning-reminders.js +57 -81
- package/dist/commands/dunning-runs.d.ts +0 -1
- package/dist/commands/dunning-runs.js +50 -74
- package/dist/commands/email-transactions.d.ts +0 -1
- package/dist/commands/email-transactions.js +52 -76
- package/dist/commands/employees.d.ts +0 -1
- package/dist/commands/employees.js +81 -105
- package/dist/commands/entity-configurations.d.ts +0 -1
- package/dist/commands/entity-configurations.js +52 -76
- package/dist/commands/event-processor-mappings.d.ts +0 -1
- package/dist/commands/event-processor-mappings.js +54 -78
- package/dist/commands/files.d.ts +0 -1
- package/dist/commands/files.js +61 -85
- package/dist/commands/health.d.ts +0 -1
- package/dist/commands/health.js +54 -78
- package/dist/commands/imports.d.ts +39 -0
- package/dist/commands/imports.js +1151 -0
- package/dist/commands/inbox.d.ts +0 -1
- package/dist/commands/inbox.js +57 -80
- package/dist/commands/integration-identities.d.ts +40 -0
- package/dist/commands/integration-identities.js +1151 -0
- package/dist/commands/integrations.d.ts +0 -1
- package/dist/commands/integrations.js +52 -76
- package/dist/commands/item-categories.d.ts +0 -1
- package/dist/commands/item-categories.js +54 -78
- package/dist/commands/items.d.ts +0 -1
- package/dist/commands/items.js +54 -78
- package/dist/commands/journal-lines.d.ts +0 -1
- package/dist/commands/journal-lines.js +50 -74
- package/dist/commands/journals.d.ts +1 -1
- package/dist/commands/journals.js +75 -96
- package/dist/commands/ledgers.d.ts +3 -2
- package/dist/commands/ledgers.js +100 -95
- package/dist/commands/my-account.d.ts +39 -0
- package/dist/commands/my-account.js +1160 -0
- package/dist/commands/office-locations.d.ts +0 -1
- package/dist/commands/office-locations.js +54 -78
- package/dist/commands/payment-methods.d.ts +0 -1
- package/dist/commands/payment-methods.js +59 -83
- package/dist/commands/payment-runs.d.ts +0 -1
- package/dist/commands/payment-runs.js +66 -90
- package/dist/commands/payment-terms.d.ts +0 -1
- package/dist/commands/payment-terms.js +55 -79
- package/dist/commands/payments.d.ts +0 -1
- package/dist/commands/payments.js +56 -80
- package/dist/commands/payroll-runs.d.ts +43 -0
- package/dist/commands/payroll-runs.js +1188 -0
- package/dist/commands/permissions.d.ts +39 -0
- package/dist/commands/permissions.js +1146 -0
- package/dist/commands/price-lists.d.ts +0 -1
- package/dist/commands/price-lists.js +59 -83
- package/dist/commands/processor-mappings.d.ts +0 -1
- package/dist/commands/processor-mappings.js +53 -77
- package/dist/commands/processors.d.ts +0 -1
- package/dist/commands/processors.js +60 -85
- package/dist/commands/purchase-order-types.d.ts +0 -1
- package/dist/commands/purchase-order-types.js +54 -78
- package/dist/commands/purchase-orders.d.ts +0 -1
- package/dist/commands/purchase-orders.js +74 -97
- package/dist/commands/reports.d.ts +0 -1
- package/dist/commands/reports.js +54 -78
- package/dist/commands/roles.d.ts +39 -0
- package/dist/commands/{text-templates.js → roles.js} +64 -90
- package/dist/commands/salary-types.d.ts +0 -1
- package/dist/commands/salary-types.js +54 -78
- package/dist/commands/sales-invoices.d.ts +0 -1
- package/dist/commands/sales-invoices.js +90 -110
- package/dist/commands/sales-orders.d.ts +0 -1
- package/dist/commands/sales-orders.js +83 -105
- package/dist/commands/saved-views.d.ts +0 -1
- package/dist/commands/saved-views.js +52 -76
- package/dist/commands/scheduled-processor-mappings.d.ts +0 -1
- package/dist/commands/scheduled-processor-mappings.js +54 -78
- package/dist/commands/schedules.d.ts +0 -1
- package/dist/commands/schedules.js +58 -82
- package/dist/commands/switch.js +4 -4
- package/dist/commands/tag-configurations.d.ts +0 -1
- package/dist/commands/tag-configurations.js +56 -79
- package/dist/commands/tags.d.ts +0 -1
- package/dist/commands/tags.js +54 -78
- package/dist/commands/tax-codes.d.ts +0 -1
- package/dist/commands/tax-codes.js +57 -81
- package/dist/commands/tax-matrix.d.ts +0 -1
- package/dist/commands/tax-matrix.js +54 -78
- package/dist/commands/templates.d.ts +39 -0
- package/dist/commands/templates.js +1157 -0
- package/dist/commands/tenants.d.ts +0 -1
- package/dist/commands/tenants.js +58 -81
- package/dist/commands/tools.d.ts +0 -1
- package/dist/commands/tools.js +51 -75
- package/dist/commands/users.d.ts +42 -0
- package/dist/commands/users.js +1174 -0
- package/dist/commands/vat-declarations.d.ts +3 -1
- package/dist/commands/vat-declarations.js +78 -93
- package/dist/commands/vendor-invoices.d.ts +0 -1
- package/dist/commands/vendor-invoices.js +87 -110
- package/dist/commands/webhooks.d.ts +0 -1
- package/dist/commands/webhooks.js +56 -80
- package/dist/commands/workflows.d.ts +0 -1
- package/dist/commands/workflows.js +52 -76
- package/dist/lib/api-client.d.ts +6 -0
- package/dist/lib/api-client.js +16 -6
- package/dist/lib/auth/constants.d.ts +11 -0
- package/dist/lib/auth/constants.js +11 -0
- package/dist/lib/auth/errors.d.ts +17 -0
- package/dist/lib/auth/errors.js +22 -0
- package/dist/lib/auth/flow.d.ts +27 -0
- package/dist/lib/auth/flow.js +163 -0
- package/dist/lib/auth/guards.d.ts +5 -0
- package/dist/lib/auth/guards.js +14 -0
- package/dist/lib/auth/http.d.ts +16 -0
- package/dist/lib/auth/http.js +49 -0
- package/dist/lib/auth/index.d.ts +49 -0
- package/dist/lib/auth/index.js +228 -0
- package/dist/lib/auth/jwks.d.ts +19 -0
- package/dist/lib/auth/jwks.js +112 -0
- package/dist/lib/auth/keycloak-provider.d.ts +91 -0
- package/dist/lib/auth/keycloak-provider.js +244 -0
- package/dist/lib/auth/pages.d.ts +25 -0
- package/dist/lib/auth/pages.js +123 -0
- package/dist/lib/auth/pkce.d.ts +11 -0
- package/dist/lib/auth/pkce.js +17 -0
- package/dist/lib/auth/tokens.d.ts +59 -0
- package/dist/lib/auth/tokens.js +105 -0
- package/dist/lib/auth/types.d.ts +61 -0
- package/dist/lib/auth/types.js +1 -0
- package/dist/lib/auth/validated-url.d.ts +6 -0
- package/dist/lib/auth/validated-url.js +53 -0
- package/dist/lib/config.d.ts +13 -3
- package/dist/lib/config.js +24 -19
- package/oclif.manifest.json +2447 -641
- package/package.json +5 -4
- package/dist/lib/auth.d.ts +0 -43
- package/dist/lib/auth.js +0 -610
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { URL } from 'node:url';
|
|
2
|
+
/**
|
|
3
|
+
* Hosts the CLI may talk to. Every outbound URL the auth layer builds — API,
|
|
4
|
+
* Keycloak discovery and the endpoints discovery returns — goes through
|
|
5
|
+
* {@link buildValidatedUrl}, so a tampered config file or discovery document
|
|
6
|
+
* cannot redirect tokens elsewhere.
|
|
7
|
+
*/
|
|
8
|
+
const ALLOWED_HOSTS = new Set([
|
|
9
|
+
'aderis-erp-nonprod.cloud-iam.com',
|
|
10
|
+
'aderis-erp-prod.cloud-iam.com',
|
|
11
|
+
'api-dev.aderis.com',
|
|
12
|
+
'api-staging.aderis.com',
|
|
13
|
+
'api-test.aderis.com',
|
|
14
|
+
'api.aderis.com',
|
|
15
|
+
'iam-dev.aderis.com',
|
|
16
|
+
'iam-staging.aderis.com',
|
|
17
|
+
'iam-test.aderis.com',
|
|
18
|
+
'iam.aderis.com',
|
|
19
|
+
'localhost',
|
|
20
|
+
]);
|
|
21
|
+
function hasTraversal(segment) {
|
|
22
|
+
return segment.includes('/../') || /\/%2e%2e\//i.test(segment);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Validates `baseUrl` against the host allowlist and optionally appends `path`.
|
|
26
|
+
* Throws `Error('Invalid URL')` for anything off-list, non-http(s), or
|
|
27
|
+
* containing path traversal.
|
|
28
|
+
*/
|
|
29
|
+
export function buildValidatedUrl(baseUrl, path) {
|
|
30
|
+
try {
|
|
31
|
+
if (hasTraversal(baseUrl)) {
|
|
32
|
+
throw new Error('Invalid path');
|
|
33
|
+
}
|
|
34
|
+
const url = new URL(baseUrl);
|
|
35
|
+
if (!ALLOWED_HOSTS.has(url.hostname)) {
|
|
36
|
+
throw new Error(`Invalid host: ${url.hostname}`);
|
|
37
|
+
}
|
|
38
|
+
if (!['http:', 'https:'].includes(url.protocol)) {
|
|
39
|
+
throw new Error('Invalid protocol');
|
|
40
|
+
}
|
|
41
|
+
if (path) {
|
|
42
|
+
if (hasTraversal(path)) {
|
|
43
|
+
throw new Error('Invalid path');
|
|
44
|
+
}
|
|
45
|
+
const cleanPath = path.startsWith('/') ? path : '/' + path;
|
|
46
|
+
url.pathname = url.pathname.replace(/\/$/, '') + cleanPath;
|
|
47
|
+
}
|
|
48
|
+
return url.href;
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
throw new Error('Invalid URL');
|
|
52
|
+
}
|
|
53
|
+
}
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Conf from 'conf';
|
|
2
|
-
export type Environment = 'dev' | 'live' | 'staging';
|
|
2
|
+
export type Environment = 'dev' | 'live' | 'staging' | 'test';
|
|
3
3
|
/**
|
|
4
4
|
* How a context authenticates against the API.
|
|
5
5
|
*
|
|
@@ -12,10 +12,10 @@ export type Environment = 'dev' | 'live' | 'staging';
|
|
|
12
12
|
export type AuthType = 'api_key' | 'oauth2';
|
|
13
13
|
export interface BaseUrls {
|
|
14
14
|
api: string;
|
|
15
|
-
auth: string;
|
|
16
15
|
}
|
|
17
16
|
export declare const BASE_URLS: Record<Environment, BaseUrls>;
|
|
18
|
-
|
|
17
|
+
/** The Keycloak CLI client: one public client (PKCE S256, loopback redirect) in every realm. */
|
|
18
|
+
export declare const DEFAULT_KEYCLOAK_CLIENT_ID = "aderis-cli-login";
|
|
19
19
|
export interface TokenData {
|
|
20
20
|
access_token: string;
|
|
21
21
|
expires_at?: number;
|
|
@@ -34,6 +34,12 @@ export interface Context {
|
|
|
34
34
|
client_id?: string;
|
|
35
35
|
client_secret?: string;
|
|
36
36
|
environment: Environment;
|
|
37
|
+
/**
|
|
38
|
+
* Keycloak origin to use instead of the environment's default host
|
|
39
|
+
* (`keycloak` contexts only; https, allowlisted, origin without a path). The
|
|
40
|
+
* realm is still the environment's.
|
|
41
|
+
*/
|
|
42
|
+
keycloak_base_url?: string;
|
|
37
43
|
name: string;
|
|
38
44
|
tenant_id?: string;
|
|
39
45
|
tokens?: TokenData;
|
|
@@ -72,6 +78,10 @@ export declare function hasCredentials(context: Context): boolean;
|
|
|
72
78
|
* the context's auth type instead of always suggesting `auth login`.
|
|
73
79
|
*/
|
|
74
80
|
export declare function missingCredentialsMessage(context: Context): string;
|
|
81
|
+
/** Error message for an expired OAuth session; `aderis switch` matches on it to offer a re-login. */
|
|
82
|
+
export declare const SESSION_EXPIRED_MESSAGE = "Session expired. Please run: aderis auth login";
|
|
83
|
+
/** The error for a 401 on a context that holds a credential. */
|
|
84
|
+
export declare function unauthorizedMessage(context: Context): string;
|
|
75
85
|
/** Redact a key for display: first and last 4 characters only. */
|
|
76
86
|
export declare function maskApiKey(apiKey: string): string;
|
|
77
87
|
export declare function getBaseUrls(environment: Environment): BaseUrls;
|
package/dist/lib/config.js
CHANGED
|
@@ -3,26 +3,21 @@ import * as fs from 'node:fs';
|
|
|
3
3
|
import * as os from 'node:os';
|
|
4
4
|
import * as path from 'node:path';
|
|
5
5
|
export const BASE_URLS = {
|
|
6
|
-
dev: {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
},
|
|
10
|
-
live: {
|
|
11
|
-
api: 'https://api.aderis.com',
|
|
12
|
-
auth: 'https://auth.aderis.com',
|
|
13
|
-
},
|
|
14
|
-
staging: {
|
|
15
|
-
api: 'https://api-staging.aderis.com',
|
|
16
|
-
auth: 'https://auth-staging.aderis.com',
|
|
17
|
-
},
|
|
18
|
-
};
|
|
19
|
-
// Default OAuth client IDs per environment (public clients, no secret required)
|
|
20
|
-
export const DEFAULT_CLIENT_IDS = {
|
|
21
|
-
dev: '74fd96f8-cf4b-49d8-b713-2a121ea22910',
|
|
22
|
-
live: '970d9568-84c9-4613-b966-30d7e1d93828',
|
|
23
|
-
staging: 'bf0e5dd6-419f-4d64-8951-2c385533651f',
|
|
6
|
+
dev: { api: 'https://api-dev.aderis.com' },
|
|
7
|
+
live: { api: 'https://api.aderis.com' },
|
|
8
|
+
staging: { api: 'https://api-staging.aderis.com' },
|
|
9
|
+
test: { api: 'https://api-test.aderis.com' },
|
|
24
10
|
};
|
|
25
|
-
|
|
11
|
+
/** The Keycloak CLI client: one public client (PKCE S256, loopback redirect) in every realm. */
|
|
12
|
+
export const DEFAULT_KEYCLOAK_CLIENT_ID = 'aderis-cli-login';
|
|
13
|
+
/**
|
|
14
|
+
* Directory of `config.json`: `ADERIS_CONFIG_DIR`, resolved to an absolute path
|
|
15
|
+
* so a relative value does not depend on each command's working directory, or
|
|
16
|
+
* `~/.aderis`.
|
|
17
|
+
*/
|
|
18
|
+
const CONFIG_DIR = process.env.ADERIS_CONFIG_DIR
|
|
19
|
+
? path.resolve(process.env.ADERIS_CONFIG_DIR)
|
|
20
|
+
: path.join(os.homedir(), '.aderis');
|
|
26
21
|
// Ensure config directory exists
|
|
27
22
|
if (!fs.existsSync(CONFIG_DIR)) {
|
|
28
23
|
fs.mkdirSync(CONFIG_DIR, { mode: 0o700, recursive: true });
|
|
@@ -160,6 +155,16 @@ export function missingCredentialsMessage(context) {
|
|
|
160
155
|
? `No API key set for context "${context.name}". Run: aderis config set-api-key --context ${context.name}`
|
|
161
156
|
: `Not logged in to context "${context.name}". Run: aderis auth login --context ${context.name}`;
|
|
162
157
|
}
|
|
158
|
+
/** Error message for an expired OAuth session; `aderis switch` matches on it to offer a re-login. */
|
|
159
|
+
export const SESSION_EXPIRED_MESSAGE = 'Session expired. Please run: aderis auth login';
|
|
160
|
+
/** The error for a 401 on a context that holds a credential. */
|
|
161
|
+
export function unauthorizedMessage(context) {
|
|
162
|
+
if (getAuthType(context) === 'api_key') {
|
|
163
|
+
return `API key for context "${context.name}" was rejected. Check the key with: aderis config set-api-key --context ${context.name}`;
|
|
164
|
+
}
|
|
165
|
+
// TODO(infrastructure-stacks#152): return SESSION_EXPIRED_MESSAGE once the API accepts iam-* issuers.
|
|
166
|
+
return 'Session rejected by the API (issuer or audience mismatch) — see https://github.com/AderisERP/infrastructure-stacks/issues/152, or run: aderis auth login';
|
|
167
|
+
}
|
|
163
168
|
/** Redact a key for display: first and last 4 characters only. */
|
|
164
169
|
export function maskApiKey(apiKey) {
|
|
165
170
|
return apiKey.length <= 8 ? '*'.repeat(apiKey.length) : `${apiKey.slice(0, 4)}${'*'.repeat(8)}${apiKey.slice(-4)}`;
|