Skip to content

Commit

Permalink
Chrome109 fix, Legacy DB Patch, IDB.open Logs, Kkip Autoblocking Bots…
Browse files Browse the repository at this point in the history
…, cleanup (#158)

* fix chrome109 issue in worker, add more logs to idb.open, remove bots from affiliated blocks

* remove block request debug log

* bump version 0.3.2

* fix error popup occurring on error responses

* fix horizontal scrollbar appearing in quickmenu

* update package lock to 0.3.2

* remove debug statement

* wrap legacy verified check to add timeout
  • Loading branch information
kheina authored Jun 29, 2023
1 parent 35b2de1 commit 71e5e73
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 94 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "blue-blocker",
"version": "0.3.1",
"version": "0.3.2",
"author": "DanielleMiu",
"description": "Blocks all Twitter Blue verified users on twitter.com",
"type": "module",
Expand Down
9 changes: 6 additions & 3 deletions src/background/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ import { api, logstr, ErrorStatus, IsVerifiedAction, ReasonExternal, SoupcanExte
import { abbreviate, CheckDbIsUserLegacyVerified, PopulateVerifiedDb } from '../utilities';
import { BlockQueue } from '../models/block_queue';

api.action.setBadgeBackgroundColor({ color: '#666' });
api.action.setBadgeTextColor({ color: '#fff' });
api.action.setBadgeBackgroundColor({ color: "#666" });
if (api.action.hasOwnProperty("setBadgeTextColor")) {
// setBadgeTextColor requires chrome 110+
api.action.setBadgeTextColor({ color: "#fff" });
}

// TODO: change to message listener ?
api.storage.local.onChanged.addListener((items) => {
if (items.hasOwnProperty('BlockCounter')) {
if (items.hasOwnProperty("BlockCounter")) {
api.action.setBadgeText({
text: abbreviate(items.BlockCounter.newValue),
});
Expand Down
6 changes: 6 additions & 0 deletions src/content/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ document.addEventListener('blue-blocker-event', function (e: CustomEvent<BlueBlo
const body_str = e.detail.body;
try {
const parsed_body = JSON.parse(body_str);
if (parsed_body?.error || parsed_body?.errors) {
// another error response, this time returned as a 200!
console.debug(logstr, "skipped", e.detail.parsedUrl[1], "response because it contained an error key:", { event: e, body_str });
return;
}

switch (e.detail.parsedUrl[1]) {
case 'HomeLatestTimeline':
case 'HomeTimeline':
Expand Down
2 changes: 1 addition & 1 deletion src/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { defineManifest } from "@crxjs/vite-plugin";
export default defineManifest({
name: "Blue Blocker",
description: "Blocks all Twitter Blue verified users on twitter.com",
version: "0.3.1",
version: "0.3.2",
manifest_version: 3,
icons: {
"128": "icon/icon-128.png",
Expand Down
1 change: 0 additions & 1 deletion src/popup/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,6 @@ document.addEventListener("DOMContentLoaded", () => {
{ action: "check_twitter_user", screen_name: "elonmusk" },
).then((r: any) => {
// we could check if response is the expected shape here, if we really wanted
console.debug(logstr, "soupcan response for @elonmusk:", r);
if (!r) {
throw new Error("extension not enabled");
}
Expand Down
1 change: 1 addition & 0 deletions src/popup/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ html {
--border-size: 1px;
--border-radius: 3px;

overflow-x: hidden;
border: var(--border-size) solid var(--bordercolor);
}
script {
Expand Down
183 changes: 99 additions & 84 deletions src/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,6 @@ function blockUser(user: { name: string, screen_name: string }, user_id: string,
method: "POST",
credentials: "include",
};
console.debug(logstr, "block request:", { url, ...options });

fetch(url, options).then(response => {
console.debug(logstr, "block response:", response);
Expand Down Expand Up @@ -371,110 +370,126 @@ function blockUser(user: { name: string, screen_name: string }, user_id: string,
});
}

const blockableAffiliateLabels = new Set(['AutomatedLabel']);
const blockableVerifiedTypes = new Set(['Business']);
const blockableAffiliateLabels: Set<string> = new Set([]);
const blockableVerifiedTypes: Set<string> = new Set(["Business"]);
export async function BlockBlueVerified(user: BlueBlockerUser, config: Config) {
// We're not currently adding anything to the queue so give up.
if (config.suspendedBlockCollection) {
return;
}

if (
user.rest_id === undefined ||
user?.legacy.name === undefined ||
user?.legacy.screen_name === undefined
) {
console.error(logstr, 'invalid user object passed to BlockBlueVerified');
return;
}

const formattedUserName = FormatLegacyName(user.legacy);
const hasBlockableVerifiedTypes = blockableVerifiedTypes.has(user.legacy?.verified_type || '');
const hasBlockableAffiliateLabels = blockableAffiliateLabels.has(
user.affiliates_highlighted_label?.label?.userLabelType || '',
);
try {
if (
user?.rest_id === undefined ||
user?.legacy?.name === undefined ||
user?.legacy?.screen_name === undefined
) {
throw new Error("invalid user object passed to BlockBlueVerified");
}

// since we can be fairly certain all user objects will be the same, break this into a separate function
if (user.legacy?.verified_type && !blockableVerifiedTypes.has(user.legacy.verified_type)) {
return;
}
if (user.legacy?.blocking) {
return;
}
const formattedUserName = FormatLegacyName(user.legacy);
const hasBlockableVerifiedTypes = blockableVerifiedTypes.has(user.legacy?.verified_type || '');
const hasBlockableAffiliateLabels = blockableAffiliateLabels.has(
user.affiliates_highlighted_label?.label?.userLabelType || '',
);

// some unified logic so it's not copied in a bunch of places. log everything as debug because it'll be noisy
if (
// group for if the user has unblocked them previously
// you cannot store sets in sync memory, so this will be a janky object
config.unblocked.hasOwnProperty(String(user.rest_id))
) {
console.debug(logstr, `skipped user ${formattedUserName} because you unblocked them previously.`);
return;
} else if (
// group for block-following option
!config.blockFollowing &&
(user.legacy?.following || user.super_following)
) {
console.debug(logstr, `skipped user ${formattedUserName} because you follow them.`);
return;
} else if (
// group for block-followers option
!config.blockFollowers &&
user.legacy?.followed_by
) {
console.debug(logstr, `skipped user ${formattedUserName} because they follow you.`);
return;
}
// since we can be fairly certain all user objects will be the same, break this into a separate function
if (user.legacy?.verified_type && !blockableVerifiedTypes.has(user.legacy.verified_type)) {
return;
}
if (user.legacy?.blocking) {
return;
}

// step 1: is user verified
if (user.is_blue_verified || hasBlockableVerifiedTypes || hasBlockableAffiliateLabels) {
// some unified logic so it's not copied in a bunch of places. log everything as debug because it'll be noisy
if (
// group for skip-verified option
config.skipVerified &&
await IsUserLegacyVerified(user.rest_id, user.legacy.screen_name)
// group for if the user has unblocked them previously
// you cannot store sets in sync memory, so this will be a janky object
config.unblocked.hasOwnProperty(String(user.rest_id))
) {
console.log(
logstr,
`did not block Twitter Blue verified user ${formattedUserName} because they are legacy verified.`,
);
console.debug(logstr, `skipped user ${formattedUserName} because you unblocked them previously.`);
return;
} else if (
// verified via an affiliated organization instead of blue
config.skipAffiliated &&
(hasBlockableAffiliateLabels || hasBlockableVerifiedTypes)
// group for block-following option
!config.blockFollowing &&
(user.legacy?.following || user.super_following)
) {
console.log(
logstr,
`did not block Twitter Blue verified user ${formattedUserName} because they are verified through an affiliated organization.`,
);
console.debug(logstr, `skipped user ${formattedUserName} because you follow them.`);
return;
} else if (
// verified by follower count
config.skip1Mplus &&
user.legacy?.followers_count > config.skipFollowerCount
// group for block-followers option
!config.blockFollowers &&
user.legacy?.followed_by
) {
console.log(logstr, `did not block Twitter Blue verified user ${formattedUserName} because they have over ${commafy(config.skipFollowerCount)} followers and Elon is an idiot.`);
} else {
let reason = ReasonBlueVerified;
if (hasBlockableVerifiedTypes) {
reason = ReasonBusinessVerified;
}
queueBlockUser(user, String(user.rest_id), reason);
console.debug(logstr, `skipped user ${formattedUserName} because they follow you.`);
return;
}
}

// step 2: is user an nft bro
if (config.blockNftAvatars && (user.has_nft_avatar || user.profile_image_shape === "Hexagon")) {
queueBlockUser(user, String(user.rest_id), ReasonNftAvatar);
return;
}
const legacyDbRejectMessage = "could not access the legacy verified database, skip legacy has been disabled.";
// step 1: is user verified
if (user.is_blue_verified || hasBlockableVerifiedTypes || hasBlockableAffiliateLabels) {
if (
// group for skip-verified option
config.skipVerified &&
await new Promise((resolve, reject) => {
// basically, we're wrapping a promise around a promise to set a timeout on it
// in case the user's device was unable to set up the legacy db
function disableSkipLegacy() {
api.storage.sync.set({ skipVerified: false });
reject(legacyDbRejectMessage);
}
const timeout = setTimeout(disableSkipLegacy, 1000); // 1 second. indexed db is crazy fast (<10ms), this should be plenty
IsUserLegacyVerified(user.rest_id, user.legacy.screen_name)
.then(resolve)
.catch(disableSkipLegacy)
.finally(() => clearTimeout(timeout));
})
) {
console.log(
logstr,
`did not block Twitter Blue verified user ${formattedUserName} because they are legacy verified.`,
);
} else if (
// verified via an affiliated organization instead of blue
config.skipAffiliated &&
(hasBlockableAffiliateLabels || hasBlockableVerifiedTypes)
) {
console.log(
logstr,
`did not block Twitter Blue verified user ${formattedUserName} because they are verified through an affiliated organization.`,
);
} else if (
// verified by follower count
config.skip1Mplus &&
user.legacy?.followers_count > config.skipFollowerCount
) {
console.log(logstr, `did not block Twitter Blue verified user ${formattedUserName} because they have over ${commafy(config.skipFollowerCount)} followers and Elon is an idiot.`);
} else {
let reason = ReasonBlueVerified;
if (hasBlockableVerifiedTypes) {
reason = ReasonBusinessVerified;
}
queueBlockUser(user, String(user.rest_id), reason);
return;
}
}

// step 3: promoted tweets
if (config.blockPromoted && user.promoted_tweet) {
queueBlockUser(user, String(user.rest_id), ReasonPromoted);
return;
// step 2: is user an nft bro
if (config.blockNftAvatars && (user.has_nft_avatar || user.profile_image_shape === "Hexagon")) {
queueBlockUser(user, String(user.rest_id), ReasonNftAvatar);
return;
}

// step 3: promoted tweets
if (config.blockPromoted && user.promoted_tweet) {
queueBlockUser(user, String(user.rest_id), ReasonPromoted);
return;
}
} catch (e) {
console.error(logstr, e);
}

// external integrations always come last
// external integrations always come last and have their own error handling
if (config.soupcanIntegration) {
// fire an event here to soupcan and check for transphobia
try {
Expand Down
7 changes: 5 additions & 2 deletions src/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ export async function PopulateVerifiedDb() {
}

const DBOpenRequest = indexedDB.open(dbName, dbVersion);
console.log(logstr, "opening legacy verified user database:", DBOpenRequest);

DBOpenRequest.onerror = DBOpenRequest.onblocked = () => {
console.log(logstr, "failed to open legacy verified user database:", DBOpenRequest);
console.error(logstr, "failed to open legacy verified user database:", DBOpenRequest);
};

DBOpenRequest.onupgradeneeded = () => {
console.debug(logstr, "DBOpenRequest.onupgradeneeded:", DBOpenRequest);
db = DBOpenRequest.result;
if (db.objectStoreNames.contains(dbStore)) {
return;
Expand All @@ -66,6 +66,7 @@ export async function PopulateVerifiedDb() {
};

DBOpenRequest.onsuccess = async () => {
console.debug(logstr, "DBOpenRequest.onsuccess:", DBOpenRequest);
db = DBOpenRequest.result;
console.log(logstr, "checking verified user database.");

Expand Down Expand Up @@ -167,6 +168,8 @@ export async function PopulateVerifiedDb() {
}
}
};

console.log(logstr, "opening legacy verified user database:", DBOpenRequest);
}

export function CheckDbIsUserLegacyVerified(user_id: string, handle: string): Promise<boolean> {
Expand Down

0 comments on commit 71e5e73

Please sign in to comment.