Recaptcha #886

Closed
liamcardenas wants to merge 5 commits from recaptcha into master
6 changed files with 71 additions and 14 deletions

View file

@ -28,6 +28,7 @@
"lbry" "lbry"
], ],
"dependencies": { "dependencies": {
"@segment/load-script": "^1.0.1",
"amplitude-js": "^4.0.0", "amplitude-js": "^4.0.0",
"classnames": "^2.2.5", "classnames": "^2.2.5",
"electron-dl": "^1.6.0", "electron-dl": "^1.6.0",
@ -46,6 +47,7 @@
"react-markdown": "^2.5.0", "react-markdown": "^2.5.0",
"react-modal": "^3.1.7", "react-modal": "^3.1.7",
"react-paginate": "^5.0.0", "react-paginate": "^5.0.0",
"react-recaptcha": "^2.3.5",
"react-redux": "^5.0.3", "react-redux": "^5.0.3",
"react-simplemde-editor": "^3.6.11", "react-simplemde-editor": "^3.6.11",
"redux": "^3.6.0", "redux": "^3.6.0",

View file

@ -20,7 +20,8 @@ const select = state => ({
}); });
const perform = dispatch => ({ const perform = dispatch => ({
verifyUserEmail: code => dispatch(doUserEmailVerify(code)), verifyUserEmail: (code, recaptcha) =>
dispatch(doUserEmailVerify(code, recaptcha)),
}); });
export default connect(select, perform)(UserEmailVerify); export default connect(select, perform)(UserEmailVerify);

View file

