...
 
Commits (5)
......@@ -22,7 +22,8 @@ export default async function callbackRoute (req, res) {
await test.save();
}
const ip = AllTests[testName].type === 'dns'
const { type } = AllTests[testName];
const ip = type === 'dns'
? req.query.ip
: req.remote().client;
......@@ -30,10 +31,10 @@ export default async function callbackRoute (req, res) {
code,
ip,
test: testName,
http: {
http: type === 'http' ? {
httpUserAgent: req.headers['user-agent'],
httpForwardedFor: ip.httpForwardedFor,
},
} : undefined,
});
await callback.save();
......
......@@ -5,6 +5,7 @@
"license": "GPL-3.0",
"dependencies": {
"next": "^1.2.3",
"react-noscript": "^1.0.2",
"whatwg-fetch": "^2.0.1"
},
"next": {
......
import React, { Component } from 'react';
import NoScript from 'react-noscript';
import css from 'next/css';
import Link from 'next/link';
......@@ -39,10 +40,16 @@ export default class HomePage extends Component {
return (
<Wrapper title="Email Privacy Tester">
<p className={ style.instructions }>
If you fill in the field below we will send you a confirmation email
with further instructions. If this is your first time here, you might
want to read the <Link href="/about">about page</Link> and/or
If this is your first time here, you might want to read
the <Link href="/about">about page</Link> and/or
the <Link href="/privacy">privacy policy</Link>.
<NoScript>
<span style={{ color: 'red' }}>
<br/>
Sorry, but you'll need to enable JavaScript to use the form
below. On the plus side, there is no cross-origin content.
</span>
</NoScript>
</p>
<form
className = { style.form }
......
......@@ -17,10 +17,10 @@ export default class PrivacyPage extends Component {
which go back as far as ten days. I will not share your email
address with anyone, ever. I will never send any email to it other
than the email that this application is designed to send
out when you submit it. The one email that I do send
to you contains an opt-out link. If you click it, I will store your
email address in the database for the lifetime of this system and
this app will be prevented from contacting it again.
out when you submit it. The email that I do send to you contains an
opt-out link. If you click it, I will store your email address in
the database for the lifetime of this system and this app will be
prevented from contacting it again.
</p>
<p>
I also store test results for a period of one week before deletion.
......
......@@ -23,6 +23,10 @@ const style = {
}),
};
function sleep (ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
export default class TestPage extends Component {
static async getInitialProps({ query }) {
......@@ -55,10 +59,11 @@ export default class TestPage extends Component {
super(props);
this.state = {
submitting: false,
error: null,
results: props.initialResults || [],
testSent: props.testSent,
submitting: false,
error: null,
results: props.initialResults || [],
testSent: props.testSent,
testSentWait: false,
};
this.send = this.send.bind(this);
this.checkResults = this.checkResults.bind(this);
......@@ -79,7 +84,7 @@ export default class TestPage extends Component {
render() {
const { email, tests } = this.props;
const { error, submitting, results, testSent } = this.state;
const { error, submitting, results, testSent, testSentWait } = this.state;
if (!email) {
return (
......@@ -101,12 +106,13 @@ export default class TestPage extends Component {
<button
className = { style.actions.action }
onClick = { this.send }
disabled = { submitting }
disabled = { submitting || testSentWait }
>
{
submitting ? 'Sending...'
: testSent ? 'Send Another Email'
: 'Send Test Email'
submitting ? 'Sending...'
: testSentWait ? 'Email Sent'
: testSent ? 'Send Another Email'
: 'Send Test Email'
}
</button>
}
......@@ -164,7 +170,7 @@ export default class TestPage extends Component {
} catch (err) {
await new Promise(r => setTimeout(r, 2000));
await sleep(2000);
}
this.checkResults();
......@@ -175,7 +181,7 @@ export default class TestPage extends Component {
const { code } = this.props;
const { submitting } = this.state;
if (submitting) return;
this.setState({ submitting: true }, async () => {
this.setState({ error: null, submitting: true }, async () => {
let newState = { submitting: false };
try {
await api.post('deleteResults', { code });
......@@ -200,10 +206,21 @@ export default class TestPage extends Component {
try {
let t = Date.now();
await api.post('sendTest', { code });
t = Date.now() - t;
if (t < 1500) await sleep(1500 - t);
this.setState({
submitting: false,
testSent: true,
submitting: false,
testSentWait: true,
}, async () => {
await sleep(2000);
this.setState({
testSentWait: false,
testSent: true,
});
});
} catch(err) {
......
......@@ -23,6 +23,10 @@ p {
line-height: 2;
}
li {
line-height: 2;
}
#__next {
height: 100%;
width: 100%;
......