├── .github
├── FUNDING.yml
└── icon.png
├── .gitignore
├── LICENSE
├── README.md
├── package-lock.json
├── package.json
├── src
├── UImodul.js
├── captchaSolver.js
├── captchaSolverApi.js
├── config.js
├── index.js
└── utils.js
└── webpack.config.js
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: red_official
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
13 | custom: #['https://www.paypal.com/donate/?hosted_button_id=LTL43KCDUWVPL']
14 |
--------------------------------------------------------------------------------
/.github/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LetsUpdate/CSN/769994b8e7f283559937b0663ebef15e60bce4d9/.github/icon.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Node.js
2 | node_modules/
3 | npm-debug.log*
4 | yarn-debug.log*
5 | yarn-error.log*
6 |
7 | # Logs
8 | logs/
9 | *.log
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 | lerna-debug.log*
14 |
15 | # Dependency directories
16 | node_modules/
17 | jspm_packages/
18 |
19 | # Optional npm cache directory
20 | .npm
21 |
22 | # Optional eslint cache
23 | .eslintcache
24 |
25 | # Optional REPL history
26 | .node_repl_history
27 |
28 | # Output of 'npm pack'
29 | *.tgz
30 |
31 | # Coverage directory used by tools like istanbul
32 | coverage/
33 |
34 | # Webpack files
35 | dist/
36 | build/
37 |
38 | # IDE specific files
39 | .vscode/
40 | .idea/
41 |
42 | # MacOS specific files
43 | .DS_Store
44 |
45 | # Environment variables
46 | .env
47 | .env.local
48 | .env.development.local
49 | .env.test.local
50 | .env.production.local
51 |
52 | # Tampermonkey specific files
53 | *.user.js
54 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 RED
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.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Captcha Solver for Neptun
2 |
3 |
4 |
5 | A **CSN** célja a Captcha kihívások megoldásának automatizálása a Neptun platformon.
6 |
7 | ## Újdonság: a script fixelve, és teljesen újra lett gondolva!
8 |
9 |
10 |
11 | *Dobj egy csillagot hogy tudjak vele menőzni!* [⭐KaptamEgyCsillagot!!!⭐](https://coub.com/view/1uvg42)
12 |
13 | Telepítési útmutató:
14 | 1. Első lépésként telepítsd a böngésződbe a [Tampermonkey](https://www.tampermonkey.net/) kiegészítőt, amely lehetővé teszi a JavaScript alapú szkriptek futtatását a böngésződben.
15 | 2. A szkript telepítéséhez [kattints ide](https://github.com/LetsUpdate/CSN/releases/latest/download/CSN.user.js). Ezután a szkript automatikusan bekerül a Tampermonkey kiegészítőbe, és már el is kezdheted használni!
16 | 3. **Az első használatkor engedélyt fog kérni a backend szerverre való csatlakozáshoz, engedélyezd ezt neki.**
17 |
18 | **Figyelem:** A script csak a captcha-t küldi el és a szerver is csak azt képes elfogadni. Ha nem hiszed, nézd meg a kódot!
19 |
20 | *tipp: Ha nem működne a PowerUp [@boglarka](https://github.com/boglarkla) írt rá egy fixet: [boglarka/npufix](https://github.com/boglarkla/npu/)*
21 |
22 |
23 |
24 | ##
25 | *Ha nagyon tetszett, akár [meghívhatsz egy kávéra](https://ko-fi.com/red_official)*
26 |
27 | [](https://ko-fi.com/Q5Q0O1LDA)
28 |
29 | koszi :P
30 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "csn2",
3 | "version": "1.0.3",
4 | "description": "Captcha Solver For Neptun",
5 | "main": "src/index.js",
6 | "scripts": {
7 | "build:prod": "webpack",
8 | "build:dev": "cross-env NODE_ENV=development webpack",
9 | "watch": "cross-env NODE_ENV=development webpack --watch",
10 | "serve": "cross-env NODE_ENV=development webpack serve --mode development"
11 | },
12 | "author": "RED",
13 | "license": "MIT",
14 | "devDependencies": {
15 | "cross-env": "^7.0.3",
16 | "eslint": "^8.36.0",
17 | "eslint-config-prettier": "^8.7.0",
18 | "npm-run-all": "^4.1.5",
19 | "prettier": "^2.8.4",
20 | "terser-webpack-plugin": "^5.3.10",
21 | "webpack": "^5.93.0",
22 | "webpack-cli": "^5.1.4",
23 | "webpack-dev-server": "^5.0.4",
24 | "webpack-userscript": "^3.2.2"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/UImodul.js:
--------------------------------------------------------------------------------
1 | const icons = {
2 | "logo": "https://raw.githubusercontent.com/LetsUpdate/CSN/main/.github/icon.png",
3 | "networkError": "data:image/png;base64,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",
4 | "scriptError": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAAsTAAALEwEAmpwYAAABNUlEQVR4nO2XUY6DMAxE0+1Z+pfrcAb641X2BFzK6YlKTrGqV/0r0ao0KgqUvJHmC4Xg0YxtnAOgCi4x/kbV26s0s4PbE6Lq7RKjvcphGL7cnhARQPflgCC9PTKqPmVe4H/nH5/Pve/n+zw5X12wMFPAHPMCSs/n9yPA0LgDuq47Vi04jeOEJR+/BMfrdXJ//n0IsDQCDuiJQHjSA+6857IW87tX7wFpZSKA4AAjAkIPMJqgMAVsE2NQT37C0rFWen5zU0ARwOMAbTkCqbCgdyODAIIDjAjIhntAWjjzH9cDEgKMOCC1HAFlD/AsQsom6NtZhZW/Qd/236AigG/bAakyEUBwgBEBoQcYTVCYAsYYFPYAYxFaGoFNsG97Fc6RX7g2XW2EDRSNAIIDbLUIAAAAcJ+PP+cSOT5diQGeAAAAAElFTkSuQmCC",
5 | }
6 |
7 | const id = "CSN_LOGO"
8 |
9 | function getCaptchaWindow() {
10 | return $('#step2Captcha > div:nth-child(1)')
11 | }
12 |
13 |
14 | function PlaceLogo() {
15 | const style = document.createElement('style');
16 | style.type = 'text/css';
17 | style.innerHTML = `
18 | @keyframes spin {
19 | from { transform: rotate(0deg); }
20 | to { transform: rotate(360deg); }
21 | }
22 | `;
23 | document.getElementsByTagName('head')[0].appendChild(style);
24 |
25 | getCaptchaWindow().append(
26 | `
27 |

28 |
`
29 | )
30 | //onclick event open https://github.com/LetsUpdate/CSN
31 | $(`#${id}`).click(() => {
32 | window.open('https://github.com/LetsUpdate/CSN', '_blank');
33 | });
34 |
35 | }
36 |
37 | const LogoState = {
38 | "default": "default",
39 | "solving": "solving",
40 | "error":"error",
41 | "networkError":"networkError",
42 | }
43 |
44 | function SetState(state){
45 | const logo = $(`#${id} > img`)
46 | switch(state){
47 | case LogoState.default:
48 | logo.attr('src', icons.logo)
49 | logo.css('animation', 'none')
50 | break;
51 | case LogoState.solving:
52 | logo.attr('src', icons.logo)
53 | logo.attr('title', 'Megoldás folyamatban...')
54 | //rotate the logo
55 | logo.css({
56 | 'animation': 'spin 0.8s linear infinite',
57 | '-webkit-animation': 'spin 0.8s linear infinite', // For Safari
58 | '-moz-animation': 'spin 0.8s linear infinite', // For Firefox
59 | '-o-animation': 'spin 0.8s linear infinite' // For Opera
60 | });
61 | break;
62 | case LogoState.error:
63 | logo.attr('src', icons.scriptError)
64 | logo.css('animation', 'none')
65 | //add hint
66 | logo.attr('title', 'Ismeretlen hiba a captcha megoldása közben')
67 | break;
68 | case LogoState.networkError:
69 | logo.attr('src', icons.networkError)
70 | logo.css('animation', 'none')
71 | logo.attr('title', 'CSN Szerver Hiba / unreachable')
72 | break;
73 | }
74 | }
75 |
76 |
77 | module.exports = { PlaceLogo, SetState, LogoState }
--------------------------------------------------------------------------------
/src/captchaSolver.js:
--------------------------------------------------------------------------------
1 | const { solveCaptcha } = require('./captchaSolverApi');
2 | const { SetState, LogoState } = require('./UImodul');
3 |
4 | const $ = window.jQuery;
5 |
6 | //
7 | function getCaptchaRefreshIcon() {
8 | return $(".captchaRefreshIcon");
9 | }
10 | //
11 | function getCaptchaImage() {
12 | return $("#upCaptchaLogin_loginCaptcha > img");
13 | }
14 | //
15 | function getCaptchaInput() {
16 | return $("#txtCaptchaLogin");
17 | }
18 | //
19 | //body > div.ui-dialog.ui-widget.ui-widget-content.ui-corner-all.ui-front.ui-dialog-buttons.ui-draggable > div.ui-dialog-buttonpane.ui-widget-content.ui-helper-clearfix > div > button:nth-child(2)
20 | function getNewLoginButton() {
21 | // Use a more specific selector to target buttons with text containing 'Belépés' or 'login' (case-insensitive)
22 | return $("button.ui-button").filter(function () {
23 | return /belépés|login/i.test($(this).text());
24 | });
25 | }
26 | //
27 | function getFirstLogin() {
28 | return $("#btnSubmit");
29 | }
30 |
31 | function getErrorLabel() {
32 | return $("#txtCaptchaLogin-error");
33 | }
34 |
35 | function scanForElementText(element, timeout = 10000) {
36 | return new Promise((resolve, reject) => {
37 | const intervalTime = 100; // Interval time in milliseconds
38 | let elapsedTime = 0;
39 |
40 | const interval = setInterval(() => {
41 | if (element === null) { return; }
42 | if (element.text().trim().length > 0) {
43 | clearInterval(interval);
44 | resolve(false); // Captcha is invalid
45 | }
46 |
47 | elapsedTime += intervalTime;
48 | if (elapsedTime >= timeout) {
49 | clearInterval(interval);
50 | reject("TIME_OUT"); // Captcha is valid (no error message appeared within the timeout)
51 | }
52 | }, intervalTime);
53 | });
54 | }
55 | let tryes = 0;
56 | async function StartSolving(imgsrc) {
57 |
58 | if (tryes > 4) {
59 | SetState(LogoState.error);
60 | return;
61 | }
62 | SetState(LogoState.solving);
63 | tryes++;
64 |
65 |
66 | const captchaImage = getCaptchaImage();
67 | const loginButton = getNewLoginButton();
68 | const captchaInput = getCaptchaInput()
69 | const captchaRefreshIcon = getCaptchaRefreshIcon();
70 |
71 | try {
72 | console.log('Solving captcha...');
73 | await new Promise((resolve) => setTimeout(resolve, 100));
74 | let captchaSolution;
75 | if (imgsrc === captchaImage[0].src) {
76 | captchaSolution = await solveCaptcha(captchaImage[0]);
77 | } else {
78 | console.log('Captcha image changed, terminating...');
79 | return;
80 | }
81 |
82 |
83 | captchaInput.val(captchaSolution);
84 |
85 | if (imgsrc === captchaImage[0].src) {
86 | await new Promise((resolve) => setTimeout(resolve, 100));
87 | loginButton.click();
88 | console.log('Captcha solved:', captchaSolution);
89 | } else {
90 | console.log('Captcha image changed, terminating...');
91 | return;
92 | }
93 |
94 | // Ne spammeljük a szervert szét
95 | await new Promise((resolve) => setTimeout(resolve, 500));
96 |
97 |
98 | //Mutotion observer observe the error label
99 | //if the captcha is invalid the error label will not be empty
100 |
101 |
102 | //wait for the error label to appear
103 | console.log('Waiting for error label...');
104 | try {
105 | await scanForElementText(getErrorLabel());
106 | console.log('Captcha is invalid:', getErrorLabel().text());
107 | getErrorLabel().text("");
108 | console.log('waitforCaptchaRefresh');
109 | captchaRefreshIcon.click();
110 | return;
111 | }
112 | catch (error) {
113 | if (error === "TIME_OUT") {
114 | console.log('TimedOut');
115 | } else {
116 | console.error('Failed to solve captcha:', error);
117 | }
118 | return;
119 | }
120 |
121 | }
122 | catch (error) {
123 |
124 | if (error === "HARD_IMAGE") {
125 | captchaRefreshIcon.click();
126 |
127 | } else {
128 |
129 | console.error('Failed to solve captcha:', error);
130 | SetState(LogoState.networkError);
131 | return;
132 | }
133 | }
134 | }
135 |
136 |
137 |
138 |
139 | function handleImageLoad() {
140 | console.log('Image loaded:', getCaptchaImage()[0].src);
141 | StartSolving(getCaptchaImage()[0].src);
142 | }
143 |
144 |
145 |
146 | function LookForCaptcha() {
147 |
148 | const $imgElement = getCaptchaImage();
149 | const imgElement = $imgElement[0];
150 |
151 | //onbutton click reset tryes
152 | getFirstLogin().click(function () {
153 | tryes = 0;
154 | });
155 |
156 | // Check if the element exists
157 | if (imgElement) {
158 | // Create a new MutationObserver
159 | const observer = new MutationObserver((mutations) => {
160 | mutations.forEach((mutation) => {
161 | if (mutation.type === 'attributes' && mutation.attributeName === 'src') {
162 | console.log('Image src changed to:', imgElement.src);
163 |
164 |
165 | // Attach a load event listener to ensure the image is loaded
166 | $imgElement.off('load').on('load', function () {
167 | if (this.complete && this.naturalWidth > 0) {
168 | handleImageLoad();
169 | }
170 | });
171 |
172 | // Also handle the case where the image might already be cached
173 | // if (imgElement.complete && imgElement.naturalWidth > 0) {
174 | // console.log('Image loaded from cache:', imgElement.src);
175 | // handleImageLoad();
176 | // }
177 |
178 |
179 | }
180 | });
181 | });
182 |
183 | // Start observing the image element for changes in its attributes
184 | observer.observe(imgElement, {
185 | attributes: true // Listen for attribute changes
186 | });
187 | } else {
188 | console.error('Image element not found');
189 | }
190 |
191 | console.log('Observing document body for changes...');
192 | }
193 |
194 |
195 |
196 | module.exports = { LookForCaptcha };
--------------------------------------------------------------------------------
/src/captchaSolverApi.js:
--------------------------------------------------------------------------------
1 | const config = require('./config');
2 |
3 | function convertImageToBase64(imageElement) {
4 | // Create a canvas element
5 | const canvas = document.createElement('canvas');
6 | const context = canvas.getContext('2d');
7 |
8 | // Set canvas dimensions to match the image
9 | canvas.width = imageElement.naturalWidth;
10 | canvas.height = imageElement.naturalHeight;
11 |
12 | // Draw the image onto the canvas
13 | context.drawImage(imageElement, 0, 0);
14 |
15 | // Convert the canvas content to a Data URL (Base64 string)
16 | const base64String = canvas.toDataURL('image/jpeg');
17 |
18 | // Resolve the promise with the Base64 string
19 | return base64String;
20 |
21 | }
22 |
23 | // if return message is "HARD_IMAGE" then the image is too hard to solve rigt now
24 | function solveCaptcha(imageElement) {
25 | return new Promise((resolve, reject) => {
26 | // Convert the canvas content to a Data URL (Base64 string)
27 | const base64String = convertImageToBase64(imageElement);
28 |
29 | if(base64String.length < 100) {
30 | reject('BASE64_CONVERSION_FAILED');
31 | return;
32 | }
33 |
34 | // Make the GM_xmlhttpRequest with the Base64 string
35 | GM_xmlhttpRequest({
36 | method: 'POST',
37 | url: config.API_URL, // Replace with your API endpoint
38 | headers: {
39 | 'Content-Type': 'application/json'
40 | },
41 | data: JSON.stringify({ image64: base64String }),
42 | onload: function(response) {
43 | if (response.status === 200) {
44 | try {
45 | const jsonResponse = JSON.parse(response.responseText);
46 | if(jsonResponse.message === "HARD_IMAGE") {
47 | reject(jsonResponse.message);
48 |
49 | }else{ resolve(jsonResponse.message);}
50 |
51 |
52 | } catch (error) {
53 | reject(new Error('Failed to parse response JSON'));
54 | }
55 | } else {
56 | console.error('Failed to solve captcha:', JSON.parse(response.responseText).error);
57 | reject(new Error('Failed to solve captcha'));
58 | }
59 | },
60 | onerror: function(error) {
61 | reject(error);
62 | }
63 | });
64 | });
65 | }
66 |
67 |
68 |
69 | // Export the function for use in other modules
70 | module.exports = { solveCaptcha, convertImageToBase64 };
--------------------------------------------------------------------------------
/src/config.js:
--------------------------------------------------------------------------------
1 | const config = {
2 | API_URL: 'https://csn.redsparks.eu/api/v1/solve',
3 | }
4 | //config.API_URL = 'http://localhost:8000/api/v1/solve';
5 | module.exports = config;
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | const utils = require("./utils");
2 | const { LookForCaptcha } = require('./captchaSolver');
3 | const {PlaceLogo} = require('./UImodul');
4 |
5 |
6 |
7 | (function () {
8 | 'use strict';
9 |
10 | if (utils.isNeptunPage() && utils.isLoginPage()) {
11 | // Set up a Mutation Observer to watch for changes in the DOM
12 |
13 | //Prevent npu to press login after the user too
14 | document.addEventListener('keydown', function(event) {
15 | if (event.key === 'Enter') {
16 | const $abortLoginLink = $('#abortLogin > a');
17 | if ($abortLoginLink.length) {
18 | $abortLoginLink[0].click();
19 | }
20 | }
21 | });
22 | console.log("LookForCaptcha");
23 | PlaceLogo();
24 | LookForCaptcha();
25 | }
26 | })();
--------------------------------------------------------------------------------
/src/utils.js:
--------------------------------------------------------------------------------
1 | const $ = window.jQuery;
2 |
3 | // Verify that we are indeed on a Neptun page
4 | function isNeptunPage() {
5 | return document.title.toLowerCase().indexOf("neptun.net") !== -1;
6 | }
7 |
8 | // Returns whether we are on the login page
9 | function isLoginPage() {
10 | return $("td.login_left_side").size() > 0;
11 | }
12 |
13 | module.exports = {
14 | isNeptunPage,
15 | isLoginPage,
16 | };
17 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const { UserscriptPlugin } = require('webpack-userscript');
3 | const TerserPlugin = require('terser-webpack-plugin');
4 |
5 |
6 | const dev = process.env.NODE_ENV === 'development';
7 |
8 | module.exports = {
9 | mode: dev ? 'development' : 'production',
10 | entry: path.resolve(__dirname, 'src', 'index.js'), // Your entry point
11 | output: {
12 | path: path.resolve(__dirname, 'dist'),
13 | filename: 'CSN.user.js', // Output file
14 | },
15 | devServer: {
16 | static: {
17 | directory: path.join(__dirname, 'dist'),
18 | },
19 | client: false, // Disable client injection
20 | hot: false, // Disable hot reloading
21 |
22 |
23 | },
24 | optimization: {
25 | minimize: dev ? false : true,
26 | minimizer: [
27 | new TerserPlugin({
28 | terserOptions: {
29 | compress: {
30 | drop_console: dev ? false : true,
31 | },
32 | },
33 | }),
34 | ],
35 | },
36 | plugins: [
37 | new UserscriptPlugin({
38 | headers(original) {
39 | const baseHeaders = {
40 | name: 'Captcha Solver For Neptun',
41 | namespace: 'https://github.com/LetsUpdate/CSN',
42 | description: 'No captcha 4 u',
43 | author: 'RED',
44 | include: [
45 | 'https://*neptun*/*hallgato*/*',
46 | 'https://*neptun*/*Hallgatoi*/*',
47 | 'https://*hallgato*.*neptun*/*',
48 | 'https://netw*.nnet.sze.hu/hallgato',
49 | 'https://nappw.dfad.duf.hu/hallgato/*',
50 | ],
51 | grant: 'GM_xmlhttpRequest',
52 | "run-at": "document-end",
53 | require: "https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js",
54 | updateURL: "https://github.com/LetsUpdate/CSN/releases/latest/download/CSN.meta.js",
55 | downloadURL:"https://github.com/LetsUpdate/CSN/releases/latest/download/CSN.user.js",
56 | supportURL:"https://github.com/LetsUpdate/CSN",
57 | icon64: "https://raw.githubusercontent.com/LetsUpdate/CSN/main/.github/icon.png",
58 | license: "MIT",
59 |
60 | };
61 |
62 | if (dev) {
63 | return {
64 | ...original,
65 | ...baseHeaders,
66 | version: `${original.version}-build.[buildNo]`,
67 | };
68 | }
69 |
70 | return {
71 | ...original,
72 | ...baseHeaders,
73 | };
74 | },
75 |
76 | }),
77 |
78 | ],
79 | };
--------------------------------------------------------------------------------