1
0
mirror of https://github.com/moparisthebest/kaiwa synced 2025-02-16 07:00:09 -05:00

All the things

This commit is contained in:
Lance Stout 2013-09-05 16:53:23 -07:00
parent f1bad70a14
commit c54bb6f7fe
21 changed files with 1840 additions and 109 deletions

View File

@ -13,48 +13,64 @@ var xmppEventHandlers = require('./helpers/xmppEventHandlers');
module.exports = {
launch: function () {
var self = this;
var self = window.app = this;
var config = localStorage.config;
if (!config) {
console.log('missing config');
window.location = '/login';
}
config = JSON.parse(config);
_.extend(this, Backbone.Events);
var app = window.app = this;
$(function () {
async.series([
function (cb) {
app.storage = new Storage();
app.storage.open(cb);
},
function (cb) {
var me = window.me = new MeModel();
new Router();
app.history = Backbone.history;
app.view = new MainView({
model: me,
el: document.body
});
app.view.render();
var client = window.client = app.client = XMPP.createClient({
rosterVer: localStorage.rosterVersion || undefined
});
xmppEventHandlers(client, app);
// we have what we need, we can now start our router and show the appropriate page
app.history.start({pushState: true, root: '/'});
async.series([
function (cb) {
app.storage = new Storage();
app.storage.open(cb);
},
function (cb) {
app.storage.rosterver.get(config.jid, function (err, ver) {
if (ver) {
config.rosterVer = ver;
}
cb();
}
]);
});
});
},
function (cb) {
window.me = new MeModel();
self.api = window.client = XMPP.createClient(config);
xmppEventHandlers(self.api, self);
self.api.connect();
self.api.once('session:started', function () {
cb();
});
},
function (cb) {
new Router();
app.history = Backbone.history;
self.view = new MainView({
model: me,
el: document.body
});
self.view.render();
// we have what we need, we can now start our router and show the appropriate page
app.history.start({pushState: true, root: '/'});
cb();
}
]);
},
whenConnected: function (func) {
if (client.sessionStarted) {
if (app.api.sessionStarted) {
func();
} else {
client.once('session:started', func);
app.api.once('session:started', func);
}
},
navigate: function (page) {

View File

@ -16,13 +16,42 @@ module.exports = function (client, app) {
log.debug(name, data);
});
client.on('credentials:update', function (creds) {
client.config.credentials = creds;
if (creds.clientKey && creds.serverKey) {
delete creds.password;
delete creds.saltedPassword;
} else if (creds.saltedPassword) {
delete creds.password;
}
localStorage.config = JSON.stringify({
jid: client.config.jid,
server: client.config.server,
wsURL: client.config.wsURL,
credentials: creds
});
});
client.on('disconnected', function () {
me.connectionStatus = 'disconnected';
});
client.on('auth:failed', function () {
console.log('auth failed');
window.location = '/login';
});
client.on('session:started', function (jid) {
me.jid = jid;
me.connectionStatus = 'connected';
client.getRoster(function (err, resp) {
resp = resp.toJSON();
localStorage.rosterVersion = resp.roster.ver;
app.storage.rosterver.set(me.barejid, resp.roster.ver);
_.each(resp.roster.items, function (item) {
console.log(item);
@ -41,7 +70,7 @@ module.exports = function (client, app) {
iq = iq.toJSON();
var items = iq.roster.items;
localStorage.rosterVersion = iq.roster.ver;
app.storage.rosterver.set(me.barejid, iq.roster.ver);
_.each(items, function (item) {
var contact = me.getContact(item.jid);

View File

@ -127,6 +127,14 @@ function Client(opts) {
self.send(new SASL.Response({
value: mech.response(self.getCredentials())
}));
if (mech.cache) {
_.each(mech.cache, function (val, key) {
self.config.credentials[key] = btoa(val);
});
self.emit('credentials:update', self.config.credentials);
}
cb();
});
self.on('sasl:failure', 'sasl', function () {
@ -377,7 +385,16 @@ Client.prototype.getCredentials = function () {
serviceName: server
};
return _.extend(defaultCreds, creds);
var result = _.extend(defaultCreds, creds);
var cachedBinary = ['saltedPassword', 'clientKey', 'serverKey'];
cachedBinary.forEach(function (key) {
if (result[key]) {
result[key] = atob(result[key]);
}
});
return result;
};
Client.prototype.connect = function (opts) {
@ -4480,8 +4497,6 @@ EntityTime.prototype = {
toString: stanza.toString,
toJSON: stanza.toJSON,
get tzo() {
console.log(this.toString());
console.log(this.parent.toString());
var split, hrs, min;
var sign = -1;
var formatted = stanza.getSubText(this.xml, this.NS, 'tzo');
@ -4491,14 +4506,11 @@ EntityTime.prototype = {
}
if (formatted.charAt(0) === '-') {
sign = 1;
formatted = formatted.slice(1);
formatted.slice(1);
}
split = formatted.split(':');
console.log(split);
hrs = parseInt(split[0], 10);
min = parseInt(split[1], 10);
console.log('hrs', hrs);
console.log('min', min);
return (hrs * 60 + min) * sign;
},
set tzo(value) {
@ -14405,8 +14417,16 @@ var Buffer=require("__browserify_Buffer").Buffer;// uuid.js
mech._clientFinalMessageWithoutProof = 'c=' + gs2Header + ',r=' + mech._nonce;
var saltedPassword = Hi(cred.password, mech._salt, mech._iterationCount);
var clientKey = HMAC(saltedPassword, 'Client Key');
var saltedPassword, clientKey, serverKey;
if (cred.clientKey && cred.serverKey) {
clientKey = cred.clientKey;
serverKey = cred.serverKey;
} else {
saltedPassword = cred.saltedPassword || Hi(cred.password, mech._salt, mech._iterationCount);
clientKey = HMAC(saltedPassword, 'Client Key');
serverKey = HMAC(saltedPassword, 'Server Key');
}
var storedKey = H(clientKey);
var authMessage = mech._clientFirstMessageBare + ',' +
mech._challenge + ',' +
@ -14416,7 +14436,6 @@ var Buffer=require("__browserify_Buffer").Buffer;// uuid.js
var xorstuff = XOR(clientKey, clientSignature);
var clientProof = new Buffer(xorstuff, 'binary').toString('base64');
var serverKey = HMAC(saltedPassword, 'Server Key');
mech._serverSignature = HMAC(serverKey, authMessage);
@ -14424,6 +14443,12 @@ var Buffer=require("__browserify_Buffer").Buffer;// uuid.js
mech._stage = 2;
mech.cache = {
saltedPassword: saltedPassword,
clientKey: clientKey,
serverKey: serverKey
};
return result;
};
responses[2] = function (mech, cred) {
@ -14832,4 +14857,4 @@ I(m)):b&&y(m);return h});f.assign=x;f.createCallback=function(a,d,b){if(null==a)
ja;f.forIn=W;f.keys=K;f.uniq=p;f.each=ja;f.extend=x;f.unique=p;f.identity=X;f.indexOf=ka;f.isArguments=v;f.isArray=T;f.isEqual=w;f.isFunction=D;f.isObject=ia;f.isString=ca;f.sortedIndex=la;f.VERSION="1.3.1";typeof define=="function"&&typeof define.amd=="object"&&define.amd?(G._=f, define(function(){return f})):N&&!N.nodeType?ma?(ma.exports=f)._=f:N._=f:G._=f})(this);
},{}]},{},[1])(1)
});
;
;

View File

@ -1,5 +1,5 @@
/*global XMPP, app, me, client*/
"use strict";
//"use strict";
var async = require('async');
var HumanModel = require('human-model');
@ -9,7 +9,7 @@ var Message = require('./message');
var crypto = XMPP.crypto;
module.exports = HumanModel.extend({
module.exports = HumanModel.define({
initialize: function (attrs) {
if (attrs.jid) {
this.cid = attrs.jid;
@ -20,6 +20,7 @@ module.exports = HumanModel.extend({
this.resources.bind('add remove reset change', this.resourceChange, this);
this.bind('change:lockedResource', this.fetchTimezone, this);
},
seal: true,
type: 'contact',
props: {
jid: ['string', true],

View File

@ -6,7 +6,7 @@ var Contacts = require('./contacts');
var Contact = require('./contact');
module.exports = HumanModel.extend({
module.exports = HumanModel.define({
session: {
jid: ['string', true, ''],
status: ['string', true, ''],

View File

@ -4,7 +4,7 @@
var HumanModel = require('human-model');
module.exports = HumanModel.extend({
module.exports = HumanModel.define({
initialize: function (attrs) {
this._created = Date.now();
},

View File

@ -3,7 +3,7 @@
var HumanModel = require('human-model');
module.exports = HumanModel.extend({
module.exports = HumanModel.define({
initialize: function () {},
type: 'resource',
session: {

View File

@ -1,44 +0,0 @@
/*global app, client*/
"use strict";
var BasePage = require('./base');
var templates = require('../templates');
module.exports = BasePage.extend({
template: templates.pages.signin,
events: {
'submit #loginForm form': 'login'
},
initialize: function (spec) {
this.renderAndBind();
},
login: function (e) {
e.preventDefault();
var jid = this.$('#jid').val();
var password = this.$('#password').val();
var wsURL = this.$('#wsURL').val();
client.connect({
jid: jid,
server: jid.slice(jid.indexOf('@') + 1),
wsURL: wsURL,
credentials: {
password: password
}
});
client.once('auth:success', 'signin', function () {
client.releaseGroup('signin');
app.navigate('/');
});
client.once('auth:failed', 'signin', function () {
client.releaseGroup('signin');
console.log('Failed Auth');
});
return false;
}
});

View File

@ -2,7 +2,6 @@
"use strict";
var Backbone = require('backbone');
var SigninPage = require('./pages/signin');
var MainPage = require('./pages/main');
var ChatPage = require('./pages/chat');
@ -10,15 +9,10 @@ var ChatPage = require('./pages/chat');
module.exports = Backbone.Router.extend({
routes: {
'': 'main',
'signin': 'signin',
'chat/:jid': 'chat'
'chat/:jid': 'chat',
'logout': 'logout'
},
// ------- ROUTE HANDLERS ---------
signin: function () {
app.renderPage(new SigninPage({
model: me
}));
},
main: function () {
app.renderPage(new MainPage({
model: me
@ -33,5 +27,9 @@ module.exports = Backbone.Router.extend({
} else {
app.navigate('/');
}
},
logout: function () {
localStorage.clear();
window.location = '/login';
}
});

View File

@ -5,6 +5,7 @@ var AvatarStorage = require('./avatars');
var RosterStorage = require('./roster');
var DiscoStorage = require('./disco');
var ArchiveStorage = require('./archive');
var RosterVerStorage = require('./rosterver');
function Storage() {
@ -15,6 +16,7 @@ function Storage() {
this.roster = new RosterStorage(this);
this.disco = new DiscoStorage(this);
this.archive = new ArchiveStorage(this);
this.rosterver = new RosterVerStorage(this);
}
Storage.prototype = {
constructor: {
@ -36,6 +38,7 @@ Storage.prototype = {
self.roster.setup(db);
self.disco.setup(db);
self.archive.setup(db);
self.rosterver.setup(db);
};
request.onerror = cb;
}

View File

@ -0,0 +1,63 @@
"use strict";
// SCHEMA
// jid: 'string',
// ver: 'string'
function RosterVerStorage(storage) {
this.storage = storage;
}
RosterVerStorage.prototype = {
constructor: {
value: RosterVerStorage
},
setup: function (db) {
db.createObjectStore('rosterver', {
keyPath: 'jid'
});
},
transaction: function (mode) {
var trans = this.storage.db.transaction('rosterver', mode);
return trans.objectStore('rosterver');
},
set: function (jid, ver, cb) {
cb = cb || function () {};
var data = {
jid: jid,
ver: ver
};
var request = this.transaction('readwrite').put(data);
request.onsuccess = function () {
cb(false, data);
};
request.onerror = cb;
},
get: function (jid, cb) {
cb = cb || function () {};
if (!jid) {
return cb('not-found');
}
var request = this.transaction('readonly').get(jid);
request.onsuccess = function (e) {
var res = request.result;
if (res === undefined) {
return cb('not-found');
}
cb(false, request.result);
};
request.onerror = cb;
},
remove: function (jid, cb) {
cb = cb || function () {};
var request = this.transaction('readwrite')['delete'](id);
request.onsuccess = function (e) {
cb(false, request.result);
};
request.onerror = cb;
}
};
module.exports = RosterVerStorage;

View File

@ -18,7 +18,6 @@ module.exports = HumanView.extend({
return this;
},
handleLinkClick: function (e) {
console.log(e);
var t = $(e.target);
var aEl = t.is('a') ? t[0] : t.closest('a')[0];
var local = window.location.host === aEl.host;

View File

@ -2,7 +2,9 @@
"isDev": true,
"http": {
"baseUrl": "https://localhost:8000",
"port": 8000
"port": 8000,
"key": "./fakekeys/privatekey.pem",
"cert": "./fakekeys/certificate.pem"
},
"session": {
"secret": "shhhhhh don't tell anyone ok?"

View File

@ -18,8 +18,8 @@
"node-uuid": "1.4.1",
"semi-static": "0.0.4",
"sound-effect-manager": "0.0.5",
"human-model": "0.3.0",
"human-view": "1.1.0",
"human-model": "1.0.0",
"human-view": "1.1.2",
"templatizer": "0.1.2",
"underscore": "1.5.1"
},

19
public/login.js Normal file
View File

@ -0,0 +1,19 @@
$('#loginbox form').on('submit', function (e) {
var jid = $('#jid').val();
var password = $('#password').val();
var wsURL = $('#wsURL').val();
localStorage.config = JSON.stringify({
jid: jid,
server: jid.slice(jid.indexOf('@') + 1),
wsURL: wsURL,
credentials: {
password: password
}
});
window.location = '/';
e.preventDefault();
return false;
});

4
public/logout.js Normal file
View File

@ -0,0 +1,4 @@
$(function () {
localStorage.clear();
window.location = '/login';
});

1565
public/zepto.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,5 @@
var fs = require('fs');
var https = require('https');
var express = require('express');
var helmet = require('helmet');
var Moonboots = require('moonboots');
@ -36,10 +38,21 @@ var clientApp = new Moonboots({
}
});
app.set('view engine', 'jade');
app.get('/login', function (req, res) {
res.render('login');
});
app.get('/logout', function (req, res) {
res.render('logout');
});
// serves app on every other url
app.get('*', clientApp.html());
app.listen(config.http.port);
https.createServer({
key: fs.readFileSync(config.http.key),
cert: fs.readFileSync(config.http.cert)
}, app).listen(config.http.port);
console.log('demo.stanza.io running at: ' + config.http.baseUrl);

14
views/layout.jade Normal file
View File

@ -0,0 +1,14 @@
!!!5
html
head
title OTalk
meta(name="viewport", content="width=device-width, initial-scale=1, user-scalable=no")
link(rel="stylesheet", href="/styles.css")
block head
body
block content
script(src='/zepto.js')
block scripts

20
views/login.jade Normal file
View File

@ -0,0 +1,20 @@
extends layout
block content
section#loginbox.content
h2 Log in
form
.fieldContainer
label(for='username') JID
input(type='text', id='jid', name='jid', placeholder='you@aweso.me', tabindex='1', autofocus)
.fieldContainer
label(for='password') Password
input(type='password', id='password', name='password', placeholder='•••••••••••••', tabindex='2')
.fieldContainer
label(for='wsURL') WebSocket URL
input(type='text', id='wsURL', name='wsURL', placeholder='wss://aweso.me:5281/xmpp-websocket', tabindex='3')
button(type='submit', tabindex='3') Go!
block scripts
script(src="/login.js")

4
views/logout.jade Normal file
View File

@ -0,0 +1,4 @@
extends layout
block scripts
script(src="/logout.js")