-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 637147d
Showing
10 changed files
with
250 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
**/node_modules | ||
**/build | ||
.vscode | ||
__pycache__ |
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,58 @@ | ||
# cookie-sync | ||
|
||
## Description | ||
|
||
## About | ||
|
||
This is a simple extension that allows you to sync cookies between Chrome and Python using the [websocket](https://en.wikipedia.org/wiki/WebSocket) protocol. | ||
|
||
## Requirements | ||
|
||
- Python >= 3.7 | ||
- [aiohttp](https://docs.aiohttp.org/en/stable) | ||
|
||
## Usage | ||
|
||
1. `pip install cookie-sync` | ||
|
||
2. Download the and unarchive the extension from [releases](https://github.com/sunney-x/cookie-sync/releases) | ||
|
||
3. Set `host_permissions` for the target website in `manifest.json` | ||
|
||
4. Load the extension in Chrome | ||
- Go to `chrome://extensions` | ||
- Click `Load unpacked` and locate the extension folder | ||
|
||
5. Quickstart example | ||
```python | ||
import aiohttp | ||
from cookie_sync import run_server | ||
|
||
session = aiohttp.ClientSession() | ||
|
||
run_server( | ||
session=session, | ||
domain='https://google.com' | ||
) | ||
``` | ||
|
||
## Documentation | ||
|
||
### **run_server** configuration options | ||
|
||
```py | ||
session: aiohttp.ClientSession | ||
- 'The session to keep cookies synced on' | ||
|
||
domain: str | ||
- 'The domain to sync cookies for' | ||
|
||
cookies: Optional[list] # Default [] | ||
- 'List of cookies to sync, if empty, all cookies will be synced' | ||
|
||
wait_for_cookies: Optional[bool] # Default True | ||
- 'If `False`, will not wait for the cookies to be synced' | ||
|
||
timeout: Optional[int] # Default 30 | ||
- 'Timeout in seconds to wait for `wait_for_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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from .server import run_server |
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,67 @@ | ||
import time | ||
from aiohttp import web | ||
from typing import Dict, List | ||
import aiohttp | ||
import json | ||
import threading | ||
import asyncio | ||
|
||
|
||
def _run_server( | ||
session: aiohttp.ClientSession, | ||
cookie_names: List[str], | ||
domain: str, | ||
): | ||
async def websocket_handler(request): | ||
ws = web.WebSocketResponse() | ||
await ws.prepare(request) | ||
|
||
await ws.send_json({ | ||
'action': 'get', | ||
'cookies': cookie_names, | ||
'domain': domain, | ||
}) | ||
|
||
async for msg in ws: | ||
if msg.type != aiohttp.WSMsgType.TEXT: | ||
continue | ||
|
||
try: | ||
cookies: List[Dict[str, str]] = msg.json() | ||
except json.decoder.JSONDecodeError: | ||
continue | ||
|
||
for c in cookies: | ||
session.cookie_jar.update_cookies(c) | ||
|
||
return ws | ||
|
||
app = web.Application() | ||
app.add_routes([web.get('/ws', websocket_handler)]) | ||
|
||
loop = asyncio.new_event_loop() | ||
asyncio.set_event_loop(loop) | ||
web.run_app(app, host='localhost', port=3001) | ||
|
||
|
||
def run_server( | ||
session: aiohttp.ClientSession, | ||
domain: str, | ||
cookies: List[str] = [], | ||
wait_for_cookies: bool = True, | ||
timeout: int = 30, | ||
): | ||
threading.Thread( | ||
target=_run_server, | ||
args=(session, cookies, domain,), | ||
daemon=True | ||
).start() | ||
|
||
if wait_for_cookies: | ||
t = time.time() | ||
|
||
while not len(session.cookie_jar): | ||
if (time.time() - t) > timeout: | ||
break | ||
|
||
pass |
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,11 @@ | ||
{ | ||
"name": "Cookie Sync", | ||
"description": "Synchronize cookies between chrome and Python", | ||
"version": "0.1", | ||
"manifest_version": 3, | ||
"host_permissions": ["*://*.google.com/*"], | ||
"permissions": ["cookies"], | ||
"background": { | ||
"service_worker": "build/sw.js" | ||
} | ||
} |
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,15 @@ | ||
{ | ||
"name": "cookie_sync", | ||
"version": "0.1", | ||
"description": "Synchronize cookies between chrome and Python", | ||
"scripts": { | ||
"dev": "tsc -p . --watch", | ||
"build": "tsc -p ." | ||
}, | ||
"keywords": [], | ||
"author": "", | ||
"license": "ISC", | ||
"dependencies": { | ||
"@types/chrome": "0.0.179" | ||
} | ||
} |
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,62 @@ | ||
interface CookieRequest { | ||
action: "get"; | ||
cookies: string[]; | ||
domain: string; | ||
} | ||
|
||
const neededCookies: string[] = []; | ||
let ws: WebSocket; | ||
|
||
const connect = () => { | ||
const _ws = new WebSocket("ws://localhost:3001/ws"); | ||
ws = _ws; | ||
ws.onopen = () => { | ||
console.log("Connected! 👌"); | ||
}; | ||
|
||
ws.onmessage = async (event): Promise<void> => { | ||
const cookieReq: CookieRequest = JSON.parse(event.data); | ||
|
||
switch (cookieReq.action) { | ||
case "get": | ||
let retrievedCookies: { [key: string]: string }[] = []; | ||
|
||
if (cookieReq.cookies.length) { | ||
const promises = cookieReq.cookies.map((c) => | ||
chrome.cookies | ||
.get({ name: c, url: cookieReq.domain }) | ||
.then((c) => c && retrievedCookies.push({ [c.name]: c.value })) | ||
); | ||
|
||
await Promise.all(promises); | ||
} else { | ||
retrievedCookies = (await chrome.cookies.getAll({})).map((c) => ({ | ||
[c.name]: c.value, | ||
})); | ||
} | ||
|
||
ws.send(JSON.stringify(retrievedCookies)); | ||
} | ||
}; | ||
|
||
ws.onclose = () => { | ||
console.log("Disconnected! 👎"); | ||
setTimeout(connect, 10 * 1000); | ||
}; | ||
|
||
ws.onerror = () => { | ||
console.log("Error! 💩"); | ||
ws.close(); | ||
}; | ||
}; | ||
|
||
connect(); | ||
|
||
chrome.cookies.onChanged.addListener((c) => { | ||
if ( | ||
c.cause === "overwrite" && | ||
(neededCookies.includes(c.cookie.name) || !neededCookies.length) | ||
) { | ||
ws.send(JSON.stringify({ [c.cookie.name]: c.cookie.value })); | ||
} | ||
}); |
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,14 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "es5", | ||
"lib": ["ES2016", "DOM"], | ||
"module": "commonjs", | ||
"outDir": "./build", | ||
"esModuleInterop": true, | ||
"forceConsistentCasingInFileNames": true, | ||
"strict": true, | ||
"skipLibCheck": true | ||
}, | ||
"include": ["src/**/*.ts"], | ||
"exclude": ["node_modules"] | ||
} |
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 @@ | ||
aiohttp == 3.8.1 |
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,17 @@ | ||
from setuptools import setup | ||
|
||
|
||
setup( | ||
name='cookie-sync', | ||
version='0.0.1', | ||
description='Sync cookies between Chrome', | ||
author='Sunney-X', | ||
author_email='sunneyxdev@gmail.com', | ||
url='https://github.com/Sunney-X/cookie-sync', | ||
packages=['cookie_sync'], | ||
long_description=open('README.md').read(), | ||
long_description_content_type="text/markdown", | ||
install_requires=[ | ||
"aiohttp" | ||
], | ||
) |