From d3fd71d9534ac540d72f7d8263e13a5e8461fa53 Mon Sep 17 00:00:00 2001 From: Jannis R Date: Tue, 6 Dec 2016 17:45:34 +0100 Subject: [PATCH] add email-specific contract, helpers, store --- js/src/3rdparty/email-verification/index.js | 53 +++++++++++++++ js/src/3rdparty/email-verification/styles.css | 20 ++++++ js/src/3rdparty/sms-verification/index.js | 13 ++++ js/src/3rdparty/sms-verification/styles.css | 20 ++++++ js/src/contracts/abi/email-verification.json | 1 + js/src/contracts/abi/index.js | 2 + js/src/modals/Verification/email-store.js | 66 +++++++++++++++++++ 7 files changed, 175 insertions(+) create mode 100644 js/src/3rdparty/email-verification/index.js create mode 100644 js/src/3rdparty/email-verification/styles.css create mode 100644 js/src/3rdparty/sms-verification/styles.css create mode 100644 js/src/contracts/abi/email-verification.json create mode 100644 js/src/modals/Verification/email-store.js diff --git a/js/src/3rdparty/email-verification/index.js b/js/src/3rdparty/email-verification/index.js new file mode 100644 index 000000000..5f4885f3b --- /dev/null +++ b/js/src/3rdparty/email-verification/index.js @@ -0,0 +1,53 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +import { stringify } from 'querystring'; +import React from 'react'; + +import styles from './styles.css'; + +export const howItWorks = ( +
+

The following steps will let you prove that you control both an account and an e-mail address.

+
    +
  1. You send a verification request to a specific contract.
  2. +
  3. Our server puts a puzzle into this contract.
  4. +
  5. The code you receive via e-mail is the solution to this puzzle.
  6. +
+
+); + +export const termsOfService = ( + +); + +export const postToServer = (query, isTestnet = false) => { + const port = isTestnet ? 28443 : 18443; + query = stringify(query); + return fetch(`https://email-verification.parity.io:${port}/?` + query, { + method: 'POST', mode: 'cors', cache: 'no-store' + }) + .then((res) => { + return res.json().then((data) => { + if (res.ok) { + return data.message; + } + throw new Error(data.message || 'unknown error'); + }); + }); +}; diff --git a/js/src/3rdparty/email-verification/styles.css b/js/src/3rdparty/email-verification/styles.css new file mode 100644 index 000000000..daa4c605c --- /dev/null +++ b/js/src/3rdparty/email-verification/styles.css @@ -0,0 +1,20 @@ +/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* This file is part of Parity. +/* +/* Parity is free software: you can redistribute it and/or modify +/* it under the terms of the GNU General Public License as published by +/* the Free Software Foundation, either version 3 of the License, or +/* (at your option) any later version. +/* +/* Parity is distributed in the hope that it will be useful, +/* but WITHOUT ANY WARRANTY; without even the implied warranty of +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/* GNU General Public License for more details. +/* +/* You should have received a copy of the GNU General Public License +/* along with Parity. If not, see . +*/ + +.list li { + padding: .1em 0; +} diff --git a/js/src/3rdparty/sms-verification/index.js b/js/src/3rdparty/sms-verification/index.js index c50b2331a..46faf084c 100644 --- a/js/src/3rdparty/sms-verification/index.js +++ b/js/src/3rdparty/sms-verification/index.js @@ -17,6 +17,19 @@ import { stringify } from 'querystring'; import React from 'react'; +import styles from './styles.css'; + +export const howItWorks = ( +
+

The following steps will let you prove that you control both an account and a phone number.

+
    +
  1. You send a verification request to a specific contract.
  2. +
  3. Our server puts a puzzle into this contract.
  4. +
  5. The code you receive via SMS is the solution to this puzzle.
  6. +
+
+); + export const termsOfService = (
  • This privacy notice relates to your use of the Parity SMS verification service. We take your privacy seriously and deal in an honest, direct and transparent way when it comes to your data.
  • diff --git a/js/src/3rdparty/sms-verification/styles.css b/js/src/3rdparty/sms-verification/styles.css new file mode 100644 index 000000000..daa4c605c --- /dev/null +++ b/js/src/3rdparty/sms-verification/styles.css @@ -0,0 +1,20 @@ +/* Copyright 2015, 2016 Ethcore (UK) Ltd. +/* This file is part of Parity. +/* +/* Parity is free software: you can redistribute it and/or modify +/* it under the terms of the GNU General Public License as published by +/* the Free Software Foundation, either version 3 of the License, or +/* (at your option) any later version. +/* +/* Parity is distributed in the hope that it will be useful, +/* but WITHOUT ANY WARRANTY; without even the implied warranty of +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/* GNU General Public License for more details. +/* +/* You should have received a copy of the GNU General Public License +/* along with Parity. If not, see . +*/ + +.list li { + padding: .1em 0; +} diff --git a/js/src/contracts/abi/email-verification.json b/js/src/contracts/abi/email-verification.json new file mode 100644 index 000000000..baa6db483 --- /dev/null +++ b/js/src/contracts/abi/email-verification.json @@ -0,0 +1 @@ +[{"constant":false,"inputs":[{"name":"_new","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"reverse","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_who","type":"address"},{"name":"_puzzle","type":"bytes32"},{"name":"_emailHash","type":"bytes32"}],"name":"puzzle","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_field","type":"string"}],"name":"getAddress","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_emailHash","type":"bytes32"}],"name":"request","outputs":[],"payable":true,"type":"function"},{"constant":false,"inputs":[{"name":"_new","type":"uint256"}],"name":"setFee","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_code","type":"bytes32"}],"name":"confirm","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"drain","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_field","type":"string"}],"name":"getUint","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"}],"name":"certified","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"fee","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_field","type":"string"}],"name":"get","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"who","type":"address"},{"indexed":false,"name":"emailHash","type":"bytes32"}],"name":"Requested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"who","type":"address"},{"indexed":true,"name":"emailHash","type":"bytes32"},{"indexed":false,"name":"puzzle","type":"bytes32"}],"name":"Puzzled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"who","type":"address"}],"name":"Confirmed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"who","type":"address"}],"name":"Revoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"old","type":"address"},{"indexed":true,"name":"current","type":"address"}],"name":"NewOwner","type":"event"}] \ No newline at end of file diff --git a/js/src/contracts/abi/index.js b/js/src/contracts/abi/index.js index f15765b1a..c8cb851dd 100644 --- a/js/src/contracts/abi/index.js +++ b/js/src/contracts/abi/index.js @@ -19,6 +19,7 @@ import basiccoin from './basiccoin.json'; import basiccoinmanager from './basiccoinmanager.json'; import dappreg from './dappreg.json'; import eip20 from './eip20.json'; +import emailverification from './email-verification.json'; import gavcoin from './gavcoin.json'; import githubhint from './githubhint.json'; import owned from './owned.json'; @@ -34,6 +35,7 @@ export { basiccoinmanager, dappreg, eip20, + emailverification, gavcoin, githubhint, owned, diff --git a/js/src/modals/Verification/email-store.js b/js/src/modals/Verification/email-store.js new file mode 100644 index 000000000..14179cfe2 --- /dev/null +++ b/js/src/modals/Verification/email-store.js @@ -0,0 +1,66 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +import { observable, computed, action } from 'mobx'; + +import VerificationStore, { + LOADING, QUERY_DATA, QUERY_CODE, POSTED_CONFIRMATION, DONE +} from './store'; +import { postToServer } from '../../3rdparty/email-verification'; + +export default class EmailVerificationStore extends VerificationStore { + @observable email = ''; + + @computed get isEmailValid () { + // See https://davidcel.is/posts/stop-validating-email-addresses-with-regex/ + return this.email && this.email.indexOf('@') >= 0; + } + + @computed get isStepValid () { + if (this.step === DONE) { + return true; + } + if (this.error) { + return false; + } + + switch (this.step) { + case LOADING: + return this.contract && this.fee && this.isVerified !== null && this.hasRequested !== null; + case QUERY_DATA: + return this.isEmailValid && this.consentGiven; + case QUERY_CODE: + return this.requestTx && this.isCodeValid === true; + case POSTED_CONFIRMATION: + return !!this.confirmationTx; + default: + return false; + } + } + + constructor (api, account, isTestnet) { + return super(api, account, isTestnet, 'emailverification'); + } + + @action setEmail = (email) => { + this.email = email; + } + + requestCode = () => { + const { email, account, isTestnet } = this; + return postToServer({ email, address: account }, isTestnet); + } +}