mirror of
https://github.com/mclueppers/xo-server.git
synced 2025-07-27 07:54:54 +02:00
Various updates.
This commit is contained in:
parent
2134e3b4d1
commit
16667e0d40
37
src/api.js
37
src/api.js
@ -144,9 +144,6 @@ Api.fn.session = {
|
||||
}
|
||||
|
||||
return this.users.findWhere({'email': p_email}).then(function (user) {
|
||||
|
||||
console.log(user);
|
||||
|
||||
if (!user)
|
||||
{
|
||||
throw Api.err.INVALID_CREDENTIAL;
|
||||
@ -177,15 +174,17 @@ Api.fn.session = {
|
||||
throw Api.err.ALREADY_AUTHENTICATED;
|
||||
}
|
||||
|
||||
var token = this.tokens.get(p_token);
|
||||
return this.tokens.get(p_token).then(function (token) {
|
||||
if (!token)
|
||||
{
|
||||
throw Api.err.INVALID_CREDENTIAL;
|
||||
}
|
||||
|
||||
session.set('token_id', token.id);
|
||||
session.set('user_id', token.user_id);
|
||||
session.set('token_id', token.get('id'));
|
||||
session.set('user_id', token.get('user_id'));
|
||||
return true;
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
'getUser': deprecated(function (session) {
|
||||
@ -195,7 +194,9 @@ Api.fn.session = {
|
||||
return null;
|
||||
}
|
||||
|
||||
return _.pick(this.users.get(user_id), 'id', 'email');
|
||||
return this.users.get(user_id).then(function (user) {
|
||||
return _.pick(user.properties, 'id', 'email');
|
||||
});
|
||||
}),
|
||||
|
||||
'getUserId': function (session) {
|
||||
@ -296,13 +297,8 @@ Api.fn.user = {
|
||||
|
||||
return users.update(user);
|
||||
}).then(
|
||||
function () {
|
||||
return true;
|
||||
},
|
||||
function () {
|
||||
// @todo Find a better error.
|
||||
return Api.err.INVALID_PARAMS;
|
||||
}
|
||||
true,
|
||||
Q.reject(Api.err.INVALID_PARAMS)
|
||||
);
|
||||
},
|
||||
};
|
||||
@ -320,7 +316,7 @@ Api.fn.token = {
|
||||
|
||||
// @todo Token permission.
|
||||
|
||||
this.tokens.generate(user_id).then(function (token) {
|
||||
return this.tokens.generate(user_id).then(function (token) {
|
||||
return token.get('id');
|
||||
});
|
||||
},
|
||||
@ -328,13 +324,14 @@ Api.fn.token = {
|
||||
'delete': function (session, req) {
|
||||
var p_token = req.params.token;
|
||||
|
||||
if (!this.tokens.get(p_token))
|
||||
var tokens = this.tokens;
|
||||
return tokens.get(p_token).then(function (token) {
|
||||
if (!token)
|
||||
{
|
||||
throw Api.err.INVALID_PARAMS;
|
||||
}
|
||||
|
||||
return this.tokens.remove(p_token).then(function () {
|
||||
return true;
|
||||
return tokens.remove(p_token).then(true);
|
||||
});
|
||||
},
|
||||
};
|
||||
@ -398,9 +395,7 @@ Api.fn.server = {
|
||||
|
||||
// @todo Disconnect the server.
|
||||
|
||||
return this.servers.remove(p_id).then(function () {
|
||||
return true;
|
||||
});
|
||||
return this.servers.remove(p_id).then(true);
|
||||
},
|
||||
|
||||
'connect': function () {
|
||||
|
@ -4,18 +4,18 @@ var Q = require('q');
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// @todo Add events.
|
||||
function Collection(items)
|
||||
function Collection(models)
|
||||
{
|
||||
// Parent constructor.
|
||||
Collection.super_.call(this);
|
||||
|
||||
this.items = [];
|
||||
this.models = [];
|
||||
|
||||
this.next_id = 0;
|
||||
|
||||
if (items)
|
||||
if (models)
|
||||
{
|
||||
this.add(items);
|
||||
this.add(models);
|
||||
}
|
||||
}
|
||||
require('util').inherits(Collection, require('events').EventEmitter);
|
||||
@ -23,56 +23,69 @@ require('util').inherits(Collection, require('events').EventEmitter);
|
||||
Collection.prototype.model = require('./model');
|
||||
|
||||
/**
|
||||
* Adds new items to this collection.
|
||||
* Adds new models to this collection.
|
||||
*/
|
||||
Collection.prototype.add = function (items) {
|
||||
Collection.prototype.add = function (models) {
|
||||
var array = true;
|
||||
if (!_.isArray(items))
|
||||
if (!_.isArray(models))
|
||||
{
|
||||
items = [items];
|
||||
models = [models];
|
||||
array = false;
|
||||
}
|
||||
|
||||
_.each(items, function (item, i) {
|
||||
if ( !(item instanceof this.model) )
|
||||
_.each(models, function (model, i) {
|
||||
if ( !(model instanceof this.model) )
|
||||
{
|
||||
item = new (this.model)(item);
|
||||
items[i] = item;
|
||||
model = new this.model(model);
|
||||
models[i] = model;
|
||||
}
|
||||
|
||||
var error = item.validate();
|
||||
var error = model.validate();
|
||||
if (undefined !== error)
|
||||
{
|
||||
// @todo Better system inspired by Backbone.js.
|
||||
throw error;
|
||||
}
|
||||
|
||||
var id = item.get('id');
|
||||
var id = model.get('id');
|
||||
|
||||
if (undefined === id)
|
||||
{
|
||||
id = this.next_id++;
|
||||
item.set('id', id);
|
||||
model.set('id', id);
|
||||
}
|
||||
|
||||
// Existing items are ignored.
|
||||
if (this.items[id])
|
||||
// Existing models are ignored.
|
||||
if (this.models[id])
|
||||
{
|
||||
return Q.reject('cannot add existing items!');
|
||||
return Q.reject('cannot add existing models!');
|
||||
}
|
||||
|
||||
this.items[id] = item.properties;
|
||||
this.models[id] = model.properties;
|
||||
}, this);
|
||||
|
||||
/* jshint newcap: false */
|
||||
return Q(array ? items : items[0]);
|
||||
return Q(array ? models : models[0]);
|
||||
};
|
||||
|
||||
Collection.prototype.get = function (id) {
|
||||
/* jshint newcap:false */
|
||||
|
||||
var model = this.models[id];
|
||||
|
||||
if (!model)
|
||||
{
|
||||
return Q(null);
|
||||
}
|
||||
|
||||
return Q(new this.model(model));
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
Collection.prototype.exists = function (id) {
|
||||
return (undefined !== this.items[id]);
|
||||
return (undefined !== this.models[id]);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -81,11 +94,13 @@ Collection.prototype.exists = function (id) {
|
||||
Collection.prototype.findWhere = function (properties) {
|
||||
/* jshint newcap: false */
|
||||
|
||||
return Q(_.findWhere(this.items, properties));
|
||||
var model = _.findWhere(this.models, properties);
|
||||
|
||||
return Q(model ? new this.model(model) : null);
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes items from this collection.
|
||||
* Removes models from this collection.
|
||||
*/
|
||||
Collection.prototype.remove = function (ids) {
|
||||
if (!_.isArray(ids))
|
||||
@ -94,8 +109,8 @@ Collection.prototype.remove = function (ids) {
|
||||
}
|
||||
|
||||
_.each(ids, function (id) {
|
||||
delete this.items[id];
|
||||
});
|
||||
delete this.models[id];
|
||||
}, this);
|
||||
|
||||
// @todo Maybe return a more meaningful value.
|
||||
/* jshint newcap: false */
|
||||
@ -103,24 +118,25 @@ Collection.prototype.remove = function (ids) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates existing items.
|
||||
* Updates existing models.
|
||||
*/
|
||||
Collection.prototype.update = function (items) {
|
||||
Collection.prototype.update = function (models) {
|
||||
var array = true;
|
||||
if (!_.isArray(items))
|
||||
if (!_.isArray(models))
|
||||
{
|
||||
items = [items];
|
||||
models = [models];
|
||||
array = false;
|
||||
}
|
||||
|
||||
_.each(items, function (properties, i) {
|
||||
// @todo Rewrite.
|
||||
_.each(models, function (properties, i) {
|
||||
if (properties instanceof this.model)
|
||||
{
|
||||
properties = properties.properties;
|
||||
}
|
||||
|
||||
// @todo
|
||||
// var error = item.validate();
|
||||
// var error = model.validate();
|
||||
// if (undefined !== error)
|
||||
// {
|
||||
// // @todo Better system inspired by Backbone.js.
|
||||
@ -129,31 +145,31 @@ Collection.prototype.update = function (items) {
|
||||
|
||||
var id = properties.id;
|
||||
|
||||
var item = this.items[id];
|
||||
var model = this.models[id];
|
||||
|
||||
// Missing items are ignored.
|
||||
if (!item)
|
||||
// Missing models are ignored.
|
||||
if (!model)
|
||||
{
|
||||
return Q.reject('missing item!');
|
||||
return Q.reject('missing model!');
|
||||
}
|
||||
|
||||
item.set(properties);
|
||||
_.extend(model.properties, model);
|
||||
|
||||
items[i] = item;
|
||||
models[i] = model;
|
||||
});
|
||||
|
||||
/* jshint newcap: false */
|
||||
return Q(array ? items : items[0]);
|
||||
return Q(array ? models : models[0]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Smartly updates the collection.
|
||||
*
|
||||
* - Adds new items.
|
||||
* - Updates existing items.
|
||||
* - Removes missing items.
|
||||
* - Adds new models.
|
||||
* - Updates existing models.
|
||||
* - Removes missing models.
|
||||
*/
|
||||
Collection.prototype.set = function (/*items*/) {
|
||||
Collection.prototype.set = function (/*models*/) {
|
||||
throw 'not implemented';
|
||||
};
|
||||
|
||||
|
12
src/main.js
12
src/main.js
@ -63,7 +63,15 @@ function json_api_call(session, message)
|
||||
'id': req.id,
|
||||
});
|
||||
},
|
||||
format_error
|
||||
function (error) {
|
||||
if (error instanceof Error)
|
||||
{
|
||||
console.error(error);
|
||||
return format_error(Api.err.SERVER_ERROR);
|
||||
}
|
||||
|
||||
return format_error(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@ -149,4 +157,4 @@ require('net').createServer(function (socket) {
|
||||
socket.once('close', function () {
|
||||
session.close();
|
||||
});
|
||||
}).listen(__dirname +'/../socket'); // @todo Should be configurable.
|
||||
}).listen(8081); // @todo Should be configurable.
|
||||
|
@ -7,7 +7,7 @@ function Model(properties)
|
||||
// Parent constructor.
|
||||
Model.super_.call(this);
|
||||
|
||||
this.properties = this['default'];
|
||||
this.properties = _.extend({}, this['default']);
|
||||
|
||||
if (properties)
|
||||
{
|
||||
|
57
src/xo.js
57
src/xo.js
@ -35,12 +35,12 @@ var check = function () {
|
||||
// user.permission).
|
||||
var Token = Model.extend({
|
||||
// Validates model attributes.
|
||||
'validate': function (attr) {
|
||||
check(attr.id).len(10);
|
||||
check(attr.user_id).isInt();
|
||||
// 'validate': function (attr) {
|
||||
// check(attr.id).len(10);
|
||||
// check(attr.user_id).isInt();
|
||||
|
||||
return check.pop();
|
||||
},
|
||||
// return check.pop();
|
||||
// },
|
||||
}, {
|
||||
'generate': function (user_id) {
|
||||
return Q.ninvoke(crypto, 'randomBytes', 32).then(function (buf) {
|
||||
@ -57,26 +57,21 @@ var User = Model.extend({
|
||||
'permission': 'none',
|
||||
},
|
||||
|
||||
'initialize': function ()
|
||||
{
|
||||
this.on('change:password', function (model, password) {
|
||||
this.unset('password', {'silent': true});
|
||||
|
||||
var user = this;
|
||||
hashy.hash(password).then(function (hash) {
|
||||
user.set('pw_hash', hash);
|
||||
}).done();
|
||||
});
|
||||
},
|
||||
|
||||
// Validates model attributes.
|
||||
'validate': function (attr) {
|
||||
check(attr.id).isInt();
|
||||
check(attr.email).isEmail();
|
||||
check(attr.pw_hash).len(40);
|
||||
check(attr.permission).isIn('none', 'read', 'write', 'admin');
|
||||
// 'validate': function (attr) {
|
||||
// check(attr.id).isInt();
|
||||
// check(attr.email).isEmail();
|
||||
// check(attr.pw_hash).len(40);
|
||||
// check(attr.permission).isIn('none', 'read', 'write', 'admin');
|
||||
|
||||
return check.pop();
|
||||
// return check.pop();
|
||||
// },
|
||||
|
||||
'setPassword': function (password) {
|
||||
var self = this;
|
||||
return hashy.hash(password).then(function (hash) {
|
||||
self.set('pw_hash', hash);
|
||||
});
|
||||
},
|
||||
|
||||
// Checks and updates the hash if necessary.
|
||||
@ -92,8 +87,10 @@ var User = Model.extend({
|
||||
|
||||
if (hashy.needsRehash(hash))
|
||||
{
|
||||
user.set('password', password);
|
||||
return user.setPassword(password).then(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
},
|
||||
|
||||
@ -122,8 +119,10 @@ var Tokens = Collection.extend({
|
||||
'model': Token,
|
||||
|
||||
'generate': function (user_id) {
|
||||
return this.model.generate(user_id).then(function (token) {
|
||||
return this.add(token);
|
||||
var self = this;
|
||||
|
||||
return Token.generate(user_id).then(function (token) {
|
||||
return self.add(token);
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -143,6 +142,10 @@ function Xo()
|
||||
this.servers = new Servers();
|
||||
this.tokens = new Tokens();
|
||||
this.users = new Users();
|
||||
this.users.add({
|
||||
'email': 'bob@gmail.com',
|
||||
'pw_hash': '$2a$10$PsSOXflmnNMEOd0I5ohJQ.cLty0R29koYydD0FBKO9Rb7.jvCelZq',
|
||||
}).done();
|
||||
|
||||
// This events are used to automatically close connections if the
|
||||
// associated credentials are invalidated.
|
||||
@ -157,7 +160,7 @@ function Xo()
|
||||
});
|
||||
});
|
||||
}
|
||||
require('util').inherits(Collection, require('events').EventEmitter);
|
||||
require('util').inherits(Xo, require('events').EventEmitter);
|
||||
|
||||
module.exports = function () {
|
||||
return new Xo();
|
||||
|
Loading…
x
Reference in New Issue
Block a user