mirror of
https://github.com/sudoxnym/habitica.git
synced 2026-08-05 03:52:14 +00:00
updated generated .html files of documentation.
This commit is contained in:
parent
48602e4f91
commit
784113e9c1
12 changed files with 2745 additions and 0 deletions
191
documentation/docs/api.html
Normal file
191
documentation/docs/api.html
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
<!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 …</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">¶</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 && npm install && 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">¶</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">¶</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">¶</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">¶</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>
|
||||
78
documentation/docs/auth.html
Normal file
78
documentation/docs/auth.html
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
<!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 …</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">¶</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>
|
||||
129
documentation/docs/config.html
Normal file
129
documentation/docs/config.html
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
<!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 …</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">¶</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">¶</a>
|
||||
</div>
|
||||
<p>.file('defaults', path.join(path.resolve(__dirname, '../config.json.example')))</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">¶</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&page=0");
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
if (conf.get('NODE_ENV') === "development") {
|
||||
Error.stackTraceLimit = Infinity;
|
||||
}</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
146
documentation/docs/deprecated.html
Normal file
146
documentation/docs/deprecated.html
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
<!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 …</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">¶</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>
|
||||
165
documentation/docs/group.html
Normal file
165
documentation/docs/group.html
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
<!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 …</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">¶</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">¶</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>
|
||||
471
documentation/docs/groups.html
Normal file
471
documentation/docs/groups.html
Normal file
|
|
@ -0,0 +1,471 @@
|
|||
<!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 …</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">¶</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 && 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">¶</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 && !~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">¶</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 && !~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">¶</a>
|
||||
</div>
|
||||
<pre><code> Group.find({type: 'guild', members: {'$in': [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 && !~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 && !~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">¶</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">¶</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">¶</a>
|
||||
</div>
|
||||
<p>If they're requesting a specific type, let'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> && 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">¶</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 && user.backer.contributor,
|
||||
npc: user.backer && 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">¶</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 && !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> && group._id == (user.invitations && user.invitations.party && 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> && user.invitations && 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 && invite.invitations.guilds && _.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 && !_.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">¶</a>
|
||||
</div>
|
||||
<p>req.body.type in 'guild', 'party'</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>
|
||||
180
documentation/docs/middleware.html
Normal file
180
documentation/docs/middleware.html
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
<!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 …</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">¶</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">¶</a>
|
||||
</div>
|
||||
<p>Note x-forwarded-proto is used by Heroku & nginx, you'll have to do something different if you'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>] && req.headers[<span class="string">'x-forwarded-proto'</span>] !== <span class="string">'https'</span>
|
||||
&& nconf.get(<span class="string">'NODE_ENV'</span>) === <span class="string">'production'</span>
|
||||
&& 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> && !req.headers[<span class="string">'x-api-user'</span>] && !req.headers[<span class="string">'x-api-key'</span>] && !(req.session && 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">¶</a>
|
||||
</div>
|
||||
<p> translate = (req, res, next) ->
|
||||
model = req.getModel()</p>
|
||||
<h1>Set locale to bg on dev</h1>
|
||||
<h1>model.set '_i18n.locale', 'bg' if process.env.NODE_ENV is "development"</h1>
|
||||
<p> next()</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content"><div class='highlight'><pre> */</pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
145
documentation/docs/pages.html
Normal file
145
documentation/docs/pages.html
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
<!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 …</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">¶</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">¶</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">¶</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>
|
||||
109
documentation/docs/seed.html
Normal file
109
documentation/docs/seed.html
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
<!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 …</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">¶</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>
|
||||
389
documentation/docs/server.html
Normal file
389
documentation/docs/server.html
Normal file
|
|
@ -0,0 +1,389 @@
|
|||
<!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 …</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">¶</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">¶</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">¶</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 <"</span> + nconf.get(<span class="string">'SMTP_USER'</span>) + <span class="string">">"</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">¶</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">¶</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">¶</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">¶</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">¶</a>
|
||||
</div>
|
||||
<p>asynchronous verification, for effect...
|
||||
process.nextTick(function () {</p>
|
||||
<p>To keep the example simple, the user'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">¶</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">¶</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">¶</a>
|
||||
</div>
|
||||
<p>app.use(express.cookieParser(nconf.get('SESSION_SECRET')));</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">¶</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">¶</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">¶</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">¶</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) ->
|
||||
# throw "404: #{req.url}"
|
||||
*/</span></pre></div></div>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
622
documentation/docs/user.html
Normal file
622
documentation/docs/user.html
Normal file
|
|
@ -0,0 +1,622 @@
|
|||
<!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 …</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">¶</a>
|
||||
</div>
|
||||
<h1>User.js</h1>
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-2">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-2">¶</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">¶</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">¶</a>
|
||||
</div>
|
||||
<h2>User Schema</h2>
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li id="section-5">
|
||||
<div class="annotation">
|
||||
|
||||
<div class="pilwrap ">
|
||||
<a class="pilcrow" href="#section-5">¶</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">¶</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">¶</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">¶</a>
|
||||
</div>
|
||||
<p>example: You'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">¶</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">¶</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">¶</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">¶</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">¶</a>
|
||||
</div>
|
||||
<p>["BearCub-Base", "Cactus-Base", ...]</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">¶</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">¶</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">¶</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 --> ["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">¶</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">¶</a>
|
||||
</div>
|
||||
<h3>Tasks Definition</h3>
|
||||
<p>We can't define <code>tasks</code> until we move off Derby, since Derby requires dictionary of objects. When we'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">¶</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">¶</a>
|
||||
</div>
|
||||
<p>Derby requires a strange storage format for somethign called "refLists". Here we hook into loading the data, so we
|
||||
can provide a more "expected" 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">¶</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">¶</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">¶</a>
|
||||
</div>
|
||||
<p>Remove some unecessary data as far as client consumers are concerned
|
||||
_.each(['habit', 'daily', 'todo', 'reward'], function(type) {
|
||||
delete doc["#{type}Ids"]
|
||||
});
|
||||
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">¶</a>
|
||||
</div>
|
||||
<p>FIXME - since we're using special @post('init') 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">¶</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>
|
||||
120
documentation/docs/utils.html
Normal file
120
documentation/docs/utils.html
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
<!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 …</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">¶</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">¶</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'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>
|
||||
Loading…
Reference in a new issue