├── LICENSE ├── README.md ├── background.js ├── config.js ├── css └── styles.css ├── images ├── error.png ├── icon-128.png ├── icon-16.png ├── icon-192.png ├── icon-32.png ├── icon-384.png ├── icon-64.png └── success.png ├── js ├── custom.js └── popup.js ├── manifest.json ├── popup.html └── scripts ├── helpers └── checkUpdate.js └── index.js /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Hoàng Hào (Kem) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

ZaloDataExtractor

2 | 3 | 4 | > [!NOTE] 5 | The purpose of this repository is to be used in conjunction with the [zca-js](https://github.com/RFS-ADRENO/zca-js/), significantly increasing its effectiveness.
Reading documents [zca-js](https://github.com/RFS-ADRENO/zca-js/) in [here](https://tdung.gitbook.io/zca-js/).
Feel free to adjust any sections if needed! 6 | 7 | ## Overview 8 | **ZaloDataExtractor** is a tool designed to extract essential information from the Zalo Web, including IMEI, Cookies, and User-Agent. This tool is perfect for developers, analysts, and anyone needing quick access to these data points for analysis, development, or app compatibility testing. 9 | 10 | ## Features 11 | 12 | - **Extract IMEI:** Retrieve the IMEI number associated with the Zalo Web. 13 | - **Fetch Cookies:** Capture session cookies for further use in development or analysis. 14 | - **Get User-Agent:** Extract the User-Agent string for compatibility testing and user environment analysis. 15 | 16 | ## Installation 17 | 18 | ```bash 19 | git clone https://github.com/JustKemForFun/ZaloDataExtractor/ 20 | ``` 21 | - Clone or download this repository to your local machine. 22 | - Open your browser and manually type `chrome://extensions/` in the *Chrome browser* or `edge://extensions/` in the *Edge browser* into the address bar. 23 | - Enable "**Developer mode**" in the top right corner. 24 | - Click on "**Load unpacked**" and select the folder where you cloned or downloaded the extension. 25 | 27 | 28 | ## Usage 29 | 30 | - Open Zalo Web in your *Chrome browser* or *Egde browser*. 31 | - Click on **Extension** and press *Refresh Page* to start getting information. 32 | - If you use incognito browser please enable incognito browsing in `chrome://extension` or `edge://extensions/` into the address bar. 33 | 34 | ## Icons 35 | 36 | - The extension comes with various icons to match different sizes (16px, 32px, 64px, 128px, 192px, 384px). 37 | 38 | ## Troubleshooting 39 | 40 | If you encounter any issues or have suggestions for improvements, please [create an issue](https://github.com/JustKemForFun/ZaloDataExtractor/issues). 41 | 42 | 45 | ## Contributors 46 | 47 | We welcome contributions from the community. 48 | 49 | | Name | GitHub Profile | Avatar | 50 | |--------------------|---------------------------------------------|----------------------------------------| 51 | | Hoàng Hào | [Kem](https://www.github.com/JustKemForFun) | Hoàng Hào | 52 | 53 | ## License 54 | 55 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. 56 | -------------------------------------------------------------------------------- /background.js: -------------------------------------------------------------------------------- 1 | function captureRequests() { 2 | chrome.webRequest.onBeforeRequest.addListener(function (details) { 3 | let url = details.url; 4 | let imeiFound = false; 5 | let imeiValue = "Not Found"; 6 | 7 | // imeiValue = localStorage.getItem("z_uuid"); // === sh_z_uuid 8 | if (url.includes("/api/login/getServerInfo") && url.indexOf("imei=") > -1) { 9 | let params = new URLSearchParams(new URL(url).search); 10 | imeiFound = true; 11 | imeiValue = params.get("imei"); 12 | 13 | chrome.runtime.sendMessage({ action: "IMEIValue", imei: imeiValue }); 14 | 15 | } 16 | 17 | // get cookies || error pls create an issue github.com/JustKemForFun/ZaloDataExtractor 18 | 19 | if (imeiFound && url.includes("chat.zalo.me")) { 20 | chrome.cookies.getAll({ url: url }, function (cookies) { 21 | let parsedCookies = cookies.map(cookie => ({ 22 | domain: cookie.domain, 23 | expirationDate: cookie.expirationDate || null, // (Date.now() / 1000) + (84600 * 365) - 1 year 24 | hostOnly: cookie.hostOnly, 25 | httpOnly: cookie.httpOnly, 26 | name: cookie.name, 27 | path: cookie.path, 28 | sameSite: cookie.sameSite || "no_restriction", 29 | secure: cookie.secure, 30 | session: cookie.session, 31 | storeId: cookie.storeId || null, 32 | value: cookie.value 33 | })); 34 | 35 | chrome.runtime.sendMessage({ action: "CookiesValue", cookies: JSON.stringify(parsedCookies) }); 36 | 37 | }); 38 | } 39 | 40 | let userAgent = navigator.userAgent; 41 | chrome.runtime.sendMessage({ action: "UserAgent", useragent: userAgent }); 42 | 43 | }, 44 | { urls: [""] }, 45 | ["requestBody"] 46 | ); 47 | } 48 | 49 | captureRequests(); 50 | -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | version_check: "https://raw.githubusercontent.com/JustKemForFun/ZaloDataExtractor/main/manifest.json", 3 | source_code: "https://github.com/JustKemForFun/ZaloDataExtractor", 4 | fallbackVersion: "1.1.0" 5 | }; 6 | -------------------------------------------------------------------------------- /css/styles.css: -------------------------------------------------------------------------------- 1 | .button-container { 2 | display: flex; 3 | flex-direction: column; 4 | margin-top: 1rem; 5 | /* flex-direction: row; 6 | width: 80vw; 7 | height: 8vh; 8 | box-sizing: border-box; */ 9 | /* justify-content: space-between; 10 | margin-top: 1rem; */ 11 | } 12 | 13 | .button-container button { 14 | flex: 1; 15 | /* margin: 0 0.5rem */ 16 | margin: 0.25rem; 17 | padding: 0.5rem 1rem; 18 | border-radius: 20px; 19 | font-size: 15px; 20 | font-weight: 400; 21 | cursor: pointer; 22 | transition: all 0.3s ease; 23 | /* flex: 1; 24 | padding: 10px; 25 | font-size: 14px; 26 | border: none; 27 | cursor: pointer; 28 | margin-top: 1rem; */ 29 | } 30 | 31 | .button-container .export-all { 32 | background-color: #FF99FF; 33 | color: white; 34 | } 35 | 36 | .button-container .export-imei { 37 | background-color: #4CAF50; 38 | color: white; 39 | } 40 | 41 | .button-container .export-cookies { 42 | background-color: #FF9800; 43 | color: white; 44 | } 45 | 46 | .export-all { 47 | background-color: #FF99FF; 48 | color: #ffffff; 49 | } 50 | 51 | .export-imei { 52 | background-color: #e67e22; 53 | color: #ffffff; 54 | } 55 | 56 | .export-cookies { 57 | background-color: #5fae02; 58 | color: #ffffff; 59 | } 60 | 61 | .export-ua { 62 | background-color: #f11919; 63 | color: #ffffff; 64 | } 65 | 66 | .rf-page { 67 | background-color: aqua; 68 | color: #ffffff; 69 | } 70 | 71 | .button-container button:hover { 72 | opacity: 0.5; 73 | } 74 | 75 | @media (max-width: 400px) { 76 | .button-container { 77 | flex-direction: column; 78 | width: 300px; 79 | height: 120px; 80 | box-sizing: border-box; 81 | } 82 | } -------------------------------------------------------------------------------- /images/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JustKemForFun/ZaloDataExtractor/228cba4cd82bc0efbe8316836d083a1f49db605b/images/error.png -------------------------------------------------------------------------------- /images/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JustKemForFun/ZaloDataExtractor/228cba4cd82bc0efbe8316836d083a1f49db605b/images/icon-128.png -------------------------------------------------------------------------------- /images/icon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JustKemForFun/ZaloDataExtractor/228cba4cd82bc0efbe8316836d083a1f49db605b/images/icon-16.png -------------------------------------------------------------------------------- /images/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JustKemForFun/ZaloDataExtractor/228cba4cd82bc0efbe8316836d083a1f49db605b/images/icon-192.png -------------------------------------------------------------------------------- /images/icon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JustKemForFun/ZaloDataExtractor/228cba4cd82bc0efbe8316836d083a1f49db605b/images/icon-32.png -------------------------------------------------------------------------------- /images/icon-384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JustKemForFun/ZaloDataExtractor/228cba4cd82bc0efbe8316836d083a1f49db605b/images/icon-384.png -------------------------------------------------------------------------------- /images/icon-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JustKemForFun/ZaloDataExtractor/228cba4cd82bc0efbe8316836d083a1f49db605b/images/icon-64.png -------------------------------------------------------------------------------- /images/success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JustKemForFun/ZaloDataExtractor/228cba4cd82bc0efbe8316836d083a1f49db605b/images/success.png -------------------------------------------------------------------------------- /js/custom.js: -------------------------------------------------------------------------------- 1 | // chrome.action.onClicked.addListener(function(tab) { 2 | // chrome.scripting.executeScript({ 3 | // target: { tabId: tab.id }, 4 | // func: copyTextToClipboard 5 | // }); 6 | // }); 7 | 8 | document.getElementById("btn-copy-imei").addEventListener("click", async () => { 9 | var textInput = document.getElementById("imei"); 10 | if (!textInput.value) return; 11 | 12 | copyTextToClipboard(textInput.value); 13 | 14 | let btnCopy = document.getElementById("btn-copy-imei"); 15 | 16 | btnCopy.innerText = "Copied"; 17 | let timeoutCopy = setTimeout(() => { 18 | btnCopy.innerHTML = ` Copy IMEI`; 19 | clearTimeout(timeoutCopy); 20 | }, 2000); 21 | }); 22 | 23 | document.getElementById("btn-copy-cookies").addEventListener("click", async () => { 24 | var textInput = document.getElementById("cookies"); 25 | if (!textInput.value) return; 26 | 27 | copyTextToClipboard(textInput.value); 28 | 29 | let btnCopy = document.getElementById("btn-copy-cookies"); 30 | 31 | btnCopy.innerText = "Copied"; 32 | let timeoutCopy = setTimeout(() => { 33 | btnCopy.innerHTML = ` Copy Cookies`; 34 | clearTimeout(timeoutCopy); 35 | }, 2000); 36 | }); 37 | 38 | document.getElementById("btn-copy-ua").addEventListener("click", async () => { 39 | var textInput = document.getElementById("user-agent"); 40 | if (!textInput.value) return; 41 | 42 | copyTextToClipboard(textInput.value); 43 | 44 | let btnCopy = document.getElementById("btn-copy-ua"); 45 | 46 | btnCopy.innerText = "Copied"; 47 | let timeoutCopy = setTimeout(() => { 48 | btnCopy.innerHTML = ` Copy User-Agent`; 49 | clearTimeout(timeoutCopy); 50 | }, 2000); 51 | }); 52 | 53 | function copyTextToClipboard(str) { 54 | const el = document.createElement("textarea"); 55 | el.value = str; 56 | el.setAttribute("readonly", ""); 57 | el.style.position = "absolute"; 58 | el.style.left = "-9999px"; 59 | document.body.appendChild(el); 60 | el.select(); 61 | document.execCommand("copy"); 62 | document.body.removeChild(el); 63 | } 64 | 65 | // document.getElementById("refresh-button").addEventListener("click", () => { 66 | // window.location.reload(); 67 | // }); 68 | 69 | document.addEventListener("DOMContentLoaded", function () { 70 | document 71 | .getElementById("refresh-button") 72 | .addEventListener("click", function () { 73 | chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { 74 | chrome.tabs.reload(tabs[0].id); 75 | }); 76 | }); 77 | }); -------------------------------------------------------------------------------- /js/popup.js: -------------------------------------------------------------------------------- 1 | // window.addEventListener('load', function() { /* my code */ }); 2 | window.addEventListener("load", function () { 3 | chrome.runtime.onMessage.addListener(function (request) { 4 | if (request.action === "IMEIValue") { 5 | document.getElementById("imei").value = request.imei; 6 | document.getElementById("imei").parentElement.classList.remove("is-disabled"); 7 | } else if (request.action === "CookiesValue") { 8 | document.getElementById("cookies").value = request.cookies; 9 | document.getElementById("cookies").parentElement.classList.remove("is-disabled"); 10 | } else if (request.action === "UserAgent") { 11 | document.getElementById("user-agent").value = request.useragent; 12 | document.getElementById("user-agent").parentElement.classList.remove("is-disabled"); 13 | } 14 | }); 15 | }); -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ZaloDataExtractor", 3 | "version": "1.1.1", 4 | "description": "ZaloDataExtractor is a tool that extracts essential information like IMEI, Cookies, and User-Agent from the Zalo APP. It's designed for easy use, allowing quick and accurate data collection for analysis, development, or app compatibility", 5 | "manifest_version": 3, 6 | "homepage_url": "https://github.com/JustKemForFun/ZaloDataExtractor/", 7 | "icons": { 8 | "16": "images/icon-16.png", 9 | "32": "images/icon-32.png", 10 | "64": "images/icon-64.png", 11 | "128": "images/icon-128.png", 12 | "192": "images/icon-192.png", 13 | "384": "images/icon-384.png" 14 | }, 15 | "background": { 16 | "service_worker": "background.js" 17 | }, 18 | "permissions": [ 19 | "tabs", 20 | "cookies", 21 | "storage", 22 | "activeTab", 23 | "webRequest", 24 | "notifications", 25 | "clipboardWrite", 26 | "declarativeNetRequest" 27 | ], 28 | "content_scripts": [ 29 | { 30 | "matches": [""], 31 | "js": ["js/popup.js"] 32 | } 33 | ], 34 | "host_permissions": [ 35 | "" 36 | ], 37 | "action": { 38 | "default_icon": { 39 | "384": "images/icon-384.png" 40 | }, 41 | "default_popup": "popup.html" 42 | }, 43 | "externally_connectable": { 44 | "matches": [ 45 | "http://localhost:3008/*", 46 | "http://127.0.0.1:3008/*" 47 | ] 48 | }, 49 | "incognito": "spanning" 50 | } 51 | -------------------------------------------------------------------------------- /popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Zalo User Information 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 |

Zalo User Information

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 | -------------------------------------------------------------------------------- /scripts/helpers/checkUpdate.js: -------------------------------------------------------------------------------- 1 | import config from '../../config.js'; 2 | 3 | const versionSpan = document.querySelector("#version"); 4 | const updateBtn = document.querySelector("#update-btn"); 5 | 6 | export async function checkUpdate() { 7 | try { 8 | let currentVersion = 'unknown'; 9 | 10 | if (typeof chrome !== 'undefined' && chrome.runtime && typeof chrome.runtime.getManifest === 'function') { 11 | try { 12 | currentVersion = chrome.runtime.getManifest().version; 13 | } catch (chromeError) { 14 | console.warn("Error getting manifest version:", chromeError); 15 | } 16 | } else { 17 | console.warn("Not running in a Chrome extension environment"); 18 | currentVersion = config.fallbackVersion || 'unknown'; 19 | } 20 | 21 | console.log("Current Version:", currentVersion); 22 | 23 | const { version_check, source_code } = config; 24 | const latestVersion = (await (await fetch(version_check)).json()).version; 25 | 26 | console.log("Latest Version from API:", latestVersion); 27 | 28 | if (updateBtn) { 29 | if (latestVersion > currentVersion) { 30 | versionSpan.innerHTML = ""; 31 | updateBtn.style.display = "inline-block"; 32 | updateBtn.innerHTML = "V" + latestVersion; 33 | updateBtn.setAttribute("data-tooltip", "Update available New V" + latestVersion); 34 | updateBtn.setAttribute("data-flow", "bottom"); 35 | updateBtn.onclick = () => { 36 | window.open(source_code); 37 | }; 38 | } else if (currentVersion !== 'unknown') { 39 | updateBtn.style.display = "none"; 40 | versionSpan.innerHTML = "V" + currentVersion + " (latest)"; 41 | } else { 42 | updateBtn.style.display = "none"; 43 | versionSpan.innerHTML = "Version check unavailable"; 44 | } 45 | } 46 | } catch (e) { 47 | console.warn("Check for update failed", e); 48 | if (versionSpan) versionSpan.innerHTML = "Version check failed"; 49 | if (updateBtn) updateBtn.style.display = "none"; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /scripts/index.js: -------------------------------------------------------------------------------- 1 | import { checkUpdate } from './helpers/checkUpdate.js'; 2 | 3 | (async function () { 4 | try { 5 | await checkUpdate(); 6 | } catch (e) { 7 | console.error("Error calling checkUpdate:", e); 8 | } 9 | })(); 10 | --------------------------------------------------------------------------------