Skip to content

Commit ab1fc71

Browse files
committed
feat: generated passwords default to 20 if unspecified or a lower value is provided @W-21055697@
1 parent 8a2ce43 commit ab1fc71

4 files changed

Lines changed: 54 additions & 16 deletions

File tree

messages/password.generate.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ To see a password that was previously generated, run "org display user".
2525

2626
<%= config.bin %> <%= command.id %>
2727

28-
- Generate a password that contains 12 characters for the original admin user of the scratch org with alias "my-scratch":
28+
- Generate a password that contains 25 characters for the original admin user of the scratch org with alias "my-scratch":
2929

30-
<%= config.bin %> <%= command.id %> --length 12 --target-org my-scratch
30+
<%= config.bin %> <%= command.id %> --length 25 --target-org my-scratch
3131

3232
- Generate a password for your default scratch org admin user that uses lower and upper case letters and numbers only:
3333

@@ -43,7 +43,7 @@ Comma-separated list of usernames or aliases to assign the password to; must hav
4343

4444
# flags.length.summary
4545

46-
Number of characters in the generated password; valid values are between 8 and 100.
46+
Number of characters in the generated password; valid values are between 20 and 100. Default value is 20.
4747

4848
# flags.complexity.summary
4949

@@ -66,6 +66,10 @@ version 51.0 of the Metadata API.
6666
- "features": ["EnableSetPasswordInApi"]
6767
- Then try creating the scratch org again.
6868

69+
# defaultingToLength20Password
70+
71+
Starting in Summer '26, passwords of length below 20 will be explicitly rejected. For now, generating a password of length 20 instead of the requested length.
72+
6973
# scratchFeaturesUrl
7074

7175
see https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs_def_file_config_values.htm

src/commands/force/user/password/generate.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export class ForceUserPasswordGenerateCommand extends UserPasswordGenerateBaseCo
4343
summary: messages.getMessage('flags.length.summary'),
4444
min: 8,
4545
max: 1000,
46-
default: 13,
46+
default: 20,
4747
}),
4848
// the higher the value, the stronger the password
4949
complexity: Flags.integer({

src/commands/org/generate/password.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export class GenerateUserPasswordCommand extends UserPasswordGenerateBaseCommand
5050
summary: messages.getMessage('flags.length.summary'),
5151
min: 8,
5252
max: 1000,
53-
default: 13,
53+
default: 20,
5454
}),
5555
// the higher the value, the stronger the password
5656
complexity: Flags.integer({
@@ -66,9 +66,14 @@ export class GenerateUserPasswordCommand extends UserPasswordGenerateBaseCommand
6666

6767
public async run(): Promise<GenerateResult> {
6868
const { flags } = await this.parse(GenerateUserPasswordCommand);
69+
let length: number = flags.length;
70+
if (length < 20) {
71+
this.info(messages.getMessage('defaultingToLength20Password'));
72+
length = 20;
73+
}
6974
return this.generate({
7075
usernames: ensureArray(flags['on-behalf-of'] ?? flags['target-org'].getUsername()),
71-
length: flags.length,
76+
length,
7277
complexity: flags.complexity,
7378
conn: flags['target-org'].getConnection(flags['api-version']),
7479
});

test/commands/password/generate.test.ts

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import { Connection, Messages, User } from '@salesforce/core';
1818
import { MockTestOrgData, TestContext } from '@salesforce/core/testSetup';
19+
import { stubSfCommandUx } from '@salesforce/sf-plugins-core';
1920
import { assert, expect } from 'chai';
2021
// dirty import to stub something we don't want to export from sfdx-core
2122
import { SecureBuffer } from '../../../node_modules/@salesforce/core/lib/crypto/secureBuffer.js';
@@ -83,16 +84,44 @@ describe('org:generate:password', () => {
8384
expect(result).to.deep.equal(expected);
8485
expect(queryStub.callCount).to.equal(1);
8586
});
86-
it('should generate a new passsword of length 12', async () => {
87-
await prepareStubs(false, false);
88-
const result = (await GenerateUserPasswordCommand.run([
89-
'--target-org',
90-
testOrg.username,
91-
'-l',
92-
'12',
93-
'--json',
94-
])) as PasswordData;
95-
expect(result.password.length).to.equal(12);
87+
88+
describe('--length handling', () => {
89+
it('when no length is specified, password should default to length 20', async () => {
90+
await prepareStubs(false, false);
91+
const result = (await GenerateUserPasswordCommand.run([
92+
'--target-org',
93+
testOrg.username,
94+
'--json',
95+
])) as PasswordData;
96+
97+
expect(result.password.length).to.equal(20);
98+
});
99+
100+
it('when length <20 is specified, logs info-level message and defaults to 20', async () => {
101+
await prepareStubs(false, false);
102+
const uxStubs = stubSfCommandUx($$.SANDBOX);
103+
const result = (await GenerateUserPasswordCommand.run([
104+
'--target-org',
105+
testOrg.username,
106+
'--length',
107+
'12',
108+
'--json',
109+
])) as PasswordData;
110+
expect(result.password.length).to.equal(20);
111+
expect(uxStubs.info.args.flat()).to.include(messages.getMessage('defaultingToLength20Password'));
112+
});
113+
114+
it('when length >20 is specified, length is used as-is', async () => {
115+
await prepareStubs(false, false);
116+
const result = (await GenerateUserPasswordCommand.run([
117+
'--target-org',
118+
testOrg.username,
119+
'--length',
120+
'50',
121+
'--json',
122+
])) as PasswordData;
123+
expect(result.password.length).to.equal(50);
124+
});
96125
});
97126
it('should throw the correct error with warning message', async () => {
98127
await prepareStubs(true);

0 commit comments

Comments
 (0)