-
Notifications
You must be signed in to change notification settings - Fork 21
@W-22438536 Auth commands #1667
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 11 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
807853e
feat: add show-access-token command
iowillhoit e2c1924
chore: add schema
iowillhoit 3b7905c
chore: add snapshot
iowillhoit 760a797
chore: remove unnecessary api-version flag
iowillhoit a758983
chore: minor refactor
iowillhoit f4cb11c
chore: longer timeout, timeout message
iowillhoit 9b2c933
feat: add show-sfdx-auth-url command
iowillhoit 32fbbc9
quick edit
jshackell-sfdc fa484a5
fix: few more edits
jshackell-sfdc f635aa6
feat: show-user-password command
iowillhoit a78d8ec
chore: pw messaging
iowillhoit 07b00b9
Apply suggestion from @iowillhoit
iowillhoit f1869ae
Update messages/org.auth.show-user-password.md
iowillhoit 3a6422d
fix: Apply suggestions from code review
jshackell-sfdc File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| # summary | ||
|
|
||
| Show the current access token for an org. | ||
|
|
||
| # description | ||
|
|
||
| Because access tokens are sensitive credentials that grant full access to an org, this command prompts for confirmation before revealing the token. Skip confirmation by specifying either the --no-prompt or --json flag. | ||
|
|
||
| # flags.no-prompt.summary | ||
|
|
||
| Skip the security warning and reveal the access token without confirmation. | ||
|
|
||
| # prompt.show-access-token | ||
|
|
||
| You're about to reveal the access token for "%s". This token grants full access to the org with your current permissions. Sharing or logging this token is equivalent to sharing your credentials. Do you want to continue? | ||
|
|
||
| # warning.show-access-token | ||
|
|
||
| This command exposes a sensitive Access Token that allows for subsequent activity using your current authenticated session. Sharing this information is equivalent to logging someone in under the current credential, resulting in unintended access and escalation of privilege. For additional information about org authorization, review https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_auth.htm. | ||
|
|
||
| # error.noAccessToken | ||
|
|
||
| No access token found for "%s". The org may need to be re-authenticated. | ||
|
|
||
| # examples | ||
|
|
||
| - Show the access token for the default org: | ||
|
|
||
| <%= config.bin %> <%= command.id %> | ||
|
|
||
| - Show the access token for an org with alias "my-org": | ||
|
|
||
| <%= config.bin %> <%= command.id %> --target-org my-org | ||
|
|
||
| - Show the access token without the confirmation prompt: | ||
|
|
||
| <%= config.bin %> <%= command.id %> --target-org my-org --no-prompt | ||
|
|
||
| - Get the access token as JSON for use in scripts: | ||
|
|
||
| <%= config.bin %> <%= command.id %> --target-org my-org --json |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| # summary | ||
|
|
||
| Show the SFDX Auth URL for an org. | ||
|
|
||
| # description | ||
|
|
||
| Shows the SFDX Auth URL for an org. This URL is only available for orgs authenticated via a web-based OAuth flow. This command prompts for confirmation before revealing it. Skip confirmation by specifying either the --no-prompt or --json flag. | ||
|
|
||
| # flags.no-prompt.summary | ||
|
|
||
| Skip the security warning and reveal the SFDX Auth URL without confirmation. | ||
|
|
||
| # prompt.show-sfdx-auth-url | ||
|
|
||
| You're about to reveal the SFDX Auth URL for "%s". This URL contains a refresh token that can be used to authenticate to the org without user interaction. Do you want to continue? | ||
|
|
||
| # warning.show-sfdx-auth-url | ||
|
|
||
| This command exposes an SFDX Auth URL. Unlike an access token, this credential contains a refresh token that allows extended access to an org. Avoid sharing or logging this URL. For additional information about org authorization, review https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_auth_url.htm. | ||
|
|
||
| # error.noRefreshToken | ||
|
|
||
| An SFDX Auth URL is not available for "%s". This URL is only available for orgs authenticated via a web-based login flow. Re-authenticate to the org using "sf org login web" to make it available. | ||
|
|
||
| # examples | ||
|
|
||
| - Show the SFDX Auth URL for the default org: | ||
|
|
||
| <%= config.bin %> <%= command.id %> | ||
|
|
||
| - Show the SFDX Auth URL for an org with alias "my-org": | ||
|
|
||
| <%= config.bin %> <%= command.id %> --target-org my-org | ||
|
|
||
| - Show the SFDX Auth URL without the confirmation prompt: | ||
|
|
||
| <%= config.bin %> <%= command.id %> --target-org my-org --no-prompt | ||
|
|
||
| - Get the SFDX Auth URL as JSON for use in scripts: | ||
|
|
||
| <%= config.bin %> <%= command.id %> --target-org my-org --json |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| # summary | ||
|
|
||
| Show the stored password for an org's user. | ||
|
|
||
| # description | ||
|
|
||
| Passwords are only available for orgs where a password was previously generated, such as by running "sf org generate password" or "sf org create user". Because passwords are sensitive credentials, this command prompts for confirmation before revealing it. Skip confirmation by specifying either the --no-prompt or --json flag. | ||
|
iowillhoit marked this conversation as resolved.
Outdated
|
||
|
|
||
| # flags.no-prompt.summary | ||
|
|
||
| Skip the security warning and reveal the password without confirmation. | ||
|
|
||
| # prompt.show-user-password | ||
|
|
||
| You're about to reveal the password for "%s". Do you want to continue? | ||
|
|
||
| # warning.show-user-password | ||
|
|
||
| This command exposes a user password. While a password alone is not sufficient to gain access to an org (additional factors like a security token or an enabled OAuth username-password flow are required), treat it as a sensitive credential and avoid sharing or logging it. | ||
|
jshackell-sfdc marked this conversation as resolved.
Outdated
|
||
|
|
||
| # error.noPassword | ||
|
|
||
| No password found for "%s". A password is only available if one was previously generated, such as by running "sf org generate password" or "sf org create user". | ||
|
iowillhoit marked this conversation as resolved.
Outdated
|
||
|
|
||
| # examples | ||
|
|
||
| - Show the password for the default org's user: | ||
|
|
||
| <%= config.bin %> <%= command.id %> | ||
|
|
||
| - Show the password for an org with alias "my-org": | ||
|
|
||
| <%= config.bin %> <%= command.id %> --target-org my-org | ||
|
|
||
| - Show the password without the confirmation prompt: | ||
|
|
||
| <%= config.bin %> <%= command.id %> --target-org my-org --no-prompt | ||
|
|
||
| - Get the password as JSON for use in scripts: | ||
|
|
||
| <%= config.bin %> <%= command.id %> --target-org my-org --json | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| { | ||
| "$schema": "http://json-schema.org/draft-07/schema#", | ||
| "$ref": "#/definitions/OrgAuthShowAccessTokenResult", | ||
| "definitions": { | ||
| "OrgAuthShowAccessTokenResult": { | ||
| "type": "object", | ||
| "properties": { | ||
| "accessToken": { | ||
| "type": "string" | ||
| } | ||
| }, | ||
| "required": ["accessToken"], | ||
| "additionalProperties": false | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| { | ||
| "$schema": "http://json-schema.org/draft-07/schema#", | ||
| "$ref": "#/definitions/OrgAuthShowSfdxAuthUrlResult", | ||
| "definitions": { | ||
| "OrgAuthShowSfdxAuthUrlResult": { | ||
| "type": "object", | ||
| "properties": { | ||
| "sfdxAuthUrl": { | ||
| "type": "string" | ||
| } | ||
| }, | ||
| "required": ["sfdxAuthUrl"], | ||
| "additionalProperties": false | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| { | ||
| "$schema": "http://json-schema.org/draft-07/schema#", | ||
| "$ref": "#/definitions/OrgAuthShowUserPasswordResult", | ||
| "definitions": { | ||
| "OrgAuthShowUserPasswordResult": { | ||
| "type": "object", | ||
| "properties": { | ||
| "password": { | ||
| "type": "string" | ||
| } | ||
| }, | ||
| "required": ["password"], | ||
| "additionalProperties": false | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| /* | ||
| * Copyright 2026, Salesforce, Inc. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| import { SfCommand, Flags } from '@salesforce/sf-plugins-core'; | ||
| import { AuthInfo, Messages, SfError } from '@salesforce/core'; | ||
|
|
||
| Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); | ||
| const messages = Messages.loadMessages('@salesforce/plugin-org', 'org.auth.show-access-token'); | ||
|
|
||
| export type OrgAuthShowAccessTokenResult = { | ||
| accessToken: string; | ||
| }; | ||
|
|
||
| export default class OrgAuthShowAccessToken extends SfCommand<OrgAuthShowAccessTokenResult> { | ||
| public static readonly summary = messages.getMessage('summary'); | ||
| public static readonly description = messages.getMessage('description'); | ||
| public static readonly examples = messages.getMessages('examples'); | ||
|
|
||
| public static readonly flags = { | ||
| 'target-org': Flags.requiredOrg(), | ||
| 'no-prompt': Flags.boolean({ | ||
| summary: messages.getMessage('flags.no-prompt.summary'), | ||
| char: 'p', | ||
| }), | ||
| }; | ||
|
|
||
| public async run(): Promise<OrgAuthShowAccessTokenResult> { | ||
| const { flags } = await this.parse(OrgAuthShowAccessToken); | ||
|
|
||
| const org = flags['target-org']; | ||
| const username = org.getUsername(); | ||
| try { | ||
| // The auth file can have a stale access token. Refresh it before getting the fields | ||
| await org.refreshAuth(); | ||
| } catch (error) { | ||
| // Even if this fails, we want to display the information we can read from the auth file | ||
| this.warn('Unable to refresh auth for org. Access token may be stale.'); | ||
| } | ||
|
|
||
| // Don't ask for confirmation if --json or --no-prompt is passed | ||
| if (!this.jsonEnabled() && !flags['no-prompt']) { | ||
| const confirmed = await this.confirm({ | ||
| message: messages.getMessage('prompt.show-access-token', [username]), | ||
| ms: 30_000, | ||
| }); | ||
| if (!confirmed) { | ||
| throw new SfError('Show access token confirmation denied or timed out.'); | ||
| } | ||
| } else { | ||
| // Note: We don't show this warning if the user has already been prompted | ||
| this.warn(messages.getMessage('warning.show-access-token')); | ||
| } | ||
|
|
||
| const authInfo = await AuthInfo.create({ username }); | ||
| const { accessToken } = authInfo.getFields(true); | ||
|
|
||
| if (!accessToken) { | ||
| throw messages.createError('error.noAccessToken', [username]); | ||
| } | ||
|
|
||
| this.table({ | ||
| overflow: 'wrap', | ||
| data: [{ key: 'Access Token', value: accessToken }], | ||
| }); | ||
|
|
||
| return { accessToken }; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| /* | ||
| * Copyright 2026, Salesforce, Inc. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| import { SfCommand, Flags } from '@salesforce/sf-plugins-core'; | ||
| import { AuthInfo, Messages, SfError } from '@salesforce/core'; | ||
|
|
||
| Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); | ||
| const messages = Messages.loadMessages('@salesforce/plugin-org', 'org.auth.show-sfdx-auth-url'); | ||
|
|
||
| export type OrgAuthShowSfdxAuthUrlResult = { | ||
| sfdxAuthUrl: string; | ||
| }; | ||
|
|
||
| export default class OrgAuthShowSfdxAuthUrl extends SfCommand<OrgAuthShowSfdxAuthUrlResult> { | ||
| public static readonly summary = messages.getMessage('summary'); | ||
| public static readonly description = messages.getMessage('description'); | ||
| public static readonly examples = messages.getMessages('examples'); | ||
|
|
||
| public static readonly flags = { | ||
| 'target-org': Flags.requiredOrg(), | ||
| 'no-prompt': Flags.boolean({ | ||
| summary: messages.getMessage('flags.no-prompt.summary'), | ||
| char: 'p', | ||
| }), | ||
| }; | ||
|
|
||
| public async run(): Promise<OrgAuthShowSfdxAuthUrlResult> { | ||
| const { flags } = await this.parse(OrgAuthShowSfdxAuthUrl); | ||
|
|
||
| const org = flags['target-org']; | ||
| const username = org.getUsername(); | ||
|
|
||
| if (!this.jsonEnabled() && !flags['no-prompt']) { | ||
| const confirmed = await this.confirm({ | ||
| message: messages.getMessage('prompt.show-sfdx-auth-url', [username]), | ||
| ms: 30_000, | ||
| }); | ||
| if (!confirmed) { | ||
| throw new SfError('Show SFDX auth URL confirmation denied or timed out.'); | ||
| } | ||
| } else { | ||
| this.warn(messages.getMessage('warning.show-sfdx-auth-url')); | ||
| } | ||
|
|
||
| const authInfo = await AuthInfo.create({ username }); | ||
| const { refreshToken } = authInfo.getFields(true); | ||
|
|
||
| if (!refreshToken) { | ||
| throw messages.createError('error.noRefreshToken', [username]); | ||
| } | ||
|
|
||
| const sfdxAuthUrl = authInfo.getSfdxAuthUrl(); | ||
|
|
||
| this.table({ | ||
| overflow: 'wrap', | ||
| data: [{ key: 'SFDX Auth URL', value: sfdxAuthUrl }], | ||
| }); | ||
|
|
||
| return { sfdxAuthUrl }; | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I DM'd you about this, but I'll ask here too. Is the idea that this CLI command can be used to show only the passwords that were generated in the DX project using a CLI command, such as
org generate passwordororg create user? In other words, if I create a user/password in Setup in the org, that password WON'T be showable with this command? If so, how about this description:---start---
This command shows only passwords that were generated locally in your DX project with either the
org generate passwordororg create userCLI command. If you generated a password for a user in Setup in your org, you can't show it with this command.Because passwords are sensitive credentials, this command prompts for confirmation before revealing it. Skip confirmation by specifying either the --no-prompt or --json flag.
---end---
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's correct, if you created a user/pw in Setup and then authed to it locally, the pw would not be stored locally.