aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArpit Chakladar <54011232+arpitchakladar@users.noreply.github.com>2025-06-13 17:31:17 +0530
committerArpit Chakladar <54011232+arpitchakladar@users.noreply.github.com>2025-06-13 17:31:24 +0530
commit976ae51dabe77686e405a2b99127485209c7c9cd (patch)
tree9c931c7a101485f42492d26ea6faadb209c79cfc
parentcaa9c3f705730886cab911cb241703a10494581c (diff)
downloadbanglar-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.lock27
-rw-r--r--flake.nix19
-rw-r--r--package-lock.json4
-rw-r--r--src/scripts.json2
-rw-r--r--src/scripts/login.ts111
-rw-r--r--src/scripts/login/index.ts112
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 });