-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* separate out firefox db logic * list firefox cookies * list chrome cookies * generic listCookies * abstract out chrome cookie database * tests * add chrome list cookies test * add firefox list cookies test * eslint * bump * Update README.md
- Loading branch information
1 parent
f154131
commit dd60dc5
Showing
13 changed files
with
399 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import * as sqlite from 'better-sqlite3'; | ||
import { ChromeCookieDatabase } from './ChromeCookieDatabase'; | ||
|
||
jest.mock('better-sqlite3'); | ||
|
||
describe('ChromeCookieDatabase', () => { | ||
it('get single cookie', () => { | ||
const getFn = jest.fn().mockReturnValue({ | ||
host_key: '.domain.com', | ||
path: '/', | ||
name: 'someCookie', | ||
encrypted_value: 'encrypted_foo', | ||
}); | ||
const prepareFn = jest.fn().mockReturnValue({ get: getFn }); | ||
(sqlite as unknown as jest.Mock).mockReturnValue({ | ||
prepare: prepareFn, | ||
}); | ||
|
||
const path = '/some/path/db.sqlite'; | ||
|
||
const db = new ChromeCookieDatabase(path); | ||
|
||
const cookie = db.findCookie('someCookie', '.domain.com'); | ||
|
||
expect(cookie).toEqual({ | ||
encrypted_value: 'encrypted_foo', | ||
host_key: '.domain.com', | ||
name: 'someCookie', | ||
path: '/', | ||
}); | ||
expect(getFn).toHaveBeenCalled(); | ||
expect(prepareFn).toHaveBeenCalledWith( | ||
`SELECT host_key, path, is_secure, expires_utc, name, value, encrypted_value, creation_utc, is_httponly, has_expires, is_persistent FROM cookies where host_key like '%.domain.com' and name like '%someCookie' ORDER BY LENGTH(path) DESC, creation_utc ASC`, | ||
); | ||
expect(sqlite as unknown as jest.Mock).toHaveBeenCalledWith(path, { | ||
readonly: true, | ||
fileMustExist: true, | ||
}); | ||
}); | ||
|
||
it('get all cookies', () => { | ||
const allFn = jest.fn().mockReturnValue([ | ||
{ | ||
host_key: '.domain.com', | ||
path: '/', | ||
name: 'someCookie', | ||
encrypted_value: 'encrypted_foo', | ||
}, | ||
]); | ||
const prepareFn = jest.fn().mockReturnValue({ all: allFn }); | ||
(sqlite as unknown as jest.Mock).mockReturnValue({ | ||
prepare: prepareFn, | ||
}); | ||
|
||
const path = '/some/path/db.sqlite'; | ||
|
||
const db = new ChromeCookieDatabase(path); | ||
|
||
const cookie = db.listCookies(); | ||
|
||
expect(cookie).toEqual([ | ||
{ | ||
encrypted_value: 'encrypted_foo', | ||
host_key: '.domain.com', | ||
name: 'someCookie', | ||
path: '/', | ||
}, | ||
]); | ||
expect(allFn).toHaveBeenCalled(); | ||
expect(prepareFn).toHaveBeenCalledWith( | ||
`SELECT host_key, path, is_secure, expires_utc, name, value, encrypted_value, creation_utc, is_httponly, has_expires, is_persistent FROM cookies`, | ||
); | ||
expect(sqlite as unknown as jest.Mock).toHaveBeenCalledWith(path, { | ||
readonly: true, | ||
fileMustExist: true, | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import sqlite from 'better-sqlite3'; | ||
|
||
type BooleanNumber = 0 | 1; | ||
|
||
export type ChromeCookie = { | ||
host_key: string; | ||
path: string; | ||
is_secure: BooleanNumber; | ||
expires_utc: number; | ||
name: string; | ||
value: string; | ||
encrypted_value: Buffer; | ||
creation_utc: number; | ||
is_httponly: BooleanNumber; | ||
has_expires: BooleanNumber; | ||
is_persistent: BooleanNumber; | ||
}; | ||
|
||
export class ChromeCookieDatabase { | ||
path: string; | ||
|
||
constructor(path: string) { | ||
this.path = path; | ||
} | ||
|
||
findCookie(cookieName: string, domain: string): ChromeCookie { | ||
const db = sqlite(this.path, { readonly: true, fileMustExist: true }); | ||
const statement = db.prepare( | ||
`SELECT host_key, path, is_secure, expires_utc, name, value, encrypted_value, creation_utc, is_httponly, has_expires, is_persistent FROM cookies where host_key like '%${domain}' and name like '%${cookieName}' ORDER BY LENGTH(path) DESC, creation_utc ASC`, | ||
); | ||
return statement.get(); | ||
} | ||
|
||
listCookies(): ChromeCookie[] { | ||
const db = sqlite(this.path, { readonly: true, fileMustExist: true }); | ||
const statement = db.prepare( | ||
`SELECT host_key, path, is_secure, expires_utc, name, value, encrypted_value, creation_utc, is_httponly, has_expires, is_persistent FROM cookies`, | ||
); | ||
const cookies: ChromeCookie[] = statement.all(); | ||
return cookies; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import * as sqlite from 'better-sqlite3'; | ||
import { FirefoxCookieDatabase } from './FirefoxCookieDatabase'; | ||
|
||
jest.mock('better-sqlite3'); | ||
|
||
describe('FirefoxCookieDatabase', () => { | ||
it('get single cookie', () => { | ||
const getFn = jest.fn().mockReturnValue({ value: 'foo' }); | ||
const prepareFn = jest.fn().mockReturnValue({ get: getFn }); | ||
(sqlite as unknown as jest.Mock).mockReturnValue({ | ||
prepare: prepareFn, | ||
}); | ||
|
||
const path = '/some/path/db.sqlite'; | ||
|
||
const db = new FirefoxCookieDatabase(path); | ||
|
||
const cookie = db.findCookie('someCookie', '.domain.com'); | ||
|
||
expect(cookie).toEqual('foo'); | ||
expect(getFn).toHaveBeenCalled(); | ||
expect(prepareFn).toHaveBeenCalledWith( | ||
"SELECT value from moz_cookies WHERE name like 'someCookie' AND host like '%.domain.com'", | ||
); | ||
expect(sqlite as unknown as jest.Mock).toHaveBeenCalledWith(path, { | ||
readonly: true, | ||
fileMustExist: true, | ||
}); | ||
}); | ||
|
||
it('get all cookies', () => { | ||
const allFn = jest.fn().mockReturnValue([{ value: 'foo' }]); | ||
const prepareFn = jest.fn().mockReturnValue({ all: allFn }); | ||
(sqlite as unknown as jest.Mock).mockReturnValue({ | ||
prepare: prepareFn, | ||
}); | ||
|
||
const path = '/some/path/db.sqlite'; | ||
|
||
const db = new FirefoxCookieDatabase(path); | ||
|
||
const cookie = db.listCookies(); | ||
|
||
expect(cookie).toEqual([{ value: 'foo' }]); | ||
expect(allFn).toHaveBeenCalled(); | ||
expect(prepareFn).toHaveBeenCalledWith( | ||
'SELECT name, value, host, path from moz_cookies', | ||
); | ||
expect(sqlite as unknown as jest.Mock).toHaveBeenCalledWith(path, { | ||
readonly: true, | ||
fileMustExist: true, | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import sqlite from 'better-sqlite3'; | ||
|
||
type MozCookie = { | ||
name: string; | ||
value: string; | ||
host: string; | ||
path: string; | ||
}; | ||
|
||
export class FirefoxCookieDatabase { | ||
path: string; | ||
|
||
constructor(path: string) { | ||
this.path = path; | ||
} | ||
|
||
findCookie(cookieName: string, domain: string): string | undefined { | ||
const db = sqlite(this.path, { readonly: true, fileMustExist: true }); | ||
|
||
const statement = db.prepare( | ||
`SELECT value from moz_cookies WHERE name like '${cookieName}' AND host like '%${domain}'`, | ||
); | ||
const res = statement.get(); | ||
return res?.value; | ||
} | ||
|
||
listCookies(): MozCookie[] { | ||
const db = sqlite(this.path, { readonly: true, fileMustExist: true }); | ||
const statement = db.prepare( | ||
`SELECT name, value, host, path from moz_cookies`, | ||
); | ||
const res: MozCookie[] = statement.all(); | ||
return res; | ||
} | ||
} |
Oops, something went wrong.