Skip to content

Commit

Permalink
feat: show reset button when the challenge is blocked
Browse files Browse the repository at this point in the history
The challenge can be reloaded during a temporary block,
without reloading the entire page.

Requires new permission: webNavigation
  • Loading branch information
dessant committed Dec 26, 2018
1 parent 61b1f97 commit 3398166
Show file tree
Hide file tree
Showing 15 changed files with 261 additions and 37 deletions.
11 changes: 1 addition & 10 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
{
"presets": [
[
"@babel/env",
{
"exclude": ["transform-regenerator"],
"modules": false
}
]
],
"presets": ["@babel/env"],
"env": {
"production": {
"plugins": ["lodash"]
}
}
}

12 changes: 11 additions & 1 deletion gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const gulp = require('gulp');
const gulpSeq = require('gulp-sequence');
const htmlmin = require('gulp-htmlmin');
const svgmin = require('gulp-svgmin');
const babel = require('gulp-babel');
const postcss = require('gulp-postcss');
const gulpif = require('gulp-if');
const del = require('del');
Expand All @@ -24,7 +25,7 @@ gulp.task('clean', function() {
return del([distDir]);
});

gulp.task('js', function(done) {
gulp.task('js:webpack', function(done) {
exec('webpack-cli --display-error-details --bail --colors', function(
err,
stdout,
Expand All @@ -36,6 +37,15 @@ gulp.task('js', function(done) {
});
});

gulp.task('js:babel', function() {
return gulp
.src(['src/content/**/*.js'], {base: '.'})
.pipe(babel())
.pipe(gulp.dest(distDir));
});

gulp.task('js', ['js:webpack', 'js:babel']);

gulp.task('html', function() {
return gulp
.src('src/**/*.html', {base: '.'})
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
"npm-check-updates": "^2.14.2",
"npm-run-all": "^4.1.5",
"postcss-loader": "^3.0.0",
"prettier": "^1.15.3",
"recursive-readdir": "^2.2.2",
"sass-loader": "^7.1.0",
"sharp": "^0.20.5",
Expand Down
19 changes: 13 additions & 6 deletions src/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,11 @@
"description": "Text of the button."
},

"buttonText_reset": {
"message": "Reset the challenge",
"description": "Text of the button."
},

"pageTitle": {
"message": "$PAGETITLE$ - $EXTENSIONNAME$",
"description": "Title of the page.",
Expand All @@ -456,20 +461,22 @@
},

"error_captchaNotSolved": {
"message":
"Captcha could not be solved. Try again after requesting a new challenge.",
"message": "Captcha could not be solved. Try again after requesting a new challenge.",
"description": "Error message."
},

"error_missingApiKey": {
"message":
"API key missing. Visit the options page to configure the service.",
"message": "API key missing. Visit the options page to configure the service.",
"description": "Error message."
},

"error_scriptsNotAllowed": {
"message": "Content scripts are not allowed on this page.",
"description": "Error message."
},

"error_internalError": {
"message":
"Something went wrong. Open the browser console for more details.",
"message": "Something went wrong. Open the browser console for more details.",
"description": "Error message."
}
}
33 changes: 32 additions & 1 deletion src/background/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ import browser from 'webextension-polyfill';
import {initStorage} from 'storage/init';
import storage from 'storage/storage';
import {showNotification, showContributePage} from 'utils/app';
import {
executeCode,
executeFile,
scriptsAllowed,
functionInContext
} from 'utils/common';

function challengeRequestCallback(details) {
const url = new URL(details.url);
Expand Down Expand Up @@ -41,7 +47,7 @@ async function setChallengeLocale() {
}
}

async function onMessage(request, sender, sendResponse) {
async function onMessage(request, sender) {
if (request.id === 'notification') {
showNotification({
message: request.message,
Expand All @@ -56,6 +62,31 @@ async function onMessage(request, sender, sendResponse) {
if ([30, 100].includes(useCount)) {
await showContributePage('use');
}
} else if (request.id === 'resetCaptcha') {
const tabId = sender.tab.id;
const frameId = (await browser.webNavigation.getFrame({
tabId,
frameId: sender.frameId
})).parentFrameId;

if (!(await scriptsAllowed(tabId, frameId))) {
await showNotification({messageId: 'error_scriptsNotAllowed'});
return;
}

if (!(await functionInContext('addListener', tabId, frameId))) {
await executeFile('/src/content/initReset.js', tabId, frameId);
}
await executeCode('addListener()', tabId, frameId);

await browser.tabs.sendMessage(
tabId,
{
id: 'resetCaptcha',
challengeUrl: request.challengeUrl
},
{frameId}
);
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/content/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"presets": ["@babel/env"],
"env": {
"production": {
"presets": [["minify", {"deadcode": false}]]
}
}
}
28 changes: 28 additions & 0 deletions src/content/initReset.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
function initReset(challengeUrl) {
const script = document.createElement('script');
script.onload = function(e) {
e.target.remove();
document.dispatchEvent(
new CustomEvent('___resetCaptcha', {detail: challengeUrl})
);
};
script.src = chrome.extension.getURL('/src/content/reset.js');
document.documentElement.appendChild(script);
}

function addListener() {
const onMessage = function(request) {
if (request.id === 'resetCaptcha') {
removeCallbacks();
initReset(request.challengeUrl);
}
};

const removeCallbacks = function() {
window.clearTimeout(timeoutId);
chrome.runtime.onMessage.removeListener(onMessage);
};
const timeoutId = window.setTimeout(removeCallbacks, 10000); // 10 seconds

chrome.runtime.onMessage.addListener(onMessage);
}
24 changes: 24 additions & 0 deletions src/content/reset.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
(function() {
const onMessage = function(e) {
window.clearTimeout(timeoutId);
const challengeUrl = e.detail;
for (const [k, v] of Object.entries(___grecaptcha_cfg.clients)) {
if (v['O'].D.src === challengeUrl) {
grecaptcha.reset(k);
break;
}
}
};

const timeoutId = window.setTimeout(function() {
document.removeEventListener('___resetCaptcha', onMessage, {
capture: true,
once: true
});
}, 10000); // 10 seconds

document.addEventListener('___resetCaptcha', onMessage, {
capture: true,
once: true
});
})();
1 change: 1 addition & 0 deletions src/contribute/App.vue
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<!-- prettier-ignore -->
<template>
<div id="app">
<v-contribute :extName="extName" :extSlug="extSlug" :notice="notice">
Expand Down
8 changes: 5 additions & 3 deletions src/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
"notifications",
"webRequest",
"webRequestBlocking",
"webNavigation",
"<all_urls>"
],

"content_security_policy":
"default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src *; object-src 'none';",
"content_security_policy": "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src *; object-src 'none';",

"icons": {
"16": "src/icons/app/icon-16.png",
Expand Down Expand Up @@ -60,5 +60,7 @@

"background": {
"page": "src/background/index.html"
}
},

"web_accessible_resources": ["src/content/reset.js"]
}
1 change: 1 addition & 0 deletions src/options/App.vue
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<!-- prettier-ignore -->
<template>
<div id="app" v-if="dataLoaded">
<div class="section">
Expand Down
55 changes: 44 additions & 11 deletions src/solve/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ let solverWorking = false;

function setSolverState({working = true} = {}) {
solverWorking = working;
const button = document.querySelector('#buster-button');
const button = document.querySelector('#solver-button');
if (button) {
if (working) {
button.classList.add('working');
Expand All @@ -27,10 +27,39 @@ function setSolverState({working = true} = {}) {
}
}

function setButton() {
const infoButton = document.body.querySelector(
'button#recaptcha-help-button'
);
function resetCaptcha() {
return browser.runtime.sendMessage({
id: 'resetCaptcha',
challengeUrl: window.location.href
});
}

function syncUI() {
if (isBlocked()) {
if (!document.querySelector('.solver-controls')) {
const div = document.createElement('div');
div.classList.add('solver-controls');

const button = document.createElement('button');
button.classList.add('rc-button');
button.setAttribute('tabindex', '0');
button.setAttribute('title', getText('buttonText_reset'));
button.id = 'reset-button';

button.addEventListener('click', resetCaptcha);
button.addEventListener('keydown', e => {
if (['Enter', ' '].includes(e.key)) {
resetCaptcha();
}
});

div.appendChild(button);
document.querySelector('.rc-footer').appendChild(div);
}
return;
}

const infoButton = document.querySelector('#recaptcha-help-button');
if (infoButton) {
infoButton.remove();

Expand All @@ -41,7 +70,7 @@ function setButton() {
button.classList.add('rc-button', 'goog-inline-block');
button.setAttribute('tabindex', '0');
button.setAttribute('title', getText('buttonText_solve'));
button.id = 'buster-button';
button.id = 'solver-button';
if (solverWorking) {
button.classList.add('working');
}
Expand All @@ -58,10 +87,14 @@ function setButton() {
}
}

async function isBlocked({timeout = 0} = {}) {
function isBlocked({timeout = 0} = {}) {
const selector = '.rc-doscaptcha-body';
if (timeout) {
return Boolean(await waitForElement(selector, {timeout}));
return new Promise(resolve => {
waitForElement(selector, {timeout}).then(result =>
resolve(Boolean(result))
);
});
}

return Boolean(document.querySelector(selector));
Expand Down Expand Up @@ -194,7 +227,7 @@ async function solve() {
let audioUrl;
let solution;

if (await isBlocked()) {
if (isBlocked()) {
return;
}

Expand Down Expand Up @@ -419,13 +452,13 @@ function start(e) {
}

function init() {
const observer = new MutationObserver(setButton);
const observer = new MutationObserver(syncUI);
observer.observe(document.body, {
childList: true,
subtree: true
});

setButton();
syncUI();
}

init();
Loading

0 comments on commit 3398166

Please sign in to comment.