login form

This commit is contained in:
ntr 2018-09-22 21:59:23 +10:00
parent 836cbddb63
commit 6188fafdf2
12 changed files with 140 additions and 35 deletions

View File

@ -1,3 +1,8 @@
export const SET_ACCOUNT = 'SET_ACCOUNT'; export const SET_ACCOUNT = 'SET_ACCOUNT';
export const setAccount = (value) => ({ type: SET_ACCOUNT, value }); export const setAccount = (value) => ({ type: SET_ACCOUNT, value });
export const SET_CRYP = 'SET_CRYP';
export const setCryp = (value) => ({ type: SET_CRYP, value });
export const SET_WS = 'SET_WS';
export const setWs = (value) => ({ type: SET_WS, value });

View File

@ -0,0 +1,10 @@
const { connect } = require('preact-redux');
const InvStats = require('./invstats');
// Add the incident from state as a property
const addState = connect(
state => ({ cryp: state.cryp }),
);
module.exports = addState(InvStats);

View File

@ -1,8 +1,8 @@
const preact = require('preact'); const preact = require('preact');
// components all the way down function InvStats({ cryp }) {
if (!cryp) return <div>not ready</div>;
function InvStats() {
return ( return (
<div className="tile is-ancestor has-text-centered has-background-grey is-dark is-10"> <div className="tile is-ancestor has-text-centered has-background-grey is-dark is-10">
<div className="tile is-6"> <div className="tile is-6">
@ -23,9 +23,9 @@ function InvStats() {
<div className="tile is-parent is-6"> <div className="tile is-parent is-6">
<article className="tile is-child notification is-info"> <article className="tile is-child notification is-info">
<figure className="image"> <figure className="image">
<svg width="160" height="160" data-jdenticon-value="UltimateCryp" /> <svg width="160" height="160" data-jdenticon-value={cryp.name} />
</figure> </figure>
<p className="title">Cryp#XYZ</p> <p className="title">{cryp.name}</p>
<p className="subtitle">The big boy</p> <p className="subtitle">The big boy</p>
</article> </article>
</div> </div>
@ -44,6 +44,10 @@ function InvStats() {
<div className="tile is-parent is-6"> <div className="tile is-parent is-6">
<article className="tile is-child notification has-background-grey is-dark"> <article className="tile is-child notification has-background-grey is-dark">
<p className="title">Stat Area</p> <p className="title">Stat Area</p>
<p>{JSON.stringify(cryp.def)}</p>
<p>{JSON.stringify(cryp.dmg)}</p>
<p>{JSON.stringify(cryp.hp)}</p>
<p>{JSON.stringify(cryp.stam)}</p>
</article> </article>
</div> </div>
</div> </div>

View File

@ -0,0 +1,43 @@
const preact = require('preact');
function renderLogin({ account, submitLogin }) {
if (account) return <div>{JSON.stringify(account)}</div>;
const details = {
name: '',
password: '',
};
return (
<div>
<div className="field">
<p className="control has-icons-left has-icons-right">
<input className="input" type="email" placeholder="Email" onChange={e => details.name = e.target.value} />
<span className="icon is-small is-left">
<i className="fas fa-user" />
</span>
<span className="icon is-small is-right">
<i className="fas fa-check" />
</span>
</p>
</div>
<div className="field">
<p className="control has-icons-left">
<input className="input" type="password" placeholder="Password" onChange={e => details.password = e.target.value} />
<span className="icon is-small is-left">
<i className="fas fa-lock" />
</span>
</p>
</div>
<div className="field">
<p className="control">
<button className="button is-success" type="submit" onClick={() => submitLogin(details.name, details.password)}>
Login
</button>
</p>
</div>
</div>
);
}
module.exports = renderLogin;

View File

@ -0,0 +1,16 @@
const { connect } = require('preact-redux');
const Login = require('./login.component');
const addState = connect(
function receiveState(state) {
const { ws } = state;
function submitLogin(name, password) {
return ws.sendAccountLogin(name, password);
}
return { account: state.account, submitLogin };
},
);
module.exports = addState(Login);

View File

@ -1,6 +0,0 @@
const preact = require('preact');
module.exports = ({ account }) => {
if (account) return <div>{JSON.stringify(account)}</div>;
return <div>not logged in</div>;
};

View File

@ -1,13 +0,0 @@
const { connect } = require('preact-redux');
const Status = require('./status.component');
// Add the incident from state as a property
const addState = connect(
state => ({ account: state.account }),
// dispatch => ({
// closeDetails() { dispatch(openIncident()); },
// }),
);
module.exports = addState(Status);

View File

@ -5,22 +5,27 @@ const { Provider } = require('preact-redux');
const { createStore, combineReducers } = require('redux'); const { createStore, combineReducers } = require('redux');
const reducers = require('./reducers'); const reducers = require('./reducers');
const actions = require('./actions');
const fizzyText = require('../lib/fizzy-text'); const fizzyText = require('../lib/fizzy-text');
const createSocket = require('./socket'); const createSocket = require('./socket');
const StatusContainer = require('./components/status.container'); const CrypContainer = require('./components/cryp.container');
const LoginContainer = require('./components/login.container');
const Navbar = require('./components/navbar'); const Navbar = require('./components/navbar');
// Redux Store // Redux Store
const store = createStore( const store = createStore(
combineReducers({ combineReducers({
account: reducers.accountReducer, account: reducers.accountReducer,
cryp: reducers.crypReducer,
ws: reducers.wsReducer,
}), }),
); );
store.subscribe(() => console.log(store.getState())); store.subscribe(() => console.log(store.getState()));
const ws = createSocket(store); const ws = createSocket(store);
store.dispatch(actions.setWs(ws));
// tells jdenticon to look for new svgs and render them // tells jdenticon to look for new svgs and render them
// so we don't have to setInnerHtml or manually call update // so we don't have to setInnerHtml or manually call update
@ -33,9 +38,9 @@ const Cryps = () => (
<section> <section>
<Navbar /> <Navbar />
<div id="fizzytext" /> <div id="fizzytext" />
<StatusContainer /> <LoginContainer />
<CrypContainer />
</section> </section>
); );
const Main = () => ( const Main = () => (

View File

@ -1,9 +1,29 @@
const { SET_ACCOUNT } = require('./actions'); const actions = require('./actions');
const defaultAccount = {}; const defaultAccount = null;
function accountReducer(state = defaultAccount, action) { function accountReducer(state = defaultAccount, action) {
switch (action.type) { switch (action.type) {
case SET_ACCOUNT: case actions.SET_ACCOUNT:
return action.value;
default:
return state;
}
}
const defaultCryp = null;
function crypReducer(state = defaultCryp, action) {
switch (action.type) {
case actions.SET_CRYP:
return action.value;
default:
return state;
}
}
const defaultWs = null;
function wsReducer(state = defaultWs, action) {
switch (action.type) {
case actions.SET_WS:
return action.value; return action.value;
default: default:
return state; return state;
@ -12,4 +32,6 @@ function accountReducer(state = defaultAccount, action) {
module.exports = { module.exports = {
accountReducer, accountReducer,
crypReducer,
wsReducer,
}; };

View File

@ -37,16 +37,26 @@ function createSocket(store) {
return send({ method: 'cryp_spawn', params: { name: 'drake' }}); return send({ method: 'cryp_spawn', params: { name: 'drake' }});
} }
function crypSpawn(cryp) { function crypSpawn(response) {
const [structName, cryp] = response;
console.log('got a new cryp', cryp); console.log('got a new cryp', cryp);
return store.dispatch(actions.setCryp(cryp));
} }
function sendAccountLogin(name, password) {
send({ method: 'account_login', params: { name, password } });
}
// when the server sends a reply it will have one of these message types
// this object wraps the reply types to a function
const handlers = { const handlers = {
cryp_spawn: crypSpawn, cryp_spawn: crypSpawn,
account_login: accountLogin, account_login: accountLogin,
account_create: accountLogin, account_create: accountLogin,
}; };
// decodes the cbor and
// calls the handlers defined above based on message type
function onMessage(event) { function onMessage(event) {
// decode binary msg from server // decode binary msg from server
const blob = new Uint8Array(event.data); const blob = new Uint8Array(event.data);
@ -62,7 +72,7 @@ function createSocket(store) {
// Connection opened // Connection opened
ws.addEventListener('open', function wsOpen(event) { ws.addEventListener('open', function wsOpen(event) {
// send({ method: 'account_create', params: { name: 'ntr', password: 'grepgrepgrep' }}); // send({ method: 'account_create', params: { name: 'ntr', password: 'grepgrepgrep' }});
send({ method: 'account_login', params: { name: 'ntr', password: 'grepgrepgrep' } }); // send({ method: 'account_login', params: { name: 'ntr', password: 'grepgrepgrep' } });
}); });
// Listen for messages // Listen for messages
@ -77,6 +87,10 @@ function createSocket(store) {
console.error('WebSocket closed', event); console.error('WebSocket closed', event);
account = null; account = null;
}); });
return {
sendAccountLogin,
};
} }
module.exports = createSocket; module.exports = createSocket;

View File

@ -1,13 +1,18 @@
* Battling * Battling
* Logins ✔️ * Logins ✔️
* Cryp Ownership * Cryp Ownership
* Matchmaking * Matchmaking
* Lobbies * Lobbies
* Create * Create
* Join * Join
* Resolve * Resolve
* Stats * Stats
* Scrabble grid
* Items
* Grid reroll
* Colour scheme
* Missions * Missions
* Bosses
* Cryp Generation * Cryp Generation
* *

View File

@ -1,5 +1,5 @@
use uuid::Uuid; use uuid::Uuid;
use bcrypt::{DEFAULT_COST, hash, verify}; use bcrypt::{hash, verify};
use rand::{thread_rng, Rng}; use rand::{thread_rng, Rng};
use rand::distributions::Alphanumeric; use rand::distributions::Alphanumeric;
use std::iter; use std::iter;
@ -61,7 +61,7 @@ pub fn create(params: AccountCreateParams, db: Db) -> Result<RpcResult, Error> {
if params.password.len() < PASSWORD_MIN_LEN { if params.password.len() < PASSWORD_MIN_LEN {
return Err(err_msg("password must be at least 12 characters")); return Err(err_msg("password must be at least 12 characters"));
} }
let password = hash(&params.password, DEFAULT_COST)?; let password = hash(&params.password, 4)?;
let mut rng = thread_rng(); let mut rng = thread_rng();
let token: String = iter::repeat(()) let token: String = iter::repeat(())