@ -2,6 +2,12 @@ import React from "react";
import Link from "component/link"; import Link from "component/link";
import { CreditAmount } from "component/common"; import { CreditAmount } from "component/common";
import { Form, FormRow, Submit } from "component/form.js"; import { Form, FormRow, Submit } from "component/form.js";
import Recaptcha from "react-recaptcha";
const sitekey =
process.env.NODE_ENV === "development"
? "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI"
: "6LcWvj0UAAAAAGBAEp6-UDoe0_iSAn8IZW0GDcf0";
class UserEmailVerify extends React.PureComponent { class UserEmailVerify extends React.PureComponent {
constructor(props) { constructor(props) {
@ -9,6 +15,7 @@ class UserEmailVerify extends React.PureComponent {
this.state = { this.state = {
code: "", code: "",
recaptcha: "",
}; };
} }
@ -19,8 +26,14 @@ class UserEmailVerify extends React.PureComponent {
} }
handleSubmit() { handleSubmit() {
const { code } = this.state; const { code, recaptcha } = this.state;
this.props.verifyUserEmail(code); this.props.verifyUserEmail(code, recaptcha);
}
verifyCallback(response) {
this.setState({
recaptcha: String(response),
});
} }
render() { render() {
@ -44,6 +57,10 @@ class UserEmailVerify extends React.PureComponent {
}} }}
errorMessage={errorMessage} errorMessage={errorMessage}
/> />
<Recaptcha
sitekey={sitekey}
verifyCallback={this.verifyCallback.bind(this)}
/>
{/* render help separately so it always shows */} {/* render help separately so it always shows */}
<div className="form-field__helper"> <div className="form-field__helper">
<p> <p>
@ -54,7 +71,10 @@ class UserEmailVerify extends React.PureComponent {
</p> </p>
</div> </div>
<div className="form-row-submit"> <div className="form-row-submit">
<Submit label={__("Verify")} disabled={isPending} /> <Submit
label={__("Verify")}
disabled={isPending || !this.state.code || !this.state.recaptcha}
/>
{cancelButton} {cancelButton}
</div> </div>
</Form> </Form>

View file

@ -17,6 +17,9 @@ const env = process.env.NODE_ENV || "production";
const { remote, ipcRenderer, shell } = require("electron"); const { remote, ipcRenderer, shell } = require("electron");
const contextMenu = remote.require("./main.js").contextMenu; const contextMenu = remote.require("./main.js").contextMenu;
const app = require("./app"); const app = require("./app");
const load = require("@segment/load-script");
load("//www.google.com/recaptcha/api.js?render=explicit");
// Workaround for https://github.com/electron-userland/electron-webpack/issues/52 // Workaround for https://github.com/electron-userland/electron-webpack/issues/52
if (process.env.NODE_ENV !== "development") { if (process.env.NODE_ENV !== "development") {

View file

@ -68,14 +68,14 @@ export function doUserEmailNew(email) {
data: { email }, data: { email },
}); });
dispatch(doUserFetch()); dispatch(doUserFetch());
} };
const failure = error => { const failure = error => {
dispatch({ dispatch({
type: types.USER_EMAIL_NEW_FAILURE, type: types.USER_EMAIL_NEW_FAILURE,
data: { error }, data: { error },
}); });
} };
lbryio lbryio
.call( .call(
@ -86,12 +86,14 @@ export function doUserEmailNew(email) {
) )
.catch(error => { .catch(error => {
if (error.response && error.response.status == 409) { if (error.response && error.response.status == 409) {
return lbryio.call( return lbryio
"user_email", .call(
"resend_token", "user_email",
{ email: email, only_if_expired: true }, "resend_token",
"post" { email: email, only_if_expired: true },
).then(success, failure); "post"
)
.then(success, failure);
} }
throw error; throw error;
}) })
@ -99,10 +101,11 @@ export function doUserEmailNew(email) {
}; };
} }
export function doUserEmailVerify(verificationToken) { export function doUserEmailVerify(verificationToken, recaptcha) {
return function(dispatch, getState) { return function(dispatch, getState) {
const email = selectEmailToVerify(getState()); const email = selectEmailToVerify(getState());
verificationToken = verificationToken.toString().trim(); verificationToken = verificationToken.toString().trim();
recaptcha = recaptcha.toString();
dispatch({ dispatch({
type: types.USER_EMAIL_VERIFY_STARTED, type: types.USER_EMAIL_VERIFY_STARTED,
@ -113,7 +116,11 @@ export function doUserEmailVerify(verificationToken) {
.call( .call(
"user_email", "user_email",
"confirm", "confirm",
{ verification_token: verificationToken, email: email }, {
verification_token: verificationToken,
email: email,
recaptcha: recaptcha,
},
"post" "post"
) )
.then(userEmail => { .then(userEmail => {

View file

@ -34,6 +34,14 @@
version "0.0.6" version "0.0.6"
resolved "https://registry.yarnpkg.com/7zip/-/7zip-0.0.6.tgz#9cafb171af82329490353b4816f03347aa150a30" resolved "https://registry.yarnpkg.com/7zip/-/7zip-0.0.6.tgz#9cafb171af82329490353b4816f03347aa150a30"
"@segment/load-script@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@segment/load-script/-/load-script-1.0.1.tgz#adb7a2def2c99ac248cc8e2c154fb4bb03094399"
dependencies:
component-type "^1.2.0"
next-tick "^0.2.2"
script-onload "^1.0.2"
"@segment/top-domain@^3.0.0": "@segment/top-domain@^3.0.0":
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/@segment/top-domain/-/top-domain-3.0.0.tgz#02e5a5a4fd42a9f6cf886b05e82f104012a3c3a7" resolved "https://registry.yarnpkg.com/@segment/top-domain/-/top-domain-3.0.0.tgz#02e5a5a4fd42a9f6cf886b05e82f104012a3c3a7"
@ -1892,6 +1900,10 @@ component-cookie@^1.1.2:
dependencies: dependencies:
debug "*" debug "*"
component-type@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/component-type/-/component-type-1.2.1.tgz#8a47901700238e4fc32269771230226f24b415a9"
component-url@^0.2.1: component-url@^0.2.1:
version "0.2.1" version "0.2.1"
resolved "https://registry.yarnpkg.com/component-url/-/component-url-0.2.1.tgz#4e4f4799c43ead9fd3ce91b5a305d220208fee47" resolved "https://registry.yarnpkg.com/component-url/-/component-url-0.2.1.tgz#4e4f4799c43ead9fd3ce91b5a305d220208fee47"
@ -5249,6 +5261,10 @@ next-event@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/next-event/-/next-event-1.0.0.tgz#e7778acde2e55802e0ad1879c39cf6f75eda61d8" resolved "https://registry.yarnpkg.com/next-event/-/next-event-1.0.0.tgz#e7778acde2e55802e0ad1879c39cf6f75eda61d8"
next-tick@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-0.2.2.tgz#75da4a927ee5887e39065880065b7336413b310d"
no-case@^2.2.0: no-case@^2.2.0:
version "2.3.2" version "2.3.2"
resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac"
@ -6619,6 +6635,10 @@ react-paginate@^5.0.0:
prop-types "^15.6.0" prop-types "^15.6.0"
react-addons-create-fragment "^15.0.0" react-addons-create-fragment "^15.0.0"
react-recaptcha@^2.3.5:
version "2.3.5"
resolved "https://registry.yarnpkg.com/react-recaptcha/-/react-recaptcha-2.3.5.tgz#a5db337125bb00fb13c2fa2e4ebfbe8b0cd06bb7"
react-redux@^5.0.3: react-redux@^5.0.3:
version "5.0.6" version "5.0.6"
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.6.tgz#23ed3a4f986359d68b5212eaaa681e60d6574946" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.6.tgz#23ed3a4f986359d68b5212eaaa681e60d6574946"
@ -7194,6 +7214,10 @@ schema-utils@^0.3.0:
dependencies: dependencies:
ajv "^5.0.0" ajv "^5.0.0"
script-onload@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/script-onload/-/script-onload-1.0.2.tgz#6bdca122875487192ccaf4e6884fcfdd0c7fde32"
scss-tokenizer@^0.2.3: scss-tokenizer@^0.2.3:
version "0.2.3" version "0.2.3"
resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1" resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1"