Remove generated html files from repo.

This commit is contained in:
Andre Casey 2013-09-24 00:50:39 -07:00 committed by Tyler Renelle
parent ac7aba4ce0
commit 883646ddaa
23 changed files with 0 additions and 3620 deletions

View file

@ -1,191 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>api.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page">
<a class="source" href="api.html">
api.js
</a>
<a class="source" href="auth.html">
auth.js
</a>
<a class="source" href="pages.html">
pages.js
</a>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>api.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="keyword">var</span> express = require(<span class="string">'express'</span>);
<span class="keyword">var</span> router = <span class="keyword">new</span> express.Router();
<span class="keyword">var</span> user = require(<span class="string">'../controllers/user'</span>);
<span class="keyword">var</span> groups = require(<span class="string">'../controllers/groups'</span>);
<span class="keyword">var</span> auth = require(<span class="string">'../controllers/auth'</span>);
<span class="comment">/*
---------- /api/v1 API ------------
Every url added to router is prefaced by /api/v1
See ./routes/coffee for routes
v1 user. Requires x-api-user (user id) and x-api-key (api key) headers, Test with:
$ cd node_modules/racer &amp;&amp; npm install &amp;&amp; cd ../..
$ mocha test/user.mocha.coffee
*/</span>
<span class="keyword">var</span> verifyTaskExists = user.verifyTaskExists
<span class="keyword">var</span> cron = user.cron;
router.get(<span class="string">'/status'</span>, <span class="keyword">function</span>(req, res) {
<span class="keyword">return</span> res.json({
status: <span class="string">'up'</span>
});
});
<span class="comment">/* Scoring*/</span>
router.post(<span class="string">'/user/task/:id/:direction'</span>, auth.auth, cron, user.scoreTask);
router.post(<span class="string">'/user/tasks/:id/:direction'</span>, auth.auth, cron, user.scoreTask);
<span class="comment">/* Tasks*/</span>
router.get(<span class="string">'/user/tasks'</span>, auth.auth, cron, user.getTasks);
router.get(<span class="string">'/user/task/:id'</span>, auth.auth, cron, user.getTask);
router.put(<span class="string">'/user/task/:id'</span>, auth.auth, cron, verifyTaskExists, user.updateTask);
router.post(<span class="string">'/user/tasks'</span>, auth.auth, cron, user.updateTasks);
router[<span class="string">"delete"</span>](<span class="string">'/user/task/:id'</span>, auth.auth, cron, verifyTaskExists, user.deleteTask);
router.post(<span class="string">'/user/task'</span>, auth.auth, cron, user.createTask);
router.put(<span class="string">'/user/task/:id/sort'</span>, auth.auth, cron, verifyTaskExists, user.sortTask);
router.post(<span class="string">'/user/clear-completed'</span>, auth.auth, cron, user.clearCompleted);
<span class="comment">/* Items*/</span>
router.post(<span class="string">'/user/buy/:type'</span>, auth.auth, cron, user.buy);
<span class="comment">/* User*/</span>
router.get(<span class="string">'/user'</span>, auth.auth, cron, user.getUser);
router.put(<span class="string">'/user'</span>, auth.auth, cron, user.updateUser);
router.post(<span class="string">'/user/revive'</span>, auth.auth, cron, user.revive);
router.post(<span class="string">'/user/batch-update'</span>, auth.auth, cron, user.batchUpdate);
router.post(<span class="string">'/user/reroll'</span>, auth.auth, cron, user.reroll);
router.post(<span class="string">'/user/buy-gems'</span>, auth.auth, user.buyGems);
router.post(<span class="string">'/user/reset'</span>, auth.auth, user.reset);
router[<span class="string">'delete'</span>](<span class="string">'/user'</span>, auth.auth, user[<span class="string">'delete'</span>]);
<span class="comment">/* Tags */</span>
router[<span class="string">'delete'</span>](<span class="string">'/user/tags/:tid'</span>, auth.auth, user.deleteTag);
<span class="comment">/* Groups*/</span>
router.get(<span class="string">'/groups'</span>, auth.auth, groups.getGroups);
router.post(<span class="string">'/groups'</span>, auth.auth, groups.createGroup);
router.get(<span class="string">'/groups/:gid'</span>, auth.auth, groups.getGroup);
router.post(<span class="string">'/groups/:gid'</span>, auth.auth, groups.attachGroup, groups.updateGroup);</pre></div></div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>DELETE /groups/:gid</p>
</div>
<div class="content"><div class='highlight'><pre>router.post(<span class="string">'/groups/:gid/join'</span>, auth.auth, groups.attachGroup, groups.join);
router.post(<span class="string">'/groups/:gid/leave'</span>, auth.auth, groups.attachGroup, groups.leave);
router.post(<span class="string">'/groups/:gid/invite'</span>, auth.auth, groups.attachGroup, groups.invite);</pre></div></div>
</li>
<li id="section-3">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<p>GET /groups/:gid/chat</p>
</div>
<div class="content"><div class='highlight'><pre>router.post(<span class="string">'/groups/:gid/chat'</span>, auth.auth, groups.attachGroup, groups.postChat);
router[<span class="string">"delete"</span>](<span class="string">'/groups/:gid/chat/:messageId'</span>, auth.auth, groups.attachGroup, groups.deleteChatMessage);</pre></div></div>
</li>
<li id="section-4">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-4">&#182;</a>
</div>
<p>PUT /groups/:gid/chat/:messageId</p>
</div>
<div class="content"><div class='highlight'><pre><span class="comment">/* Members */</span>
router.get(<span class="string">'/members/:uid'</span>, groups.getMember);</pre></div></div>
</li>
<li id="section-5">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">&#182;</a>
</div>
<p>Market</p>
</div>
<div class="content"><div class='highlight'><pre>router.post(<span class="string">'/market/buy'</span>, auth.auth, user.marketBuy);
module.exports = router;</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

View file

@ -1,78 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>auth.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page">
<a class="source" href="api.html">
api.js
</a>
<a class="source" href="auth.html">
auth.js
</a>
<a class="source" href="pages.html">
pages.js
</a>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>auth.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="keyword">var</span> auth = require(<span class="string">'../controllers/auth'</span>);
<span class="keyword">var</span> express = require(<span class="string">'express'</span>);
<span class="keyword">var</span> router = <span class="keyword">new</span> express.Router();
<span class="comment">/* auth.auth*/</span>
auth.setupPassport(router); <span class="comment">//FIXME make this consistent with the others</span>
router.post(<span class="string">'/api/v1/register'</span>, auth.registerUser);
router.post(<span class="string">'/api/v1/user/auth/local'</span>, auth.loginLocal);
router.post(<span class="string">'/api/v1/user/auth/facebook'</span>, auth.loginFacebook);
router.post(<span class="string">'/api/v1/user/reset-password'</span>, auth.resetPassword);
router.post(<span class="string">'/api/v1/user/change-password'</span>, auth.auth, auth.changePassword);
module.exports = router;</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

View file

