Skip to content

Commit 4d168a1

Browse files
authored
Merge pull request #805 from salesforcecli/sm/jwt-hyperforce-exception
feat: add hyperforce jwt exception
2 parents d929cea + f024e3e commit 4d168a1

File tree

6 files changed

+198
-95
lines changed

6 files changed

+198
-95
lines changed

messages/create.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,15 @@ See more details about this user by running "%s org user display -o %s".
7575
# flags.target-hub.deprecation
7676

7777
The --target-dev-hub flag is deprecated and is no longer used by this command. The flag will be removed in API version 57.0 or later.
78+
79+
# error.nonScratchOrg
80+
81+
This command works with only scratch orgs.
82+
83+
# error.jwtHyperforce
84+
85+
This command doesn't work when authorizing an org using the JWT flow if the org is on Hyperforce.
86+
87+
# error.jwtHyperforce.actions
88+
89+
- Authorize your Dev Hub with either the `org login web` or `org login sfdx-url` command. You can then successfully use the `org create user` command on scratch orgs that you create with your Dev Hub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"bugs": "https://github.com/forcedotcom/cli/issues",
77
"dependencies": {
88
"@oclif/core": "^3.12.0",
9-
"@salesforce/core": "^6.2.1",
9+
"@salesforce/core": "^6.3.0",
1010
"@salesforce/kit": "^3.0.15",
1111
"@salesforce/sf-plugins-core": "^5.0.5",
1212
"@salesforce/ts-types": "^2.0.9"

src/commands/org/create/user.ts

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@ import {
1414
DefaultUserFields,
1515
Logger,
1616
Messages,
17+
Org,
1718
REQUIRED_FIELDS,
1819
SfError,
1920
StateAggregator,
2021
User,
2122
UserFields,
2223
} from '@salesforce/core';
2324
import { mapKeys, omit, toBoolean } from '@salesforce/kit';
24-
import { Dictionary, ensureString, getString, isArray, JsonMap } from '@salesforce/ts-types';
25+
import { Dictionary, ensureString, getString, JsonMap } from '@salesforce/ts-types';
2526
import {
2627
Flags,
2728
loglevel,
@@ -46,13 +47,6 @@ type FailureMsg = {
4647
message: string;
4748
};
4849

49-
const permsetsStringToArray = (fieldsPermsets: string | string[] | undefined): string[] => {
50-
if (!fieldsPermsets) return [];
51-
return isArray(fieldsPermsets)
52-
? fieldsPermsets
53-
: fieldsPermsets.split(',').map((item) => item.replace("'", '').trim());
54-
};
55-
5650
export class CreateUserCommand extends SfCommand<CreateUserOutput> {
5751
public static strict = false;
5852
public static readonly deprecateAliases = true;
@@ -106,7 +100,8 @@ export class CreateUserCommand extends SfCommand<CreateUserOutput> {
106100
const logger = await Logger.child(this.constructor.name);
107101
this.varargs = parseVarArgs({}, argv as string[]);
108102

109-
const conn = flags['target-org'].getConnection(flags['api-version']);
103+
const conn = await getValidatedConnection(flags['target-org'], flags['api-version']);
104+
110105
const defaultUserFields = await DefaultUserFields.create({
111106
templateUser: ensureString(flags['target-org'].getUsername()),
112107
});
@@ -315,3 +310,26 @@ const catchCreateUser = async (respBody: Error, fields: UserFields, conn: Connec
315310
throw SfError.wrap(errMessage);
316311
}
317312
};
313+
314+
/** the org must be a scratch org AND not use JWT with hyperforce */
315+
const getValidatedConnection = async (targetOrg: Org, apiVersion?: string): Promise<Connection> => {
316+
if (!(await targetOrg.determineIfScratch())) {
317+
throw messages.createError('error.nonScratchOrg');
318+
}
319+
const conn = targetOrg.getConnection(apiVersion);
320+
if (
321+
conn.getAuthInfo().isJwt() &&
322+
// hyperforce sandbox instances end in S like USA254S
323+
targetOrg.getField<string>(Org.Fields.CREATED_ORG_INSTANCE).endsWith('S')
324+
) {
325+
throw messages.createError('error.jwtHyperforce');
326+
}
327+
return conn;
328+
};
329+
330+
const permsetsStringToArray = (fieldsPermsets: string | string[] | undefined): string[] => {
331+
if (!fieldsPermsets) return [];
332+
return Array.isArray(fieldsPermsets)
333+
? fieldsPermsets
334+
: fieldsPermsets.split(',').map((item) => item.replace("'", '').trim());
335+
};

src/commands/org/display/user.ts

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import { dirname } from 'node:path';
99
import { fileURLToPath } from 'node:url';
1010
import { AuthFields, Connection, Logger, Messages, StateAggregator } from '@salesforce/core';
11-
import { ensureString, getString } from '@salesforce/ts-types';
11+
import { ensureString } from '@salesforce/ts-types';
1212
import {
1313
loglevel,
1414
optionalHubFlagWithDeprecations,
@@ -75,7 +75,9 @@ export class DisplayUserCommand extends SfCommand<DisplayUserResult> {
7575
profileName = 'unknown';
7676
const logger = await Logger.child(this.constructor.name);
7777
logger.debug(
78-
`Query for the profile name failed for username: ${username} with message: ${getString(err, 'message')}`
78+
`Query for the profile name failed for username: ${username} with message: ${
79+
err instanceof Error ? err.message : ''
80+
}`
7981
);
8082
}
8183

@@ -87,7 +89,11 @@ export class DisplayUserCommand extends SfCommand<DisplayUserResult> {
8789
} catch (err) {
8890
userId = 'unknown';
8991
const logger = await Logger.child(this.constructor.name);
90-
logger.debug(`Query for the user ID failed for username: ${username} with message: ${getString(err, 'message')}`);
92+
logger.debug(
93+
`Query for the user ID failed for username: ${username} with message: ${
94+
err instanceof Error ? err.message : ''
95+
}`
96+
);
9197
}
9298

9399
const result: DisplayUserResult = {
@@ -118,24 +124,25 @@ export class DisplayUserCommand extends SfCommand<DisplayUserResult> {
118124
}
119125

120126
private print(result: DisplayUserResult): void {
121-
const columns = {
122-
key: { header: 'key' },
123-
label: { header: 'label' },
124-
};
125-
type TT = { key: string; label: string };
126-
const tableRow: TT[] = [];
127-
// to get proper capitalization and spacing, enter the rows
128-
tableRow.push({ key: 'Username', label: result.username ?? 'unknown' });
129-
tableRow.push({ key: 'Profile Name', label: result.profileName });
130-
tableRow.push({ key: 'Id', label: result.id });
131-
tableRow.push({ key: 'Org Id', label: result.orgId });
132-
tableRow.push({ key: 'Access Token', label: result.accessToken ?? '' });
133-
tableRow.push({ key: 'Instance Url', label: result.instanceUrl ?? '' });
134-
tableRow.push({ key: 'Login Url', label: result.loginUrl ?? '' });
135-
if (result.alias) tableRow.push({ key: 'Alias', label: result.alias });
136-
if (result.password) tableRow.push({ key: 'Password', label: result.password });
137-
138127
this.styledHeader('User Description');
139-
this.table(tableRow, columns);
128+
this.table(
129+
// to get proper capitalization and spacing, enter th e rows
130+
[
131+
{ key: 'Username', label: result.username ?? 'unknown' },
132+
{ key: 'Profile Name', label: result.profileName },
133+
{ key: 'Profile Name', label: result.profileName },
134+
{ key: 'Id', label: result.id },
135+
{ key: 'Org Id', label: result.orgId },
136+
...(result.accessToken ? [{ key: 'Access Token', label: result.accessToken }] : []),
137+
...(result.instanceUrl ? [{ key: 'Instance Url', label: result.instanceUrl }] : []),
138+
...(result.loginUrl ? [{ key: 'Login Url', label: result.loginUrl }] : []),
139+
...(result.alias ? [{ key: 'Alias', label: result.alias }] : []),
140+
...(result.password ? [{ key: 'Password', label: result.password }] : []),
141+
] satisfies Array<{ key: string; label: string }>,
142+
{
143+
key: { header: 'key' },
144+
label: { header: 'label' },
145+
}
146+
);
140147
}
141148
}

0 commit comments

Comments
 (0)