Skip to content

Commit

Permalink
Merge pull request #805 from salesforcecli/sm/jwt-hyperforce-exception
Browse files Browse the repository at this point in the history
feat: add hyperforce jwt exception
  • Loading branch information
shetzel authored Dec 5, 2023
2 parents d929cea + f024e3e commit 4d168a1
Show file tree
Hide file tree
Showing 6 changed files with 198 additions and 95 deletions.
12 changes: 12 additions & 0 deletions messages/create.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,15 @@ See more details about this user by running "%s org user display -o %s".
# flags.target-hub.deprecation

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.

# error.nonScratchOrg

This command works with only scratch orgs.

# error.jwtHyperforce

This command doesn't work when authorizing an org using the JWT flow if the org is on Hyperforce.

# error.jwtHyperforce.actions

- 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.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"bugs": "https://github.com/forcedotcom/cli/issues",
"dependencies": {
"@oclif/core": "^3.12.0",
"@salesforce/core": "^6.2.1",
"@salesforce/core": "^6.3.0",
"@salesforce/kit": "^3.0.15",
"@salesforce/sf-plugins-core": "^5.0.5",
"@salesforce/ts-types": "^2.0.9"
Expand Down
36 changes: 27 additions & 9 deletions src/commands/org/create/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ import {
DefaultUserFields,
Logger,
Messages,
Org,
REQUIRED_FIELDS,
SfError,
StateAggregator,
User,
UserFields,
} from '@salesforce/core';
import { mapKeys, omit, toBoolean } from '@salesforce/kit';
import { Dictionary, ensureString, getString, isArray, JsonMap } from '@salesforce/ts-types';
import { Dictionary, ensureString, getString, JsonMap } from '@salesforce/ts-types';
import {
Flags,
loglevel,
Expand All @@ -46,13 +47,6 @@ type FailureMsg = {
message: string;
};

const permsetsStringToArray = (fieldsPermsets: string | string[] | undefined): string[] => {
if (!fieldsPermsets) return [];
return isArray(fieldsPermsets)
? fieldsPermsets
: fieldsPermsets.split(',').map((item) => item.replace("'", '').trim());
};

export class CreateUserCommand extends SfCommand<CreateUserOutput> {
public static strict = false;
public static readonly deprecateAliases = true;
Expand Down Expand Up @@ -106,7 +100,8 @@ export class CreateUserCommand extends SfCommand<CreateUserOutput> {
const logger = await Logger.child(this.constructor.name);
this.varargs = parseVarArgs({}, argv as string[]);

const conn = flags['target-org'].getConnection(flags['api-version']);
const conn = await getValidatedConnection(flags['target-org'], flags['api-version']);

const defaultUserFields = await DefaultUserFields.create({
templateUser: ensureString(flags['target-org'].getUsername()),
});
Expand Down Expand Up @@ -315,3 +310,26 @@ const catchCreateUser = async (respBody: Error, fields: UserFields, conn: Connec
throw SfError.wrap(errMessage);
}
};

/** the org must be a scratch org AND not use JWT with hyperforce */
const getValidatedConnection = async (targetOrg: Org, apiVersion?: string): Promise<Connection> => {
if (!(await targetOrg.determineIfScratch())) {
throw messages.createError('error.nonScratchOrg');
}
const conn = targetOrg.getConnection(apiVersion);
if (
conn.getAuthInfo().isJwt() &&
// hyperforce sandbox instances end in S like USA254S
targetOrg.getField<string>(Org.Fields.CREATED_ORG_INSTANCE).endsWith('S')
) {
throw messages.createError('error.jwtHyperforce');
}
return conn;
};

const permsetsStringToArray = (fieldsPermsets: string | string[] | undefined): string[] => {
if (!fieldsPermsets) return [];
return Array.isArray(fieldsPermsets)
? fieldsPermsets
: fieldsPermsets.split(',').map((item) => item.replace("'", '').trim());
};
49 changes: 28 additions & 21 deletions src/commands/org/display/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { AuthFields, Connection, Logger, Messages, StateAggregator } from '@salesforce/core';
import { ensureString, getString } from '@salesforce/ts-types';
import { ensureString } from '@salesforce/ts-types';
import {
loglevel,
optionalHubFlagWithDeprecations,
Expand Down Expand Up @@ -75,7 +75,9 @@ export class DisplayUserCommand extends SfCommand<DisplayUserResult> {
profileName = 'unknown';
const logger = await Logger.child(this.constructor.name);
logger.debug(
`Query for the profile name failed for username: ${username} with message: ${getString(err, 'message')}`
`Query for the profile name failed for username: ${username} with message: ${
err instanceof Error ? err.message : ''
}`
);
}

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

const result: DisplayUserResult = {
Expand Down Expand Up @@ -118,24 +124,25 @@ export class DisplayUserCommand extends SfCommand<DisplayUserResult> {
}

private print(result: DisplayUserResult): void {
const columns = {
key: { header: 'key' },
label: { header: 'label' },
};
type TT = { key: string; label: string };
const tableRow: TT[] = [];
// to get proper capitalization and spacing, enter the rows
tableRow.push({ key: 'Username', label: result.username ?? 'unknown' });
tableRow.push({ key: 'Profile Name', label: result.profileName });
tableRow.push({ key: 'Id', label: result.id });
tableRow.push({ key: 'Org Id', label: result.orgId });
tableRow.push({ key: 'Access Token', label: result.accessToken ?? '' });
tableRow.push({ key: 'Instance Url', label: result.instanceUrl ?? '' });
tableRow.push({ key: 'Login Url', label: result.loginUrl ?? '' });
if (result.alias) tableRow.push({ key: 'Alias', label: result.alias });
if (result.password) tableRow.push({ key: 'Password', label: result.password });

this.styledHeader('User Description');
this.table(tableRow, columns);
this.table(
// to get proper capitalization and spacing, enter th e rows
[
{ key: 'Username', label: result.username ?? 'unknown' },
{ key: 'Profile Name', label: result.profileName },
{ key: 'Profile Name', label: result.profileName },
{ key: 'Id', label: result.id },
{ key: 'Org Id', label: result.orgId },
...(result.accessToken ? [{ key: 'Access Token', label: result.accessToken }] : []),
...(result.instanceUrl ? [{ key: 'Instance Url', label: result.instanceUrl }] : []),
...(result.loginUrl ? [{ key: 'Login Url', label: result.loginUrl }] : []),
...(result.alias ? [{ key: 'Alias', label: result.alias }] : []),
...(result.password ? [{ key: 'Password', label: result.password }] : []),
] satisfies Array<{ key: string; label: string }>,
{
key: { header: 'key' },
label: { header: 'label' },
}
);
}
}
Loading

0 comments on commit 4d168a1

Please sign in to comment.