From 68d6ffe82335974d40387222d164b4cabdebbc2a Mon Sep 17 00:00:00 2001 From: soridalac Date: Wed, 4 Mar 2026 14:55:28 -0800 Subject: [PATCH 1/2] feat: add display message --- messages/web.login.md | 4 ++ src/commands/org/login/web.ts | 17 +++++++ test/commands/org/login/login.web.test.ts | 57 ++++++++++++++++++++++- 3 files changed, 76 insertions(+), 2 deletions(-) diff --git a/messages/web.login.md b/messages/web.login.md index e09c1908..870b3fc5 100644 --- a/messages/web.login.md +++ b/messages/web.login.md @@ -79,3 +79,7 @@ Unable to open the browser you specified (%s). # error.cannotOpenBrowser.actions - Ensure that %s is installed on your computer. Or specify a different browser using the --browser flag. + +# verificationCode + +- Your verification code is %s. Enter this in the browser window that just opened. SECURITY NOTE: Enter this PIN only if you initiated this login. diff --git a/src/commands/org/login/web.ts b/src/commands/org/login/web.ts index d3caf6a8..0e3c40a0 100644 --- a/src/commands/org/login/web.ts +++ b/src/commands/org/login/web.ts @@ -14,12 +14,20 @@ * limitations under the License. */ +import { createHash } from 'node:crypto'; import open, { apps, AppName } from 'open'; import { Flags, SfCommand, loglevel } from '@salesforce/sf-plugins-core'; import { AuthFields, AuthInfo, Logger, Messages, OAuth2Config, SfError, WebOAuthServer } from '@salesforce/core'; import { Env } from '@salesforce/kit'; import common from '../../../common.js'; +export const CODE_BUILDER_STATE_ENV_VAR = 'CODE_BUILDER_STATE'; + +export const getVerificationCode = (codeBuilderState: string): string => { + const hash = createHash('sha256').update(codeBuilderState, 'utf8').digest('hex'); + return hash.substring(0, 4); +}; + Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); const messages = Messages.loadMessages('@salesforce/plugin-auth', 'web.login'); const commonMessages = Messages.loadMessages('@salesforce/plugin-auth', 'messages'); @@ -112,6 +120,15 @@ export default class LoginWeb extends SfCommand { throw new SfError(messages.getMessage('error.headlessWebAuth')); } + // Display verification code for Code Builder mode if env is set + const env = new Env(); + const codeBuilderState = env.getString(CODE_BUILDER_STATE_ENV_VAR); + if (codeBuilderState) { + const verificationCode = getVerificationCode(codeBuilderState); + + this.log(messages.getMessage('verificationCode', [verificationCode])); + } + if (await common.shouldExitCommand(flags['no-prompt'])) return {}; // Add ca/eca to already existing auth info. diff --git a/test/commands/org/login/login.web.test.ts b/test/commands/org/login/login.web.test.ts index 3c7f9a5a..2fcbbe96 100644 --- a/test/commands/org/login/login.web.test.ts +++ b/test/commands/org/login/login.web.test.ts @@ -17,15 +17,21 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ import { Config } from '@oclif/core'; -import { AuthFields, AuthInfo, SfError } from '@salesforce/core'; +import { AuthFields, AuthInfo, SfError, Messages } from '@salesforce/core'; import { MockTestOrgData, TestContext } from '@salesforce/core/testSetup'; import { StubbedType, stubInterface, stubMethod } from '@salesforce/ts-sinon'; import { assert, expect } from 'chai'; import { Env } from '@salesforce/kit'; import { SfCommand, Ux } from '@salesforce/sf-plugins-core'; -import LoginWeb, { ExecuteLoginFlowParams } from '../../../../src/commands/org/login/web.js'; +import LoginWeb, { + ExecuteLoginFlowParams, + CODE_BUILDER_STATE_ENV_VAR, + getVerificationCode, +} from '../../../../src/commands/org/login/web.js'; describe('org:login:web', () => { + Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); + const messages = Messages.loadMessages('@salesforce/plugin-auth', 'web.login'); const $$ = new TestContext(); const testData = new MockTestOrgData(); const config = stubInterface($$.SANDBOX, { @@ -302,4 +308,51 @@ describe('org:login:web', () => { expect(callArgs.clientApp?.username).to.equal('test@example.com'); expect(callArgs.scopes).to.be.undefined; }); + + it('should display verification code when CODE_BUILDER_STATE env var is set', async () => { + const codeBuilderState = 'CODE_BUILDER_STATE'; + const envStub = $$.SANDBOX.stub(Env.prototype, 'getString'); + envStub.withArgs(CODE_BUILDER_STATE_ENV_VAR).returns(codeBuilderState); + envStub.returns(''); // Default for other calls + + $$.SANDBOX.stub(Env.prototype, 'getBoolean').returns(false); // Prevent container mode checks + + const logStub = stubMethod($$.SANDBOX, SfCommand.prototype, 'log'); + + const login = await createNewLoginCommand([], false, undefined); + await login.run(); + + // Verify that log was called with the verification code message + const verificationCode = getVerificationCode(codeBuilderState); + const calls = logStub.getCalls(); + const verificationCodeCall = calls.find( + (call) => typeof call.args[0] === 'string' && call.args[0].includes(verificationCode) + ); + expect(verificationCodeCall).to.exist; + expect(verificationCode).to.match(/^[0-9a-f]{4}$/); + expect(verificationCodeCall?.args[0]).to.include(messages.getMessage('verificationCode', [verificationCode])); + }); + + it('should not display verification code when CODE_BUILDER_STATE env var is not set', async () => { + const envStub = stubMethod($$.SANDBOX, Env.prototype, 'getString'); + envStub.withArgs('CODE_BUILDER_STATE').returns(undefined); + envStub.returns(''); + + $$.SANDBOX.stub(Env.prototype, 'getBoolean').returns(false); // Prevent container mode checks + + const logStub = $$.SANDBOX.stub(SfCommand.prototype, 'log'); + const logSuccessStub = $$.SANDBOX.stub(SfCommand.prototype, 'logSuccess'); + + const login = await createNewLoginCommand([], false, undefined); + await login.run(); + + // Verify that log was NOT called for verification code + expect(logStub.callCount).to.equal(0); + const calls = logSuccessStub.getCalls(); + const verificationCodeCall = calls.find( + (call) => call.args[0]?.includes('verification code') || call.args[0]?.includes('Enter this') + ); + expect(verificationCodeCall).to.not.exist; + expect(logSuccessStub.callCount).to.equal(1); + }); }); From f69d0b8578a5e1f325a95b4245f4b61f4ff143d9 Mon Sep 17 00:00:00 2001 From: svc-cli-bot Date: Wed, 4 Mar 2026 23:32:11 +0000 Subject: [PATCH 2/2] chore(release): 4.2.2-cb.0 [skip ci] --- README.md | 12 ++++++------ package.json | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index bc742b50..5c4eefc4 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ EXAMPLES $ sf org list auth ``` -_See code: [src/commands/org/list/auth.ts](https://github.com/salesforcecli/plugin-auth/blob/4.2.1/src/commands/org/list/auth.ts)_ +_See code: [src/commands/org/list/auth.ts](https://github.com/salesforcecli/plugin-auth/blob/4.2.2-cb.0/src/commands/org/list/auth.ts)_ ## `sf org login access-token` @@ -161,7 +161,7 @@ FLAG DESCRIPTIONS To specify a sandbox, set --instance-url to "https://--.sandbox.my.salesforce.com". ``` -_See code: [src/commands/org/login/access-token.ts](https://github.com/salesforcecli/plugin-auth/blob/4.2.1/src/commands/org/login/access-token.ts)_ +_See code: [src/commands/org/login/access-token.ts](https://github.com/salesforcecli/plugin-auth/blob/4.2.2-cb.0/src/commands/org/login/access-token.ts)_ ## `sf org login jwt` @@ -252,7 +252,7 @@ FLAG DESCRIPTIONS To specify a sandbox, set --instance-url to "https://--.sandbox.my.salesforce.com". ``` -_See code: [src/commands/org/login/jwt.ts](https://github.com/salesforcecli/plugin-auth/blob/4.2.1/src/commands/org/login/jwt.ts)_ +_See code: [src/commands/org/login/jwt.ts](https://github.com/salesforcecli/plugin-auth/blob/4.2.2-cb.0/src/commands/org/login/jwt.ts)_ ## `sf org login sfdx-url` @@ -322,7 +322,7 @@ EXAMPLES $ echo url | sf org login sfdx-url --sfdx-url-stdin ``` -_See code: [src/commands/org/login/sfdx-url.ts](https://github.com/salesforcecli/plugin-auth/blob/4.2.1/src/commands/org/login/sfdx-url.ts)_ +_See code: [src/commands/org/login/sfdx-url.ts](https://github.com/salesforcecli/plugin-auth/blob/4.2.2-cb.0/src/commands/org/login/sfdx-url.ts)_ ## `sf org login web` @@ -427,7 +427,7 @@ FLAG DESCRIPTIONS To specify a sandbox, set --instance-url to "https://--.sandbox.my.salesforce.com". ``` -_See code: [src/commands/org/login/web.ts](https://github.com/salesforcecli/plugin-auth/blob/4.2.1/src/commands/org/login/web.ts)_ +_See code: [src/commands/org/login/web.ts](https://github.com/salesforcecli/plugin-auth/blob/4.2.2-cb.0/src/commands/org/login/web.ts)_ ## `sf org logout` @@ -493,6 +493,6 @@ FLAG DESCRIPTIONS All orgs includes Dev Hubs, sandboxes, DE orgs, and expired, deleted, and unknown-status scratch orgs. ``` -_See code: [src/commands/org/logout.ts](https://github.com/salesforcecli/plugin-auth/blob/4.2.1/src/commands/org/logout.ts)_ +_See code: [src/commands/org/logout.ts](https://github.com/salesforcecli/plugin-auth/blob/4.2.2-cb.0/src/commands/org/logout.ts)_ diff --git a/package.json b/package.json index a2bd1ba8..3b334268 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@salesforce/plugin-auth", "description": "plugin for sf auth commands", - "version": "4.2.1", + "version": "4.2.2-cb.0", "author": "Salesforce", "bugs": "https://github.com/forcedotcom/cli/issues", "enableO11y": true,