diff --git a/client/assets/styles/styles.less b/client/assets/styles/styles.less
index 76fe12bf..f234fcd0 100644
--- a/client/assets/styles/styles.less
+++ b/client/assets/styles/styles.less
@@ -74,6 +74,10 @@ figure {
text-align: center;
}
+p {
+ margin-bottom: 1em;
+}
+
#mnml {
display: grid;
grid-template-columns: minmax(min-content, 1fr) 8fr 1fr;
@@ -189,11 +193,28 @@ button[disabled] {
LOGIN
*/
-.login {
- width: 50%;
- display: flex;
- flex-flow: column;
- margin-bottom: 2em;
+.welcome {
+ .highlight {
+ color: black;
+ background: @white;
+ border: 1px solid @white;
+ }
+
+ .login {
+ width: 50%;
+ display: flex;
+ flex-flow: column;
+ margin-bottom: 2em;
+ }
+
+ .options {
+ width: 50%;
+ display: flex;
+ flex-flow: row;
+ button {
+ flex: 1;
+ }
+ }
h2 {
margin-bottom: 0.5em;
diff --git a/client/assets/styles/styles.mobile.css b/client/assets/styles/styles.mobile.css
index 263761ff..c0db0c18 100644
--- a/client/assets/styles/styles.mobile.css
+++ b/client/assets/styles/styles.mobile.css
@@ -53,10 +53,19 @@
padding: 0 0.5em;
}
- .login {
+ .welcome .login {
width: 100%;
}
+ .welcome .options {
+ width: 100%;
+ flex-flow: row wrap;
+ }
+
+ .welcome .options button {
+ flex: 1 0 50%;
+ }
+
.timer-container {
margin: 0.5em 0 0 0;
}
diff --git a/client/index.html b/client/index.html
index 88515382..453c4706 100644
--- a/client/index.html
+++ b/client/index.html
@@ -16,7 +16,10 @@
-
+
diff --git a/client/src/components/login.jsx b/client/src/components/login.jsx
deleted file mode 100644
index 6b7eefd3..00000000
--- a/client/src/components/login.jsx
+++ /dev/null
@@ -1,170 +0,0 @@
-// eslint-disable-next-line
-const preact = require('preact');
-const { Component } = require('preact')
-const { connect } = require('preact-redux');
-const linkState = require('linkstate').default;
-
-const { postData, errorToast } = require('../utils');
-
-const addState = connect(
- (state) => {
- const {
- ws
- } = state;
- function submitLogin(name, password) {
- postData('/account/login', { name, password })
- .then(res => res.json())
- .then(data => {
- if (data.error) return errorToast(data.error);
- console.log(data.response);
- ws.connect();
- })
- .catch(error => errorToast(error));
- }
-
- function submitRegister(name, password, code) {
- postData('/account/register', { name, password, code })
- .then(res => res.json())
- .then(data => {
- if (data.error) return errorToast(data.error);
- console.log(data.response);
- ws.connect();
- })
- .catch(error => errorToast(error));
- }
-
- return {
- submitLogin,
- submitRegister,
- }
- },
-);
-
-class Login extends Component {
- constructor(props) {
- super(props);
-
- this.state = {
- login: { name: '', password: '', code: ''},
- register: { name: '', password: '', confirm: '', code: ''},
- };
-
- this.loginSubmit = this.loginSubmit.bind(this);
- this.registerSubmit = this.registerSubmit.bind(this);
- }
-
- loginSubmit(event) {
- event.preventDefault();
- console.log(this.state);
- this.props.submitLogin(this.state.login.name, this.state.login.password);
- this.setState({ login: { name: '', password: '' }});
- }
-
- registerSubmit(event) {
- event.preventDefault();
- this.props.submitRegister(this.state.register.name, this.state.register.password, this.state.register.code);
- this.setState({ register: { name: '', password: '', confirm: '', code: ''}});
- }
-
- render() {
- const registerConfirm = () =>
- this.state.register.password === this.state.register.confirm;
-
- const loginDisabled = () => {
- const { password, name } = this.state.login;
- return !(password && name);
- }
-
- const registerDisabled = () => {
- const { password, name, code } = this.state.register;
- return !(registerConfirm() && password && name && code);
- }
-
- return (
-
- mnml.gg
-
-
mnml is an abstract turn based strategy game
-
free to play
-
no email required
-
-
-
Login
-
-
-
-
-
-
-
-
Register
-
-
-
-
-
-
-
-
-
-
-
-
- );
- }
-}
-
-module.exports = addState(Login);
diff --git a/client/src/components/main.jsx b/client/src/components/main.jsx
index 44948fe2..57abab03 100644
--- a/client/src/components/main.jsx
+++ b/client/src/components/main.jsx
@@ -2,7 +2,7 @@
const preact = require('preact');
const { connect } = require('preact-redux');
-const Login = require('./login');
+const Welcome = require('./welcome');
const Game = require('./game');
const Instance = require('./instance.component');
const Team = require('./team');
@@ -25,7 +25,7 @@ function Main(props) {
} = props;
if (!account) {
- return ;
+ return ;
}
if (game) {
diff --git a/client/src/components/welcome.about.jsx b/client/src/components/welcome.about.jsx
new file mode 100644
index 00000000..0f33b942
--- /dev/null
+++ b/client/src/components/welcome.about.jsx
@@ -0,0 +1,69 @@
+// eslint-disable-next-line
+const preact = require('preact');
+const { Component } = require('preact')
+const { connect } = require('preact-redux');
+const linkState = require('linkstate').default;
+
+const { postData, errorToast, infoToast } = require('../utils');
+
+const addState = connect(
+ (state) => {
+ const {
+ ws
+ } = state;
+
+ function submitRegister(name, password, code) {
+ postData('/account/register', { name, password, code })
+ .then(res => res.json())
+ .then(data => {
+ if (data.error) return errorToast(data.error);
+ infoToast(data.message);
+ ws.connect();
+ })
+ .catch(error => errorToast(error));
+ }
+
+ return {
+ submitRegister,
+ }
+ },
+);
+
+function Register(args) {
+ const {
+ submitRegister,
+ navRegister,
+ } = args;
+
+ return (
+
+
+ mnml is made deep in the southern hemisphere by ntr & mashy.
+
+
+ if you like this game please support the development by buying credits or subscribing.
+
+
+ this site has no trackers or ads.
+
+
+ you can reach us for feedback and support with the discord and email buttons below.
+
+
+ the access code grep842 is currently active.
+
+
+
+
+ );
+}
+
+module.exports = addState(Register);
diff --git a/client/src/components/welcome.help.jsx b/client/src/components/welcome.help.jsx
new file mode 100644
index 00000000..b864e6a0
--- /dev/null
+++ b/client/src/components/welcome.help.jsx
@@ -0,0 +1,91 @@
+// eslint-disable-next-line
+const preact = require('preact');
+const { Component } = require('preact')
+const { connect } = require('preact-redux');
+const linkState = require('linkstate').default;
+
+const { postData, errorToast, infoToast } = require('../utils');
+
+const addState = connect(
+ (state) => {
+ const {
+ ws
+ } = state;
+
+ function submitRecover(email) {
+ postData('/account/recover', { email })
+ .then(res => res.json())
+ .then(data => {
+ if (data.error) return errorToast(data.error);
+ infoToast(data.message);
+ })
+ .catch(error => errorToast(error));
+ }
+
+ return {
+ submitRecover,
+ }
+ },
+);
+
+const EMAIL_SUBJECT = name => `
+account support: ${name || 'CHANGEME'}
+`;
+
+const EMAIL_BODY = `
+---
+include some details regarding your account. ie.
+- account name
+- construct names
+---
+`;
+
+function Register(args) {
+ const {
+ submitRecover,
+ } = args;
+
+ const { email } = this.state;
+
+ const buttonSubmit = (event) => {
+ event.preventDefault();
+ submitRecover(email);
+ // this.setState({ email: '' });
+ };
+
+ const buttonDisabled = () => {
+ return !email;
+ };
+
+ const supportLink = encodeURI(`mailto:humans@mnml.gg?subject=${EMAIL_SUBJECT(email)}&body=${EMAIL_BODY}`);
+
+ return (
+
+
+ send a recovery email to your account's confirmed email address.
+
+
+ if you have not set and confirmed an email address for your account
+ please contact support.
+
+
+
+
+
+
+ );
+}
+
+module.exports = addState(Register);
diff --git a/client/src/components/welcome.jsx b/client/src/components/welcome.jsx
new file mode 100644
index 00000000..27575d98
--- /dev/null
+++ b/client/src/components/welcome.jsx
@@ -0,0 +1,61 @@
+// eslint-disable-next-line
+const preact = require('preact');
+
+const Login = require('./welcome.login');
+const Register = require('./welcome.register');
+const Help = require('./welcome.help');
+const About = require('./welcome.about');
+
+function Welcome() {
+ const page = this.state.page || 'login';
+
+ const navRegister = () => this.setState({ page: 'register' });
+ const pageEl = () => {
+ if (page === 'login') return ;
+ if (page === 'register') return ;
+ if (page === 'about') return ;
+ if (page === 'help') return ;
+ return false;
+ };
+
+ return (
+
+ mnml.gg
+
+
mnml is an abstract turn based strategy game
+
free to play
+
no email required
+
glhf
+
+
+
+
+
+
+
+ {pageEl()}
+
+ );
+}
+
+module.exports = Welcome;
diff --git a/client/src/components/welcome.login.jsx b/client/src/components/welcome.login.jsx
new file mode 100644
index 00000000..aa65f20d
--- /dev/null
+++ b/client/src/components/welcome.login.jsx
@@ -0,0 +1,80 @@
+// eslint-disable-next-line
+const preact = require('preact');
+const { Component } = require('preact')
+const { connect } = require('preact-redux');
+const linkState = require('linkstate').default;
+
+const { postData, errorToast } = require('../utils');
+
+const addState = connect(
+ (state) => {
+ const {
+ ws
+ } = state;
+ function submitLogin(name, password) {
+ postData('/account/login', { name, password })
+ .then(res => res.json())
+ .then(data => {
+ if (data.error) return errorToast(data.error);
+ console.log(data.message);
+ ws.connect();
+ })
+ .catch(error => errorToast(error));
+ }
+
+ return {
+ submitLogin,
+ }
+ },
+);
+
+
+function Login(args) {
+ const {
+ submitLogin,
+ } = args;
+
+ const { password, name } = this.state;
+
+ const loginSubmit = (event) => {
+ event.preventDefault();
+ submitLogin(name, password);
+ this.setState({ name: '', password: '' });
+ };
+
+ const loginDisabled = () => {
+ return !(password && name);
+ };
+
+ return (
+
+
+
+
+
+
+
+ );
+}
+
+module.exports = addState(Login);
diff --git a/client/src/components/welcome.register.jsx b/client/src/components/welcome.register.jsx
new file mode 100644
index 00000000..7051a8ce
--- /dev/null
+++ b/client/src/components/welcome.register.jsx
@@ -0,0 +1,96 @@
+// eslint-disable-next-line
+const preact = require('preact');
+const { Component } = require('preact')
+const { connect } = require('preact-redux');
+const linkState = require('linkstate').default;
+
+const { postData, errorToast, infoToast } = require('../utils');
+
+const addState = connect(
+ (state) => {
+ const {
+ ws
+ } = state;
+
+ function submitRegister(name, password, code) {
+ postData('/account/register', { name, password, code })
+ .then(res => res.json())
+ .then(data => {
+ if (data.error) return errorToast(data.error);
+ infoToast(data.message);
+ ws.connect();
+ })
+ .catch(error => errorToast(error));
+ }
+
+ return {
+ submitRegister,
+ }
+ },
+);
+
+function Register(args) {
+ const {
+ submitRegister,
+ } = args;
+
+ const { password, confirm, name, code } = this.state;
+
+ const registerSubmit = (event) => {
+ event.preventDefault();
+ submitRegister(name, password, code);
+ // this.setState({ name: '', password: '', confirm: '', code: ''});
+ }
+
+ const registerConfirm = () =>
+ password === confirm;
+
+ const registerDisabled = () => {
+ return !(registerConfirm() && password && name && code);
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+module.exports = addState(Register);
diff --git a/ops/migrations/20180913000513_create_accounts.js b/ops/migrations/20180913000513_create_accounts.js
index 3184ff08..17eddca3 100755
--- a/ops/migrations/20180913000513_create_accounts.js
+++ b/ops/migrations/20180913000513_create_accounts.js
@@ -9,6 +9,7 @@ exports.up = async knex => {
table.string('token', 64)
.notNullable()
.index();
+
table.timestamp('token_expiry').notNullable();
table.bigInteger('balance')
diff --git a/server/src/mail.rs b/server/src/mail.rs
index 00d3950c..9e7813ad 100644
--- a/server/src/mail.rs
+++ b/server/src/mail.rs
@@ -42,10 +42,13 @@ pub enum Mail {
fn recover(email: &String, name: &String, token: &String) -> SendableEmail {
let body = format!("{:},
the link below will recover your account.
-please change your password immediately in the account page
+please change your password immediately in the account page.
+this link will expire in 48 hours or once used.
+
http://mnml.gg/api/account/recover?recover_token={:}
-glhf", name, token);
+glhf
+--mnml", name, token);
Email::builder()
.from("machines@mnml.gg")
@@ -62,7 +65,8 @@ fn confirm(email: &String, name: &String, token: &String) -> SendableEmail {
please click the link below to confirm your email
http://mnml.gg/api/account/email/confirm?confirm_token={:}
-glhf", name, token);
+glhf
+--mnml", name, token);
Email::builder()
.from("machines@mnml.gg")