code refactor
This commit is contained in:
parent
41e2212c11
commit
62c64de359
|
@ -4,6 +4,7 @@
|
|||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
|
@ -11,7 +12,7 @@
|
|||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}/src/server.js"
|
||||
"program": "${workspaceFolder}/src/start.js"
|
||||
}
|
||||
]
|
||||
}
|
663
dev/mat.json
663
dev/mat.json
|
@ -1 +1,662 @@
|
|||
{}
|
||||
{
|
||||
"OxXrEtvErYzN": {
|
||||
"mat": [
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.6,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.6,
|
||||
0.6,
|
||||
0.6,
|
||||
0.6,
|
||||
0.6
|
||||
],
|
||||
"nums": 1,
|
||||
"obj": 0
|
||||
},
|
||||
"zKsAXcOCNd9U": {
|
||||
"mat": [
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.6,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4
|
||||
],
|
||||
"nums": 1,
|
||||
"obj": 0
|
||||
},
|
||||
"AyxF5UB7GyPC": {
|
||||
"mat": [
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.6,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4
|
||||
],
|
||||
"nums": 1,
|
||||
"obj": 0
|
||||
},
|
||||
"AD8Vjgv2zCjf": {
|
||||
"mat": [
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.6,
|
||||
0.6,
|
||||
0.6,
|
||||
0.6
|
||||
],
|
||||
"nums": 1,
|
||||
"obj": 0
|
||||
},
|
||||
"VEhAvRf5SlqP": {
|
||||
"mat": [
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.6,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.6,
|
||||
0.4,
|
||||
0.4,
|
||||
0.6,
|
||||
0.6
|
||||
],
|
||||
"nums": 1,
|
||||
"obj": 0
|
||||
},
|
||||
"REemIAxKWPOr": {
|
||||
"mat": [
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.5,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.5,
|
||||
0.5
|
||||
],
|
||||
"nums": 2,
|
||||
"obj": 0
|
||||
},
|
||||
"ilzrt3XTmEGI": {
|
||||
"mat": [
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.5,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.5,
|
||||
0.7
|
||||
],
|
||||
"nums": 2,
|
||||
"obj": 0
|
||||
},
|
||||
"sq8XFCoHMsjh": {
|
||||
"mat": [
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.4,
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.4,
|
||||
0.6
|
||||
],
|
||||
"nums": 3,
|
||||
"obj": 0
|
||||
},
|
||||
"Rkb9KvzIK8i6": {
|
||||
"mat": [
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
0.20000000000000004,
|
||||
2.7755575615628914e-17,
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.4
|
||||
],
|
||||
"nums": 5,
|
||||
"obj": 0
|
||||
},
|
||||
"zAQrZUdBtAul": {
|
||||
"mat": [
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
0.20000000000000004,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
0.20000000000000004,
|
||||
0.4
|
||||
],
|
||||
"nums": 5,
|
||||
"obj": 0
|
||||
},
|
||||
"s0LDtVUcozVA": {
|
||||
"mat": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0.10000000000000003,
|
||||
0,
|
||||
0,
|
||||
0.10000000000000003,
|
||||
0.30000000000000004
|
||||
],
|
||||
"nums": 6,
|
||||
"obj": 0
|
||||
},
|
||||
"Ern8By1vuGjV": {
|
||||
"mat": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2.7755575615628914e-17,
|
||||
0,
|
||||
0,
|
||||
2.7755575615628914e-17,
|
||||
0.20000000000000004
|
||||
],
|
||||
"nums": 7,
|
||||
"obj": 0
|
||||
},
|
||||
"hn1uGROIKjnM": {
|
||||
"mat": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0.10000000000000003
|
||||
],
|
||||
"nums": 8,
|
||||
"obj": 0
|
||||
},
|
||||
"4q7BkDtACkDx": {
|
||||
"mat": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2.7755575615628914e-17
|
||||
],
|
||||
"nums": 9,
|
||||
"obj": 0
|
||||
},
|
||||
"WlEm9ZGsDOlN": {
|
||||
"mat": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"nums": 10,
|
||||
"obj": 0
|
||||
},
|
||||
"4d6y7SDP9r9c": {
|
||||
"mat": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"nums": 11,
|
||||
"obj": 0
|
||||
},
|
||||
"AkGcL0NHOVGy": {
|
||||
"mat": [
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.5,
|
||||
0.5,
|
||||
0.5,
|
||||
0.5
|
||||
],
|
||||
"nums": 2,
|
||||
"obj": 0
|
||||
},
|
||||
"GHI69eo7oMwY": {
|
||||
"mat": [
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.5,
|
||||
0.5,
|
||||
0.7,
|
||||
0.7,
|
||||
0.7,
|
||||
0.7
|
||||
],
|
||||
"nums": 2,
|
||||
"obj": 0
|
||||
},
|
||||
"MkvjgP0uimhW": {
|
||||
"mat": [
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.4,
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.4,
|
||||
0.4,
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.6,
|
||||
0.6,
|
||||
0.6,
|
||||
0.6,
|
||||
0.7999999999999999,
|
||||
0.7999999999999999
|
||||
],
|
||||
"nums": 3,
|
||||
"obj": 0
|
||||
},
|
||||
"gFuaeUebn0lE": {
|
||||
"mat": [
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.5,
|
||||
0.5,
|
||||
0.5,
|
||||
0.30000000000000004,
|
||||
0.5,
|
||||
0.5,
|
||||
0.5
|
||||
],
|
||||
"nums": 2,
|
||||
"obj": 0
|
||||
},
|
||||
"xplUg1qXcCDV": {
|
||||
"mat": [
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.5,
|
||||
0.5,
|
||||
0.5,
|
||||
0.5,
|
||||
0.7,
|
||||
0.7,
|
||||
0.5
|
||||
],
|
||||
"nums": 2,
|
||||
"obj": 0
|
||||
},
|
||||
"KNRZDFuT4X45": {
|
||||
"mat": [
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.20000000000000004,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.6,
|
||||
0.7999999999999999,
|
||||
0.6
|
||||
],
|
||||
"nums": 3,
|
||||
"obj": 0
|
||||
},
|
||||
"G68Efl2ZE0U1": {
|
||||
"mat": [
|
||||
0.10000000000000003,
|
||||
0.10000000000000003,
|
||||
0.10000000000000003,
|
||||
0.10000000000000003,
|
||||
0.10000000000000003,
|
||||
0.10000000000000003,
|
||||
0.10000000000000003,
|
||||
0.10000000000000003,
|
||||
0.10000000000000003,
|
||||
0.30000000000000004,
|
||||
0.5,
|
||||
0.5,
|
||||
0.30000000000000004,
|
||||
0.5,
|
||||
0.8999999999999999,
|
||||
0.7
|
||||
],
|
||||
"nums": 4,
|
||||
"obj": 0
|
||||
},
|
||||
"JOAT6FV7VKKi": {
|
||||
"mat": [
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
2.7755575615628914e-17,
|
||||
0.20000000000000004,
|
||||
0.4,
|
||||
0.4,
|
||||
0.20000000000000004,
|
||||
0.4,
|
||||
0.7999999999999999,
|
||||
0.6
|
||||
],
|
||||
"nums": 5,
|
||||
"obj": 0
|
||||
},
|
||||
"B25hZGGvUjZw": {
|
||||
"mat": [
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4
|
||||
],
|
||||
"nums": 1,
|
||||
"obj": 0
|
||||
},
|
||||
"mX0MuHDZJFVx": {
|
||||
"mat": [
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004
|
||||
],
|
||||
"nums": 2,
|
||||
"obj": 0
|
||||
},
|
||||
"GuOSUS3pciGR": {
|
||||
"mat": [
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.6,
|
||||
0.6,
|
||||
0.4,
|
||||
0.6,
|
||||
0.6,
|
||||
0.6
|
||||
],
|
||||
"nums": 1,
|
||||
"obj": 0
|
||||
},
|
||||
"OaeOLRd0m1Nu": {
|
||||
"mat": [
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4
|
||||
],
|
||||
"nums": 1,
|
||||
"obj": 0
|
||||
},
|
||||
"jvceqG1K3aGV": {
|
||||
"mat": [
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004,
|
||||
0.30000000000000004
|
||||
],
|
||||
"nums": 2,
|
||||
"obj": 0
|
||||
},
|
||||
"0iMT2yXLK0vj": {
|
||||
"mat": [
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4,
|
||||
0.4
|
||||
],
|
||||
"nums": 1,
|
||||
"obj": 0
|
||||
}
|
||||
}
|
1
src/R.js
1
src/R.js
|
@ -15,4 +15,3 @@ export const TAGS = [
|
|||
export const IMAGES_FOLDER = path.join(PROJECT_ROOT, 'public', 'images');
|
||||
|
||||
export const MAX_SESSION_TIME = 60 * 30;
|
||||
|
||||
|
|
|
@ -70,10 +70,9 @@ function uCaptchaBox(websiteKey) {
|
|||
captchaBox.appendChild(btn);
|
||||
|
||||
checkbox.onclick = async function() {
|
||||
/** @type {import('../shared/models/UserSession.js').UserSession} */
|
||||
const session = await reloadSession(websiteKey);
|
||||
|
||||
qs('#ucaptcha-caption').innerHTML = `Select all squares with <b>${session.getImageTag()}s</b>`;
|
||||
qs('#ucaptcha-caption').innerHTML = `Select all squares with <b>${session.imageTag}s</b>`;
|
||||
|
||||
const imageGrid = ce('table', {id: 'ucaptcha-grid'});
|
||||
for (let i = 0; i < 4; i++) {
|
||||
|
@ -90,8 +89,7 @@ function uCaptchaBox(websiteKey) {
|
|||
}
|
||||
|
||||
btn.addEventListener('click', (e)=>{
|
||||
verifyImage(session, imageGrid);
|
||||
getImage(session, captchaBox);
|
||||
verifyImage(session, captchaBox);
|
||||
});
|
||||
|
||||
captchaContainer.appendChild(imageGrid);
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
import request from '../util/request.js';
|
||||
/**
|
||||
* @typedef {import('../../models/UserSession.js').UserSession} UserSession
|
||||
* @typedef {import('../../models/Session.js').Session} Session
|
||||
*/
|
||||
|
||||
/**
|
||||
* Instantiate the uCaptcha loop
|
||||
* @param {UserSession} session
|
||||
* @param {Session} session
|
||||
* @param {HTMLElement} captchaBox
|
||||
*/
|
||||
export default function instantiateLoop(session, captchaBox) {
|
||||
console.log(captchaBox);
|
||||
request(`/api/image?s=${session.getSessionId()}`, {_responseType: 'blob'})
|
||||
export default function getImage(session, captchaBox) {
|
||||
request(`/api/image?s=${session.sessionId}`, {_responseType: 'blob'})
|
||||
.then((blob)=>{
|
||||
const imageUrl = URL.createObjectURL(blob);
|
||||
console.log(imageUrl);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import request from '../util/request.js';
|
||||
import Session from '../../models/Session.js';
|
||||
import {Session} from '../../models/Session.js';
|
||||
|
||||
/**
|
||||
* @param {string} websiteKey
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
import request from '../util/request.js';
|
||||
import UserSession from '../../models/UserSession.js';
|
||||
import getImage from './getImage.js';
|
||||
import {Session} from '../../models/Session.js';
|
||||
import {querySelector as qs} from '../util/document.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../../models/UserSession.js')} UserSession
|
||||
* @typedef {import('../../models/Session.js').Session} Session
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Verify the image
|
||||
* @param {UserSession} session
|
||||
* @param {HTMLElement} captchaGrid
|
||||
* @param {Session} session
|
||||
* @param {HTMLElement} captchaBox
|
||||
*/
|
||||
export default async function verifyImage(session, captchaGrid) {
|
||||
export default async function verifyImage(session, captchaBox) {
|
||||
const captchaGrid = captchaBox.querySelector('#ucaptcha-grid');
|
||||
|
||||
captchaGrid.classList.add('blurred');
|
||||
const tds = captchaGrid.querySelectorAll('td');
|
||||
const selectedTds = [];
|
||||
|
@ -28,7 +31,7 @@ export default async function verifyImage(session, captchaGrid) {
|
|||
}
|
||||
|
||||
const body = {
|
||||
's': session.getSessionId(),
|
||||
's': session.sessionId,
|
||||
'mat': mat,
|
||||
};
|
||||
|
||||
|
@ -36,7 +39,9 @@ export default async function verifyImage(session, captchaGrid) {
|
|||
|
||||
session.deserialize(resp);
|
||||
qs('#ucaptcha-caption')
|
||||
.innerHTML = `Select all squares with <b>${session.getImageTag()}s</b>`;
|
||||
.innerHTML = `Select all squares with <b>${session.imageTag}s</b>`;
|
||||
|
||||
getImage(session, captchaBox);
|
||||
|
||||
captchaGrid.classList.remove('blurred');
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import fs from 'fs';
|
||||
import {IMAGES_FOLDER} from '../R.js';
|
||||
import {randomChoice} from '../helpers/utils.js';
|
||||
|
||||
/**
|
||||
* @return {Promise<string>} Image file without extension
|
||||
|
@ -8,10 +9,11 @@ export default () => {
|
|||
return new Promise((resolve, reject)=>{
|
||||
fs.readdir(IMAGES_FOLDER, (err, files)=>{
|
||||
if (err) return reject(err);
|
||||
return resolve(
|
||||
files[
|
||||
Math.floor(Math.random() * files.length)
|
||||
].split('.')[0]);
|
||||
|
||||
const filename = randomChoice(files);
|
||||
console.log(filename);
|
||||
|
||||
return resolve(filename);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
|
@ -13,25 +13,27 @@ import {Session} from '../models/Session.js';
|
|||
* @return {Promise<Session>}
|
||||
*/
|
||||
export default async function initializeSession(websiteKey, cookies) {
|
||||
const image = await pickRandomFile();
|
||||
const image = (await pickRandomFile()).split('.')[0];
|
||||
|
||||
const imageTagId = 1; // TODO: Change later to be dynamic based on `image`
|
||||
const sessionId = cookies[websiteKey] ? cookies[websiteKey] : randomBytes(8);
|
||||
const sessionId = cookies[websiteKey] || randomBytes(8);
|
||||
|
||||
client.setex(sessionId, MAX_SESSION_TIME, JSON.stringify({
|
||||
/** @type {import('../models/Session.js').IDBSession} */
|
||||
const idbPayload = {
|
||||
sessionId,
|
||||
websiteKey,
|
||||
image,
|
||||
image: image,
|
||||
obj: imageTagId,
|
||||
score: 0.5,
|
||||
}));
|
||||
};
|
||||
|
||||
client.setex(sessionId, MAX_SESSION_TIME, JSON.stringify(idbPayload));
|
||||
|
||||
|
||||
const session = new Session({
|
||||
sessionId,
|
||||
websiteKey,
|
||||
imageTagId: TAGS[imageTagId],
|
||||
});
|
||||
const session = new Session();
|
||||
session.sessionId = sessionId;
|
||||
session.websiteKey = websiteKey;
|
||||
session.imageTag = TAGS[imageTagId];
|
||||
|
||||
return session;
|
||||
};
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
console.log(import.meta.url, ' is deprecated please use res.json() directly')
|
||||
/**
|
||||
* @param {import('express').Response} res
|
||||
* @param {JSON} json
|
||||
|
@ -6,5 +5,4 @@ console.log(import.meta.url, ' is deprecated please use res.json() directly')
|
|||
export default (res, json) => {
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.send(`:)${JSON.stringify(json)}`);
|
||||
return;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
import {client} from '../idb.js';
|
||||
|
||||
/**
|
||||
* serveImage
|
||||
* @param {string} sessionId
|
||||
* @return {Promise<[Error, string]>}
|
||||
*/
|
||||
export default function serveImage(sessionId) {
|
||||
return new Promise((resolve, reject)=>{
|
||||
client.get(sessionId, (err, resp)=>{
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
if (!resp) {
|
||||
// TODO: We need a way to communicate expired session back to client
|
||||
resolve([
|
||||
'Session expired',
|
||||
null,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @type {import('../models/Session.js').IDBSession} */
|
||||
const result = JSON.parse(resp);
|
||||
|
||||
const {
|
||||
image,
|
||||
} = result;
|
||||
console.log(image);
|
||||
|
||||
resolve([
|
||||
null,
|
||||
image + '.jpg',
|
||||
]);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import {client} from '../idb.js';
|
||||
import {PROJECT_ROOT, MAX_SESSION_TIME, TAGS} from '../R.js';
|
||||
import {argmaxThresh} from './utils.js';
|
||||
import pickRandomFile from './pickRandomFile.js';
|
||||
import {Session} from '../models/Session.js';
|
||||
|
||||
// Anything above this value is considered a true selection within image matrix
|
||||
const TOLERANCE = 0.6;
|
||||
|
||||
/**
|
||||
* @typedef {Object} FileMat
|
||||
* @property {Array<number>} mat Matrix of floats
|
||||
* @property {number} nums Number of users that have seen this challenge
|
||||
* @property {number} obj The object in the image
|
||||
*/
|
||||
|
||||
/** @type {FileMat} */
|
||||
const defaultMat = {
|
||||
mat: Array(16).fill(0.5),
|
||||
nums: 0,
|
||||
obj: 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* Get file matrix
|
||||
* @param {string} image
|
||||
* @return {FileMat}
|
||||
*/
|
||||
function getMat(image) {
|
||||
const mats = JSON.parse(
|
||||
fs.readFileSync(
|
||||
path.join(PROJECT_ROOT, 'dev', 'mat.json'), {encoding: 'utf8'}));
|
||||
|
||||
return mats[image] || defaultMat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the image mat
|
||||
* @param {FileMat} imageMat
|
||||
* @param {Array<number>} userMat
|
||||
* @param {string} image
|
||||
*/
|
||||
function updateMat(imageMat, userMat, image) {
|
||||
const updatedMat = [...imageMat.mat];
|
||||
for (let i = 0; i < imageMat.mat.length; i++) {
|
||||
const delta = 0.1;
|
||||
if (userMat[i] === 1) {
|
||||
if (updatedMat[i] + delta > 1) {
|
||||
updatedMat[i] = 1.0;
|
||||
} else {
|
||||
updatedMat[i] += delta;
|
||||
}
|
||||
} else {
|
||||
if (updatedMat[i] < delta) {
|
||||
updatedMat[i] = 0.0;
|
||||
} else {
|
||||
updatedMat[i] -= delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// console.log('OLD MAT: ', imageMat.mat);
|
||||
// console.log('NEW MAT: ', updatedMat);
|
||||
|
||||
imageMat.nums += 1;
|
||||
imageMat.mat = updatedMat;
|
||||
|
||||
const mats = JSON.parse(
|
||||
fs.readFileSync(
|
||||
path.join(PROJECT_ROOT, 'dev', 'mat.json'), {encoding: 'utf8'}));
|
||||
mats[image] = imageMat;
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(PROJECT_ROOT, 'dev', 'mat.json'),
|
||||
JSON.stringify(mats, null, 2), {encoding: 'utf8'});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} sessionId
|
||||
* @param {Array<number>} userMat
|
||||
* @return {Promise<Session>}
|
||||
*/
|
||||
export default function verifyImage(sessionId, userMat) {
|
||||
return new Promise((resolve, reject)=>{
|
||||
client.get(sessionId, (err, resp)=>{
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
if (!resp) {
|
||||
reject(new Error('Session expired'));
|
||||
}
|
||||
|
||||
/** @type {import('../models/Session').IDBSession} */
|
||||
const result = JSON.parse(resp);
|
||||
console.log('Result: ', result);
|
||||
|
||||
let {image, score, websiteKey} = result;
|
||||
const imageMat = getMat(image);
|
||||
const trueArgmax = argmaxThresh(imageMat.mat, TOLERANCE).join(',');
|
||||
const userArgmax = argmaxThresh(userMat, 1).join(',');
|
||||
|
||||
updateMat(imageMat, userMat, image);
|
||||
|
||||
console.log('trueArgmax: ', trueArgmax);
|
||||
console.log('userArgmax: ', userArgmax);
|
||||
|
||||
const delta = imageMat.nums * 0.05;
|
||||
|
||||
if (userArgmax !== trueArgmax) {
|
||||
// TODO: Decrease the score based on mat dispersion
|
||||
// High variance = small reduction
|
||||
// Low variance = high reduction
|
||||
score -= delta;
|
||||
} else {
|
||||
score += delta;
|
||||
}
|
||||
|
||||
pickRandomFile()
|
||||
.then((newImageFilename)=>{
|
||||
console.log('New image', newImageFilename);
|
||||
// TODO: Make imageTagId dynamic
|
||||
const newImageTagId = 1;
|
||||
const update = JSON.stringify(
|
||||
Object.assign(result, {
|
||||
image: newImageFilename.split('.')[0],
|
||||
obj: newImageTagId,
|
||||
score,
|
||||
}));
|
||||
|
||||
client.setex(sessionId, MAX_SESSION_TIME, update, (err)=>{
|
||||
if (err) reject(err);
|
||||
const session = new Session();
|
||||
session.sessionId = sessionId;
|
||||
session.websiteKey = websiteKey;
|
||||
session.imageTag = TAGS[newImageTagId];
|
||||
|
||||
resolve(session);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,19 +1,18 @@
|
|||
/**
|
||||
* Session storage in IDB
|
||||
* User session model
|
||||
* @property {string} [sessionId] User session ID
|
||||
* @property {string} [websiteKey] Website ID
|
||||
* @property {string} [image] Image URL for challenge
|
||||
* @property {number} [obj] Image object ID
|
||||
* @property {number} [score] How likely is the user to be a human?
|
||||
* @property {string} [imageTag] Human readable text image tag
|
||||
*/
|
||||
export class Session {
|
||||
/**
|
||||
*
|
||||
* @param {*} obj
|
||||
*/
|
||||
constructor(obj={}) {
|
||||
Object.assign(this, obj);
|
||||
*
|
||||
*/
|
||||
constructor() {
|
||||
// Object.assign(this, obj);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set session ID
|
||||
* @param {string} id
|
||||
|
@ -30,6 +29,7 @@ export class Session {
|
|||
return this._sessionId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set session ID
|
||||
* @param {string} id
|
||||
|
@ -45,37 +45,67 @@ export class Session {
|
|||
get websiteKey() {
|
||||
return this._websiteKey;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the human readable image tag
|
||||
* @param {string} imageTag
|
||||
*/
|
||||
set imageTag(imageTag) {
|
||||
this._imageTag = imageTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
get imageTag() {
|
||||
return this._imageTag;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serialize the session into a JSON object
|
||||
* @return {Array<any>}
|
||||
*/
|
||||
serialize() {
|
||||
const {sessionId, websiteKey} = this;
|
||||
const {
|
||||
sessionId,
|
||||
websiteKey,
|
||||
imageTag,
|
||||
} = this;
|
||||
if (!sessionId || !websiteKey) {
|
||||
throw Error();
|
||||
}
|
||||
return [sessionId, websiteKey];
|
||||
return [
|
||||
sessionId,
|
||||
websiteKey,
|
||||
imageTag,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize session data from JSON object
|
||||
* @param {Array<any>} payload
|
||||
*/
|
||||
deserialize([sessionId, websiteKey]) {
|
||||
Object.assign(this, {sessionId, websiteKey});
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param {*} sessionId
|
||||
*/
|
||||
async get(sessionId) {
|
||||
if (!window) {
|
||||
return import('util')
|
||||
.then(({promisify}) => import('../idb.js')
|
||||
.then(({client}) => promisify(client.get)(sessionId)));
|
||||
}
|
||||
// HTTP Logic here
|
||||
// fetch(`/api/reload?k=${websiteKey}`)
|
||||
deserialize([
|
||||
sessionId,
|
||||
websiteKey,
|
||||
imageTag,
|
||||
]) {
|
||||
Object.assign(this, {
|
||||
sessionId,
|
||||
websiteKey,
|
||||
imageTag,
|
||||
});
|
||||
}
|
||||
}
|
||||
export default Session;
|
||||
|
||||
/**
|
||||
* @typedef {Object} IDBSession User session model in IDB
|
||||
* @property {string} sessionId User session ID
|
||||
* @property {string} websiteKey Website ID
|
||||
* @property {string} imageTag Human readable text image tag
|
||||
* @property {string} image Image URL for challenge
|
||||
* @property {number} obj Image object ID
|
||||
* @property {number} score How likely is the user to be a human?
|
||||
*/
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import {Router} from '../../helpers/express-router.js';
|
||||
import {serveImage} from './verify.js';
|
||||
import express from 'express';
|
||||
import path from 'path';
|
||||
import {IMAGES_FOLDER} from '../../R.js';
|
||||
const router = new Router();
|
||||
import serveImage from '../../helpers/serveImage.js';
|
||||
|
||||
const router = new express.Router();
|
||||
|
||||
export default router.get('/image', async (req, res) => {
|
||||
const sessionId = req.query.s;
|
||||
if (!sessionId) {
|
||||
|
@ -10,9 +12,12 @@ export default router.get('/image', async (req, res) => {
|
|||
return;
|
||||
}
|
||||
|
||||
const [suspicious, filename] = await serveImage(sessionId);
|
||||
if (suspicious) {
|
||||
res.end();
|
||||
const [error, filename] = await serveImage(sessionId);
|
||||
|
||||
if (error) {
|
||||
res.json({
|
||||
error,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,14 +2,14 @@ import express from 'express';
|
|||
import sendJson from '../../helpers/sendJson.js';
|
||||
import {MAX_SESSION_TIME} from '../../R.js';
|
||||
import reloadSession from '../../helpers/reloadSession.js';
|
||||
const router = express.Router();
|
||||
|
||||
const router = new express.Router();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {express.Request} req
|
||||
* @param {express.Response} res
|
||||
*/
|
||||
const reloadHandler = async (req, res) => {
|
||||
const reloadSessionHandler = async (req, res) => {
|
||||
try {
|
||||
const websiteKey = req.query.k;
|
||||
if (!websiteKey) {
|
||||
|
@ -23,7 +23,7 @@ const reloadHandler = async (req, res) => {
|
|||
websiteKey, sessionId,
|
||||
{httpOnly: true, maxAge: MAX_SESSION_TIME * 1000},
|
||||
);
|
||||
res.json(session);
|
||||
sendJson(res, session.serialize());
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
res.end();
|
||||
|
@ -31,4 +31,4 @@ const reloadHandler = async (req, res) => {
|
|||
};
|
||||
|
||||
|
||||
export default router.get('/reload', reloadHandler);
|
||||
export default router.get('/reload', reloadSessionHandler);
|
||||
|
|
|
@ -1,190 +1,19 @@
|
|||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import {client} from '../../idb.js';
|
||||
import {promisify} from 'util';
|
||||
import {PROJECT_ROOT, MAX_SESSION_TIME, TAGS} from '../../R.js';
|
||||
import {argmaxThresh} from '../../helpers/utils.js';
|
||||
import pickRandomFile from '../../helpers/pickRandomFile.js';
|
||||
import Session from '../../models/Session.js';
|
||||
import express from 'express';
|
||||
const router = express.Router();
|
||||
import sendJson from '../../helpers/sendJson.js';
|
||||
import verifyImage from '../../helpers/verifyImage.js';
|
||||
|
||||
const router = new express.Router();
|
||||
|
||||
/**
|
||||
* @typedef {Object} FileMat
|
||||
* @property {Array<number>} mat Matrix of floats
|
||||
* @property {number} nums Number of users that have seen this challenge
|
||||
* @property {number} obj The object in the image
|
||||
* @param {express.Request} req
|
||||
* @param {express.Response} res
|
||||
*/
|
||||
|
||||
/** @type {FileMat} */
|
||||
const defaultMat = {
|
||||
mat: Array(16).fill(0.5),
|
||||
nums: 0,
|
||||
obj: 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* Get file matrix
|
||||
* @param {string} image
|
||||
* @return {FileMat}
|
||||
*/
|
||||
function getMat(image) {
|
||||
const mats = JSON.parse(
|
||||
fs.readFileSync(
|
||||
path.join(PROJECT_ROOT, 'dev', 'mat.json'), {encoding: 'utf8'}));
|
||||
|
||||
return mats[image] || defaultMat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the image mat
|
||||
* @param {FileMat} imageMat
|
||||
* @param {Array<number>} userMat
|
||||
* @param {string} image
|
||||
*/
|
||||
function updateMat(imageMat, userMat, image) {
|
||||
const updatedMat = [...imageMat.mat];
|
||||
for (let i = 0; i < imageMat.mat.length; i++) {
|
||||
const delta = 0.1;
|
||||
if (userMat[i] === 1) {
|
||||
if (updatedMat[i] + delta > 1) {
|
||||
updatedMat[i] = 1.0;
|
||||
} else {
|
||||
updatedMat[i] += delta;
|
||||
}
|
||||
} else {
|
||||
if (updatedMat[i] < delta) {
|
||||
updatedMat[i] = 0.0;
|
||||
} else {
|
||||
updatedMat[i] -= delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('OLD MAT: ', imageMat.mat);
|
||||
console.log('NEW MAT: ', updatedMat);
|
||||
|
||||
imageMat.nums += 1;
|
||||
imageMat.mat = updatedMat;
|
||||
|
||||
const mats = JSON.parse(
|
||||
fs.readFileSync(
|
||||
path.join(PROJECT_ROOT, 'dev', 'mat.json'), {encoding: 'utf8'}));
|
||||
mats[image] = imageMat;
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(PROJECT_ROOT, 'dev', 'mat.json'),
|
||||
JSON.stringify(mats, null, 2), {encoding: 'utf8'});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} sessionId
|
||||
* @param {Array<number>} userMat
|
||||
* @return {Promise}
|
||||
*/
|
||||
async function verify(sessionId, userMat) {
|
||||
const redisGet = promisify(client.get);
|
||||
const session = await redisGet(sessionId)
|
||||
.then((resp) => {
|
||||
if (!resp) {
|
||||
throw new Error('Session expired');
|
||||
}
|
||||
/** @type {Session} */
|
||||
const result = JSON.parse(resp);
|
||||
let {image, score, websiteKey} = result;
|
||||
const imageMat = getMat(image);
|
||||
const trueArgmax = argmaxThresh(imageMat.mat, 0.6).join(',');
|
||||
const userArgmax = argmaxThresh(userMat, 1).join(',');
|
||||
|
||||
updateMat(imageMat, userMat, image);
|
||||
|
||||
console.log('trueArgmax', trueArgmax);
|
||||
console.log('userArgmax', userArgmax);
|
||||
|
||||
const delta = imageMat.nums * 0.05;
|
||||
|
||||
if (userArgmax !== trueArgmax) {
|
||||
// TODO: Decrease the score based on mat dispersion
|
||||
// High variance = small reduction
|
||||
// Low variance = high reduction
|
||||
score -= delta;
|
||||
} else {
|
||||
score += delta;
|
||||
}
|
||||
|
||||
|
||||
return pickRandomFile().then((image)=>{
|
||||
// TODO: Make me dynamic
|
||||
const newImageTag = 1;
|
||||
const update = JSON.stringify(
|
||||
Object.assign(result, {
|
||||
image: image,
|
||||
obj: newImageTag,
|
||||
}));
|
||||
|
||||
return promisify(client.setex)(sessionId, MAX_SESSION_TIME, update).then(()=>new Session({
|
||||
sessionId, websiteKey, imageTag: TAGS[newImageTag],
|
||||
}));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {import('../../models/Session.js').Session} IDBSession
|
||||
*/
|
||||
|
||||
/**
|
||||
* serveImage
|
||||
* @param {string} sessionId
|
||||
* @return {Promise}
|
||||
*/
|
||||
export function serveImage(sessionId) {
|
||||
const redisGet = promisify(client.get);
|
||||
return redisGet(sessionId)
|
||||
.then((result) => {
|
||||
if (!result) {
|
||||
throw new Error('Session expired');
|
||||
}
|
||||
return result;
|
||||
})
|
||||
.then((result) => {
|
||||
/** @type {Session} */
|
||||
const sessionData = JSON.parse(result);
|
||||
|
||||
console.log(sessionData);
|
||||
|
||||
const {
|
||||
// sessionId,
|
||||
image,
|
||||
// score,
|
||||
} = sessionData;
|
||||
|
||||
// if (score < 0.1) {
|
||||
// client.del(sessionId, (err)=>{
|
||||
// if (err) return reject(err);
|
||||
|
||||
// return resolve([
|
||||
// true,
|
||||
// null,
|
||||
// ]);
|
||||
// });
|
||||
// }
|
||||
|
||||
return [
|
||||
null,
|
||||
image + '.jpg',
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
export default router.post('/verify', async (req, res)=>{
|
||||
const verifyImageHandler = async (req, res)=>{
|
||||
const sessionId = req.body.s;
|
||||
const mat = req.body.mat;
|
||||
console.log(req.body);
|
||||
|
||||
const session = await verify(sessionId, mat);
|
||||
res.json(session);
|
||||
});
|
||||
const session = await verifyImage(sessionId, mat);
|
||||
sendJson(res, session.serialize());
|
||||
};
|
||||
|
||||
export default router.post('/verify', verifyImageHandler);
|
||||
|
|
|
@ -20,10 +20,9 @@ if (process.env.NODE_ENV === 'development') {
|
|||
});
|
||||
}
|
||||
|
||||
//import apis from './routes/api/index.js';
|
||||
import apiImage from './routes/api/image.js';
|
||||
import apiVerify from './routes/api/verify.js';
|
||||
import apiReload from './routes/api/reload.js';
|
||||
app.use('/api', [apiImage,apiVerify,apiReload]);
|
||||
app.use('/api', [apiImage, apiVerify, apiReload]);
|
||||
|
||||
export {app};
|
||||
|
|
Loading…
Reference in New Issue