before
This commit is contained in:
parent
8fb7a3ae1e
commit
a78b796c55
21
client/.eslintrc.js
Executable file
21
client/.eslintrc.js
Executable file
@ -0,0 +1,21 @@
|
||||
module.exports = {
|
||||
extends: 'airbnb-base',
|
||||
rules: {
|
||||
// prevents stupid complaints a la
|
||||
// (req) {
|
||||
// req.something = x;
|
||||
// }
|
||||
'no-param-reassign': [2, {
|
||||
props: false,
|
||||
}],
|
||||
'no-multi-spaces': [0],
|
||||
'max-len': ['error', 120],
|
||||
'import/no-extraneous-dependencies': [0],
|
||||
'prefer-arrow-callback': [0],
|
||||
'arrow-body-style': [0],
|
||||
'no-console': [0],
|
||||
// i like loops
|
||||
'no-plusplus': [0],
|
||||
'no-await-in-loop': [0],
|
||||
},
|
||||
};
|
||||
@ -1,3 +1,5 @@
|
||||
const { toast } = require('bulma-toast');
|
||||
|
||||
const cbor = require('borc');
|
||||
const assert = require('assert');
|
||||
// Create WebSocket connection.
|
||||
@ -8,13 +10,22 @@ ws.binaryType = 'arraybuffer';
|
||||
// https://www.christian-schneider.net/CrossSiteWebSocketHijacking.html
|
||||
let user = null;
|
||||
|
||||
function error_toast(err) {
|
||||
console.error(err);
|
||||
return toast({
|
||||
message: err,
|
||||
type: "is-warning",
|
||||
duration: 5000,
|
||||
});
|
||||
}
|
||||
|
||||
function user_login(res) {
|
||||
[struct, created] = res;
|
||||
[struct, user] = res;
|
||||
|
||||
user = created;
|
||||
user = user;
|
||||
|
||||
console.log(created);
|
||||
return send({ method: 'cryp_spawn', params: { level: 64 }});
|
||||
console.log(user);
|
||||
return send({ method: 'cryp_spawn', params: { name: 'drake' }});
|
||||
}
|
||||
|
||||
function new_cryp(cryp) {
|
||||
@ -27,8 +38,14 @@ const handlers = {
|
||||
'user_create': user_login,
|
||||
};
|
||||
|
||||
function receive(res) {
|
||||
if (res.err) return console.error(res.err);
|
||||
function on_message(event) {
|
||||
// decode binary msg from server
|
||||
const blob = new Uint8Array(event.data);
|
||||
const res = cbor.decode(blob);
|
||||
console.log(res);
|
||||
|
||||
// check for error and split into response type and data
|
||||
if (res.err) return error_toast(res.err);
|
||||
const { method, params } = res;
|
||||
return handlers[method](params);
|
||||
}
|
||||
@ -40,17 +57,12 @@ function send(msg) {
|
||||
|
||||
// Connection opened
|
||||
ws.addEventListener('open', function (event) {
|
||||
send({ method: 'user_login', params: { name: 'somebodyelse', password: 'grepgrepgrep' }});
|
||||
// send({ method: 'user_create', params: { name: 'ntr', password: 'grepgrepgrep' }});
|
||||
send({ method: 'user_login', params: { name: 'ntr', password: 'grepgrepgrep' }});
|
||||
});
|
||||
|
||||
// Listen for messages
|
||||
ws.addEventListener('message', function (event) {
|
||||
console.log('Message from server ', event.data);
|
||||
const blob = new Uint8Array(event.data);
|
||||
const decoded = cbor.decode(blob);
|
||||
console.log(decoded);
|
||||
return receive(decoded);
|
||||
});
|
||||
ws.addEventListener('message', on_message);
|
||||
|
||||
ws.addEventListener('error', function (event) {
|
||||
console.error('WebSocket error', event);
|
||||
|
||||
@ -11,6 +11,12 @@
|
||||
"license": "UNLICENSED",
|
||||
"dependencies": {
|
||||
"borc": "^2.0.3",
|
||||
"parcel": "^1.9.7"
|
||||
"bulma-toast": "^1.2.0",
|
||||
"parcel": "^1.9.7",
|
||||
"docco": "^0.7.0",
|
||||
"eslint": "^3.18.0",
|
||||
"eslint-config-airbnb-base": "^11.1.1",
|
||||
"eslint-plugin-import": "^2.2.0",
|
||||
"jest": "^18.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
exports.up = async knex => {
|
||||
return knex.schema.createTable('users', table => {
|
||||
return knex.schema.createTable('accounts', table => {
|
||||
table.uuid('id').primary();
|
||||
table.string('name', 42).notNullable().unique();
|
||||
table.string('password').notNullable();
|
||||
14
ops/migrations/20180916221309_cryps_table.js
Executable file
14
ops/migrations/20180916221309_cryps_table.js
Executable file
@ -0,0 +1,14 @@
|
||||
exports.up = async knex => {
|
||||
return knex.schema.createTable('cryps', table => {
|
||||
table.uuid('id').primary();
|
||||
table.uuid('account').notNullable()
|
||||
table.foreign('account')
|
||||
.references('id')
|
||||
.inTable('accounts')
|
||||
.onDelete('CASCADE');
|
||||
table.binary('data').notNullable();
|
||||
table.index('id');
|
||||
});
|
||||
};
|
||||
|
||||
exports.down = async () => {};
|
||||
@ -1,5 +1,5 @@
|
||||
* Battling
|
||||
* Logins
|
||||
* Logins ✔️
|
||||
* Cryp Ownership
|
||||
* Matchmaking
|
||||
* Lobbies
|
||||
@ -19,5 +19,10 @@
|
||||
|
||||
teams
|
||||
|
||||
physical, magic, pure dmg?
|
||||
elemental?
|
||||
|
||||
items give skills
|
||||
|
||||
gem td style attr combinations
|
||||
stoney + spikey = jagged
|
||||
@ -1,7 +1,13 @@
|
||||
use uuid::Uuid;
|
||||
use rand::prelude::*;
|
||||
use serde_cbor::*;
|
||||
use serde_cbor::{to_vec};
|
||||
|
||||
use failure::Error;
|
||||
use failure::err_msg;
|
||||
|
||||
use net::Db;
|
||||
use user::User;
|
||||
use rpc::{CrypSpawnParams};
|
||||
use skill::{Skill};
|
||||
|
||||
@ -176,12 +182,32 @@ impl Cryp {
|
||||
|
||||
}
|
||||
|
||||
pub fn spawn(params: CrypSpawnParams) -> Cryp {
|
||||
Cryp::new()
|
||||
.named("hatchling".to_string())
|
||||
.level(params.level)
|
||||
.learn(Skill::Stoney)
|
||||
.create()
|
||||
pub fn spawn(params: CrypSpawnParams, db: Db, user: User) -> Result<Cryp, Error> {
|
||||
let cryp = Cryp::new()
|
||||
.named(params.name)
|
||||
.level(1)
|
||||
.create();
|
||||
|
||||
let cryp_bytes = to_vec(&cryp)?;
|
||||
|
||||
let query = "
|
||||
INSERT INTO cryps (id, user, data)
|
||||
VALUES ($1, $2, $3)
|
||||
RETURNING id, user;
|
||||
";
|
||||
|
||||
let tx = db.transaction()?;
|
||||
|
||||
let result = tx
|
||||
.query(query, &[&cryp.id, &user.id, &cryp_bytes])?;
|
||||
|
||||
let _returned = result.iter().next().expect("no row returned");
|
||||
|
||||
println!("{:?} spawned cryp {:}", user.id, cryp.id);
|
||||
|
||||
tx.commit()?;
|
||||
|
||||
return Ok(cryp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ static DB_POOL_SIZE: u32 = 20;
|
||||
|
||||
pub type Db = PooledConnection<PostgresConnectionManager>;
|
||||
|
||||
use rpc::{Rpc, RpcResult};
|
||||
use rpc::{Rpc};
|
||||
|
||||
struct Server {
|
||||
out: Sender,
|
||||
@ -39,6 +39,7 @@ impl Handler for Server {
|
||||
self.out.send(response)
|
||||
},
|
||||
Err(e) => {
|
||||
println!("{:?}", e);
|
||||
let response = to_vec(&RpcErrorResponse { err: e.to_string() })
|
||||
.expect("failed to serialize error response");
|
||||
self.out.send(response)
|
||||
|
||||
@ -5,7 +5,7 @@ use failure::err_msg;
|
||||
|
||||
use net::Db;
|
||||
use cryp::{Cryp, spawn};
|
||||
use user::{User, create, login};
|
||||
use user::{User, create, login, from_token};
|
||||
|
||||
pub struct Rpc;
|
||||
|
||||
@ -18,17 +18,27 @@ impl Rpc {
|
||||
match from_slice::<RpcMessage>(&data) {
|
||||
Ok(v) => {
|
||||
|
||||
println!("{:?}", v.token);
|
||||
let user: Option<User> = match v.token {
|
||||
Some(t) => Some(from_token(t, &db)?),
|
||||
None => None,
|
||||
};
|
||||
|
||||
println!("{:?}", user);
|
||||
|
||||
// now we have the method name
|
||||
// match on that to determine what fn to call
|
||||
match v.method.as_ref() {
|
||||
"cryp_spawn" => {
|
||||
match from_slice::<CrypSpawnMsg>(&data) {
|
||||
Ok(v) => Ok(RpcResponse {
|
||||
method: v.method,
|
||||
params: RpcResult::Cryp(spawn(v.params))
|
||||
}),
|
||||
Ok(v) => {
|
||||
match user {
|
||||
Some(u) => Ok(RpcResponse {
|
||||
method: v.method,
|
||||
params: RpcResult::SpawnCryp(spawn(v.params, db, u)?)
|
||||
}),
|
||||
None => Err(err_msg("auth required")),
|
||||
}
|
||||
}
|
||||
Err(_e) => Err(err_msg("invalid params")),
|
||||
}
|
||||
},
|
||||
@ -67,7 +77,7 @@ pub struct RpcResponse {
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
pub enum RpcResult {
|
||||
Cryp(Cryp),
|
||||
SpawnCryp(Cryp),
|
||||
User(User),
|
||||
}
|
||||
|
||||
@ -85,7 +95,7 @@ struct CrypSpawnMsg {
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
pub struct CrypSpawnParams {
|
||||
pub level: u8,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
|
||||
@ -12,10 +12,12 @@ use rpc::{UserCreateParams, UserLoginParams, RpcResult};
|
||||
use failure::Error;
|
||||
use failure::err_msg;
|
||||
|
||||
static PASSWORD_MIN_LEN: usize = 12;
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
pub struct User {
|
||||
id: Uuid,
|
||||
name: String,
|
||||
pub id: Uuid,
|
||||
pub name: String,
|
||||
token: String,
|
||||
}
|
||||
|
||||
@ -27,7 +29,31 @@ struct UserEntry {
|
||||
token: String,
|
||||
}
|
||||
|
||||
static PASSWORD_MIN_LEN: usize = 12;
|
||||
// MAYBE
|
||||
// hash tokens with a secret
|
||||
pub fn from_token(token: String, db: &Db) -> Result<User, Error> {
|
||||
let query = "
|
||||
SELECT id, name, token
|
||||
FROM users
|
||||
WHERE token = $1;
|
||||
";
|
||||
|
||||
let result = db
|
||||
.query(query, &[&token])?;
|
||||
|
||||
let returned = match result.iter().next() {
|
||||
Some(row) => row,
|
||||
None => return Err(err_msg("invalid token")),
|
||||
};
|
||||
|
||||
let entry = User {
|
||||
id: returned.get(0),
|
||||
name: returned.get(1),
|
||||
token: returned.get(2),
|
||||
};
|
||||
|
||||
return Ok(entry);
|
||||
}
|
||||
|
||||
pub fn create(params: UserCreateParams, db: Db) -> Result<RpcResult, Error> {
|
||||
let id = Uuid::new_v4();
|
||||
@ -73,7 +99,7 @@ pub fn create(params: UserCreateParams, db: Db) -> Result<RpcResult, Error> {
|
||||
|
||||
tx.commit()?;
|
||||
|
||||
Ok(RpcResult::User(entry))
|
||||
return Ok(RpcResult::User(entry));
|
||||
}
|
||||
|
||||
pub fn login(params: UserLoginParams, db: Db) -> Result<RpcResult, Error> {
|
||||
@ -83,13 +109,13 @@ pub fn login(params: UserLoginParams, db: Db) -> Result<RpcResult, Error> {
|
||||
WHERE name = $1;
|
||||
";
|
||||
|
||||
// let tx = db.transaction()?;
|
||||
|
||||
let result = db
|
||||
.query(query, &[¶ms.name])?;
|
||||
|
||||
let returned = match result.iter().next() {
|
||||
Some(row) => row,
|
||||
// MAYBE
|
||||
// verify gibberish to delay response for timing attacks
|
||||
None => return Err(err_msg("user not found")),
|
||||
};
|
||||
|
||||
@ -110,13 +136,11 @@ pub fn login(params: UserLoginParams, db: Db) -> Result<RpcResult, Error> {
|
||||
// update token?
|
||||
// don't necessarily want to log every session out when logging in
|
||||
|
||||
// tx.commit()?;
|
||||
|
||||
let user = User {
|
||||
id: entry.id,
|
||||
name: entry.name,
|
||||
token: entry.token,
|
||||
};
|
||||
|
||||
Ok(RpcResult::User(user))
|
||||
return Ok(RpcResult::User(user));
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user