Last active
December 20, 2015 16:29
-
-
Save tbjers/6162027 to your computer and use it in GitHub Desktop.
Node.js: Scaffolding Modern Web Applications with Flatiron
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Flatiron Example</title> | |
</head> | |
<body> | |
<div id="body"></div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var path = require('path') | |
, flatiron = require('flatiron') | |
, plates = require('plates') | |
, resourceful = require('resourceful') | |
, restful = require('restful') | |
, views = require('./app/plugins/plates.js') | |
, controllers = require('./app/plugins/controllers.js') | |
, app = module.exports = flatiron.app | |
, env = process.env.NODE_ENV || 'development' | |
// Configuration file | |
app.config.file({ file: path.join(__dirname, 'config.json') }) | |
// Load HTTP plugin | |
app.use(flatiron.plugins.http, { | |
headers: { | |
'x-powered-by': 'flatiron-' + flatiron.version | |
} | |
}) | |
// Use resourceful plugin, automatically loads resources | |
app.use(flatiron.plugins.resourceful, { root: __dirname }) | |
// Use plates plugin to support layouts and views | |
app.use(views, { root: __dirname }) | |
// Use controllers plugin to set up routes | |
app.use(controllers, { root: __dirname }) | |
// Use RESTful Director | |
app.use(restful, app.config.get('restful') || {}) | |
// Start application | |
app.start(app.config.get('port') || 4000, function (err) { | |
if (err) { | |
app.log.err(err) | |
throw err | |
} | |
var addr = app.server.address() | |
app.log.info('Server started on http://' + addr.address + ':' + addr.port + ' in ' + env) | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"port": "8000" | |
, "restful": { | |
"strict": true | |
, "explore": true | |
, "prefix": "api" | |
} | |
, "resourceful": { | |
"engine": "couchdb" | |
, "uri": "couchdb://localhost:5984/<DATABASE>" | |
, "auth": "<USER>:<PASS>" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var path = require('path'), | |
fs = require('fs'), | |
flatiron = require('flatiron'), | |
common = flatiron.common, | |
existsSync = fs.existsSync || path.existsSync | |
exports.name = 'controllers' | |
exports.attach = function (options) { | |
var app = this | |
options = options || {} | |
// | |
// Accept string `options`. | |
// | |
if (typeof options === 'string') | |
options = { root: options } | |
app.controllers = app.controllers || {} | |
// | |
// Load the controllers directory based on a few intelligent defaults: | |
// | |
// * `options.dir`: Explicit path to controllers directory | |
// * `options.root`: Relative root to the controllers directory ('/app/controllers') | |
// * `app.root`: Relative root to the controllers directory ('/app/controllers') | |
// | |
if (options.dir || options.root || app.root) { | |
app._controllerDir = options.dir | |
|| path.join(options.root || app.root, 'app', 'controllers') | |
try { | |
existsSync(app._controllerDir) | |
} | |
catch (err) { | |
console.error('invalid controller path: ' + app._controllerDir) | |
return | |
} | |
var files = common.tryReaddirSync(app._controllerDir) | |
if (files.length === 0) | |
console.warn('no controllers found at: ' + app._controllerDir) | |
files.forEach(function (file) { | |
file = file.replace('.js', '') | |
delete app.controllers[common.capitalize(file)] | |
app.controllers[common.capitalize(file)] = require( | |
path.resolve(app._controllerDir, file) | |
) | |
app.controllers[common.capitalize(file)].init() | |
}) | |
} | |
} | |
exports.init = function (done) { | |
var app = this | |
, options | |
// | |
// Attempt to merge defaults passed to `app.use(flatiron.plugins.controllers)` | |
// with any additional configuration that may have been loaded. | |
// | |
options = common.mixin( | |
{} | |
, app.options['controllers'] | |
, app.config.get('controllers') || {} | |
) | |
app.config.set('controllers', options) | |
done() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var flatiron = require('flatiron') | |
, app = flatiron.app | |
var indexGet = function () { | |
var req = this.req | |
, res = this.res | |
res.writeHead(200, { 'content-type': 'text/html' }) | |
res.end(app.view('index')) | |
} | |
module.exports.init = function () { | |
app.router.get('/', indexGet) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<h1>Aenean Nullam Tristique</h1> | |
<p>Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Curabitur blandit tempus porttitor. Donec id elit non mi porta gravida at eget metus. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "flatiron-example" | |
, "version": "0.0.0" | |
, "dependencies": { | |
"flatiron": "0.3.8" | |
, "plates": "0.4.8" | |
, "resourceful": "0.3.3" | |
, "restful": "0.4.4" | |
, "union": "0.3.7" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* plates.js: Top-level plugin for exposing plates to flatiron app | |
* | |
* Original version here: | |
* https://github.com/flatiron/flatiron/blob/scaffolding/lib/flatiron/plugins/plates.js | |
* | |
* (C) 2011, Nodejitsu Inc. | |
* MIT LICENSE | |
* | |
* Modified by @xorcode | |
*/ | |
var path = require('path') | |
, fs = require('fs') | |
, flatiron = require('flatiron') | |
, plates | |
try { | |
// | |
// Attempt to require plates | |
// | |
plates = require('plates') | |
} | |
catch (ex) { | |
// | |
// Do nothing since this is a progressive enhancement | |
// | |
console.warn('flatiron.plugins.plates requires the `plates` module from npm') | |
console.warn('install using `npm install plates`.') | |
console.trace() | |
process.exit(1) | |
} | |
exports.name = 'plates' | |
exports.attach = function (options) { | |
var app = this | |
if (!options) options = {} | |
exports._platesDir = options.dir || path.join(options.root, 'app', 'views') | |
exports._layoutsDir = options.layouts || path.join(exports._platesDir, 'layouts') | |
exports._defaultLayout = options.layout || 'app' | |
exports._extname = options.extname || '.html' | |
exports._cachedViews = {} | |
exports._cachedLayouts = {} | |
app.view = function (view, data, options) { | |
var layout | |
, html | |
if (!options) options = {} | |
if (process.env.NODE_ENV != 'production') { | |
exports._cachedViews = {} | |
exports._cachedLayouts = {} | |
} | |
layout = options.layout || exports._defaultLayout | |
if (!exports._cachedViews[view]) { | |
exports._cachedViews[view] = exports.readFileSync(path.join(exports._platesDir, view + exports._extname)) | |
} | |
html = exports._cachedViews[view] | |
if (layout) { | |
if (!exports._cachedLayouts[layout]) { | |
exports._cachedLayouts[layout] = exports.readFileSync(path.join(exports._layoutsDir, layout + exports._extname)) | |
} | |
html = plates.bind(exports._cachedLayouts[layout], { body: html }) | |
} | |
return plates.bind(html, data) | |
} | |
} | |
exports.readFileSync = function (file) { | |
try { | |
return fs.readFileSync(file, 'utf8') | |
} catch (ex) { | |
return '' | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* User resource | |
* | |
* Create password example: | |
* | |
* app.resources.User.create({ | |
* username: 'testuser' | |
* , email: 'testuser@example.org' | |
* , active: true | |
* }, function (err, user) { | |
* if (err || !user) | |
* return app.log.err(err) | |
* user.encryptPassword('thepassword', function (err, user) { | |
* if (err || !user) | |
* return app.log.error(err) | |
* user.save() | |
* }) | |
* }) | |
*/ | |
var resourceful = require('resourceful') | |
, crypto = require('crypto') | |
, utils = require('../utils') | |
module.exports = resourceful.define('user', function () { | |
this.restful = true | |
this.remote = true | |
this.string('username') | |
this.string('email', { format: 'email', required: false }) | |
this.string('salt') | |
this.string('key') | |
this.bool('active', { required: false, default: true }) | |
this.timestamps() | |
var encryptPassword = function (secret, callback) { | |
var that = this | |
utils.hasher({ | |
plaintext: secret | |
}, function (err, result) { | |
if (err) return callback(err) | |
that.salt = result.salt.toString('hex') | |
that.key = result.key.toString('hex') | |
callback(null, that) | |
}) | |
} | |
this.method('encryptPassword', encryptPassword) | |
var verifyPassword = function (secret, callback) { | |
var that = this | |
, salt = new Buffer(that.salt, 'hex') | |
utils.hasher({ | |
plaintext: secret | |
, salt: salt | |
}, function (err, result) { | |
if (err) return callback(err) | |
if (that.key === result.key.toString('hex')) | |
return callback(null, true) | |
return callback(null, false) | |
}) | |
} | |
this.method('verifyPassword', verifyPassword) | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var crypto = require('crypto') | |
module.exports = { | |
hasher: function (opts, callback) { | |
var that = this | |
if (!opts.plaintext) { | |
return crypto.randomBytes(6, function (err, buf) { | |
if (err) callback(err) | |
opts.plaintext = buf.toString('base64') | |
return that.hasher(opts, callback) | |
}) | |
} | |
if (!opts.salt) { | |
return crypto.randomBytes(64, function (err, buf) { | |
if (err) return callback(err) | |
opts.salt = buf | |
return that.hasher(opts, callback) | |
}) | |
} | |
opts.hash = 'sha1' | |
opts.iterations = opts.iterations || 10000 | |
return crypto.pbkdf2(opts.plaintext, opts.salt, opts.iterations, 64, function (err, key) { | |
if (err) return callback(err) | |
opts.key = new Buffer(key) | |
return callback(null, opts) | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
good work