Permalink
Browse files

Refactored, renamed, and added a few test cases.

  • Loading branch information...
1 parent 9d33262 commit a23a8138f057b725f28c108c046055594b9e1080 @eschnou committed Mar 6, 2011
View
@@ -61,6 +61,7 @@ var _result = function(result) {
for(key in result) {
console.log(key + ": " + result[key]);
}
+ console.log(result);
}
};
File renamed without changes.
@@ -46,7 +46,7 @@ function render(host, updates, profile, callback) {
});
}
-function getFeed(url, callback) {
+function fromUrl(url, callback) {
console.log("Requesting atom feed at " + url);
Flow.exec(
function() {
@@ -55,7 +55,7 @@ function getFeed(url, callback) {
function(err,response,body) {
if (err) return callback(err);
if (response.statusCode != 200) return callback(new Error("Http request returned status " + response.statusCode));
- parseFeed(body, this);
+ fromXml(body, this);
},
function(err, activities) {
if (err) return callback(err);
@@ -65,7 +65,7 @@ function getFeed(url, callback) {
);
}
-function parseFeed(body, callback) {
+function fromXml(body, callback) {
try {
var doc = Xml.parseFromString(body);
var childNodes = doc.documentElement.childNodes;
@@ -179,6 +179,6 @@ function _parseUpdated(node, entry) {
return entry;
}
-exports.getFeed = getFeed;
-exports.parseFeed = parseFeed;
+exports.fromUrl = fromUrl;
+exports.fromXml = fromXml;
exports.render = render;
View
@@ -23,7 +23,7 @@
*/
var Hcard = require("./hcard")
-, Atom = require("./atom")
+, As = require("./as")
, Webfinger = require("./webfinger");
function activities(identifier, callback) {
@@ -41,7 +41,7 @@ function activities(identifier, callback) {
for (i=0;i<links.length;i++) {
var link = links[i];
if (link.rel == "http://schemas.google.com/g/2010#updates-from") {
- Atom.getFeed(link.href, callback);
+ As.fromUrl(link.href, callback);
}
}
});
View
@@ -29,9 +29,10 @@ var helper = require('./helper.js')
Mu.root = Path.join(__dirname,'./templates');
// Exports
-exports.atom = require('./atom.js');
+exports.as = require('./as.js');
exports.push = require('./push.js');
exports.hcard = require('./hcard.js');
exports.webfinger = require('./webfinger.js');
+exports.salmon = require('./salmon.js');
exports.activities = helper.activities;
exports.profile = helper.profile;
View
@@ -0,0 +1,83 @@
+/*
+ * node-ostatus - An implementation of OStatus for node.js
+ *
+ * Copyright (C) 2010 Laurent Eschenauer <laurent@eschenauer.be>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+*/
+
+var Sys = require('sys'),
+ Url = require('url'),
+ Flow = require('flow'),
+ Util = require('util'),
+ Http = require('./http.js'),
+ Xml = require('o3-xml');
+ Path = require('path'),
+ Mu = require('mu');
+ Base64 = require('base64');
+ Buffer = require('buffer').Buffer;
+
+function unpack(body, callback) {
+ try {
+ var doc = Xml.parseFromString(body);
+ var childNodes = doc.documentElement.childNodes;
+ var result = {};
+ result.sigs = [];
+ for ( var i = 0; i < childNodes.length; i++) {
+ var node = childNodes[i];
+ var name = node.nodeName;
+ if (name == "data") {
+ result.data = node.nodeValue;
+ if (attribute = node.attributes.getNamedItem("type")) result["data_type"] = attribute.value;
+ } else if (name == "sig") {
+ var sig = {"value": node.nodeValue};
+ if (attribute = node.attributes.getNamedItem("key_id")) sig["key_id"] = attribute.value;
+ result.sigs.push(sig);
+ } else {
+ var value = node.nodeValue;
+ result[name] = value;
+ }
+ }
+ callback(null, result);
+ } catch (exception) {
+ callback(exception);
+ }
+}
+
+function verify_signature(data, data_type, encoding, alg, cert, signature) {
+ var m = data + "." + base64url_encode(data_type) + "." + base64url_encode(encoding) + "." + base64url_encode(alg);
+ var v = crypto.createVerify('RSA-SHA256');
+ v.update(m);
+ return v.verify(cert, signature);
+}
+
+//From: https://github.com/ptarjan/base64url/blob/master/node.js
+function base64url_decode(input) {
+ return Base64.decode(input.replace(/-/g, '+').replace(/_/g, '/'));
+}
+
+function base64url_encode(input) {
+ var buf = new Buffer(input);
+ return Base64.encode(buf).replace(/\+/g, '-').replace(/\//g, '_');
+}
+
+exports.unpack = unpack;
+exports.base64url_decode = base64url_decode;
+exports.base64url_encode = base64url_encode;
+exports.verify_signature = verify_signature;
View
@@ -5,7 +5,7 @@
, "keywords": ["ostatus", "hcard", "pubsubhubbub", "atom", "activity", "salmon"]
, "homepage": "http://github.com/eschnou/node-ostatus"
, "author": "Laurent Eschenauer <laurent@eschenauer.be> (http://eschnou.com)"
-, "bin" : { "status" : "./bin/status.js", "profile": "./bin/profile.js", "wfinger": "./bin/wfinger.js"}
+, "bin" : { "status" : "./bin/status.js", "profile": "./bin/profile.js", "webfinger": "./bin/webfinger.js"}
, "main" : "./lib/ostatus"
, "repository" : { "type": "git", "url": "https://github.com/eschnou/node-ostatus.git"}
, "dependencies" : {
View
@@ -0,0 +1,38 @@
+var assert = require('assert');
+var fs = require('fs');
+var path = require('path');
+var ostatus = require('ostatus');
+var xml = fs.readFileSync(path.join(__dirname, 'test-as.xml'), 'utf-8');
+
+function test_render() {
+ ostatus.as.render("http://example.com", activities, profile, function(err, result) {
+ assert.equal(result, xml, "Xml output did not match expected result.");
+ });
+}
+
+var activities = [
+ {
+ id: "tag:eschnou@shoutr.org,2011-03-06:FKZbF1nx",
+ title: "Hello, World",
+ content: "Hello, <b>World</b>",
+ verb: "post",
+ type:"note",
+ updated:"2011-03-06T15:02:56"
+ },
+ {
+ id: "tag:eschnou@shoutr.org,2011-03-07:FKdgfF1nx",
+ title: "Another one for the road.",
+ content: "Another one for the road.",
+ verb: "post",
+ type:"note",
+ updated:"2011-03-07T09:02:56"
+ }
+];
+
+var profile = {
+ username: "eschnou",
+ fullname: "Laurent Eschenauer",
+ avatar: "http://shoutr.org/avatar/eschnou.jpg"
+};
+
+test_render();
View
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:georss="http://www.georss.org/georss" xmlns:activity="http://activitystrea.ms/spec/1.0/" xmlns:media="http://purl.org/syndication/atommedia" xmlns:poco="http://portablecontacts.net/spec/1.0" xmlns:ostatus="http://ostatus.org/schema/1.0" xmlns:statusnet="http://status.net/schema/api/1/">
+ <id>http://http://example.com/updates/eschnou.atom</id>
+ <title>Latest updates from Laurent Eschenauer</title>
+ <updated>2011-03-06T15:02:56</updated>
+ <link rel="alternate" href="http://http://example.com/users/eschnou" type="text/html"/>
+ <link rel="hub" href="http://http://example.com/push/hub" />
+ <link rel="salmon" href="http://http://example.com/salmon/user/eschnou" />
+ <link rel="self" href="http://http://example.com/updates/eschnou.atom" type="application/atom+xml"/>
+ <author>
+ <name>Laurent Eschenauer</name>
+ <uri>http://http://example.com/users/eschnou</uri>
+ </author>
+ <activity:subject>
+ <activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
+ <id>http://http://example.com/users/eschnou</id>
+ <title>Laurent Eschenauer</title>
+ <link rel="alternate" type="text/html" href="http://http://example.com/users/eschnou"/>
+ <link rel="avatar" type="image/jpeg" media:width="73" media:height="73" href="http://shoutr.org/avatar/eschnou.jpg"/>
+ <poco:preferredUsername>eschnou</poco:preferredUsername>
+ <poco:displayName>Laurent Eschenauer</poco:displayName>
+ <poco:note></poco:note>
+ <poco:address>
+ <poco:formatted></poco:formatted>
+ </poco:address>
+ </activity:subject>
+
+ <entry>
+ <id>tag:eschnou@shoutr.org,2011-03-06:FKZbF1nx</id>
+ <updated>2011-03-06T15:02:56</updated>
+ <title>Hello, World</title>
+ <content type="html">Hello, &lt;b&gt;World&lt;/b&gt;</content>
+ <activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
+ <activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
+ </entry>
+
+ <entry>
+ <id>tag:eschnou@shoutr.org,2011-03-07:FKdgfF1nx</id>
+ <updated>2011-03-07T09:02:56</updated>
+ <title>Another one for the road.</title>
+ <content type="html">Another one for the road.</content>
+ <activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
+ <activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
+ </entry>
+
+</feed>
+
View
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<me:env xmlns:me="http://salmon-protocol.org/ns/magic-env"><me:data type="application/atom xml">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiID8-PGVudHJ5IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDA1L0F0b20iIHhtbG5zOnRocj0iaHR0cDovL3B1cmwub3JnL3N5bmRpY2F0aW9uL3RocmVhZC8xLjAiIHhtbG5zOmFjdGl2aXR5PSJodHRwOi8vYWN0aXZpdHlzdHJlYS5tcy9zcGVjLzEuMC8iIHhtbG5zOmdlb3Jzcz0iaHR0cDovL3d3dy5nZW9yc3Mub3JnL2dlb3JzcyIgeG1sbnM6b3N0YXR1cz0iaHR0cDovL29zdGF0dXMub3JnL3NjaGVtYS8xLjAiIHhtbG5zOnBvY289Imh0dHA6Ly9wb3J0YWJsZWNvbnRhY3RzLm5ldC9zcGVjLzEuMCIgeG1sbnM6bWVkaWE9Imh0dHA6Ly9wdXJsLm9yZy9zeW5kaWNhdGlvbi9hdG9tbWVkaWEiIHhtbG5zOnN0YXR1c25ldD0iaHR0cDovL3N0YXR1cy5uZXQvc2NoZW1hL2FwaS8xLyI-CiA8YWN0aXZpdHk6b2JqZWN0LXR5cGU-aHR0cDovL2FjdGl2aXR5c3RyZWEubXMvc2NoZW1hLzEuMC9ub3RlPC9hY3Rpdml0eTpvYmplY3QtdHlwZT4KIDxpZD5odHRwOi8vaWRlbnRpLmNhL25vdGljZS82NTEzOTc5MjwvaWQ-CiA8dGl0bGU-dGhpcyBvbmUgaXMgZm9yIEBjYXBhQGVzY2hlbmF1ZXIuYmUgLSBlbmpveSAhPC90aXRsZT4KIDxjb250ZW50IHR5cGU9Imh0bWwiPnRoaXMgb25lIGlzIGZvciBAJmx0O3NwYW4gY2xhc3M9JnF1b3Q7dmNhcmQmcXVvdDsmZ3Q7Jmx0O2EgaHJlZj0mcXVvdDtodHRwOi8vZXNjaGVuYXVlci5iZS91c2Vycy9jYXBhJnF1b3Q7IGNsYXNzPSZxdW90O3VybCZxdW90OyZndDsmbHQ7c3BhbiBjbGFzcz0mcXVvdDtmbiBuaWNrbmFtZSZxdW90OyZndDtjYXBhQGVzY2hlbmF1ZXIuYmUmbHQ7L3NwYW4mZ3Q7Jmx0Oy9hJmd0OyZsdDsvc3BhbiZndDsgLSBlbmpveSAhPC9jb250ZW50PgogPGxpbmsgcmVsPSJhbHRlcm5hdGUiIHR5cGU9InRleHQvaHRtbCIgaHJlZj0iaHR0cDovL2lkZW50aS5jYS9ub3RpY2UvNjUxMzk3OTIiLz4KIDxhY3Rpdml0eTp2ZXJiPmh0dHA6Ly9hY3Rpdml0eXN0cmVhLm1zL3NjaGVtYS8xLjAvcG9zdDwvYWN0aXZpdHk6dmVyYj4KIDxwdWJsaXNoZWQ-MjAxMS0wMi0yMlQyMToyMjo0OSswMDowMDwvcHVibGlzaGVkPgogPHVwZGF0ZWQ-MjAxMS0wMi0yMlQyMToyMjo0OSswMDowMDwvdXBkYXRlZD4KIDxhdXRob3I-CiAgPGFjdGl2aXR5Om9iamVjdC10eXBlPmh0dHA6Ly9hY3Rpdml0eXN0cmVhLm1zL3NjaGVtYS8xLjAvcGVyc29uPC9hY3Rpdml0eTpvYmplY3QtdHlwZT4KICA8dXJpPmh0dHA6Ly9pZGVudGkuY2EvdXNlci8zODUyMTY8L3VyaT4KICA8bmFtZT5zaG91dHI8L25hbWU-CiAgPGxpbmsgcmVsPSJhbHRlcm5hdGUiIHR5cGU9InRleHQvaHRtbCIgaHJlZj0iaHR0cDovL2lkZW50aS5jYS9zaG91dHIiLz4KICA8bGluayByZWw9ImF2YXRhciIgdHlwZT0iaW1hZ2UvcG5nIiBtZWRpYTp3aWR0aD0iOTYiIG1lZGlhOmhlaWdodD0iOTYiIGhyZWY9Imh0dHA6Ly90aGVtZS5pZGVudGkuY2EvMC45LjdiZXRhMi9pZGVudGljYS9kZWZhdWx0LWF2YXRhci1wcm9maWxlLnBuZyIvPgogIDxsaW5rIHJlbD0iYXZhdGFyIiB0eXBlPSJpbWFnZS9wbmciIG1lZGlhOndpZHRoPSI0OCIgbWVkaWE6aGVpZ2h0PSI0OCIgaHJlZj0iaHR0cDovL3RoZW1lLmlkZW50aS5jYS8wLjkuN2JldGEyL2lkZW50aWNhL2RlZmF1bHQtYXZhdGFyLXN0cmVhbS5wbmciLz4KICA8bGluayByZWw9ImF2YXRhciIgdHlwZT0iaW1hZ2UvcG5nIiBtZWRpYTp3aWR0aD0iMjQiIG1lZGlhOmhlaWdodD0iMjQiIGhyZWY9Imh0dHA6Ly90aGVtZS5pZGVudGkuY2EvMC45LjdiZXRhMi9pZGVudGljYS9kZWZhdWx0LWF2YXRhci1taW5pLnBuZyIvPgogIDxwb2NvOnByZWZlcnJlZFVzZXJuYW1lPnNob3V0cjwvcG9jbzpwcmVmZXJyZWRVc2VybmFtZT4KICA8cG9jbzpkaXNwbGF5TmFtZT5TaG91dHI8L3BvY286ZGlzcGxheU5hbWU-CiAgPHBvY286dXJscz4KICAgPHBvY286dHlwZT5ob21lcGFnZTwvcG9jbzp0eXBlPgogICA8cG9jbzp2YWx1ZT5odHRwOi8vc2hvdXRyLm9yZzwvcG9jbzp2YWx1ZT4KICAgPHBvY286cHJpbWFyeT50cnVlPC9wb2NvOnByaW1hcnk-CjwvcG9jbzp1cmxzPgo8L2F1dGhvcj4KIDwhLS1EZXByZWNhdGlvbiB3YXJuaW5nOiBhY3Rpdml0eTphY3RvciBpcyBwcmVzZW50IG9ubHkgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkuIEl0IHdpbGwgYmUgcmVtb3ZlZCBpbiB0aGUgbmV4dCB2ZXJzaW9uIG9mIFN0YXR1c05ldC4tLT4KIDxhY3Rpdml0eTphY3Rvcj4KICA8YWN0aXZpdHk6b2JqZWN0LXR5cGU-aHR0cDovL2FjdGl2aXR5c3RyZWEubXMvc2NoZW1hLzEuMC9wZXJzb248L2FjdGl2aXR5Om9iamVjdC10eXBlPgogIDxpZD5odHRwOi8vaWRlbnRpLmNhL3VzZXIvMzg1MjE2PC9pZD4KICA8dGl0bGU-U2hvdXRyPC90aXRsZT4KICA8bGluayByZWw9ImFsdGVybmF0ZSIgdHlwZT0idGV4dC9odG1sIiBocmVmPSJodHRwOi8vaWRlbnRpLmNhL3Nob3V0ciIvPgogIDxsaW5rIHJlbD0iYXZhdGFyIiB0eXBlPSJpbWFnZS9wbmciIG1lZGlhOndpZHRoPSI5NiIgbWVkaWE6aGVpZ2h0PSI5NiIgaHJlZj0iaHR0cDovL3RoZW1lLmlkZW50aS5jYS8wLjkuN2JldGEyL2lkZW50aWNhL2RlZmF1bHQtYXZhdGFyLXByb2ZpbGUucG5nIi8-CiAgPGxpbmsgcmVsPSJhdmF0YXIiIHR5cGU9ImltYWdlL3BuZyIgbWVkaWE6d2lkdGg9IjQ4IiBtZWRpYTpoZWlnaHQ9IjQ4IiBocmVmPSJodHRwOi8vdGhlbWUuaWRlbnRpLmNhLzAuOS43YmV0YTIvaWRlbnRpY2EvZGVmYXVsdC1hdmF0YXItc3RyZWFtLnBuZyIvPgogIDxsaW5rIHJlbD0iYXZhdGFyIiB0eXBlPSJpbWFnZS9wbmciIG1lZGlhOndpZHRoPSIyNCIgbWVkaWE6aGVpZ2h0PSIyNCIgaHJlZj0iaHR0cDovL3RoZW1lLmlkZW50aS5jYS8wLjkuN2JldGEyL2lkZW50aWNhL2RlZmF1bHQtYXZhdGFyLW1pbmkucG5nIi8-CiAgPHBvY286cHJlZmVycmVkVXNlcm5hbWU-c2hvdXRyPC9wb2NvOnByZWZlcnJlZFVzZXJuYW1lPgogIDxwb2NvOmRpc3BsYXlOYW1lPlNob3V0cjwvcG9jbzpkaXNwbGF5TmFtZT4KICA8cG9jbzp1cmxzPgogICA8cG9jbzp0eXBlPmhvbWVwYWdlPC9wb2NvOnR5cGU-CiAgIDxwb2NvOnZhbHVlPmh0dHA6Ly9zaG91dHIub3JnPC9wb2NvOnZhbHVlPgogICA8cG9jbzpwcmltYXJ5PnRydWU8L3BvY286cHJpbWFyeT4KPC9wb2NvOnVybHM-CjwvYWN0aXZpdHk6YWN0b3I-CiA8bGluayByZWw9Im9zdGF0dXM6Y29udmVyc2F0aW9uIiBocmVmPSJodHRwOi8vaWRlbnRpLmNhL2NvbnZlcnNhdGlvbi82NDM4Mjk1NSIvPgogPGxpbmsgcmVsPSJvc3RhdHVzOmF0dGVudGlvbiIgaHJlZj0iaHR0cDovL2VzY2hlbmF1ZXIuYmUvdXNlcnMvY2FwYSIvPgogPGxpbmsgcmVsPSJtZW50aW9uZWQiIGhyZWY9Imh0dHA6Ly9lc2NoZW5hdWVyLmJlL3VzZXJzL2NhcGEiLz4KIDxnZW9yc3M6cG9pbnQ-NTAuNTY2NjcgNS41ODMzMzwvZ2VvcnNzOnBvaW50PgogPHNvdXJjZT4KICA8aWQ-aHR0cDovL2VzY2hlbmF1ZXIuYmUvdXBkYXRlcy9jYXBhLmF0b208L2lkPgogIDx0aXRsZT5jYXBhPC90aXRsZT4KICA8bGluayByZWw9ImFsdGVybmF0ZSIgdHlwZT0idGV4dC9odG1sIiBocmVmPSJodHRwOi8vZXNjaGVuYXVlci5iZS91c2Vycy9jYXBhIi8-CiAgPGxpbmsgcmVsPSJzZWxmIiB0eXBlPSJhcHBsaWNhdGlvbi9hdG9tK3htbCIgaHJlZj0iaHR0cDovL2VzY2hlbmF1ZXIuYmUvdXBkYXRlcy9jYXBhLmF0b20iLz4KICA8aWNvbj5odHRwOi8vdGhlbWUuaWRlbnRpLmNhLzAuOS43YmV0YTIvaWRlbnRpY2EvZGVmYXVsdC1hdmF0YXItcHJvZmlsZS5wbmc8L2ljb24-Cjwvc291cmNlPgogPGxpbmsgcmVsPSJzZWxmIiB0eXBlPSJhcHBsaWNhdGlvbi9hdG9tK3htbCIgaHJlZj0iaHR0cDovL2lkZW50aS5jYS9hcGkvc3RhdHVzZXMvc2hvdy82NTEzOTc5Mi5hdG9tIi8-CiA8bGluayByZWw9ImVkaXQiIHR5cGU9ImFwcGxpY2F0aW9uL2F0b20reG1sIiBocmVmPSJodHRwOi8vaWRlbnRpLmNhL2FwaS9zdGF0dXNlcy9zaG93LzY1MTM5NzkyLmF0b20iLz4KIDxzdGF0dXNuZXQ6bm90aWNlX2luZm8gbG9jYWxfaWQ9IjY1MTM5NzkyIiBzb3VyY2U9IndlYiI-PC9zdGF0dXNuZXQ6bm90aWNlX2luZm8-CjwvZW50cnk-Cg==</me:data><me:encoding>base64url</me:encoding><me:alg>RSA-SHA256</me:alg><me:sig>UqKwh0XSOhdSD7U9nVHxB67sCNt8lQzkl5aPELQTfuhrlBoktbExhhkP4QGFg0WS0FgPnQpG24z5S4XIk2BTjI8My-VlwRWdeU72NtnLhZjz8EzA1aJTI_Drs71-YICuM_dLAJgo55pF4nIMkRN9KA-rS-y7oC3cwt01MknR8UQ=</me:sig></me:env>
+
Oops, something went wrong.

0 comments on commit a23a813

Please sign in to comment.