diff options
| author | Arpit Chakladar <54011232+arpitchakladar@users.noreply.github.com> | 2025-06-13 17:31:17 +0530 |
|---|---|---|
| committer | Arpit Chakladar <54011232+arpitchakladar@users.noreply.github.com> | 2025-06-13 17:31:24 +0530 |
| commit | 976ae51dabe77686e405a2b99127485209c7c9cd (patch) | |
| tree | 9c931c7a101485f42492d26ea6faadb209c79cfc | |
| parent | caa9c3f705730886cab911cb241703a10494581c (diff) | |
| download | banglar-bhumi-utils-976ae51dabe77686e405a2b99127485209c7c9cd.tar.gz banglar-bhumi-utils-976ae51dabe77686e405a2b99127485209c7c9cd.zip | |
Adding a flake.nix.
Cleaning up the captcha for the OCR.
| -rw-r--r-- | flake.lock | 27 | ||||
| -rw-r--r-- | flake.nix | 19 | ||||
| -rw-r--r-- | package-lock.json | 4 | ||||
| -rw-r--r-- | src/scripts.json | 2 | ||||
| -rw-r--r-- | src/scripts/login.ts | 111 | ||||
| -rw-r--r-- | src/scripts/login/index.ts | 112 |
6 files changed, 161 insertions, 114 deletions
diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..a67fb22 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1749285348, + "narHash": "sha256-frdhQvPbmDYaScPFiCnfdh3B/Vh81Uuoo0w5TkWmmjU=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "3e3afe5174c561dee0df6f2c2b2236990146329f", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..a3ce275 --- /dev/null +++ b/flake.nix @@ -0,0 +1,19 @@ +{ + description = "Flake for development environment for better-containers."; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + }; + + outputs = { self, nixpkgs }: + let + pkgs = nixpkgs.legacyPackages."x86_64-linux"; + in { + devShells."x86_64-linux".default = pkgs.mkShell { + packages = with pkgs; [ + nodejs_22 + nodePackages.typescript-language-server + ]; + }; + }; +} diff --git a/package-lock.json b/package-lock.json index fb961b9..1c51f5d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "banglar-bhumi-utils", - "version": "1.0.0", + "version": "1.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "banglar-bhumi-utils", - "version": "1.0.0", + "version": "1.1.0", "license": "MIT", "devDependencies": { "@types/chrome": "^0.0.213", diff --git a/src/scripts.json b/src/scripts.json index 43d506c..74a465d 100644 --- a/src/scripts.json +++ b/src/scripts.json @@ -1,7 +1,7 @@ { "injected": { "stop-blocking.ts": "*", - "login.ts": "*", + "login/index.ts": "*", "otps/grievance-application.ts": "GrievAppViewAction.action", "otps/mutation-application.ts": "MuteApplication.action", "otps/warish-application.ts": "WarishAppViewAction.action", diff --git a/src/scripts/login.ts b/src/scripts/login.ts deleted file mode 100644 index 0fe5239..0000000 --- a/src/scripts/login.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { interceptPost, interceptGet } from "@/shared/intercept-jquery-ajax"; - -interceptPost("viewLoginAreaAction", args => { - const callback = args[1]; - args[1] = (html: any) => { - callback(html); - const captchaInputElement = $("#txtCaptcha"); - const captchaValueElement = $("#txtInput"); - captchaInputElement.val("FFFFFF"); - captchaValueElement.val("FFFFFF"); - (window as any).DrawLoginCaptcha = () => {}; - (window as any).validateLoginCaptcha = () => true; - captchaValueElement.hide(); - captchaInputElement.hide(); - $(".captcharefresh").hide(); - } -}); -interceptPost("viewPasswordRecoveryArea", args => { - const callback = args[1]; - args[1] = (html: any) => { - callback(html); - const captchaInputElement = $("#dText"); - const captchaValueElement = $("#captaText"); - captchaInputElement.val("FFFFFF"); - captchaValueElement.val("FFFFFF"); - (window as any).Captcha = () => {}; - captchaValueElement.hide(); - captchaInputElement.hide(); - $("#captchaRef").hide(); - } -}); -interceptPost("login.action", args => { - const callback = args[2]; - args[2] = (data: any) => { - const loginData = args[1]; - if (!data.exception && data.checkmsg === "success") { - window.localStorage.setItem("loginData", btoa(JSON.stringify(loginData))); - } - - callback(data); - $("#txtInput").val("FFFFFF"); - $("#beforeLoginDiv").hide(); - $("#afterLoginDiv").css("display", "block"); - $("#afterLoginLabel").css("display", "block"); - const username = atob(loginData.username.split("RGxycyMxMjM=")[1]); - $("#afterLoginLabel > label").html(`--> ${username}`); - }; -}); -interceptPost("changePassword.action", args => { - const callback = args[2]; - args[2] = (data: any) => { - callback(data); - $("#txtInput").val("FFFFFF"); - }; -}); -interceptGet("viewRegistrationAreaAction", args => { - const callback = args[1]; - args[1] = (html: any) => { - callback(html); - const captchaInputElement = $("#regInputCaptcha"); - const captchaValueElement = $("#regCaptcha"); - captchaInputElement.val("FFFFFF"); - captchaValueElement.val("FFFFFF"); - $("#registrationForm > div > div:nth-child(5) > div:nth-child(3)").hide(); - $("#registrationForm > div > div:nth-child(5) > div:nth-child(4)").hide(); - $("#registrationForm > div > div:nth-child(5) > div:nth-child(5)").hide(); - (window as any).DrawRegistrationCaptcha = () => {}; - (window as any).validateRegistrationCaptcha = () => true; - } -}); -interceptGet("viewChangePasswordAction", args => { - const callback = args[1]; - args[1] = (html: any) => { - callback(html); - const captchaValueElement = $("#txtCaptcha"); - const captchaInputElement = $("#txtInput"); - captchaValueElement.val("FFFFFF"); - captchaInputElement.val("FFFFFF"); - (window as any).DrawLoginCaptcha = () => {}; - captchaValueElement.hide(); - captchaInputElement.hide(); - $(".captcharefresh").hide(); - } -}); - -document.addEventListener("DOMContentLoaded", () => { - $("#afterLoginDiv > a").click(() => { - window.localStorage.removeItem("loginData"); - }); - - const login = () => { - let loginData = window.localStorage.getItem("loginData"); - loginData = loginData ? JSON.parse(atob(loginData)) : null; - - if (loginData) { - $.post( - "/BanglarBhumi/login.action", - loginData, - data => { - if (data.exception || data.checkmsg !== "success") { - loginData = null; - } - }, - "json" - ); - } - }; - - login(); - setInterval(login, 1000 * 60); -}); diff --git a/src/scripts/login/index.ts b/src/scripts/login/index.ts new file mode 100644 index 0000000..b7503b9 --- /dev/null +++ b/src/scripts/login/index.ts @@ -0,0 +1,112 @@ +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"); + // 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 }); |
