Skip to content

Commit 67041ce

Browse files
committed
feat: cross-platform Chrome profile resolution with tests
- Resolve Chrome profile lazily inside getCookiesFromBrowser; fall back to chrome-cookies-secure's own default when no match is found - Add getChromeUserDataDir() with macOS, Linux, and Windows paths so auto-detect and email/display-name lookup work on all three OSes - Drop --env-file=.env from npm start so the script works without a .env file; document .env as an optional way to set CHROME_PROFILE - Add unit tests for resolveProfile with on-disk profile fixtures - Migrate test imports from ts-jest/utils to jest-mock (deprecated in ts-jest v27, removed in v28) - Strip deprecated husky.sh sourcing from pre-commit and pre-push hooks (warned by husky v8+, fails in v10) - Restore cli.ts to tsconfig include so lib/cli.js is built - Pin engines.node to >=16
1 parent f5cf3e6 commit 67041ce

15 files changed

Lines changed: 118 additions & 66 deletions

File tree

.env.example

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# Chrome profile to read cookies from.
1+
# Chrome profile to read cookies from. Works on macOS, Linux, and Windows.
22
# Accepted values:
33
# - Email address: <firstname>.<lastname>@eficode.com
44
# - Profile name: Eficode
5-
# - Directory name: Profile 2
5+
# - Directory name: Default, Profile 2
66
#
77
# If not set, defaults to the first profile with an @eficode.com email.
88
# If no @eficode.com profile is found, falls back to "Default".

.husky/pre-commit

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1 @@
1-
#!/bin/sh
2-
. "$(dirname "$0")/_/husky.sh"
3-
41
npx lint-staged

.husky/pre-push

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1 @@
1-
#!/bin/sh
2-
. "$(dirname "$0")/_/husky.sh"
3-
41
npm run typecheck && npm run test

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,18 @@ Sign in to [Timesheets](https://timesheets.eficode.fi/) on Chrome.
88

99
## Chrome profiles
1010

11-
If you use multiple Chrome profiles, the CLI tries to auto-detect your work profile by looking for one signed in with an `@eficode.com` email. Auto-detect works on macOS, Linux, and Windows. To override, set `CHROME_PROFILE` in a `.env` file (see `.env.example`):
11+
If you use multiple Chrome profiles, the CLI tries to auto-detect your work profile by looking for one signed in with an `@eficode.com` email. Auto-detect works on macOS, Linux, and Windows.
12+
13+
To override, set the `CHROME_PROFILE` environment variable:
1214

1315
CHROME_PROFILE=your.name@eficode.com # or "Eficode", or "Profile 2"
1416

1517
It accepts the account email, the profile display name, or the directory name (e.g. `Default`, `Profile 2`).
1618

19+
Optionally, you can put it in a `.env` file (see `.env.example`) and load it with Node ≥20.6:
20+
21+
node --env-file=.env lib/cli.js
22+
1723
## Running
1824

1925
`npx @eficode/tscli`

package.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,17 @@
1515
"bin": {
1616
"tscli": "lib/cli.js"
1717
},
18+
"engines": {
19+
"node": ">=16"
20+
},
1821
"files": [
1922
"lib/**/*"
2023
],
2124
"scripts": {
2225
"prepare": "husky install && npm run build",
2326
"prepublishOnly": "npm test && npm run lint",
2427
"preversion": "npm run lint",
25-
"start": "tsc && node --env-file=.env lib/cli.js",
28+
"start": "tsc && node lib/cli.js",
2629
"build": "tsc",
2730
"release": "./node_modules/.bin/standard-version && git push --follow-tags",
2831
"test": "jest",
@@ -66,6 +69,8 @@
6669
},
6770
"lint-staged": {
6871
"*.{js,ts,json,md,html,yml,yaml}": "prettier --write",
69-
"*.ts": "tslint -p tsconfig.json"
72+
"*.ts": [
73+
"bash -c 'tslint -p tsconfig.json'"
74+
]
7075
}
7176
}

src/cookies.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ const getChromeUserDataDir = (): string | undefined => {
2525
}
2626
};
2727

28-
const resolveProfile = (profileOrHint?: string): string | undefined => {
29-
const chromeDir = getChromeUserDataDir();
28+
export const resolveProfile = (
29+
profileOrHint?: string,
30+
chromeDir: string | undefined = getChromeUserDataDir(),
31+
): string | undefined => {
3032
if (!chromeDir || !existsSync(chromeDir)) return profileOrHint;
3133

3234
let eficodeProfile: string | undefined;

test/auth.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { mocked } from 'ts-jest/utils';
1+
import { mocked } from 'jest-mock';
22

33
import { existsSync, promises } from 'fs';
44

test/cookies.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import * as path from 'path';
2+
import { resolveProfile } from '../src/cookies';
3+
4+
const fixtureDir = path.join(__dirname, 'data/chrome-profiles');
5+
6+
describe('resolveProfile', () => {
7+
it('matches by account email', () => {
8+
expect(resolveProfile('first.last@eficode.com', fixtureDir)).toBe('Profile 1');
9+
});
10+
11+
it('matches by profile display name', () => {
12+
expect(resolveProfile('Eficode', fixtureDir)).toBe('Profile 1');
13+
});
14+
15+
it('matches by directory name', () => {
16+
expect(resolveProfile('Profile 2', fixtureDir)).toBe('Profile 2');
17+
});
18+
19+
it('auto-detects an @eficode.com profile when no hint is given', () => {
20+
expect(resolveProfile(undefined, fixtureDir)).toBe('Profile 1');
21+
});
22+
23+
it('returns the hint when no profile matches', () => {
24+
expect(resolveProfile('Profile 9', fixtureDir)).toBe('Profile 9');
25+
});
26+
27+
it('returns the hint when the chrome dir does not exist', () => {
28+
expect(resolveProfile('Default', '/nonexistent/path')).toBe('Default');
29+
});
30+
31+
it('returns undefined when no hint, no chrome dir, and no eficode profile', () => {
32+
expect(resolveProfile(undefined, '/nonexistent/path')).toBeUndefined();
33+
});
34+
});
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"profile": { "name": "Personal" },
3+
"account_info": [{ "email": "personal@gmail.com" }]
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"profile": { "name": "Eficode" },
3+
"account_info": [{ "email": "first.last@eficode.com" }]
4+
}

0 commit comments

Comments
 (0)