-
-
Save purplebar0/faf7c789f69214755e09ed41412d9f1d to your computer and use it in GitHub Desktop.
Bypass Bluesky age verification by removing labels
This file contains hidden or 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
| // ==UserScript== | |
| // @name Bluesky - remove labels | |
| // @version 1.0 | |
| // @match https://bsky.app/* | |
| // @match https://main.bsky.dev/* | |
| // @grant GM_xmlhttpRequest | |
| // @grant unsafeWindow | |
| // @run-at document-start | |
| // ==/UserScript== | |
| (function() { | |
| 'use strict'; | |
| // Post data endpoints to filter | |
| const TARGET_PATHS = [ | |
| '/xrpc/app.bsky.feed.getAuthorFeed', | |
| '/xrpc/app.bsky.unspecced.getPostThreadV2' | |
| ]; | |
| /** | |
| * Checks if a given URL matches any of the configured target paths. | |
| * @param {string} url - The full URL string. | |
| * @returns {boolean} - True if the path matches one of the targets. | |
| */ | |
| function isTargetUrl(url) { | |
| try { | |
| const parsedUrl = new URL(url, location.origin); | |
| const path = parsedUrl.pathname + parsedUrl.search; | |
| return TARGET_PATHS.some(pattern => { | |
| if (pattern instanceof RegExp) { | |
| return pattern.test(path); | |
| } | |
| return path.startsWith(pattern); | |
| }); | |
| } catch (e) { | |
| return false; | |
| } | |
| } | |
| /** | |
| * Recursively replaces any value associated with the key "labels" (if array) with []. | |
| */ | |
| function cleanLabels(obj) { | |
| if (!obj || typeof obj !== 'object') return obj; | |
| if (Array.isArray(obj)) { | |
| return obj.map(item => cleanLabels(item)); | |
| } | |
| const newObj = {}; | |
| for (const key in obj) { | |
| if (Object.prototype.hasOwnProperty.call(obj, key)) { | |
| if (key === 'labels' && Array.isArray(obj[key])) { | |
| newObj[key] = []; | |
| } else { | |
| newObj[key] = cleanLabels(obj[key]); | |
| } | |
| } | |
| } | |
| return newObj; | |
| } | |
| /** | |
| * Overrides the fetch API to intercept responses from matching paths. | |
| */ | |
| function overrideFetch() { | |
| const originalFetch = unsafeWindow.fetch; | |
| unsafeWindow.fetch = function(...args) { | |
| // Extract URL string from arguments | |
| let urlStr = ''; | |
| if (args[0] instanceof Request) { | |
| urlStr = args[0].url; | |
| } else if (typeof args[0] === 'string') { | |
| urlStr = args[0]; | |
| } | |
| if (urlStr && isTargetUrl(urlStr)) { | |
| return new Promise((resolve, reject) => { | |
| const options = args[1] || {}; | |
| GM_xmlhttpRequest({ | |
| method: options.method || 'GET', | |
| url: urlStr, | |
| headers: options.headers || {}, | |
| data: options.body || null, | |
| onload: function(response) { | |
| try { | |
| const json = JSON.parse(response.responseText); | |
| const cleanedJson = cleanLabels(json); | |
| const newBody = JSON.stringify(cleanedJson); | |
| // Reconstruct headers | |
| const headers = new Headers(); | |
| if (response.responseHeaders) { | |
| const rawHeaders = response.responseHeaders.split(/\r\n/); | |
| rawHeaders.forEach(line => { | |
| const parts = line.split(': '); | |
| if (parts.length >= 2) { | |
| headers.append(parts[0], parts.slice(1).join(': ')); | |
| } | |
| }); | |
| } | |
| headers.set('Content-Type', 'application/json'); | |
| const newResponse = new Response(newBody, { | |
| status: response.status, | |
| statusText: response.statusText, | |
| headers: headers | |
| }); | |
| resolve(newResponse); | |
| } catch (e) { | |
| console.warn('Intercepted non-JSON or parse error:', e); | |
| // Fallback to original | |
| const fallbackResponse = new Response(response.responseText, { | |
| status: response.status, | |
| statusText: response.statusText, | |
| headers: response.responseHeaders | |
| }); | |
| resolve(fallbackResponse); | |
| } | |
| }, | |
| onerror: function(err) { | |
| reject(err); | |
| } | |
| }); | |
| }); | |
| } | |
| return originalFetch.apply(this, args); | |
| }; | |
| } | |
| overrideFetch(); | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment