diff --git a/src/store/modules/ProfileModule.ts b/src/store/modules/ProfileModule.ts index 0115278d9..cbb9cb16c 100644 --- a/src/store/modules/ProfileModule.ts +++ b/src/store/modules/ProfileModule.ts @@ -18,6 +18,7 @@ import ManagerSettings from '../../r2mm/manager/ManagerSettings'; import * as PackageDb from '../../r2mm/manager/PackageDexieStore'; import ModListSort from '../../r2mm/mods/ModListSort'; import ProfileModList from '../../r2mm/mods/ProfileModList'; +import FileUtils from '../../utils/FileUtils'; import SearchUtils from '../../utils/SearchUtils'; interface State { @@ -301,9 +302,9 @@ export default { async generateTroubleshootingString({dispatch, getters, rootGetters, rootState}): Promise { const steamDirectory = await GameDirectoryResolverProvider.instance.getSteamDirectory(); - const steamPath = steamDirectory instanceof R2Error ? '-' : steamDirectory; + const steamPath = steamDirectory instanceof R2Error ? '-' : FileUtils.hideWindowsUsername(steamDirectory); const gameDirectory = await GameDirectoryResolverProvider.instance.getDirectory(rootState.activeGame); - const gamePath = gameDirectory instanceof R2Error ? '-' : gameDirectory; + const gamePath = gameDirectory instanceof R2Error ? '-' : FileUtils.hideWindowsUsername(gameDirectory); const packageCacheDate = await PackageDb.getLastPackageListUpdateTime(rootState.activeGame.internalFolderName); const packageCacheSize = await PackageDb.getPackageCount(rootState.activeGame.internalFolderName); const packageVuexState: string = await dispatch('tsMods/generateTroubleshootingString', null, {root: true}); @@ -313,7 +314,7 @@ export default { Game: ${rootState.activeGame.displayName} (${rootState.activeGame.activePlatform.storePlatform}) Steam path: ${steamPath} Game path: ${gamePath} - Profile path: ${getters.activeProfile.getProfilePath()} + Profile path: ${FileUtils.hideWindowsUsername(getters.activeProfile.getProfilePath())} Custom launch arguments: ${rootGetters.settings.getContext().gameSpecific.launchParameters || '-'} Mod list in cache: ${packageCacheSize} mods, hash updated ${packageCacheDate || 'never'} Mod list in memory: ${packageVuexState} diff --git a/src/utils/FileUtils.ts b/src/utils/FileUtils.ts index 2be531fdd..3c1d0ee80 100644 --- a/src/utils/FileUtils.ts +++ b/src/utils/FileUtils.ts @@ -31,6 +31,15 @@ export default class FileUtils { return Promise.resolve(); } + // Obfuscates the Windows username if it's part of the path. + public static hideWindowsUsername(dir: string) { + const separator = dir.includes('/') ? '/' : '\\'; + return dir.replace( + /([A-Za-z]:)[\\\/]Users[\\\/][^\\\/]+[\\\/]/, + `$1${separator}Users${separator}***${separator}` + ); + } + public static humanReadableSize(bytes: number) { // NumberFormat renders GBs as BBs ("billion bytes") when using "byte" unit type. if (bytes > 999999999 && bytes < 1000000000000) { diff --git a/test/jest/__tests__/utils/utils.FileUtils.ts.spec.ts b/test/jest/__tests__/utils/utils.FileUtils.ts.spec.ts new file mode 100644 index 000000000..21c389a94 --- /dev/null +++ b/test/jest/__tests__/utils/utils.FileUtils.ts.spec.ts @@ -0,0 +1,69 @@ +import FileUtils from "../../../../src/utils/FileUtils"; + +describe("FileUtils.hideWindowsUsername", () => { + it("Doesn't change slashes", () => { + expect( + FileUtils.hideWindowsUsername('C:\\Users\\Alice\\appData') + ).toStrictEqual('C:\\Users\\***\\appData'); + + expect( + FileUtils.hideWindowsUsername('C:/Users/Bob/appData') + ).toStrictEqual('C:/Users/***/appData'); + }); + + it("Doesn't change drive letters", () => { + expect( + FileUtils.hideWindowsUsername('C:\\Users\\Charlie\\appData') + ).toStrictEqual('C:\\Users\\***\\appData'); + + expect( + FileUtils.hideWindowsUsername('x:\\Users\\David\\appData') + ).toStrictEqual('x:\\Users\\***\\appData'); + }); + + it("Doesn't change the rest of the path", () => { + expect( + FileUtils.hideWindowsUsername('C:\\Users\\Eve\\') + ).toStrictEqual('C:\\Users\\***\\'); + + expect( + FileUtils.hideWindowsUsername('C:\\Users\\Frank\\Desktop') + ).toStrictEqual('C:\\Users\\***\\Desktop'); + + expect( + FileUtils.hideWindowsUsername('C:\\Users\\Grace\\Desktop\\') + ).toStrictEqual('C:\\Users\\***\\Desktop\\'); + + expect( + FileUtils.hideWindowsUsername('C:\\Users\\Heidi\\Desktop\\file.txt') + ).toStrictEqual('C:\\Users\\***\\Desktop\\file.txt'); + }); + + it("Doesn't affect other paths", () => { + expect( + FileUtils.hideWindowsUsername('C:\\LUsers\\Ivan\\') + ).toStrictEqual('C:\\LUsers\\Ivan\\'); + + expect( + FileUtils.hideWindowsUsername('C:\\temp\\Users\\Judy\\') + ).toStrictEqual('C:\\temp\\Users\\Judy\\'); + }); + + it("Isn't tricked by odd usernames", () => { + expect( + FileUtils.hideWindowsUsername('C:\\Users\\123\\') + ).toStrictEqual('C:\\Users\\***\\'); + + expect( + FileUtils.hideWindowsUsername('C:\\Users\\@admin\\') + ).toStrictEqual('C:\\Users\\***\\'); + + expect( + FileUtils.hideWindowsUsername('C:\\Users\\_\\') + ).toStrictEqual('C:\\Users\\***\\'); + + expect( + FileUtils.hideWindowsUsername('C:\\Users\\***\\') + ).toStrictEqual('C:\\Users\\***\\'); + }); +});