From f11ea44fb1bb97f80dade93c9d4fd99be6454e69 Mon Sep 17 00:00:00 2001 From: soridalac Date: Mon, 2 Mar 2026 17:14:07 -0800 Subject: [PATCH 1/7] feat: add display message in CodeBuilderMode --- messages/web.login.md | 4 ++++ src/commands/org/login/web.ts | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/messages/web.login.md b/messages/web.login.md index e09c1908..921c001a 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: Only enter this PIN if you initiated this login. diff --git a/src/commands/org/login/web.ts b/src/commands/org/login/web.ts index d3caf6a8..434bf759 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,14 @@ 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.logSuccess(messages.getMessage('verificationCode', [verificationCode])); + } + if (await common.shouldExitCommand(flags['no-prompt'])) return {}; // Add ca/eca to already existing auth info. From 2ac408a8ab85f219515116e69dc519b7ead8113b Mon Sep 17 00:00:00 2001 From: soridalac Date: Mon, 2 Mar 2026 17:27:04 -0800 Subject: [PATCH 2/7] feat: add test for env set/unset --- test/commands/org/login/login.web.test.ts | 46 ++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/test/commands/org/login/login.web.test.ts b/test/commands/org/login/login.web.test.ts index 3c7f9a5a..30f538e4 100644 --- a/test/commands/org/login/login.web.test.ts +++ b/test/commands/org/login/login.web.test.ts @@ -23,7 +23,11 @@ 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', () => { const $$ = new TestContext(); @@ -302,4 +306,44 @@ 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 logSuccessStub = stubMethod($$.SANDBOX, SfCommand.prototype, 'logSuccess'); + + const login = await createNewLoginCommand([], false, undefined); + await login.run(); + + // Verify that logSuccess was called with the verification code message + const verificationCode = getVerificationCode(codeBuilderState); + expect(logSuccessStub.callCount).to.be.greaterThan(0); + const calls = logSuccessStub.getCalls(); + const verificationCodeCall = calls.find( + (call) => typeof call.args[0] === 'string' && call.args[0].includes(verificationCode) + ); + expect(verificationCodeCall).to.exist; + }); + + 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(''); + const logSuccessStub = $$.SANDBOX.stub(SfCommand.prototype, 'logSuccess'); + + const login = await createNewLoginCommand([], false, undefined); + await login.run(); + + 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 0cca00222933f154039ac53dbb1e8711193e7432 Mon Sep 17 00:00:00 2001 From: soridalac Date: Mon, 2 Mar 2026 18:34:59 -0800 Subject: [PATCH 3/7] fix: change logSuccess to log --- src/commands/org/login/web.ts | 3 ++- test/commands/org/login/login.web.test.ts | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/commands/org/login/web.ts b/src/commands/org/login/web.ts index 434bf759..0e3c40a0 100644 --- a/src/commands/org/login/web.ts +++ b/src/commands/org/login/web.ts @@ -125,7 +125,8 @@ export default class LoginWeb extends SfCommand { const codeBuilderState = env.getString(CODE_BUILDER_STATE_ENV_VAR); if (codeBuilderState) { const verificationCode = getVerificationCode(codeBuilderState); - this.logSuccess(messages.getMessage('verificationCode', [verificationCode])); + + this.log(messages.getMessage('verificationCode', [verificationCode])); } if (await common.shouldExitCommand(flags['no-prompt'])) return {}; diff --git a/test/commands/org/login/login.web.test.ts b/test/commands/org/login/login.web.test.ts index 30f538e4..420f0668 100644 --- a/test/commands/org/login/login.web.test.ts +++ b/test/commands/org/login/login.web.test.ts @@ -315,15 +315,15 @@ describe('org:login:web', () => { $$.SANDBOX.stub(Env.prototype, 'getBoolean').returns(false); // Prevent container mode checks - const logSuccessStub = stubMethod($$.SANDBOX, SfCommand.prototype, 'logSuccess'); + const logStub = stubMethod($$.SANDBOX, SfCommand.prototype, 'log'); const login = await createNewLoginCommand([], false, undefined); await login.run(); - // Verify that logSuccess was called with the verification code message + // Verify that log was called with the verification code message const verificationCode = getVerificationCode(codeBuilderState); - expect(logSuccessStub.callCount).to.be.greaterThan(0); - const calls = logSuccessStub.getCalls(); + expect(logStub.callCount).to.be.greaterThan(0); + const calls = logStub.getCalls(); const verificationCodeCall = calls.find( (call) => typeof call.args[0] === 'string' && call.args[0].includes(verificationCode) ); From 09296450f149e4172fe2b89218a593c63a81a277 Mon Sep 17 00:00:00 2001 From: soridalac Date: Mon, 2 Mar 2026 21:05:52 -0800 Subject: [PATCH 4/7] fix: update test --- test/commands/org/login/login.web.test.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/test/commands/org/login/login.web.test.ts b/test/commands/org/login/login.web.test.ts index 420f0668..2fcbbe96 100644 --- a/test/commands/org/login/login.web.test.ts +++ b/test/commands/org/login/login.web.test.ts @@ -17,7 +17,7 @@ /* 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'; @@ -30,6 +30,8 @@ import LoginWeb, { } 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, { @@ -322,23 +324,30 @@ describe('org:login:web', () => { // Verify that log was called with the verification code message const verificationCode = getVerificationCode(codeBuilderState); - expect(logStub.callCount).to.be.greaterThan(0); 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') From ba3c346977469a43fe3a069043135a69888cd2a0 Mon Sep 17 00:00:00 2001 From: Sorida Lac <96142310+soridalac@users.noreply.github.com> Date: Tue, 3 Mar 2026 08:20:33 -0800 Subject: [PATCH 5/7] Update messages/web.login.md Co-authored-by: Juliet Shackell <63259011+jshackell-sfdc@users.noreply.github.com> --- messages/web.login.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messages/web.login.md b/messages/web.login.md index 921c001a..6394b2a8 100644 --- a/messages/web.login.md +++ b/messages/web.login.md @@ -82,4 +82,4 @@ Unable to open the browser you specified (%s). # verificationCode -- Your verification code is %s. Enter this in the browser window that just opened. SECURITY NOTE: Only enter this PIN if you initiated this login. +- Your verification code is %s. Enter this in the browser window that just opened. WARNING: Enter this verification code only if you initiated this login. From 005c91e397da74de4403ac015a03af7da7653f6c Mon Sep 17 00:00:00 2001 From: soridalac Date: Tue, 3 Mar 2026 08:59:51 -0800 Subject: [PATCH 6/7] fix: update the message --- messages/web.login.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messages/web.login.md b/messages/web.login.md index 6394b2a8..921c001a 100644 --- a/messages/web.login.md +++ b/messages/web.login.md @@ -82,4 +82,4 @@ Unable to open the browser you specified (%s). # verificationCode -- Your verification code is %s. Enter this in the browser window that just opened. WARNING: Enter this verification code only if you initiated this login. +- Your verification code is %s. Enter this in the browser window that just opened. SECURITY NOTE: Only enter this PIN if you initiated this login. From 052b6ad0fc0b2c4242d2dd70c682cab5d0d573d9 Mon Sep 17 00:00:00 2001 From: Sorida Lac <96142310+soridalac@users.noreply.github.com> Date: Tue, 3 Mar 2026 09:35:59 -0800 Subject: [PATCH 7/7] Update messages/web.login.md Co-authored-by: Juliet Shackell <63259011+jshackell-sfdc@users.noreply.github.com> --- messages/web.login.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messages/web.login.md b/messages/web.login.md index 921c001a..870b3fc5 100644 --- a/messages/web.login.md +++ b/messages/web.login.md @@ -82,4 +82,4 @@ Unable to open the browser you specified (%s). # verificationCode -- Your verification code is %s. Enter this in the browser window that just opened. SECURITY NOTE: Only enter this PIN if you initiated this login. +- 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.