Skip to content

Commit

Permalink
feat: update password generation functionality
Browse files Browse the repository at this point in the history
generating password by retrieving password policies.
@W-5829533@
  • Loading branch information
vamsimundra committed Jul 1, 2021
1 parent 59d5231 commit b1e9c39
Showing 1 changed file with 45 additions and 3 deletions.
48 changes: 45 additions & 3 deletions src/commands/force/user/password/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import * as os from 'os';
import { flags, FlagsConfig, SfdxCommand } from '@salesforce/command';
import { Aliases, AuthInfo, Connection, Messages, Org, SfdxError, User } from '@salesforce/core';

Messages.importMessagesDirectory(__dirname);
const messages = Messages.loadMessages('@salesforce/plugin-user', 'password.generate');

Expand All @@ -16,6 +15,27 @@ interface PasswordData {
password: string;
}

interface PasswordConditions {
length: number;
complexity: number;
}

interface OrgPasswordPolicy {
passwordPolicies?: {
minimumPasswordLength: number;
complexity: string;
};
}

enum PasswordComplexityTypes {
NoRestriction = 0,
AlphaNumeric = 1,
UpperLowerCaseNumeric = 3,
UpperLowerCaseNumericSpecialCharacters = 4,
Any3UpperLowerCaseNumericSpecialCharacters = 5,
SpecialCharacters = 5,
}

export class UserPasswordGenerateCommand extends SfdxCommand {
public static readonly description = messages.getMessage('description');
public static readonly examples = messages.getMessage('examples').split(os.EOL);
Expand Down Expand Up @@ -45,13 +65,35 @@ export class UserPasswordGenerateCommand extends SfdxCommand {
const connection: Connection = await Connection.create({ authInfo });
const org = await Org.create({ connection });
const user: User = await User.create({ org });
const password = User.generatePasswordUtf8();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const list: any = await connection.metadata.list({ type: 'ProfilePasswordPolicy' });
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
const profPasswordPolicies: any = await connection.metadata.read('ProfilePasswordPolicy', [list.fullName]);
const passwordCondition: PasswordConditions = {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
length: profPasswordPolicies.minimumPasswordLength,
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
complexity: profPasswordPolicies.passwordComplexity,
};

if (!passwordCondition.length || !passwordCondition.complexity) {
const orgPasswordPolicies = await connection.metadata.read('SecuritySettings', ['passwordPolicies']);
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
const orgPasswordPolicy: OrgPasswordPolicy = JSON.parse(JSON.stringify(orgPasswordPolicies));
passwordCondition.length = passwordCondition.length
? passwordCondition.length
: orgPasswordPolicy.passwordPolicies.minimumPasswordLength;
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
passwordCondition.complexity = passwordCondition.complexity
? passwordCondition.length
: PasswordComplexityTypes[orgPasswordPolicy.passwordPolicies.complexity];
}
const password = User.generatePasswordUtf8(passwordCondition);
// we only need the Id, so instead of User.retrieve we'll just query
// this avoids permission issues if ProfileId is restricted for the user querying for it
const result: { Id: string } = await connection.singleRecordQuery(
`SELECT Id FROM User WHERE Username='${username}'`
);

// userId is used by `assignPassword` so we need to set it here
authInfo.getFields().userId = result.Id;
await user.assignPassword(authInfo, password);
Expand Down

0 comments on commit b1e9c39

Please sign in to comment.