From 1860665981b1dba9a7b184bedc3d5713ea5fa8f9 Mon Sep 17 00:00:00 2001 From: alvarosabu Date: Tue, 29 Oct 2024 13:46:32 +0100 Subject: [PATCH] feat: remove all netrc entries on logout --- src/commands/login/index.test.ts | 6 +++--- src/commands/logout/index.test.ts | 7 ++++--- src/commands/logout/index.ts | 4 ++-- src/creds.test.ts | 18 +++++++++++++++++- src/creds.ts | 6 ++++++ 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/commands/login/index.test.ts b/src/commands/login/index.test.ts index dd730e25..be7fb574 100644 --- a/src/commands/login/index.test.ts +++ b/src/commands/login/index.test.ts @@ -139,7 +139,7 @@ describe('loginCommand', () => { await loginCommand.parseAsync(['node', 'test']) - expect(konsola.error).toHaveBeenCalledWith(mockError, true) + expect(konsola.error).toHaveBeenCalledWith(mockError, false) }) }) @@ -210,7 +210,7 @@ describe('loginCommand', () => { await loginCommand.parseAsync(['node', 'test', '--token', 'invalid-token']) // expect(handleError).toHaveBeenCalledWith(mockError, true) - expect(konsola.error).toHaveBeenCalledWith(mockError, true) + expect(konsola.error).toHaveBeenCalledWith(mockError, false) }) }) @@ -218,7 +218,7 @@ describe('loginCommand', () => { it('should handle invalid region error with correct message', async () => { await loginCommand.parseAsync(['node', 'test', '--region', 'invalid-region']) - expect(konsola.error).toHaveBeenCalledWith(expect.any(Error), true) + expect(konsola.error).toHaveBeenCalledWith(expect.any(Error), false) // Access the error argument const errorArg = vi.mocked(konsola.error).mock.calls[0][0] diff --git a/src/commands/logout/index.test.ts b/src/commands/logout/index.test.ts index 30db71aa..54c01a91 100644 --- a/src/commands/logout/index.test.ts +++ b/src/commands/logout/index.test.ts @@ -1,9 +1,10 @@ -import { isAuthorized, removeNetrcEntry } from '../../creds' +import { isAuthorized, removeAllNetrcEntries } from '../../creds' import { logoutCommand } from './' vi.mock('../../creds', () => ({ isAuthorized: vi.fn(), removeNetrcEntry: vi.fn(), + removeAllNetrcEntries: vi.fn(), })) describe('logoutCommand', () => { @@ -16,12 +17,12 @@ describe('logoutCommand', () => { vi.mocked(isAuthorized).mockResolvedValue(true) await logoutCommand.parseAsync(['node', 'test']) - expect(removeNetrcEntry).toHaveBeenCalled() + expect(removeAllNetrcEntries).toHaveBeenCalled() }) it('should not log out the user if has not previously login', async () => { vi.mocked(isAuthorized).mockResolvedValue(false) await logoutCommand.parseAsync(['node', 'test']) - expect(removeNetrcEntry).not.toHaveBeenCalled() + expect(removeAllNetrcEntries).not.toHaveBeenCalled() }) }) diff --git a/src/commands/logout/index.ts b/src/commands/logout/index.ts index 405d633b..78ea43be 100644 --- a/src/commands/logout/index.ts +++ b/src/commands/logout/index.ts @@ -1,4 +1,4 @@ -import { isAuthorized, removeNetrcEntry } from '../../creds' +import { isAuthorized, removeAllNetrcEntries, removeNetrcEntry } from '../../creds' import { commands } from '../../constants' import { getProgram } from '../../program' import { handleError, konsola } from '../../utils' @@ -17,7 +17,7 @@ export const logoutCommand = program return } try { - await removeNetrcEntry('api.storyblok.com') + await removeAllNetrcEntries() konsola.ok(`Successfully logged out`) } diff --git a/src/creds.test.ts b/src/creds.test.ts index 766a89f8..5d8585a2 100644 --- a/src/creds.test.ts +++ b/src/creds.test.ts @@ -1,4 +1,4 @@ -import { addNetrcEntry, getNetrcCredentials, getNetrcFilePath, isAuthorized, removeNetrcEntry } from './creds' +import { addNetrcEntry, getNetrcCredentials, getNetrcFilePath, isAuthorized, removeAllNetrcEntries, removeNetrcEntry } from './creds' import { vol } from 'memfs' import { join } from 'pathe' // tell vitest to use fs mock from __mocks__ folder @@ -180,6 +180,22 @@ describe('creds', async () => { }) }) + describe('removeAllNetrcEntries', () => { + it('should remove all entries from .netrc file', async () => { + vol.fromJSON({ + 'test/.netrc': `machine api.storyblok.com + login julio.iglesias@storyblok.com + password my_access_token + region eu`, + }, '/temp') + + await removeAllNetrcEntries('/temp/test/.netrc') + + const content = vol.readFileSync('/temp/test/.netrc', 'utf8') + + expect(content).toBe('') + }) + }) describe('isAuthorized', () => { beforeEach(() => { vol.reset() diff --git a/src/creds.ts b/src/creds.ts index a0ccc0f1..69e8b68c 100644 --- a/src/creds.ts +++ b/src/creds.ts @@ -234,6 +234,12 @@ export const removeNetrcEntry = async ( } } +export function removeAllNetrcEntries(filePath = getNetrcFilePath()) { + return writeFile(filePath, '', { + mode: 0o600, // Set file permissions + }) +} + export async function isAuthorized() { try { const machines = await getNetrcCredentials()