aboutsummaryrefslogtreecommitdiffstats
path: root/src/scripts/login/index.ts
blob: b7e0a737e6785a2697ca9e2840f88f848f0f2538 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import { interceptPost, interceptGet } from "@/shared/intercept-jquery-ajax";

function prepareCaptcha(ctx: CanvasRenderingContext2D, width: number, height: number) {
	const imgData = ctx.getImageData(0, 0, width, height);
	const data = imgData.data;
	const radius = 1;

	function isBlack(r: number, g: number, b: number) {
		return r < 50 && g < 50 && b < 50;
	}

	function isGrayish(r: number, g: number, b: number) {
		return Math.abs(r - g) < 15 && Math.abs(g - b) < 15 && r > 100 && r < 200;
	}

	function hasNearbyBlack(x: number, y: number) {
		for (let dx = -radius; dx <= radius; dx++) {
			for (let dy = -radius; dy <= radius; dy++) {
				const nx = x + dx;
				const ny = y + dy;
				if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
					const i = (ny * width + nx) * 4;
					if (isBlack(data[i], data[i + 1], data[i + 2])) return true;
				}
			}
		}
		return false;
	}

	for (let y = 0; y < height; y++) {
		for (let x = 0; x < width; x++) {
			const i = (y * width + x) * 4;
			const [r, g, b] = [data[i], data[i + 1], data[i + 2]];
			if (isGrayish(r, g, b) && !hasNearbyBlack(x, y)) {
				data[i] = data[i + 1] = data[i + 2] = 255;
			}
		}
	}
	for (let y = 0; y < height; y++) {
		for (let x = 0; x < width; x++) {
			const i = (y * width + x) * 4;
			const [r, g, b] = [data[i], data[i + 1], data[i + 2]];

			if (isGrayish(r, g, b)) {
				data[i] = data[i + 1] = data[i + 2] = 0; // make black
			}
		}
	}
	ctx.putImageData(imgData, 0, 0);
}

const observer = new MutationObserver((mutationsList, obs) => {
	for (const mutation of mutationsList) {
		for (const node of mutation.addedNodes) {
			if ((node as any).nodeType === 1 && (node as any).id === "loginform") {
				const img = (node as HTMLFormElement).querySelector("#captchaImg") as HTMLImageElement;
				const captchaInput = (node as HTMLFormElement).querySelector("txtInput") as HTMLInputElement;

				// Wait for image to load to get correct dimensions
				img.addEventListener("load", async () => {
					const { width, height } = img;

					// 1. Create canvas
					const canvas = document.createElement("canvas");
					canvas.width = width;
					canvas.height = height;
					canvas.style.display = "block";

					// 2. Copy styles (optional)
					canvas.style.cssText = getComputedStyle(img).cssText;
					canvas.style.display = "none";

					// 3. Insert canvas before image
					img.parentNode!.querySelectorAll("canvas").forEach(c => c.remove());
					img.parentNode!.insertBefore(canvas, img);

					// 4. Hide image
					img.style.display = "none";

					// 5. Draw the image onto the canvas
					const ctx = canvas.getContext("2d")!;
					ctx.drawImage(img, 0, 0);
					prepareCaptcha(ctx, canvas.width, canvas.height);
					canvas.style.display = "";
					const dataURL = canvas.toDataURL("image/png");
					chrome.runtime.sendMessage({ type: "OCR", dataURL }, console.log);
					// TODO: Perform OCR
					// window.postMessage({
					// 	type: "RUN_OCR",
					// 	dataURL: dataURL
					// }, "*");
					//
					// // Listen for OCR result
					// function recieveOCRResult(event: any) {
					// 	if (event.data.type === "OCR_RESULT") {
					// 		console.log("Tesseract result:", event.data.text, "Confidence:", event.data.confidence);
					// 		window.removeEventListener("message", recieveOCRResult);
					// 		if (event.data.confidence < 80 || event.data.text.length !== 6) {
					// 			img.src = "generateCaptcha?" + new Date().getTime();
					// 		} else {
					// 			captchaInput.value = event.data.text;
					// 		}
					// 	}
					// }
					// window.addEventListener("message", recieveOCRResult);
				});
			}
		}
	}
});

// Start observing the body
observer.observe(document.body, { childList: true, subtree: true });