Skip to content

Commit 958dbdd

Browse files
committed
Add support for new x-bc value
Fixes #7
1 parent 114797f commit 958dbdd

File tree

6 files changed

+158
-8
lines changed

6 files changed

+158
-8
lines changed

README.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Follow the steps on [Chrome's "Getting Started" tutorial](https://developer.chro
2828
- The extension may say it contains errors and then highlight a permission called "contextualIdentities": ![](https://i.marcus.pw/ss/2021-10-22_qxfIFE.png)
2929
- It's safe to ignore, as it's a permission meant for Firefox users, but does not affect Chrome / Brave.
3030

31-
These steps MAY work on Microsoft Edge (the new version), but no guarantees.
31+
These steps MAY work on Microsoft Edge, but no guarantees.
3232

3333
## How to use
3434

@@ -49,13 +49,29 @@ For example:
4949

5050
### Preview
5151

52-
Screenshot as of extension version v1.0.3.
52+
Screenshot as of extension version v1.0.3, which means it's slightly outdated.
5353
A few things to note:
5454
- `auth_hash`, `auth_uniq_`, `email` and `password` are _typically empty_. Don't panic if they don't have any values, as it's completely normal.
5555
- The `username` field is by default set to "u" plus the same number as `auth_id`. It _does not_ need to be your actual OnlyFans username.
5656

5757
![Preview of extension](https://i.marcus.pw/ss/2021-05-20_5hI4rK.png)
5858

59+
## Permissions
60+
61+
Overview of permissions and why they're required.
62+
63+
- `cookies`
64+
- Values such as `auth_id` and `sess` are contained within cookies.
65+
- Keep in mind that the `cookies` permission only applies for `onlyfans.com` and no other websites.
66+
- `clipboardWrite`
67+
- To copy the `auth.json` values into your clipboard
68+
- `storage`
69+
- This is specifically just to "synchronize" the `x_bc` value to the popup (so it can be copied).
70+
- `x_bc` isn't available via the regular `cookies` permission, so we need a workaround (which utilizes the `storage` permission).
71+
- `contextualIdentities`
72+
- On Firefox, it's used to support multi-account containers.
73+
- On Chromium-based browsers (Google Chrome, Brave, Microsoft Edge etc.) it does nothing. However, it will give a warning (that you can ignore).
74+
5975
## LICENSE
6076

6177
[MIT License](./LICENSE.md)

background/background.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
const ls = chrome.storage.local;
2+
3+
/**
4+
* Helper for storing the new bcTokens object
5+
*/
6+
function storeBcTokens(bcTokens)
7+
{
8+
ls.set({'bcTokens': bcTokens});
9+
}
10+
11+
/**
12+
* Retrieve the stored bcTokens object
13+
* If none, return a fresh object
14+
*/
15+
async function getStoredBcTokens()
16+
{
17+
return new Promise((resolve, reject) => {
18+
ls.get(['bcTokens'], function(data) {
19+
if (!data.bcTokens) {
20+
storeBcTokens({});
21+
resolve({});
22+
return;
23+
}
24+
25+
resolve(data.bcTokens);
26+
});
27+
});
28+
}
29+
30+
async function handleBcToken(data)
31+
{
32+
const { bcTokenSha, id } = data;
33+
34+
const bcTokens = await getStoredBcTokens();
35+
bcTokens[id] = bcTokenSha;
36+
storeBcTokens(bcTokens);
37+
38+
return true;
39+
}
40+
41+
chrome.runtime.onMessage.addListener(handleBcToken);

content_scripts/bcToken.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
async function getBcToken()
2+
{
3+
const ls = window.localStorage;
4+
if (!ls.bcTokenSha) {
5+
return;
6+
}
7+
8+
const bcToken = ls.bcTokenSha;
9+
10+
/**
11+
* We don't have access to all cookies here, so instead we use a workaround
12+
* with the few cookie values we _do_ have access to.
13+
*/
14+
const match = document.cookie.match(/st=(\w{64})/);
15+
const id = match[1];
16+
17+
try {
18+
const message = await chrome.runtime.sendMessage({
19+
bcTokenSha: bcToken,
20+
id: id,
21+
});
22+
}
23+
catch (err) {
24+
console.error('Error occurred when trying to send bcToken to background script', err);
25+
}
26+
}
27+
28+
// Handle changes/updates to localStorage
29+
window.addEventListener('storage', function() {
30+
const ls = window.localStorage;
31+
32+
if (ls.bcTokenSha) {
33+
getBcToken();
34+
}
35+
});
36+
37+
getBcToken();

manifest.json

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
{
22
"manifest_version": 2,
33
"name": "OnlyFans Cookie Helper",
4-
"version": "2.0.1",
5-
"description": "Helper extension that makes it easier to copy config.json values for the DIGITALCRIMINAL/OnlyFans software",
4+
"version": "2.1.0",
5+
"description": "Helper extension that makes it easier to copy config.json values for the DIGITALCRIMINALS/OnlyFans scraper",
66
"icons": {
77
"48": "icons/cookie.png"
88
},
9+
"background": {
10+
"scripts": ["background/background.js"]
11+
},
912
"permissions": [
1013
"*://*.onlyfans.com/",
1114
"cookies",
1215
"clipboardWrite",
16+
"storage",
1317
"contextualIdentities"
1418
],
1519
"web_accessible_resources": [],
@@ -20,5 +24,11 @@
2024
},
2125
"default_title": "OnlyFans Cookie Helper",
2226
"default_popup": "popup/cookies.html"
23-
}
27+
},
28+
"content_scripts": [
29+
{
30+
"matches": ["*://*.onlyfans.com/*", "*://*.onlyfans.com/"],
31+
"js": ["content_scripts/bcToken.js"]
32+
}
33+
]
2434
}

