2023-08-13 09:40:40 +00:00
|
|
|
import {hashSha256, log, querySelectorAll} from "../../utilities/exports.js";
|
|
|
|
import {
|
|
|
|
type AnonymizeUsernamesData,
|
|
|
|
ReplacementType,
|
|
|
|
} from "../../storage/exports.js";
|
2022-02-23 17:17:22 +00:00
|
|
|
|
2023-08-13 09:40:40 +00:00
|
|
|
export async function runAnonymizeUsernamesFeature(
|
|
|
|
data: AnonymizeUsernamesData,
|
|
|
|
) {
|
|
|
|
const count = await anonymizeUsernames(data);
|
2022-02-23 17:17:22 +00:00
|
|
|
log(`Anonymize Usernames: Initialized for ${count} user links.`);
|
|
|
|
}
|
|
|
|
|
2023-08-13 09:40:40 +00:00
|
|
|
async function anonymizeUsernames(
|
|
|
|
data: AnonymizeUsernamesData,
|
|
|
|
): Promise<number> {
|
2022-02-23 17:17:22 +00:00
|
|
|
const usernameElements = querySelectorAll<HTMLElement>(
|
2023-06-23 10:52:03 +00:00
|
|
|
".link-user:not(.trx-anonymized)",
|
2022-02-23 17:17:22 +00:00
|
|
|
);
|
2023-08-13 09:40:40 +00:00
|
|
|
const replacements = await generateReplacements(usernameElements, data);
|
2022-02-23 17:17:22 +00:00
|
|
|
|
|
|
|
for (const element of usernameElements) {
|
|
|
|
let username = usernameFromElement(element);
|
2023-06-23 10:52:03 +00:00
|
|
|
const isMention = username.startsWith("@");
|
2022-02-23 17:17:22 +00:00
|
|
|
if (isMention) {
|
|
|
|
username = username.slice(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
const replacement = replacements[username];
|
|
|
|
element.textContent = isMention ? `@${replacement}` : `${replacement}`;
|
|
|
|
|
2023-06-23 10:52:03 +00:00
|
|
|
element.classList.add("trx-anonymized");
|
2022-02-23 17:17:22 +00:00
|
|
|
element.dataset.trxUsername = username;
|
|
|
|
}
|
|
|
|
|
|
|
|
return usernameElements.length;
|
|
|
|
}
|
|
|
|
|
2023-08-13 09:40:40 +00:00
|
|
|
async function generateReplacements(
|
|
|
|
elements: HTMLElement[],
|
|
|
|
data: AnonymizeUsernamesData,
|
|
|
|
): Promise<Record<string, string>> {
|
2022-02-23 17:17:22 +00:00
|
|
|
const usernames = new Set(
|
2023-06-23 10:52:03 +00:00
|
|
|
elements.map((element) => usernameFromElement(element).replace(/@/g, "")),
|
2022-02-23 17:17:22 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
const replacements: Record<string, string> = {};
|
|
|
|
for (const [index, username] of Array.from(usernames).entries()) {
|
2023-08-13 09:40:40 +00:00
|
|
|
switch (data.replacementType) {
|
|
|
|
case ReplacementType.Hashed: {
|
|
|
|
const hash = await hashSha256(username);
|
|
|
|
replacements[username] = hash.slice(0, 10).toUpperCase();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ReplacementType.Numerical: {
|
|
|
|
replacements[username] = `Anonymous ${index + 1}`;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default: {
|
|
|
|
throw new Error(
|
|
|
|
`Unknown ReplacementType in AnonymizeUsernamesData: ${JSON.stringify(
|
|
|
|
data,
|
|
|
|
)}`,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2022-02-23 17:17:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return replacements;
|
|
|
|
}
|
|
|
|
|
|
|
|
function usernameFromElement(element: HTMLElement): string {
|
2023-07-18 11:16:20 +00:00
|
|
|
return (element.textContent ?? "<unknown>").trim().toLowerCase();
|
2022-02-23 17:17:22 +00:00
|
|
|
}
|