@ -1,129 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>config.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page">
<a class="source" href="config.html">
config.js
</a>
<a class="source" href="middleware.html">
middleware.js
</a>
<a class="source" href="seed.html">
seed.js
</a>
<a class="source" href="server.html">
server.js
</a>
<a class="source" href="utils.html">
utils.js
</a>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>config.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="comment">/* Load nconf and define default configuration values if config.json or ENV vars are not found*/</span>
<span class="keyword">var</span> conf = require(<span class="string">"nconf"</span>);
<span class="keyword">var</span> path = require(<span class="string">"path"</span>);
conf.argv()
.env()</pre></div></div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>.file(&#39;defaults&#39;, path.join(path.resolve(__dirname, &#39;../config.json.example&#39;)))</p>
</div>
<div class="content"><div class='highlight'><pre> .file(<span class="string">'user'</span>, path.join(path.resolve(__dirname, <span class="string">'../config.json'</span>)));
<span class="comment">/*
var agent;
if (process.env.NODE_ENV === 'development') {</pre></div></div>
</li>
<li id="section-3">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<p>Follow these instructions for profiling / debugging leaks
<em> <a href="https://developers.google.com/chrome-developer-tools/docs/heap-profiling">https://developers.google.com/chrome-developer-tools/docs/heap-profiling</a>
</em> <a href="https://developers.google.com/chrome-developer-tools/docs/memory-analysis-101">https://developers.google.com/chrome-developer-tools/docs/memory-analysis-101</a></p>
</div>
<div class="content"><div class='highlight'><pre> agent = require('webkit-devtools-agent');
console.log("To debug memory leaks:" +
"\n\t(1) Run `kill -SIGUSR2 " + process.pid + "`" +
"\n\t(2) open http://c4milo.github.com/node-webkit-agent/21.0.1180.57/inspector.html?host=localhost:1337&amp;page=0");
}
*/
if (conf.get('NODE_ENV') === "development") {
Error.stackTraceLimit = Infinity;
}</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

View file

@ -1,146 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>deprecated.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page">
<a class="source" href="auth.html">
auth.js
</a>
<a class="source" href="deprecated.html">
deprecated.js
</a>
<a class="source" href="groups.html">
groups.js
</a>
<a class="source" href="user.html">
user.js
</a>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>deprecated.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="keyword">var</span> express = require(<span class="string">'express'</span>);
<span class="keyword">var</span> router = <span class="keyword">new</span> express.Router();
<span class="keyword">var</span> _ = require(<span class="string">'lodash'</span>);
<span class="keyword">var</span> icalendar = require(<span class="string">'icalendar'</span>);
<span class="keyword">var</span> api = require(<span class="string">'./user'</span>);
<span class="keyword">var</span> auth = require(<span class="string">'./auth'</span>);
<span class="comment">/* ---------- Deprecated Paths ------------*/</span>
<span class="keyword">var</span> deprecatedMessage = <span class="string">'This API is no longer supported, see https://github.com/lefnire/habitrpg/wiki/API for new protocol'</span>;
router.get(<span class="string">'/:uid/up/:score?'</span>, <span class="keyword">function</span>(req, res) {
<span class="keyword">return</span> res.send(<span class="number">500</span>, deprecatedMessage);
});
router.get(<span class="string">'/:uid/down/:score?'</span>, <span class="keyword">function</span>(req, res) {
<span class="keyword">return</span> res.send(<span class="number">500</span>, deprecatedMessage);
});
router.post(<span class="string">'/users/:uid/tasks/:taskId/:direction'</span>, <span class="keyword">function</span>(req, res) {
<span class="keyword">return</span> res.send(<span class="number">500</span>, deprecatedMessage);
});
<span class="comment">/* Redirect to new API*/</span>
<span class="keyword">var</span> initDeprecated = <span class="keyword">function</span>(req, res, next) {
req.headers[<span class="string">'x-api-user'</span>] = req.params.uid;
req.headers[<span class="string">'x-api-key'</span>] = req.body.apiToken;
<span class="keyword">return</span> next();
};
router.post(<span class="string">'/v1/users/:uid/tasks/:taskId/:direction'</span>, initDeprecated, auth.auth, api.scoreTask);
router.get(<span class="string">'/v1/users/:uid/calendar.ics'</span>, <span class="keyword">function</span>(req, res, next) {
<span class="keyword">return</span> next() <span class="comment">//disable for now</span>
<span class="keyword">var</span> apiToken, model, query, uid;
uid = req.params.uid;
apiToken = req.query.apiToken;
model = req.getModel();
query = model.query(<span class="string">'users'</span>).withIdAndToken(uid, apiToken);
<span class="keyword">return</span> query.fetch(<span class="keyword">function</span>(err, result) {
<span class="keyword">var</span> formattedIcal, ical, tasks, tasksWithDates;
<span class="keyword">if</span> (err) {
<span class="keyword">return</span> res.send(<span class="number">500</span>, err);
}
tasks = result.get(<span class="string">'tasks'</span>);
<span class="comment">/* tasks = result[0].tasks*/</span>
tasksWithDates = _.filter(tasks, <span class="keyword">function</span>(task) {
<span class="keyword">return</span> !!task.date;
});
<span class="keyword">if</span> (_.isEmpty(tasksWithDates)) {
<span class="keyword">return</span> res.send(<span class="number">500</span>, <span class="string">"No events found"</span>);
}
ical = <span class="keyword">new</span> icalendar.iCalendar();
ical.addProperty(<span class="string">'NAME'</span>, <span class="string">'HabitRPG'</span>);
_.each(tasksWithDates, <span class="keyword">function</span>(task) {
<span class="keyword">var</span> d, event;
event = <span class="keyword">new</span> icalendar.VEvent(task.id);
event.setSummary(task.text);
d = <span class="keyword">new</span> Date(task.date);
d.date_only = <span class="literal">true</span>;
event.setDate(d);
ical.addComponent(event);
<span class="keyword">return</span> <span class="literal">true</span>;
});
res.type(<span class="string">'text/calendar'</span>);
formattedIcal = ical.toString().replace(<span class="regexp">/DTSTART\:/g</span>, <span class="string">'DTSTART;VALUE=DATE:'</span>);
<span class="keyword">return</span> res.send(<span class="number">200</span>, formattedIcal);
});
});
module.exports = router;</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

View file

@ -1,500 +0,0 @@
/*--------------------- Typography ----------------------------*/
@font-face {
font-family: 'aller-light';
src: url('public/fonts/aller-light.eot');
src: url('public/fonts/aller-light.eot?#iefix') format('embedded-opentype'),
url('public/fonts/aller-light.woff') format('woff'),
url('public/fonts/aller-light.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'aller-bold';
src: url('public/fonts/aller-bold.eot');
src: url('public/fonts/aller-bold.eot?#iefix') format('embedded-opentype'),
url('public/fonts/aller-bold.woff') format('woff'),
url('public/fonts/aller-bold.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'novecento-bold';
src: url('public/fonts/novecento-bold.eot');
src: url('public/fonts/novecento-bold.eot?#iefix') format('embedded-opentype'),
url('public/fonts/novecento-bold.woff') format('woff'),
url('public/fonts/novecento-bold.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
/*--------------------- Layout ----------------------------*/
html { height: 100%; }
body {
font-family: "aller-light";
font-size: 14px;
line-height: 18px;
color: #30404f;
margin: 0; padding: 0;
height:100%;
}
#container { min-height: 100%; }
a {
color: #000;
}
b, strong {
font-weight: normal;
font-family: "aller-bold";
}
p, ul, ol {
margin: 15px 0 0px;
}
h1, h2, h3, h4, h5, h6 {
color: #112233;
line-height: 1em;
font-weight: normal;
font-family: "novecento-bold";
text-transform: uppercase;
margin: .25em 0 1em 0;
}
h1 {
margin-top: 40px;
}
hr {
border: 0;
background: 1px solid #ddd;
height: 1px;
margin: 20px 0;
}
pre, tt, code {
font-size: 12px; line-height: 16px;
font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace;
margin: 0; padding: 0;
}
.annotation pre {
display: block;
margin: 0;
padding: 7px 10px;
background: #fcfcfc;
-moz-box-shadow: inset 0 0 10px rgba(0,0,0,0.1);
-webkit-box-shadow: inset 0 0 10px rgba(0,0,0,0.1);
box-shadow: inset 0 0 10px rgba(0,0,0,0.1);
overflow-x: auto;
}
.annotation pre code {
border: 0;
padding: 0;
background: transparent;
}
blockquote {
border-left: 5px solid #ccc;
margin: 0;
padding: 1px 0 1px 1em;
}
.sections blockquote p {
font-family: Menlo, Consolas, Monaco, monospace;
font-size: 12px; line-height: 16px;
color: #999;
margin: 10px 0 0;
white-space: pre-wrap;
}
ul.sections {
list-style: none;
padding:0 0 5px 0;;
margin:0;
}
/*
Force border-box so that % widths fit the parent
container without overlap because of margin/padding.
More Info : http://www.quirksmode.org/css/box.html
*/
ul.sections > li > div {
-moz-box-sizing: border-box; /* firefox */
-ms-box-sizing: border-box; /* ie */
-webkit-box-sizing: border-box; /* webkit */
-khtml-box-sizing: border-box; /* konqueror */
box-sizing: border-box; /* css3 */
}
/*---------------------- Jump Page -----------------------------*/
#jump_to, #jump_page {
margin: 0;
background: white;
-webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777;
-webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px;
font: 16px Arial;
cursor: pointer;
text-align: right;
list-style: none;
}
#jump_to a {
text-decoration: none;
}
#jump_to a.large {
display: none;
}
#jump_to a.small {
font-size: 22px;
font-weight: bold;
color: #676767;
}
#jump_to, #jump_wrapper {
position: fixed;
right: 0; top: 0;
padding: 10px 15px;
margin:0;
}
#jump_wrapper {
display: none;
padding:0;
}
#jump_to:hover #jump_wrapper {
display: block;
}
#jump_page {
padding: 5px 0 3px;
margin: 0 0 25px 25px;
}
#jump_page .source {
display: block;
padding: 15px;
text-decoration: none;
border-top: 1px solid #eee;
}
#jump_page .source:hover {
background: #f5f5ff;
}
#jump_page .source:first-child {
}
/*---------------------- Low resolutions (> 320px) ---------------------*/
@media only screen and (min-width: 320px) {
.pilwrap { display: none; }
ul.sections > li > div {
display: block;
padding:0px 10px 0 10px;
}
ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol {
padding-left: 30px;
}
ul.sections > li > div.content {
background: #f5f5ff;
overflow-x:auto;
-webkit-box-shadow: inset 0 0 5px #e5e5ee;
box-shadow: inset 0 0 5px #e5e5ee;
border: 1px solid #dedede;
margin:0px 10px 5px 10px;
padding-bottom: 5px;
}
ul.sections > li > div.annotation pre {
margin: 7px 0 7px;
padding-left: 15px;
}
ul.sections > li > div.annotation p tt, .annotation code {
background: #f8f8ff;
border: 1px solid #dedede;
font-size: 12px;
padding: 0 0.2em;
}
}
/*---------------------- (> 481px) ---------------------*/
@media only screen and (min-width: 481px) {
#container {
position: relative;
}
body {
background-color: #F5F5FF;
font-size: 15px;
line-height: 21px;
}
pre, tt, code {
line-height: 18px;
}
p, ul, ol {
margin: 0 0 15px;
}
#jump_to {
padding: 5px 10px;
}
#jump_wrapper {
padding: 0;
}
#jump_to, #jump_page {
font: 10px Arial;
text-transform: uppercase;
}
#jump_page .source {
padding: 5px 10px;
}
#jump_to a.large {
display: inline-block;
}
#jump_to a.small {
display: none;
}
#background {
position: absolute;
top: 0; bottom: 0;
width: 350px;
background: #fff;
border-right: 1px solid #e5e5ee;
z-index: -1;
}
ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol {
padding-left: 40px;
}
ul.sections > li {
white-space: nowrap;
}
ul.sections > li > div {
display: inline-block;
}
ul.sections > li > div.annotation {
max-width: 350px;
min-width: 350px;
min-height: 5px;
padding: 13px;
overflow-x: hidden;
white-space: normal;
vertical-align: top;
text-align: left;
}
ul.sections > li > div.annotation pre {
margin: 15px 0 15px;
padding-left: 15px;
}
ul.sections > li > div.content {
padding: 13px;
vertical-align: top;
background: #f5f5ff;
border: none;
-webkit-box-shadow: none;
box-shadow: none;
}
.pilwrap {
position: relative;
display: inline;
}
.pilcrow {
font: 12px Arial;
text-decoration: none;
color: #454545;
position: absolute;
top: 3px; left: -20px;
padding: 1px 2px;
opacity: 0;
-webkit-transition: opacity 0.2s linear;
}
.for-h1 .pilcrow {
top: 47px;
}
.for-h2 .pilcrow, .for-h3 .pilcrow, .for-h4 .pilcrow {
top: 35px;
}
ul.sections > li > div.annotation:hover .pilcrow {
opacity: 1;
}
}
/*---------------------- (> 1025px) ---------------------*/
@media only screen and (min-width: 1025px) {
body {
font-size: 16px;
line-height: 24px;
}
#background {
width: 525px;
}
ul.sections > li > div.annotation {
max-width: 525px;
min-width: 525px;
padding: 10px 25px 1px 50px;
}
ul.sections > li > div.content {
padding: 9px 15px 16px 25px;
}
}
/*---------------------- Syntax Highlighting -----------------------------*/
td.linenos { background-color: #f0f0f0; padding-right: 10px; }
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
/*
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
*/
pre code {
display: block; padding: 0.5em;
color: #000;
background: #f8f8ff
}
pre .comment,
pre .template_comment,
pre .diff .header,
pre .javadoc {
color: #408080;
font-style: italic
}
pre .keyword,
pre .assignment,
pre .literal,
pre .css .rule .keyword,
pre .winutils,
pre .javascript .title,
pre .lisp .title,
pre .subst {
color: #954121;
/*font-weight: bold*/
}
pre .number,
pre .hexcolor {
color: #40a070
}
pre .string,
pre .tag .value,
pre .phpdoc,
pre .tex .formula {
color: #219161;
}
pre .title,
pre .id {
color: #19469D;
}
pre .params {
color: #00F;
}
pre .javascript .title,
pre .lisp .title,
pre .subst {
font-weight: normal
}
pre .class .title,
pre .haskell .label,
pre .tex .command {
color: #458;
font-weight: bold
}
pre .tag,
pre .tag .title,
pre .rules .property,
pre .django .tag .keyword {
color: #000080;
font-weight: normal
}
pre .attribute,
pre .variable,
pre .instancevar,
pre .lisp .body {
color: #008080
}
pre .regexp {
color: #B68
}
pre .class {
color: #458;
font-weight: bold
}
pre .symbol,
pre .ruby .symbol .string,
pre .ruby .symbol .keyword,
pre .ruby .symbol .keymethods,
pre .lisp .keyword,
pre .tex .special,
pre .input_number {
color: #990073
}
pre .builtin,
pre .constructor,
pre .built_in,
pre .lisp .title {
color: #0086b3
}
pre .preprocessor,
pre .pi,
pre .doctype,
pre .shebang,
pre .cdata {
color: #999;
font-weight: bold
}
pre .deletion {
background: #fdd
}
pre .addition {
background: #dfd
}
pre .diff .change {
background: #0086b3
}
pre .chunk {
color: #aaa
}
pre .tex .formula {
opacity: 0.5;
}

View file

@ -1,165 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>group.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page">
<a class="source" href="group.html">
group.js
</a>
<a class="source" href="user.html">
user.js
</a>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>group.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="keyword">var</span> mongoose = require(<span class="string">"mongoose"</span>);
<span class="keyword">var</span> Schema = mongoose.Schema;
<span class="keyword">var</span> helpers = require(<span class="string">'habitrpg-shared/script/helpers'</span>);
<span class="keyword">var</span> _ = require(<span class="string">'lodash'</span>);
<span class="keyword">var</span> GroupSchema = <span class="keyword">new</span> Schema({
_id: {type: String, <span class="string">'default'</span>: helpers.uuid},
name: String,
description: String,
leader: {
type: String,
ref: <span class="string">'User'</span>
},
members: [
{
type: String,
ref: <span class="string">'User'</span>
}
],
invites: [
{
type: String,
ref: <span class="string">'User'</span>
}
],
type: {
type: String,
<span class="string">"enum"</span>: [<span class="string">'guild'</span>, <span class="string">'party'</span>]
},
privacy: {
type: String,
<span class="string">"enum"</span>: [<span class="string">'private'</span>, <span class="string">'public'</span>]
},
_v: {
Number: Number,
<span class="string">'default'</span>: <span class="number">0</span>
},
websites: Array,
chat: Array,
<span class="comment">/*
# [{
# timestamp: Date
# user: String
# text: String
# contributor: String
# uuid: String
# id: String
# }]
*/</span>
balance: Number,
logo: String,
leaderMessage: String
}, {strict: <span class="string">'throw'</span>});
<span class="comment">/**
* Derby duplicated stuff. This is a temporary solution, once we're completely off derby we'll run an mongo migration
* to remove duplicates, then take these fucntions out
*/</span>
<span class="function"><span class="keyword">function</span> <span class="title">removeDuplicates</span><span class="params">(doc)</span>{</span></pre></div></div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>Remove duplicate members</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="keyword">if</span> (doc.members) {
<span class="keyword">var</span> uniqMembers = _.uniq(doc.members);
<span class="keyword">if</span> (uniqMembers.length != doc.members.length) {
doc.members = uniqMembers;
}
}
<span class="keyword">if</span> (doc.websites) {
<span class="keyword">var</span> uniqWebsites = _.uniq(doc.websites);
<span class="keyword">if</span> (uniqWebsites.length != doc.websites.length) {
doc.websites = uniqWebsites;
}
console.log(doc.websites);
}
}
GroupSchema.pre(<span class="string">'save'</span>, <span class="keyword">function</span>(next){
removeDuplicates(<span class="keyword">this</span>);
next();
})
GroupSchema.methods.toJSON = <span class="keyword">function</span>(){
<span class="keyword">var</span> doc = <span class="keyword">this</span>.toObject();
removeDuplicates(doc);
<span class="keyword">return</span> doc;
}
module.exports.schema = GroupSchema;
module.exports.model = mongoose.model(<span class="string">"Group"</span>, GroupSchema);</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

View file

@ -1,471 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>groups.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page">
<a class="source" href="auth.html">
auth.js
</a>
<a class="source" href="deprecated.html">
deprecated.js
</a>
<a class="source" href="groups.html">
groups.js
</a>
<a class="source" href="user.html">
user.js
</a>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>groups.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
<p>@see ../routes for routing</p>
</div>
<div class="content"><div class='highlight'><pre><span class="keyword">var</span> _ = require(<span class="string">'lodash'</span>);
<span class="keyword">var</span> nconf = require(<span class="string">'nconf'</span>);
<span class="keyword">var</span> async = require(<span class="string">'async'</span>);
<span class="keyword">var</span> algos = require(<span class="string">'habitrpg-shared/script/algos'</span>);
<span class="keyword">var</span> helpers = require(<span class="string">'habitrpg-shared/script/helpers'</span>);
<span class="keyword">var</span> items = require(<span class="string">'habitrpg-shared/script/items'</span>);
<span class="keyword">var</span> User = require(<span class="string">'./../models/user'</span>).model;
<span class="keyword">var</span> Group = require(<span class="string">'./../models/group'</span>).model;
<span class="keyword">var</span> api = module.exports;
<span class="comment">/*
------------------------------------------------------------------------
Groups
------------------------------------------------------------------------
*/</span>
<span class="keyword">var</span> usernameFields = <span class="string">'auth.local.username auth.facebook.displayName auth.facebook.givenName auth.facebook.familyName auth.facebook.name'</span>;
<span class="keyword">var</span> partyFields = <span class="string">'profile preferences items stats achievements party backer flags.rest auth.timestamps '</span> + usernameFields;
<span class="function"><span class="keyword">function</span> <span class="title">removeSelf</span><span class="params">(group, user)</span>{</span>
group.members = _.filter(group.members, <span class="keyword">function</span>(m){<span class="keyword">return</span> m._id != user._id});
}
api.getMember = <span class="keyword">function</span>(req, res) {
User.findById(req.params.uid).select(partyFields).exec(<span class="keyword">function</span>(err, user){
<span class="keyword">if</span> (err) <span class="keyword">return</span> res.json(<span class="number">500</span>,{err:err});
<span class="keyword">if</span> (!user) <span class="keyword">return</span> res.json(<span class="number">400</span>,{err:<span class="string">'User not found'</span>});
res.json(user);
})
}
<span class="comment">/**
* Get groups. If req.query.type privided, returned as an array (so ngResource can use). If not, returned as
* object {guilds, public, party, tavern}. req.query.type can be comma-separated `type=guilds,party`
* @param req
* @param res
* @param next
*/</span>
api.getGroups = <span class="keyword">function</span>(req, res, next) {
<span class="keyword">var</span> user = res.locals.user;
<span class="keyword">var</span> type = req.query.type &amp;&amp; req.query.type.split(<span class="string">','</span>);</pre></div></div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>First get all groups</p>
</div>
<div class="content"><div class='highlight'><pre> async.parallel({
party: <span class="keyword">function</span>(cb) {
<span class="keyword">if</span> (type &amp;&amp; !~type.indexOf(<span class="string">'party'</span>)) <span class="keyword">return</span> cb(<span class="literal">null</span>, {});
Group
.findOne({type: <span class="string">'party'</span>, members: {<span class="string">'$in'</span>: [user._id]}})
.populate({
path: <span class="string">'members'</span>,</pre></div></div>
</li>
<li id="section-3">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<p>match: {_id: {$ne: user._id}}, //fixme this causes it to hang??</p>
</div>
<div class="content"><div class='highlight'><pre> select: partyFields
})
.exec(cb);
},
guilds: <span class="keyword">function</span>(cb) {
<span class="keyword">if</span> (type &amp;&amp; !~type.indexOf(<span class="string">'guilds'</span>)) <span class="keyword">return</span> cb(<span class="literal">null</span>, []);
Group.find({type: <span class="string">'guild'</span>, members: {<span class="string">'$in'</span>: [user._id]}}).populate(<span class="string">'members'</span>, usernameFields).exec(cb);</pre></div></div>
</li>
<li id="section-4">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-4">&#182;</a>
</div>
<pre><code> Group.find({type: &#39;guild&#39;, members: {&#39;$in&#39;: [user._id]}}, cb);</code></pre>
</div>
<div class="content"><div class='highlight'><pre> },
tavern: <span class="keyword">function</span>(cb) {
<span class="keyword">if</span> (type &amp;&amp; !~type.indexOf(<span class="string">'tavern'</span>)) <span class="keyword">return</span> cb(<span class="literal">null</span>, {});
Group.findOne({_id: <span class="string">'habitrpg'</span>}, cb);
},
<span class="string">"public"</span>: <span class="keyword">function</span>(cb) {
<span class="keyword">if</span> (type &amp;&amp; !~type.indexOf(<span class="string">'public'</span>)) <span class="keyword">return</span> cb(<span class="literal">null</span>, []);
Group.find({privacy: <span class="string">'public'</span>}, {name:<span class="number">1</span>, description:<span class="number">1</span>, members:<span class="number">1</span>}, cb);
}
}, <span class="keyword">function</span>(err, results){
<span class="keyword">if</span> (err) <span class="keyword">return</span> res.json(<span class="number">500</span>, {err: err});</pre></div></div>
</li>
<li id="section-5">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">&#182;</a>
</div>
<p>Remove self from party (see above failing <code>match</code> directive in <code>populate</code></p>
</div>
<div class="content"><div class='highlight'><pre> <span class="keyword">if</span> (results.party) {
removeSelf(results.party, user);
}</pre></div></div>
</li>
<li id="section-6">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-6">&#182;</a>
</div>
<p>Sort public groups by members length (not easily doable in mongoose)</p>
</div>
<div class="content"><div class='highlight'><pre> results.public = _.sortBy(results.public, <span class="keyword">function</span>(group){
<span class="keyword">return</span> -group.members.length;
});</pre></div></div>
</li>
<li id="section-7">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-7">&#182;</a>
</div>
<p>If they&#39;re requesting a specific type, let&#39;s return it as an array so that $ngResource
can utilize it properly</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="keyword">if</span> (type) {
results = _.reduce(type, <span class="keyword">function</span>(m,t){
<span class="keyword">return</span> m.concat(_.isArray(results[t]) ? results[t] : [results[t]]);
}, []);
}
res.json(results);
})
};
<span class="comment">/**
* Get group
*/</span>
api.getGroup = <span class="keyword">function</span>(req, res, next) {
<span class="keyword">var</span> user = res.locals.user;
<span class="keyword">var</span> gid = req.params.gid;
Group.findById(gid).populate(<span class="string">'members'</span>, partyFields).exec(<span class="keyword">function</span>(err, group){
<span class="keyword">if</span> ( (group.type == <span class="string">'guild'</span> &amp;&amp; group.privacy == <span class="string">'private'</span>) || group.type == <span class="string">'party'</span>) {
<span class="keyword">return</span> res.json(<span class="number">401</span>, {err: <span class="string">"You don't have access to this group"</span>});
}</pre></div></div>
</li>
<li id="section-8">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-8">&#182;</a>
</div>
<p>Remove self from party (see above failing <code>match</code> directive in <code>populate</code></p>
</div>
<div class="content"><div class='highlight'><pre> <span class="keyword">if</span> (group.type == <span class="string">'party'</span>) {
removeSelf(group, user);
}
res.json(group);
})
};
api.createGroup = <span class="keyword">function</span>(req, res, next) {
<span class="keyword">var</span> group = <span class="keyword">new</span> Group(req.body);
group.save(<span class="keyword">function</span>(err, saved){
<span class="keyword">if</span> (err) <span class="keyword">return</span> res.json(<span class="number">500</span>,{err:err});
res.json(saved);
})
}
api.updateGroup = <span class="keyword">function</span>(req, res, next) {
<span class="keyword">var</span> group = res.locals.group;
<span class="string">'name description logo websites logo leaderMessage'</span>.split(<span class="string">' '</span>).forEach(<span class="keyword">function</span>(attr){
group[attr] = req.body[attr];
});
async.series([
<span class="keyword">function</span>(cb){group.save(cb);},
<span class="keyword">function</span>(cb){
<span class="keyword">var</span> fields = group.type == <span class="string">'party'</span> ? partyFields : usernameFields;
Group.findById(group._id).populate(<span class="string">'members'</span>, fields).exec(cb);
}
], <span class="keyword">function</span>(err, results){
<span class="keyword">if</span> (err) <span class="keyword">return</span> res.json(<span class="number">500</span>,{err:err});
removeSelf(results[<span class="number">1</span>], res.locals.user);
res.json(results[<span class="number">1</span>]);
})
}
api.attachGroup = <span class="keyword">function</span>(req, res, next) {
Group.findById(req.params.gid, <span class="keyword">function</span>(err, group){
<span class="keyword">if</span>(err) <span class="keyword">return</span> res.json(<span class="number">500</span>, {err:err});
res.locals.group = group;
next();
})
}
api.postChat = <span class="keyword">function</span>(req, res, next) {
<span class="keyword">var</span> user = res.locals.user
<span class="keyword">var</span> group = res.locals.group;
<span class="keyword">var</span> message = {
id: helpers.uuid(),
uuid: user._id,
contributor: user.backer &amp;&amp; user.backer.contributor,
npc: user.backer &amp;&amp; user.backer.npc,
text: req.query.message, <span class="comment">// FIXME this should be body, but ngResource is funky</span>
user: helpers.username(user.auth, user.profile.name),
timestamp: +(<span class="keyword">new</span> Date)
};
group.chat.unshift(message);
group.chat.splice(<span class="number">200</span>);
<span class="keyword">if</span> (group.type === <span class="string">'party'</span>) {
user.party.lastMessageSeen = message.id;
user.save();
}
async.series([
<span class="keyword">function</span>(cb){group.save(cb)},
<span class="keyword">function</span>(cb){
Group.findById(group._id).populate(<span class="string">'members'</span>, partyFields).exec(cb);
}
], <span class="keyword">function</span>(err, results){
<span class="keyword">if</span> (err) <span class="keyword">return</span> res.json(<span class="number">500</span>, {err:err});</pre></div></div>
</li>
<li id="section-9">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-9">&#182;</a>
</div>
<p>TODO This is less efficient, but see <a href="https://github.com/lefnire/habitrpg/commit/41255dc#commitcomment-4014583">https://github.com/lefnire/habitrpg/commit/41255dc#commitcomment-4014583</a></p>
</div>
<div class="content"><div class='highlight'><pre> <span class="keyword">var</span> saved = results[<span class="number">1</span>];
removeSelf(saved, user);
res.json(saved);
})
}
api.deleteChatMessage = <span class="keyword">function</span>(req, res, next){
<span class="keyword">var</span> user = res.locals.user
<span class="keyword">var</span> group = res.locals.group;
<span class="keyword">var</span> message = _.find(group.chat, {id: req.params.messageId, uuid: user.id});
<span class="keyword">if</span>(message === <span class="literal">undefined</span>) <span class="keyword">return</span> res.json(<span class="number">404</span>, {err: <span class="string">"Message not found!"</span>});
<span class="keyword">if</span>(user.id !== message.uuid){
<span class="keyword">if</span>(!user.backer || (user.backer &amp;&amp; !user.backer.admin)){
<span class="keyword">return</span> res.json(<span class="number">401</span>, {err: <span class="string">"Not authorized to delete this message!"</span>})
}
}
group.chat = _.without(group.chat, message);
group.save(<span class="keyword">function</span>(err, data){
<span class="keyword">if</span>(err) <span class="keyword">return</span> res.json(<span class="number">500</span>, {err: err});
res.send(<span class="number">204</span>);
});
}
api.join = <span class="keyword">function</span>(req, res, next) {
<span class="keyword">var</span> user = res.locals.user,
group = res.locals.group;
<span class="keyword">if</span> (group.type == <span class="string">'party'</span> &amp;&amp; group._id == (user.invitations &amp;&amp; user.invitations.party &amp;&amp; user.invitations.party.id)) {
user.invitations.party = <span class="literal">undefined</span>;
user.save();
}
<span class="keyword">else</span> <span class="keyword">if</span> (group.type == <span class="string">'guild'</span> &amp;&amp; user.invitations &amp;&amp; user.invitations.guilds) {
<span class="keyword">var</span> i = _.findIndex(user.invitations.guilds, {id:group._id});
<span class="keyword">if</span> (~i) user.invitations.guilds.splice(i,<span class="number">1</span>);
user.save();
}
group.members.push(user._id);
async.series([
<span class="keyword">function</span>(cb){
group.save(cb);
},
<span class="keyword">function</span>(cb){
Group.findById(group._id).populate(<span class="string">'members'</span>, partyFields).exec(cb);
}
], <span class="keyword">function</span>(err, results){
<span class="keyword">if</span> (err) <span class="keyword">return</span> res.json(<span class="number">500</span>,{err:err});
res.json(results[<span class="number">1</span>]);
});
}
api.leave = <span class="keyword">function</span>(req, res, next) {
<span class="keyword">var</span> user = res.locals.user,
group = res.locals.group;
Group.update({_id:group._id},{$pull:{members:user._id}}, <span class="keyword">function</span>(err, saved){
<span class="keyword">if</span> (err) <span class="keyword">return</span> res.json(<span class="number">500</span>,{err:err});
res.send(<span class="number">200</span>, {_id: saved._id});
})
}
api.invite = <span class="keyword">function</span>(req, res, next) {
<span class="keyword">var</span> group = res.locals.group;
<span class="keyword">var</span> uuid = req.query.uuid;
User.findById(uuid, <span class="keyword">function</span>(err,invite){
<span class="keyword">if</span> (err) <span class="keyword">return</span> res.json(<span class="number">500</span>,{err:err});
<span class="keyword">if</span> (!invite)
<span class="keyword">return</span> res.json(<span class="number">400</span>,{err:<span class="string">'User with id '</span>+req.query.uid+<span class="string">' not found'</span>});
<span class="keyword">if</span> (group.type == <span class="string">'guild'</span>) {
<span class="keyword">if</span> (_.contains(group.members,uuid))
<span class="keyword">return</span> res.json(<span class="number">400</span>,{err: <span class="string">"User already in that group"</span>});
<span class="keyword">if</span> (invite.invitations &amp;&amp; invite.invitations.guilds &amp;&amp; _.find(invite.invitations.guilds, {id:group._id}))
<span class="keyword">return</span> res.json(<span class="number">400</span>, {err:<span class="string">"User already invited to that group"</span>});
sendInvite();
} <span class="keyword">else</span> <span class="keyword">if</span> (group.type == <span class="string">'party'</span>) {
<span class="keyword">if</span> (invite.invitations &amp;&amp; !_.isEmpty(invite.invitations.party))
<span class="keyword">return</span> res.json(<span class="number">400</span>,{err:<span class="string">"User already pending invitation."</span>});
Group.find({type:<span class="string">'party'</span>, members:{$<span class="keyword">in</span>:[uuid]}}, <span class="keyword">function</span>(err, groups){
<span class="keyword">if</span> (err) <span class="keyword">return</span> res.json(<span class="number">500</span>,{err:err});
<span class="keyword">if</span> (!_.isEmpty(groups))
<span class="keyword">return</span> res.json(<span class="number">400</span>,{err:<span class="string">"User already in a party."</span>})
sendInvite();
})
}
<span class="function"><span class="keyword">function</span> <span class="title">sendInvite</span> <span class="params">()</span>{</span>
<span class="keyword">if</span>(group.type === <span class="string">'guild'</span>){
invite.invitations.guilds.push({id: group._id, name: group.name});
}<span class="keyword">else</span>{</pre></div></div>
</li>
<li id="section-10">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</a>
</div>
<p>req.body.type in &#39;guild&#39;, &#39;party&#39;</p>
</div>
<div class="content"><div class='highlight'><pre> invite.invitations.party = {id: group._id, name: group.name}
}
invite.save();
Group.findById(group._id)
.populate(<span class="string">'members'</span>, partyFields).exec(<span class="keyword">function</span>(err, saved){
res.json(saved);
});
}
});
}</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

View file

@ -1,180 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>middleware.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page">
<a class="source" href="config.html">
config.js
</a>
<a class="source" href="middleware.html">
middleware.js
</a>
<a class="source" href="seed.html">
seed.js
</a>
<a class="source" href="server.html">
server.js
</a>
<a class="source" href="utils.html">
utils.js
</a>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>middleware.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="keyword">var</span> nconf = require(<span class="string">'nconf'</span>);
<span class="keyword">var</span> _ = require(<span class="string">'lodash'</span>);
<span class="keyword">var</span> fs = require(<span class="string">'fs'</span>);
<span class="keyword">var</span> path = require(<span class="string">'path'</span>);
module.exports.forceSSL = <span class="keyword">function</span>(req, res, next){
<span class="keyword">var</span> baseUrl = nconf.get(<span class="string">"BASE_URL"</span>);</pre></div></div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>Note x-forwarded-proto is used by Heroku &amp; nginx, you&#39;ll have to do something different if you&#39;re not using those</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="keyword">if</span> (req.headers[<span class="string">'x-forwarded-proto'</span>] &amp;&amp; req.headers[<span class="string">'x-forwarded-proto'</span>] !== <span class="string">'https'</span>
&amp;&amp; nconf.get(<span class="string">'NODE_ENV'</span>) === <span class="string">'production'</span>
&amp;&amp; baseUrl.indexOf(<span class="string">'https'</span>) === <span class="number">0</span>) {
<span class="keyword">return</span> res.redirect(baseUrl + req.url);
}
next()
}
module.exports.splash = <span class="keyword">function</span>(req, res, next) {
<span class="keyword">if</span> (req.url == <span class="string">'/'</span> &amp;&amp; !req.headers[<span class="string">'x-api-user'</span>] &amp;&amp; !req.headers[<span class="string">'x-api-key'</span>] &amp;&amp; !(req.session &amp;&amp; req.session.userId))
<span class="keyword">return</span> res.redirect(<span class="string">'/static/front'</span>)
next()
};
module.exports.cors = <span class="keyword">function</span>(req, res, next) {
res.header(<span class="string">"Access-Control-Allow-Origin"</span>, req.headers.origin || <span class="string">"*"</span>);
res.header(<span class="string">"Access-Control-Allow-Methods"</span>, <span class="string">"OPTIONS,GET,POST,PUT,HEAD,DELETE"</span>);
res.header(<span class="string">"Access-Control-Allow-Headers"</span>, <span class="string">"Content-Type,Accept,Content-Encoding,X-Requested-With,x-api-user,x-api-key"</span>);
<span class="keyword">if</span> (req.method === <span class="string">'OPTIONS'</span>) <span class="keyword">return</span> res.send(<span class="number">200</span>);
<span class="keyword">return</span> next();
};
<span class="keyword">var</span> buildFiles = [];
<span class="keyword">var</span> walk = <span class="keyword">function</span>(folder){
<span class="keyword">var</span> res = fs.readdirSync(folder);
res.forEach(<span class="keyword">function</span>(fileName){
file = folder + <span class="string">'/'</span> + fileName;
<span class="keyword">if</span>(fs.statSync(file).isDirectory()){
walk(file);
}<span class="keyword">else</span>{
<span class="keyword">var</span> relFolder = path.relative(path.join(__dirname, <span class="string">"/../build"</span>), folder);
<span class="keyword">var</span> old = fileName.replace(<span class="regexp">/-.{8}(\.[\d\w]+)$/</span>, <span class="string">'$1'</span>);
<span class="keyword">if</span>(relFolder){
old = relFolder + <span class="string">'/'</span> + old;
fileName = relFolder + <span class="string">'/'</span> + fileName;
}
buildFiles[old] = fileName
}
});
}
walk(path.join(__dirname, <span class="string">"/../build"</span>));
<span class="keyword">var</span> getBuildUrl = <span class="keyword">function</span>(url){
console.log(<span class="string">"CALLED "</span>, url)
<span class="keyword">if</span>(buildFiles[url]) <span class="keyword">return</span> buildFiles[url];
<span class="keyword">return</span> filename;
}
module.exports.locals = <span class="keyword">function</span>(req, res, next) {
res.locals.habitrpg = res.locals.habitrpg || {}
_.defaults(res.locals.habitrpg, {
NODE_ENV: nconf.get(<span class="string">'NODE_ENV'</span>),
IS_MOBILE: <span class="regexp">/Android|webOS|iPhone|iPad|iPod|BlackBerry/i</span>.test(req.header(<span class="string">'User-Agent'</span>)),
STRIPE_PUB_KEY: nconf.get(<span class="string">'STRIPE_PUB_KEY'</span>),
getBuildUrl: getBuildUrl
});
next()
}
<span class="comment">/*</pre></div></div>
</li>
<li id="section-3">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<p> translate = (req, res, next) -&gt;
model = req.getModel()</p>
<h1>Set locale to bg on dev</h1>
<h1>model.set &#39;_i18n.locale&#39;, &#39;bg&#39; if process.env.NODE_ENV is &quot;development&quot;</h1>
<p> next()</p>
</div>
<div class="content"><div class='highlight'><pre> */</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

View file

@ -1,145 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>pages.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page">
<a class="source" href="api.html">
api.js
</a>
<a class="source" href="auth.html">
auth.js
</a>
<a class="source" href="pages.html">
pages.js
</a>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>pages.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="keyword">var</span> nconf = require(<span class="string">'nconf'</span>);
<span class="keyword">var</span> express = require(<span class="string">'express'</span>);
<span class="keyword">var</span> router = <span class="keyword">new</span> express.Router();
<span class="keyword">var</span> _ = require(<span class="string">'lodash'</span>);</pre></div></div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>-------- App --------</p>
</div>
<div class="content"><div class='highlight'><pre>router.get(<span class="string">'/'</span>, <span class="keyword">function</span>(req, res) {
<span class="keyword">return</span> res.render(<span class="string">'index'</span>, {
title: <span class="string">'HabitRPG | Your Life, The Role Playing Game'</span>,
env: res.locals.habitrpg
});
});
router.get(<span class="string">'/partials/tasks'</span>, <span class="keyword">function</span>(req, res) {
res.render(<span class="string">'tasks/index'</span>, {env: res.locals.habitrpg});
});
router.get(<span class="string">'/partials/options'</span>, <span class="keyword">function</span>(req, res) {
res.render(<span class="string">'options'</span>, {env: res.locals.habitrpg});
});</pre></div></div>
</li>
<li id="section-3">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<p>-------- Marketing --------</p>
</div>
<div class="content"><div class='highlight'><pre>router.get(<span class="string">'/splash.html'</span>, <span class="keyword">function</span>(req, res) {
res.redirect(<span class="string">'/static/front'</span>);
});
router.get(<span class="string">'/static/front'</span>, <span class="keyword">function</span>(req, res) {
res.render(<span class="string">'static/front'</span>, {env: res.locals.habitrpg});
});
router.get(<span class="string">'/static/about'</span>, <span class="keyword">function</span>(req, res) {
res.redirect(<span class="string">'http://community.habitrpg.com/node/97'</span>);
});
router.get(<span class="string">'/static/team'</span>, <span class="keyword">function</span>(req, res) {
res.redirect(<span class="string">'http://community.habitrpg.com/node/96'</span>);
});
router.get(<span class="string">'/static/extensions'</span>, <span class="keyword">function</span>(req, res) {
res.redirect(<span class="string">'http://community.habitrpg.com/extensions'</span>);
});
router.get(<span class="string">'/static/faq'</span>, <span class="keyword">function</span>(req, res) {
res.redirect(<span class="string">'http://community.habitrpg.com/faq-page'</span>);
});
router.get(<span class="string">'/static/privacy'</span>, <span class="keyword">function</span>(req, res) {
res.render(<span class="string">'static/privacy'</span>, {env: res.locals.habitrpg});
});
router.get(<span class="string">'/static/terms'</span>, <span class="keyword">function</span>(req, res) {
res.render(<span class="string">'static/terms'</span>, {env: res.locals.habitrpg});
});
module.exports = router;</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

View file

@ -1,375 +0,0 @@
/*! normalize.css v2.0.1 | MIT License | git.io/normalize */
/* ==========================================================================
HTML5 display definitions
========================================================================== */
/*
* Corrects `block` display not defined in IE 8/9.
*/
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
nav,
section,
summary {
display: block;
}
/*
* Corrects `inline-block` display not defined in IE 8/9.
*/
audio,
canvas,
video {
display: inline-block;
}
/*
* Prevents modern browsers from displaying `audio` without controls.
* Remove excess height in iOS 5 devices.
*/
audio:not([controls]) {
display: none;
height: 0;
}
/*
* Addresses styling for `hidden` attribute not present in IE 8/9.
*/
[hidden] {
display: none;
}
/* ==========================================================================
Base
========================================================================== */
/*
* 1. Sets default font family to sans-serif.
* 2. Prevents iOS text size adjust after orientation change, without disabling
* user zoom.
*/
html {
font-family: sans-serif; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
-ms-text-size-adjust: 100%; /* 2 */
}
/*
* Removes default margin.
*/
body {
margin: 0;
}
/* ==========================================================================
Links
========================================================================== */
/*
* Addresses `outline` inconsistency between Chrome and other browsers.
*/
a:focus {
outline: thin dotted;
}
/*
* Improves readability when focused and also mouse hovered in all browsers.
*/
a:active,
a:hover {
outline: 0;
}
/* ==========================================================================
Typography
========================================================================== */
/*
* Addresses `h1` font sizes within `section` and `article` in Firefox 4+,
* Safari 5, and Chrome.
*/
h1 {
font-size: 2em;
}
/*
* Addresses styling not present in IE 8/9, Safari 5, and Chrome.
*/
abbr[title] {
border-bottom: 1px dotted;
}
/*
* Addresses style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
*/
b,
strong {
font-weight: bold;
}
/*
* Addresses styling not present in Safari 5 and Chrome.
*/
dfn {
font-style: italic;
}
/*
* Addresses styling not present in IE 8/9.
*/
mark {
background: #ff0;
color: #000;
}
/*
* Corrects font family set oddly in Safari 5 and Chrome.
*/
code,
kbd,
pre,
samp {
font-family: monospace, serif;
font-size: 1em;
}
/*
* Improves readability of pre-formatted text in all browsers.
*/
pre {
white-space: pre;
white-space: pre-wrap;
word-wrap: break-word;
}
/*
* Sets consistent quote types.
*/
q {
quotes: "\201C" "\201D" "\2018" "\2019";
}
/*
* Addresses inconsistent and variable font size in all browsers.
*/
small {
font-size: 80%;
}
/*
* Prevents `sub` and `sup` affecting `line-height` in all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
/* ==========================================================================
Embedded content
========================================================================== */
/*
* Removes border when inside `a` element in IE 8/9.
*/
img {
border: 0;
}
/*
* Corrects overflow displayed oddly in IE 9.
*/
svg:not(:root) {
overflow: hidden;
}
/* ==========================================================================
Figures
========================================================================== */
/*
* Addresses margin not present in IE 8/9 and Safari 5.
*/
figure {
margin: 0;
}
/* ==========================================================================
Forms
========================================================================== */
/*
* Define consistent border, margin, and padding.
*/
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
/*
* 1. Corrects color not being inherited in IE 8/9.
* 2. Remove padding so people aren't caught out if they zero out fieldsets.
*/
legend {
border: 0; /* 1 */
padding: 0; /* 2 */
}
/*
* 1. Corrects font family not being inherited in all browsers.
* 2. Corrects font size not being inherited in all browsers.
* 3. Addresses margins set differently in Firefox 4+, Safari 5, and Chrome
*/
button,
input,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 2 */
margin: 0; /* 3 */
}
/*
* Addresses Firefox 4+ setting `line-height` on `input` using `!important` in
* the UA stylesheet.
*/
button,
input {
line-height: normal;
}
/*
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
* and `video` controls.
* 2. Corrects inability to style clickable `input` types in iOS.
* 3. Improves usability and consistency of cursor style between image-type
* `input` and others.
*/
button,
html input[type="button"], /* 1 */
input[type="reset"],
input[type="submit"] {
-webkit-appearance: button; /* 2 */
cursor: pointer; /* 3 */
}
/*
* Re-set default cursor for disabled elements.
*/
button[disabled],
input[disabled] {
cursor: default;
}
/*
* 1. Addresses box sizing set to `content-box` in IE 8/9.
* 2. Removes excess padding in IE 8/9.
*/
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/*
* 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome.
* 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome
* (include `-moz` to future-proof).
*/
input[type="search"] {
-webkit-appearance: textfield; /* 1 */
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box; /* 2 */
box-sizing: content-box;
}
/*
* Removes inner padding and search cancel button in Safari 5 and Chrome
* on OS X.
*/
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/*
* Removes inner padding and border in Firefox 4+.
*/
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
}
/*
* 1. Removes default vertical scrollbar in IE 8/9.
* 2. Improves readability and alignment in all browsers.
*/
textarea {
overflow: auto; /* 1 */
vertical-align: top; /* 2 */
}
/* ==========================================================================
Tables
========================================================================== */
/*
* Remove most spacing between table cells.
*/
table {
border-collapse: collapse;
border-spacing: 0;
}

View file

@ -1,109 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>seed.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page">
<a class="source" href="config.html">
config.js
</a>
<a class="source" href="middleware.html">
middleware.js
</a>
<a class="source" href="seed.html">
seed.js
</a>
<a class="source" href="server.html">
server.js
</a>
<a class="source" href="utils.html">
utils.js
</a>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>seed.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre>require(<span class="string">'coffee-script'</span>) <span class="comment">// for habitrpg-shared</span>
<span class="keyword">var</span> nconf = require(<span class="string">'nconf'</span>);
require(<span class="string">'./config'</span>);
<span class="keyword">var</span> async = require(<span class="string">'async'</span>);
<span class="keyword">var</span> mongoose = require(<span class="string">'mongoose'</span>);
User = require(<span class="string">'./models/user'</span>).model;
Group = require(<span class="string">'./models/group'</span>).model;
async.waterfall([
<span class="keyword">function</span>(cb){
mongoose.connect(nconf.get(<span class="string">'NODE_DB_URI'</span>), cb);
},
<span class="keyword">function</span>(cb){
Group.findById(<span class="string">'habitrpg'</span>, cb);
},
<span class="keyword">function</span>(tavern, cb){
console.log({tavern:tavern,cb:cb});
<span class="keyword">if</span> (!tavern) {
tavern = <span class="keyword">new</span> Group({
_id: <span class="string">'habitrpg'</span>,
chat: [],
leader: <span class="string">'9'</span>,
name: <span class="string">'HabitRPG'</span>,
type: <span class="string">'guild'</span>
});
tavern.save(cb)
} <span class="keyword">else</span> {
cb();
}
}
],<span class="keyword">function</span>(err){
<span class="keyword">if</span> (err) <span class="keyword">throw</span> err;
console.log(<span class="string">"Dont initializing database"</span>);
})</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

View file

@ -1,389 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>server.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page">
<a class="source" href="config.html">
config.js
</a>
<a class="source" href="middleware.html">
middleware.js
</a>
<a class="source" href="seed.html">
seed.js
</a>
<a class="source" href="server.html">
server.js
</a>
<a class="source" href="utils.html">
utils.js
</a>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>server.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre>require(<span class="string">'coffee-script'</span>) <span class="comment">// remove this once we've fully converted over</span>
<span class="keyword">var</span> express = require(<span class="string">"express"</span>);
<span class="keyword">var</span> http = require(<span class="string">"http"</span>);
<span class="keyword">var</span> path = require(<span class="string">"path"</span>);
<span class="keyword">var</span> app = express();
<span class="keyword">var</span> nconf = require(<span class="string">'nconf'</span>);
<span class="keyword">var</span> utils = require(<span class="string">'./utils'</span>);
<span class="keyword">var</span> middleware = require(<span class="string">'./middleware'</span>);
<span class="keyword">var</span> server;
<span class="keyword">var</span> TWO_WEEKS = <span class="number">1000</span> * <span class="number">60</span> * <span class="number">60</span> * <span class="number">24</span> * <span class="number">14</span>;</pre></div></div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>------------ Setup configurations ------------</p>
</div>
<div class="content"><div class='highlight'><pre>require(<span class="string">'./config'</span>);
process.on(<span class="string">"uncaughtException"</span>, <span class="keyword">function</span>(error) {</pre></div></div>
</li>
<li id="section-3">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<p>when we hit an error, send it to admin as an email. If no ADMIN_EMAIL is present, just send it to yourself (SMTP_USER)</p>
</div>
<div class="content"><div class='highlight'><pre> utils.sendEmail({
from: <span class="string">"HabitRPG &lt;"</span> + nconf.get(<span class="string">'SMTP_USER'</span>) + <span class="string">"&gt;"</span>,
to: nconf.get(<span class="string">'ADMIN_EMAIL'</span>) || nconf.get(<span class="string">'SMTP_USER'</span>),
subject: <span class="string">"HabitRPG Error"</span>,
text: error.stack
});
console.error(error.stack);
});</pre></div></div>
</li>
<li id="section-4">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-4">&#182;</a>
</div>
<p>------------ MongoDB Configuration ------------</p>
</div>
<div class="content"><div class='highlight'><pre>mongoose = require(<span class="string">'mongoose'</span>);
require(<span class="string">'./models/user'</span>); <span class="comment">//load up the user schema - TODO is this necessary?</span>
require(<span class="string">'./models/group'</span>);
mongoose.connect(nconf.get(<span class="string">'NODE_DB_URI'</span>), <span class="keyword">function</span>(err) {
<span class="keyword">if</span> (err) <span class="keyword">throw</span> err;
console.info(<span class="string">'Connected with Mongoose'</span>);
});</pre></div></div>
</li>
<li id="section-5">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">&#182;</a>
</div>
<p>------------ Passport Configuration ------------</p>
</div>
<div class="content"><div class='highlight'><pre><span class="keyword">var</span> passport = require(<span class="string">'passport'</span>)
<span class="keyword">var</span> util = require(<span class="string">'util'</span>)
<span class="keyword">var</span> FacebookStrategy = require(<span class="string">'passport-facebook'</span>).Strategy;</pre></div></div>
</li>
<li id="section-6">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-6">&#182;</a>
</div>
<p>Passport session setup.
To support persistent login sessions, Passport needs to be able to
serialize users into and deserialize users out of the session. Typically,
this will be as simple as storing the user ID when serializing, and finding
the user by ID when deserializing. However, since this example does not
have a database of user records, the complete Facebook profile is serialized
and deserialized.</p>
</div>
<div class="content"><div class='highlight'><pre>passport.serializeUser(<span class="keyword">function</span>(user, done) {
done(<span class="literal">null</span>, user);
});
passport.deserializeUser(<span class="keyword">function</span>(obj, done) {
done(<span class="literal">null</span>, obj);
});</pre></div></div>
</li>
<li id="section-7">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-7">&#182;</a>
</div>
<p>Use the FacebookStrategy within Passport.
Strategies in Passport require a <code>verify</code> function, which accept
credentials (in this case, an accessToken, refreshToken, and Facebook
profile), and invoke a callback with a user object.</p>
</div>
<div class="content"><div class='highlight'><pre>passport.use(<span class="keyword">new</span> FacebookStrategy({
clientID: nconf.get(<span class="string">"FACEBOOK_KEY"</span>),
clientSecret: nconf.get(<span class="string">"FACEBOOK_SECRET"</span>),
callbackURL: nconf.get(<span class="string">"BASE_URL"</span>) + <span class="string">"/auth/facebook/callback"</span>
},
<span class="keyword">function</span>(accessToken, refreshToken, profile, done) {</pre></div></div>
</li>
<li id="section-8">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-8">&#182;</a>
</div>
<p>asynchronous verification, for effect...
process.nextTick(function () {</p>
<p>To keep the example simple, the user&#39;s Facebook profile is returned to
represent the logged-in user. In a typical application, you would want
to associate the Facebook account with a user record in your database,
and return that user instead.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="keyword">return</span> done(<span class="literal">null</span>, profile);</pre></div></div>
</li>
<li id="section-9">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-9">&#182;</a>
</div>
<p>});</p>
</div>
<div class="content"><div class='highlight'><pre> }
));</pre></div></div>
</li>
<li id="section-10">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</a>
</div>
<p>------------ Server Configuration ------------</p>
</div>
<div class="content"><div class='highlight'><pre>app.set(<span class="string">"port"</span>, nconf.get(<span class="string">'PORT'</span>));
app.use(express.logger(<span class="string">"dev"</span>));
app.use(express.compress());
app.set(<span class="string">"views"</span>, __dirname + <span class="string">"/../views"</span>);
app.set(<span class="string">"view engine"</span>, <span class="string">"jade"</span>);
app.use(express.favicon());
app.use(middleware.cors);
app.use(middleware.forceSSL);
app.use(express.bodyParser());
app.use(express.methodOverride());</pre></div></div>
</li>
<li id="section-11">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-11">&#182;</a>
</div>
<p>app.use(express.cookieParser(nconf.get(&#39;SESSION_SECRET&#39;)));</p>
</div>
<div class="content"><div class='highlight'><pre>app.use(express.cookieParser());
app.use(express.cookieSession({ secret: nconf.get(<span class="string">'SESSION_SECRET'</span>), httpOnly: <span class="literal">false</span>, cookie: { maxAge: TWO_WEEKS }}));</pre></div></div>
</li>
<li id="section-12">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-12">&#182;</a>
</div>
<p>app.use(express.session());</p>
</div>
<div class="content"><div class='highlight'><pre>app.use(middleware.splash);
app.use(middleware.locals);</pre></div></div>
</li>
<li id="section-13">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-13">&#182;</a>
</div>
<p>Initialize Passport! Also use passport.session() middleware, to support
persistent login sessions (recommended).</p>
</div>
<div class="content"><div class='highlight'><pre>app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
<span class="keyword">var</span> oneYear = <span class="number">31536000000</span>;
app.use(express[<span class="string">'static'</span>](path.join(__dirname, <span class="string">"/../build"</span>), { maxAge: oneYear }));
app.use(express[<span class="string">'static'</span>](path.join(__dirname, <span class="string">"/../public"</span>)));</pre></div></div>
</li>
<li id="section-14">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-14">&#182;</a>
</div>
<p>development only</p>
</div>
<div class="content"><div class='highlight'><pre><span class="keyword">if</span> (<span class="string">"development"</span> === app.get(<span class="string">"env"</span>)) {
app.use(express.errorHandler());
}</pre></div></div>
</li>
<li id="section-15">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-15">&#182;</a>
</div>
<p>Custom Directives</p>
</div>
<div class="content"><div class='highlight'><pre>app.use(require(<span class="string">'./routes/pages'</span>).middleware);
app.use(require(<span class="string">'./routes/auth'</span>).middleware);
app.use(<span class="string">'/api/v1'</span>, require(<span class="string">'./routes/api'</span>).middleware);
app.use(require(<span class="string">'./controllers/deprecated'</span>).middleware);
server = http.createServer(app).listen(app.get(<span class="string">"port"</span>), <span class="keyword">function</span>() {
<span class="keyword">return</span> console.log(<span class="string">"Express server listening on port "</span> + app.get(<span class="string">"port"</span>));
});
module.exports = server;
<span class="comment">/*
#ONE_YEAR = 1000 * 60 * 60 * 24 * 365
#root = path.dirname path.dirname __dirname
#publicPath = path.join root, 'public'
#
#
#expressApp
# .use(express.favicon("#{publicPath}/favicon.ico"))
# # Gzip static files and serve from memory
# .use(gzippo.staticGzip(publicPath, maxAge: ONE_YEAR))
# # Gzip dynamically rendered content
# .use(express.compress())
# .use(middleware.translate)
# .use(auth.middleware(strategies, options))
# .use(serverError(root))
#
#
## Errors
#expressApp.all '*', (req) -&gt;
# throw "404: #{req.url}"
*/</span></pre></div></div>
</li>
</ul>
</div>
</body>
</html>

View file

@ -1,622 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>User.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page">
<a class="source" href="group.html">
group.js
</a>
<a class="source" href="user.html">
user.js
</a>
</div>
</li>
</ul>
<ul class="sections">
<li id="section-1">
<div class="annotation">
<div class="pilwrap for-h1">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
<h1>User.js</h1>
</div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>Defines the user data model (schema) for use via the API.</p>
<h2>Dependencies</h2>
</div>
</li>
<li id="section-3">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="keyword">var</span> mongoose = require(<span class="string">"mongoose"</span>);
<span class="keyword">var</span> Schema = mongoose.Schema;
<span class="keyword">var</span> helpers = require(<span class="string">'habitrpg-shared/script/helpers'</span>);
<span class="keyword">var</span> _ = require(<span class="string">'lodash'</span>);</pre></div></div>
</li>
<li id="section-4">
<div class="annotation">
<div class="pilwrap for-h2">
<a class="pilcrow" href="#section-4">&#182;</a>
</div>
<h2>User Schema</h2>
</div>
</li>
<li id="section-5">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="keyword">var</span> UserSchema = <span class="keyword">new</span> Schema({</pre></div></div>
</li>
<li id="section-6">
<div class="annotation">
<div class="pilwrap for-h3">
<a class="pilcrow" href="#section-6">&#182;</a>
</div>
<h3>UUID and API Token</h3>
</div>
<div class="content"><div class='highlight'><pre> _id: {
type: String,
<span class="string">'default'</span>: helpers.uuid
},
apiToken: {
type: String,
<span class="string">'default'</span>: helpers.uuid
},</pre></div></div>
</li>
<li id="section-7">
<div class="annotation">
<div class="pilwrap for-h3">
<a class="pilcrow" href="#section-7">&#182;</a>
</div>
<h3>Mongoode Update Object</h3>
<p>We want to know <em>every</em> time an object updates. Mongoose uses __v to designate when an object contains arrays which
have been updated (<a href="http://goo.gl/gQLz41">http://goo.gl/gQLz41</a>), but we want <em>every</em> update</p>
</div>
<div class="content"><div class='highlight'><pre> _v: {
type: Number,
<span class="string">'default'</span>: <span class="number">0</span>
},
achievements: {
originalUser: Boolean,
helpedHabit: Boolean,
ultimateGear: Boolean,
beastMaster: Boolean,
streak: Number
},
auth: {
facebook: Schema.Types.Mixed,
local: {
email: String,
hashed_password: String,
salt: String,
username: String
},
timestamps: {
created: {
type: Date,
<span class="string">'default'</span>: Date.now
},
loggedin: Date
}
},
backer: {
tier: Number,
admin: Boolean,
npc: String,
contributor: String,
tokensApplied: Boolean
},
balance: Number,
habitIds: Array,
dailyIds: Array,
todoIds: Array,
rewardIds: Array,
filters: {type: Schema.Types.Mixed, <span class="string">'default'</span>: {}},
flags: {
showTour: {type: Boolean, <span class="string">'default'</span>: <span class="literal">true</span>},
ads: {type: String, <span class="string">'default'</span>: <span class="string">'show'</span>}, <span class="comment">// FIXME make this a boolean, run migration</span>
dropsEnabled: {type: Boolean, <span class="string">'default'</span>: <span class="literal">false</span>},
itemsEnabled: {type: Boolean, <span class="string">'default'</span>: <span class="literal">false</span>},
newStuff: {type: String, <span class="string">'default'</span>: <span class="string">'hide'</span>}, <span class="comment">//FIXME to boolean (currently show/hide)</span>
rewrite: {type: Boolean, <span class="string">'default'</span>: <span class="literal">true</span>},
partyEnabled: Boolean, <span class="comment">// FIXME do we need this?</span>
petsEnabled: {type: Boolean, <span class="string">'default'</span>: <span class="literal">false</span>},
rest: {type: Boolean, <span class="string">'default'</span>: <span class="literal">false</span>} <span class="comment">// fixme - change to preferences.resting once we're off derby</span>
},
history: {
exp: [
{
date: Date,
value: Number
}
],
todos: [
{
data: Date,
value: Number
}
]
},
<span class="comment">/* FIXME remove?*/</span>
invitations: {
guilds: {type: Array, <span class="string">'default'</span>: []},
party: Schema.Types.Mixed
},
items: {
armor: Number,
weapon: Number,
head: Number,
shield: Number,
<span class="comment">/*FIXME - tidy this up, not the best way to store current pet*/</span>
currentPet: {
<span class="comment">/*Cactus*/</span>
text: String,
<span class="comment">/*Cactus*/</span>
name: String,
<span class="comment">/*3*/</span>
value: Number,
<span class="comment">/*"Find a hatching potion to pour on this egg, and one day it will hatch into a loyal pet.",*/</span>
notes: String,
<span class="comment">/*Skeleton*/</span>
modifier: String,
<span class="comment">/*Cactus-Skeleton*/</span>
str: String
},
eggs: [
{</pre></div></div>
</li>
<li id="section-8">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-8">&#182;</a>
</div>
<p>example: You&#39;ve found a Wolf Egg! Find a hatching potion to pour on this egg, and one day it will hatch into a loyal pet</p>
</div>
<div class="content"><div class='highlight'><pre> dialog: String,</pre></div></div>
</li>
<li id="section-9">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-9">&#182;</a>
</div>
<p>example: Wolf</p>
</div>
<div class="content"><div class='highlight'><pre> name: String,</pre></div></div>
</li>
<li id="section-10">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</a>
</div>
<p>example: Find a hatching potion to pour on this egg, and one day it will hatch into a loyal pet.</p>
</div>
<div class="content"><div class='highlight'><pre> notes: String,</pre></div></div>
</li>
<li id="section-11">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-11">&#182;</a>
</div>
<p>example: Wolf </p>
</div>
<div class="content"><div class='highlight'><pre> text: String,
<span class="comment">/* type: String, //Egg // this is forcing mongoose to return object as "[object Object]", but I don't think this is needed anyway? */</span></pre></div></div>
</li>
<li id="section-12">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-12">&#182;</a>
</div>
<p>example: 3</p>
</div>
<div class="content"><div class='highlight'><pre> value: Number
}
],
hatchingPotions: Array, <span class="comment">// ["Base", "Skeleton",...]</span>
lastDrop: {
date: {type: Date, <span class="string">'default'</span>: Date.now},
count: {type: Number, <span class="string">'default'</span>: <span class="number">0</span>}
},</pre></div></div>
</li>
<li id="section-13">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-13">&#182;</a>
</div>
<p>[&quot;BearCub-Base&quot;, &quot;Cactus-Base&quot;, ...]</p>
</div>
<div class="content"><div class='highlight'><pre> pets: Array
},</pre></div></div>
</li>
<li id="section-14">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-14">&#182;</a>
</div>
<p>FIXME store as Date?</p>
</div>
<div class="content"><div class='highlight'><pre> lastCron: {
type: Date,
<span class="string">'default'</span>: Date.now
},</pre></div></div>
</li>
<li id="section-15">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-15">&#182;</a>
</div>
<p>FIXME remove?</p>
</div>
<div class="content"><div class='highlight'><pre> party: {</pre></div></div>
</li>
<li id="section-16">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-16">&#182;</a>
</div>
<p>party._id // FIXME make these populate docs?</p>
</div>
<div class="content"><div class='highlight'><pre> current: String, <span class="comment">// party._id</span>
invitation: String, <span class="comment">// party._id</span>
lastMessageSeen: String,
leader: Boolean
},
preferences: {
armorSet: String,
dayStart: {type:Number, <span class="string">'default'</span>: <span class="number">0</span>},
gender: {type:String, <span class="string">'default'</span>: <span class="string">'m'</span>},
hair: {type:String, <span class="string">'default'</span>:<span class="string">'blond'</span>},
hideHeader: {type:Boolean, <span class="string">'default'</span>:<span class="literal">false</span>},
showHelm: {type:Boolean, <span class="string">'default'</span>:<span class="literal">true</span>},
skin: {type:String, <span class="string">'default'</span>:<span class="string">'white'</span>},
timezoneOffset: Number
},
profile: {
blurb: String,
imageUrl: String,
name: String,
websites: Array <span class="comment">// styled like --&gt; ["http://ocdevel.com" ]</span>
},
stats: {
hp: Number,
exp: Number,
gp: Number,
lvl: Number
},
tags: [
{</pre></div></div>
</li>
<li id="section-17">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-17">&#182;</a>
</div>
<p>FIXME use refs?</p>
</div>
<div class="content"><div class='highlight'><pre> id: String,
name: String
}
],</pre></div></div>
</li>
<li id="section-18">
<div class="annotation">
<div class="pilwrap for-h3">
<a class="pilcrow" href="#section-18">&#182;</a>
</div>
<h3>Tasks Definition</h3>
<p>We can&#39;t define <code>tasks</code> until we move off Derby, since Derby requires dictionary of objects. When we&#39;re off, migrate
to array of subdocs</p>
</div>
<div class="content"><div class='highlight'><pre> tasks: Schema.Types.Mixed
<span class="comment">/*
# history: {date, value}
# id
# notes
# tags { "4ddf03d9-54bd-41a3-b011-ca1f1d2e9371" : true },
# text
# type
# up
# down
# value
# completed
# priority: '!!'
# repeat {m: true, t: true}
# streak
*/</span>
}, {
strict: <span class="literal">true</span>
});</pre></div></div>
</li>
<li id="section-19">
<div class="annotation">
<div class="pilwrap for-h2">
<a class="pilcrow" href="#section-19">&#182;</a>
</div>
<h2>Legacy Derby Function?</h2>
</div>
</li>
<li id="section-20">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-20">&#182;</a>
</div>
<p>Derby requires a strange storage format for somethign called &quot;refLists&quot;. Here we hook into loading the data, so we
can provide a more &quot;expected&quot; storage format for our various helper methods. Since the attributes are passed by reference,
the underlying data will be modified too - so when we save back to the database, it saves it in the way Derby likes.
This will go away after the rewrite is complete</p>
</div>
<div class="content"><div class='highlight'><pre><span class="function"><span class="keyword">function</span> <span class="title">transformTaskLists</span><span class="params">(doc)</span> {</span>
_.each([<span class="string">'habit'</span>, <span class="string">'daily'</span>, <span class="string">'todo'</span>, <span class="string">'reward'</span>], <span class="keyword">function</span>(type) {</pre></div></div>
</li>
<li id="section-21">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-21">&#182;</a>
</div>
<p>we use <em>.transform instead of a simple </em>.where in order to maintain sort-order</p>
</div>
<div class="content"><div class='highlight'><pre> doc[type + <span class="string">"s"</span>] = _.reduce(doc[type + <span class="string">"Ids"</span>], <span class="keyword">function</span>(m, tid) {
<span class="keyword">if</span> (!doc.tasks[tid]) <span class="keyword">return</span> m; <span class="comment">// FIXME tmp hotfix, people still have null tasks?</span>
<span class="keyword">if</span> (!doc.tasks[tid].tags) doc.tasks[tid].tags = {}; <span class="comment">// FIXME remove this when we switch tasks to subdocs and can define tags default in schema</span>
m.push(doc.tasks[tid]);
<span class="keyword">return</span> m;
}, []);
});
}
UserSchema.post(<span class="string">'init'</span>, <span class="keyword">function</span>(doc) {
transformTaskLists(doc);
});
UserSchema.methods.toJSON = <span class="keyword">function</span>() {
<span class="keyword">var</span> doc = <span class="keyword">this</span>.toObject();
doc.id = doc._id;
transformTaskLists(doc); <span class="comment">// we need to also transform for our server-side routes</span></pre></div></div>
</li>
<li id="section-22">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-22">&#182;</a>
</div>
<p>FIXME? Is this a reference to <code>doc.filters</code> or just disabled code? Remove?</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="comment">/*</pre></div></div>
</li>
<li id="section-23">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-23">&#182;</a>
</div>
<p>Remove some unecessary data as far as client consumers are concerned
_.each([&#39;habit&#39;, &#39;daily&#39;, &#39;todo&#39;, &#39;reward&#39;], function(type) {
delete doc[&quot;#{type}Ids&quot;]
});
delete doc.tasks</p>
</div>
<div class="content"><div class='highlight'><pre> */
doc.filters = {};
return doc;
};</pre></div></div>
</li>
<li id="section-24">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-24">&#182;</a>
</div>
<p>FIXME - since we&#39;re using special @post(&#39;init&#39;) above, we need to flag when the original path was modified.
Custom setter/getter virtuals?</p>
</div>
<div class="content"><div class='highlight'><pre>UserSchema.pre(<span class="string">'save'</span>, <span class="keyword">function</span>(next) {
<span class="keyword">this</span>.markModified(<span class="string">'tasks'</span>);</pre></div></div>
</li>
<li id="section-25">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-25">&#182;</a>
</div>
<p>our own version incrementer</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="keyword">this</span>._v++;
next();
});
module.exports.schema = UserSchema;
module.exports.model = mongoose.model(<span class="string">"User"</span>, UserSchema);</pre></div></div>
</li>
</ul>
</div>
</body>
</html>

View file

@ -1,120 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>utils.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To &hellip;</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page">
<a class="source" href="config.html">
config.js
</a>
<a class="source" href="middleware.html">
middleware.js
</a>
<a class="source" href="seed.html">
seed.js
</a>
<a class="source" href="server.html">
server.js
</a>
<a class="source" href="utils.html">
utils.js
</a>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>utils.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">&#182;</a>
</div>
</div>
<div class="content"><div class='highlight'><pre><span class="keyword">var</span> nodemailer = require(<span class="string">'nodemailer'</span>);
<span class="keyword">var</span> nconf = require(<span class="string">'nconf'</span>);
<span class="keyword">var</span> crypto = require(<span class="string">'crypto'</span>);
module.exports.sendEmail = <span class="keyword">function</span>(mailData) {
<span class="keyword">var</span> smtpTransport = nodemailer.createTransport(<span class="string">"SMTP"</span>,{
service: nconf.get(<span class="string">'SMTP_SERVICE'</span>),
auth: {
user: nconf.get(<span class="string">'SMTP_USER'</span>),
pass: nconf.get(<span class="string">'SMTP_PASS'</span>)
}
});
smtpTransport.sendMail(mailData, <span class="keyword">function</span>(error, response){
<span class="keyword">if</span>(error){
console.log(error);
}<span class="keyword">else</span>{
console.log(<span class="string">"Message sent: "</span> + response.message);
}
smtpTransport.close(); <span class="comment">// shut down the connection pool, no more messages</span>
});
}</pre></div></div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>Encryption using <a href="http://dailyjs.com/2010/12/06/node-tutorial-5/">http://dailyjs.com/2010/12/06/node-tutorial-5/</a>
Note: would use <a href="https://github.com/davidwood/node-password-hash">password-hash</a>, but we need to run
model.query().equals(), so it&#39;s a PITA to work in their verify() function</p>
</div>
<div class="content"><div class='highlight'><pre>module.exports.encryptPassword = <span class="keyword">function</span>(password, salt) {
<span class="keyword">return</span> crypto.createHmac(<span class="string">'sha1'</span>, salt).update(password).digest(<span class="string">'hex'</span>);
}
module.exports.makeSalt = <span class="keyword">function</span>() {
<span class="keyword">var</span> len = <span class="number">10</span>;
<span class="keyword">return</span> crypto.randomBytes(Math.ceil(len / <span class="number">2</span>)).toString(<span class="string">'hex'</span>).substring(<span class="number">0</span>, len);
}</pre></div></div>
</li>
</ul>
</div>
</body>
</html>