popup/cookies.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
<body>
2424
<div>
2525
<code><pre id="json"></pre></code>
26+
<span id="errorMessage" class="hidden red"></span>
2627
<br><br>
2728
<button id="copy-to-clipboard">Copy to clipboard</button>
2829
</div>

popup/cookies.js

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,25 @@ async function copyStringToClipboard (str) {
2424
const containerNames = {};
2525
const containersEnabled = browser.contextualIdentities !== undefined;
2626

27+
/**
28+
* Get the correct bcToken from storage
29+
*/
30+
async function getBcTokenSha(id)
31+
{
32+
return new Promise((resolve, reject) => {
33+
chrome.storage.local.get(['bcTokens'], function(data) {
34+
const bcTokens = data.bcTokens || {};
35+
36+
if (bcTokens[id]) {
37+
resolve(bcTokens[id]);
38+
return;
39+
}
40+
41+
resolve(null);
42+
});
43+
});
44+
}
45+
2746
async function getContainers()
2847
{
2948
/**
@@ -113,6 +132,7 @@ async function grabCookies(cookieStoreId) {
113132
const sess = mappedCookies.sess;
114133
const copyBtn = document.querySelector('#copy-to-clipboard');
115134
const jsonElement = document.querySelector('#json');
135+
const errorElement = document.querySelector('#errorMessage');
116136

117137
/**
118138
* If authId isn't specified, user is not logged into
@@ -125,17 +145,41 @@ async function grabCookies(cookieStoreId) {
125145
errorMessage = `Could not find valid cookie values in container: <strong>${containerName}</strong><br>Make sure you are logged into OnlyFans.`;
126146
}
127147

128-
jsonElement.innerHTML = errorMessage;
148+
errorElement.innerHTML = errorMessage;
149+
errorElement.classList.remove('hidden');
150+
151+
if (!copyBtn.classList.contains('hidden')) {
152+
copyBtn.classList.add('hidden');
153+
jsonElement.classList.add('hidden');
154+
}
155+
156+
return;
157+
}
158+
159+
// See `background/background.js` as to why we use `st` here
160+
const st = mappedCookies.st;
161+
const bcToken = await getBcTokenSha(st);
162+
if (!bcToken) {
163+
let errorMessage = 'Could not find valid x_bc value. Please open OnlyFans.com once and make sure it fully loads.';
164+
if (containersEnabled) {
165+
const containerName = containerNames[cookieStoreId] || 'Default (no container)';
166+
errorMessage = `Could not find valid x_bc value. Please open OnlyFans.com once in container: <strong>${containerName}</strong><br>Make sure it fully loads. If you are not logged in, please log in and <i>refresh the page</i>.`;
167+
}
168+
169+
errorElement.innerHTML = errorMessage;
170+
errorElement.classList.remove('hidden');
171+
129172
if (!copyBtn.classList.contains('hidden')) {
130173
copyBtn.classList.add('hidden');
131-
jsonElement.classList.add('red');
174+
jsonElement.classList.add('hidden');
132175
}
133176

134177
return;
135178
}
136179

137180
copyBtn.classList.remove('hidden');
138-
jsonElement.classList.remove('red');
181+
jsonElement.classList.remove('hidden');
182+
errorElement.classList.add('hidden');
139183

140184
/**
141185
* Fill out the object that OnlyFans excepts
@@ -145,6 +189,7 @@ async function grabCookies(cookieStoreId) {
145189
cookie: `auth_id=${authId}; sess=${sess}; auth_hash=; auth_uniq_${authId}=; auth_uid_${authId}=;`,
146190
// TODO: Still need to handle this better...
147191
user_agent: navigator.userAgent,
192+
x_bc: bcToken,
148193
support_2fa: true,
149194
active: true,
150195
email: "",

0 commit comments

Comments
 (0)