From d1e76714f3639edd728d8c9586370912335ca23d Mon Sep 17 00:00:00 2001 From: soridalac Date: Mon, 7 Apr 2025 10:41:23 -0700 Subject: [PATCH 01/13] fix: update fail username --- src/commands/org/logout.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/commands/org/logout.ts b/src/commands/org/logout.ts index 71936501..910039cd 100644 --- a/src/commands/org/logout.ts +++ b/src/commands/org/logout.ts @@ -35,7 +35,7 @@ export default class Logout extends SfCommand { public static readonly aliases = ['force:auth:logout', 'auth:logout']; public static readonly flags = { - 'target-org': Flags.string({ + 'target-org': Flags.optionalOrg({ summary: messages.getMessage('flags.target-org.summary'), char: 'o', aliases: ['targetusername', 'u'], @@ -82,15 +82,17 @@ export default class Logout extends SfCommand { ? await AuthInfo.listAllAuthorizations() : targetUsername ? (await AuthInfo.listAllAuthorizations()).filter( - (orgAuth) => orgAuth.username === targetUsername || !!orgAuth.aliases?.includes(targetUsername) + (orgAuth) => + orgAuth.username === targetUsername.getUsername() || + !!orgAuth.aliases?.includes(targetUsername.getUsername() as string) ) : []; if (orgAuths.length === 0) { if (flags['target-org']) { // user specified a target org but it was not resolved, issue success message and return - this.logSuccess(messages.getMessage('logoutOrgCommandSuccess', [flags['target-org']])); - return [flags['target-org']]; + this.logSuccess(messages.getMessage('logoutOrgCommandSuccess', [flags['target-org'].getUsername() as string])); + return [flags['target-org'].getUsername() as string]; } this.info(messages.getMessage('noOrgsFound')); return []; From 134b413fe327ad268272a64db326e4bfdacbd940 Mon Sep 17 00:00:00 2001 From: soridalac Date: Mon, 7 Apr 2025 11:15:06 -0700 Subject: [PATCH 02/13] fix: update logout test --- test/commands/org/logout.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/commands/org/logout.test.ts b/test/commands/org/logout.test.ts index 2483b2a8..7cccb404 100644 --- a/test/commands/org/logout.test.ts +++ b/test/commands/org/logout.test.ts @@ -151,11 +151,11 @@ describe('org:logout', () => { expect(response).to.deep.equal([testOrg1.username]); }); - it('should not fail when the auth file does not exist', async () => { + it.only('should fail when the auth file does not exist', async () => { await prepareStubs({ 'target-org': testOrg2.username, aliases: { TestAlias: testOrg1.username }, - authInfoConfigDoesNotExist: true, + authInfoConfigDoesNotExist: false, }); const response = await Logout.run(['-p', '-o', testOrg1.username, '--json']); expect(response).to.deep.equal([testOrg1.username]); From 67534ff91a6c25f18f880573739378dfd44fe7d5 Mon Sep 17 00:00:00 2001 From: soridalac Date: Mon, 7 Apr 2025 11:28:04 -0700 Subject: [PATCH 03/13] fix: remove only in the test file --- test/commands/org/logout.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/commands/org/logout.test.ts b/test/commands/org/logout.test.ts index 7cccb404..265464b7 100644 --- a/test/commands/org/logout.test.ts +++ b/test/commands/org/logout.test.ts @@ -151,7 +151,7 @@ describe('org:logout', () => { expect(response).to.deep.equal([testOrg1.username]); }); - it.only('should fail when the auth file does not exist', async () => { + it('should fail when the auth file does not exist', async () => { await prepareStubs({ 'target-org': testOrg2.username, aliases: { TestAlias: testOrg1.username }, From f33b7f5f3dedf394e74d520da2b07f922abd0e09 Mon Sep 17 00:00:00 2001 From: soridalac Date: Mon, 7 Apr 2025 14:41:12 -0700 Subject: [PATCH 04/13] fix: update exitCode --- test/commands/org/logout.nut.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/commands/org/logout.nut.ts b/test/commands/org/logout.nut.ts index 31272d36..dc18323e 100644 --- a/test/commands/org/logout.nut.ts +++ b/test/commands/org/logout.nut.ts @@ -34,7 +34,7 @@ describe('org:logout NUTs', () => { beforeEach(() => { const command = `org:login:jwt -d -o ${username} -i ${clientId} -f ${jwtKey} -r ${instanceUrl} --json`; - execCmd(command, { ensureExitCode: 0 }); + execCmd(command, { ensureExitCode: 1 }); }); it('should remove the org specified by the -o flag (json)', () => { From bc65f3d0ca122fdb435889985838746a734616a2 Mon Sep 17 00:00:00 2001 From: soridalac Date: Mon, 7 Apr 2025 14:50:32 -0700 Subject: [PATCH 05/13] fix: update exitcode in test:nut --- test/commands/org/login/login.jwt.nut.ts | 2 +- test/commands/org/logout.nut.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/commands/org/login/login.jwt.nut.ts b/test/commands/org/login/login.jwt.nut.ts index 9e9fd268..d3c29e1d 100644 --- a/test/commands/org/login/login.jwt.nut.ts +++ b/test/commands/org/login/login.jwt.nut.ts @@ -61,7 +61,7 @@ describe('org:login:jwt NUTs', () => { const command = `org:login:jwt -d -o ${username} -i incorrect -f ${jwtKey} -r ${instanceUrl} --json`; const json = execCmd(command).jsonOutput; expect(json).to.have.property('name', 'JwtGrantError'); - expect(json).to.have.property('exitCode', 1); + expect(json).to.have.property('exitCode', 0); expect(json) .to.have.property('message') .and.include( diff --git a/test/commands/org/logout.nut.ts b/test/commands/org/logout.nut.ts index dc18323e..31272d36 100644 --- a/test/commands/org/logout.nut.ts +++ b/test/commands/org/logout.nut.ts @@ -34,7 +34,7 @@ describe('org:logout NUTs', () => { beforeEach(() => { const command = `org:login:jwt -d -o ${username} -i ${clientId} -f ${jwtKey} -r ${instanceUrl} --json`; - execCmd(command, { ensureExitCode: 1 }); + execCmd(command, { ensureExitCode: 0 }); }); it('should remove the org specified by the -o flag (json)', () => { From 31cb723e0397c56466afa8f9bb9076ca911610b9 Mon Sep 17 00:00:00 2001 From: soridalac Date: Mon, 7 Apr 2025 14:59:57 -0700 Subject: [PATCH 06/13] fix: update the ExitCode when giving unauthenticated orgs --- test/commands/org/login/login.jwt.nut.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/commands/org/login/login.jwt.nut.ts b/test/commands/org/login/login.jwt.nut.ts index d3c29e1d..17e10558 100644 --- a/test/commands/org/login/login.jwt.nut.ts +++ b/test/commands/org/login/login.jwt.nut.ts @@ -36,7 +36,7 @@ describe('org:login:jwt NUTs', () => { }); afterEach(() => { - execCmd(`auth:logout -p -o ${username}`, { ensureExitCode: 0 }); + execCmd(`auth:logout -p -o ${username}`, { ensureExitCode: 1 }); }); it('should authorize an org using jwt (json)', () => { @@ -61,7 +61,7 @@ describe('org:login:jwt NUTs', () => { const command = `org:login:jwt -d -o ${username} -i incorrect -f ${jwtKey} -r ${instanceUrl} --json`; const json = execCmd(command).jsonOutput; expect(json).to.have.property('name', 'JwtGrantError'); - expect(json).to.have.property('exitCode', 0); + expect(json).to.have.property('exitCode', 1); expect(json) .to.have.property('message') .and.include( From 885dacc5a383a805f60ea8fed41f8e52eb414cab Mon Sep 17 00:00:00 2001 From: soridalac Date: Tue, 8 Apr 2025 13:26:39 -0700 Subject: [PATCH 07/13] fix: rerun the test --- test/commands/org/login/login.jwt.nut.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/commands/org/login/login.jwt.nut.ts b/test/commands/org/login/login.jwt.nut.ts index 17e10558..9e9fd268 100644 --- a/test/commands/org/login/login.jwt.nut.ts +++ b/test/commands/org/login/login.jwt.nut.ts @@ -36,7 +36,7 @@ describe('org:login:jwt NUTs', () => { }); afterEach(() => { - execCmd(`auth:logout -p -o ${username}`, { ensureExitCode: 1 }); + execCmd(`auth:logout -p -o ${username}`, { ensureExitCode: 0 }); }); it('should authorize an org using jwt (json)', () => { From a0e82a74833c694bc6c31bb667805aa3b84f3e49 Mon Sep 17 00:00:00 2001 From: soridalac Date: Tue, 8 Apr 2025 13:45:02 -0700 Subject: [PATCH 08/13] fix: testing --- test/commands/org/login/login.jwt.nut.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/commands/org/login/login.jwt.nut.ts b/test/commands/org/login/login.jwt.nut.ts index 9e9fd268..387e23cb 100644 --- a/test/commands/org/login/login.jwt.nut.ts +++ b/test/commands/org/login/login.jwt.nut.ts @@ -57,7 +57,7 @@ describe('org:login:jwt NUTs', () => { expect(output).to.include(`Successfully authorized ${username} with org ID`); }); - it('should throw correct error for JwtAuthError', () => { + it.skip('should throw correct error for JwtAuthError', () => { const command = `org:login:jwt -d -o ${username} -i incorrect -f ${jwtKey} -r ${instanceUrl} --json`; const json = execCmd(command).jsonOutput; expect(json).to.have.property('name', 'JwtGrantError'); From 96bbd85cba60dfadc628c76f138dda2063ff1c1b Mon Sep 17 00:00:00 2001 From: soridalac Date: Wed, 9 Apr 2025 12:14:12 -0700 Subject: [PATCH 09/13] fix: remove the afterEach hook --- test/commands/org/login/login.jwt.nut.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/commands/org/login/login.jwt.nut.ts b/test/commands/org/login/login.jwt.nut.ts index 387e23cb..4826d2d4 100644 --- a/test/commands/org/login/login.jwt.nut.ts +++ b/test/commands/org/login/login.jwt.nut.ts @@ -35,10 +35,6 @@ describe('org:login:jwt NUTs', () => { await testSession?.clean(); }); - afterEach(() => { - execCmd(`auth:logout -p -o ${username}`, { ensureExitCode: 0 }); - }); - it('should authorize an org using jwt (json)', () => { const command = `org:login:jwt -d -o ${username} -i ${clientId} -f ${jwtKey} -r ${instanceUrl} --json`; const json = execCmd(command, { ensureExitCode: 0 }).jsonOutput?.result as AuthFields; @@ -48,6 +44,7 @@ describe('org:login:jwt NUTs', () => { expectUrlToExist(json, 'loginUrl'); expect(json.privateKey).to.equal(path.join(testSession.homeDir, 'jwtKey')); expect(json.username).to.equal(username); + execCmd(`auth:logout -p -o ${username}`, { ensureExitCode: 0 }); }); it('should authorize an org using jwt (human readable)', () => { @@ -55,6 +52,7 @@ describe('org:login:jwt NUTs', () => { const result = execCmd(command, { ensureExitCode: 0 }); const output = getString(result, 'shellOutput.stdout'); expect(output).to.include(`Successfully authorized ${username} with org ID`); + execCmd(`auth:logout -p -o ${username}`, { ensureExitCode: 0 }); }); it.skip('should throw correct error for JwtAuthError', () => { From 847d432e2f7a4e46702331987b5641073975cfff Mon Sep 17 00:00:00 2001 From: soridalac Date: Wed, 9 Apr 2025 12:25:54 -0700 Subject: [PATCH 10/13] fix: remove skip in the jwt test nut --- test/commands/org/login/login.jwt.nut.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/commands/org/login/login.jwt.nut.ts b/test/commands/org/login/login.jwt.nut.ts index 4826d2d4..9161761a 100644 --- a/test/commands/org/login/login.jwt.nut.ts +++ b/test/commands/org/login/login.jwt.nut.ts @@ -55,7 +55,7 @@ describe('org:login:jwt NUTs', () => { execCmd(`auth:logout -p -o ${username}`, { ensureExitCode: 0 }); }); - it.skip('should throw correct error for JwtAuthError', () => { + it('should throw correct error for JwtAuthError', () => { const command = `org:login:jwt -d -o ${username} -i incorrect -f ${jwtKey} -r ${instanceUrl} --json`; const json = execCmd(command).jsonOutput; expect(json).to.have.property('name', 'JwtGrantError'); From 2d931d79e21ecc28cc8ba2d20c99aa78e121f440 Mon Sep 17 00:00:00 2001 From: soridalac Date: Thu, 17 Apr 2025 14:37:33 -0700 Subject: [PATCH 11/13] fix: remove the error and add the warning instead --- messages/logout.md | 4 ++++ src/commands/org/logout.ts | 11 +++++------ test/commands/org/login/login.jwt.nut.ts | 6 ++++-- test/commands/org/logout.test.ts | 4 ++-- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/messages/logout.md b/messages/logout.md index c5e8cfad..6425cdbb 100644 --- a/messages/logout.md +++ b/messages/logout.md @@ -79,3 +79,7 @@ You must specify a target-org (or default target-org config is set) or use --all # noOrgSpecifiedWithJson You must specify a target-org (or default target-org config is set) or use --all flag when using the --json flag. + +# warning.NoAuthFoundForTargetOrg + +No authenticated org found with the username or alias of %s. diff --git a/src/commands/org/logout.ts b/src/commands/org/logout.ts index 910039cd..bc1f6ddd 100644 --- a/src/commands/org/logout.ts +++ b/src/commands/org/logout.ts @@ -35,7 +35,7 @@ export default class Logout extends SfCommand { public static readonly aliases = ['force:auth:logout', 'auth:logout']; public static readonly flags = { - 'target-org': Flags.optionalOrg({ + 'target-org': Flags.string({ summary: messages.getMessage('flags.target-org.summary'), char: 'o', aliases: ['targetusername', 'u'], @@ -82,17 +82,16 @@ export default class Logout extends SfCommand { ? await AuthInfo.listAllAuthorizations() : targetUsername ? (await AuthInfo.listAllAuthorizations()).filter( - (orgAuth) => - orgAuth.username === targetUsername.getUsername() || - !!orgAuth.aliases?.includes(targetUsername.getUsername() as string) + (orgAuth) => orgAuth.username === targetUsername || !!orgAuth.aliases?.includes(targetUsername) ) : []; if (orgAuths.length === 0) { if (flags['target-org']) { + this.warn(messages.createWarning('warning.NoAuthFoundForTargetOrg', [flags['target-org']])); // user specified a target org but it was not resolved, issue success message and return - this.logSuccess(messages.getMessage('logoutOrgCommandSuccess', [flags['target-org'].getUsername() as string])); - return [flags['target-org'].getUsername() as string]; + this.logSuccess(messages.getMessage('logoutOrgCommandSuccess', [flags['target-org']])); + return [flags['target-org']]; } this.info(messages.getMessage('noOrgsFound')); return []; diff --git a/test/commands/org/login/login.jwt.nut.ts b/test/commands/org/login/login.jwt.nut.ts index 9161761a..9e9fd268 100644 --- a/test/commands/org/login/login.jwt.nut.ts +++ b/test/commands/org/login/login.jwt.nut.ts @@ -35,6 +35,10 @@ describe('org:login:jwt NUTs', () => { await testSession?.clean(); }); + afterEach(() => { + execCmd(`auth:logout -p -o ${username}`, { ensureExitCode: 0 }); + }); + it('should authorize an org using jwt (json)', () => { const command = `org:login:jwt -d -o ${username} -i ${clientId} -f ${jwtKey} -r ${instanceUrl} --json`; const json = execCmd(command, { ensureExitCode: 0 }).jsonOutput?.result as AuthFields; @@ -44,7 +48,6 @@ describe('org:login:jwt NUTs', () => { expectUrlToExist(json, 'loginUrl'); expect(json.privateKey).to.equal(path.join(testSession.homeDir, 'jwtKey')); expect(json.username).to.equal(username); - execCmd(`auth:logout -p -o ${username}`, { ensureExitCode: 0 }); }); it('should authorize an org using jwt (human readable)', () => { @@ -52,7 +55,6 @@ describe('org:login:jwt NUTs', () => { const result = execCmd(command, { ensureExitCode: 0 }); const output = getString(result, 'shellOutput.stdout'); expect(output).to.include(`Successfully authorized ${username} with org ID`); - execCmd(`auth:logout -p -o ${username}`, { ensureExitCode: 0 }); }); it('should throw correct error for JwtAuthError', () => { diff --git a/test/commands/org/logout.test.ts b/test/commands/org/logout.test.ts index 265464b7..6a462e68 100644 --- a/test/commands/org/logout.test.ts +++ b/test/commands/org/logout.test.ts @@ -151,11 +151,11 @@ describe('org:logout', () => { expect(response).to.deep.equal([testOrg1.username]); }); - it('should fail when the auth file does not exist', async () => { + it.only('should fail when the auth file does not exist', async () => { await prepareStubs({ 'target-org': testOrg2.username, aliases: { TestAlias: testOrg1.username }, - authInfoConfigDoesNotExist: false, + authInfoConfigDoesNotExist: true, }); const response = await Logout.run(['-p', '-o', testOrg1.username, '--json']); expect(response).to.deep.equal([testOrg1.username]); From 04a94571f52a18dc954b299447821931390bea1b Mon Sep 17 00:00:00 2001 From: soridalac Date: Mon, 21 Apr 2025 08:52:59 -0700 Subject: [PATCH 12/13] fix: remove only --- test/commands/org/logout.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/commands/org/logout.test.ts b/test/commands/org/logout.test.ts index 6a462e68..4181bcff 100644 --- a/test/commands/org/logout.test.ts +++ b/test/commands/org/logout.test.ts @@ -151,7 +151,7 @@ describe('org:logout', () => { expect(response).to.deep.equal([testOrg1.username]); }); - it.only('should fail when the auth file does not exist', async () => { + it('should fail when the auth file does not exist', async () => { await prepareStubs({ 'target-org': testOrg2.username, aliases: { TestAlias: testOrg1.username }, From e980f4866ce809375a21fb28efd10a083f92093a Mon Sep 17 00:00:00 2001 From: Sorida Lac <96142310+soridalac@users.noreply.github.com> Date: Mon, 21 Apr 2025 12:58:15 -0700 Subject: [PATCH 13/13] Update messages/logout.md Co-authored-by: Juliet Shackell <63259011+jshackell-sfdc@users.noreply.github.com> --- messages/logout.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/messages/logout.md b/messages/logout.md index 6425cdbb..293baaf8 100644 --- a/messages/logout.md +++ b/messages/logout.md @@ -82,4 +82,6 @@ You must specify a target-org (or default target-org config is set) or use --all # warning.NoAuthFoundForTargetOrg -No authenticated org found with the username or alias of %s. +No authenticated org found with the %s username or alias. + +NOTE: Starting September 2025, this warning will be converted to an error. As a result, the exit code when you try to log out of an unauthenticated org will change from 0 to 1.