Sails app
This commit is contained in:
45
.gitignore
vendored
Normal file
45
.gitignore
vendored
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
########################
|
||||||
|
# sails
|
||||||
|
########################
|
||||||
|
.sails
|
||||||
|
.waterline
|
||||||
|
.rigging
|
||||||
|
.tmp
|
||||||
|
|
||||||
|
|
||||||
|
########################
|
||||||
|
# node.js / npm
|
||||||
|
########################
|
||||||
|
lib-cov
|
||||||
|
*.seed
|
||||||
|
*.log
|
||||||
|
*.csv
|
||||||
|
*.dat
|
||||||
|
*.out
|
||||||
|
*.pid
|
||||||
|
*.gz
|
||||||
|
|
||||||
|
pids
|
||||||
|
logs
|
||||||
|
results
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
npm-debug.log
|
||||||
|
|
||||||
|
|
||||||
|
########################
|
||||||
|
# misc / editors
|
||||||
|
########################
|
||||||
|
*~
|
||||||
|
*#
|
||||||
|
.DS_STORE
|
||||||
|
.netbeans
|
||||||
|
nbproject
|
||||||
|
.idea
|
||||||
|
|
||||||
|
|
||||||
|
########################
|
||||||
|
# local config
|
||||||
|
########################
|
||||||
|
config/local.js
|
||||||
484
Gruntfile.js
Normal file
484
Gruntfile.js
Normal file
@@ -0,0 +1,484 @@
|
|||||||
|
/**
|
||||||
|
* Gruntfile
|
||||||
|
*
|
||||||
|
* If you created your Sails app with `sails new foo --linker`,
|
||||||
|
* the following files will be automatically injected (in order)
|
||||||
|
* into the EJS and HTML files in your `views` and `assets` folders.
|
||||||
|
*
|
||||||
|
* At the top part of this file, you'll find a few of the most commonly
|
||||||
|
* configured options, but Sails' integration with Grunt is also fully
|
||||||
|
* customizable. If you'd like to work with your assets differently
|
||||||
|
* you can change this file to do anything you like!
|
||||||
|
*
|
||||||
|
* More information on using Grunt to work with static assets:
|
||||||
|
* http://gruntjs.com/configuring-tasks
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = function (grunt) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CSS files to inject in order
|
||||||
|
* (uses Grunt-style wildcard/glob/splat expressions)
|
||||||
|
*
|
||||||
|
* By default, Sails also supports LESS in development and production.
|
||||||
|
* To use SASS/SCSS, Stylus, etc., edit the `sails-linker:devStyles` task
|
||||||
|
* below for more options. For this to work, you may need to install new
|
||||||
|
* dependencies, e.g. `npm install grunt-contrib-sass`
|
||||||
|
*/
|
||||||
|
|
||||||
|
var cssFilesToInject = [
|
||||||
|
'linker/**/*.css'
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Javascript files to inject in order
|
||||||
|
* (uses Grunt-style wildcard/glob/splat expressions)
|
||||||
|
*
|
||||||
|
* To use client-side CoffeeScript, TypeScript, etc., edit the
|
||||||
|
* `sails-linker:devJs` task below for more options.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var jsFilesToInject = [
|
||||||
|
|
||||||
|
// Below, as a demonstration, you'll see the built-in dependencies
|
||||||
|
// linked in the proper order order
|
||||||
|
|
||||||
|
// Bring in the socket.io client
|
||||||
|
'linker/js/socket.io.js',
|
||||||
|
|
||||||
|
// then beef it up with some convenience logic for talking to Sails.js
|
||||||
|
'linker/js/sails.io.js',
|
||||||
|
|
||||||
|
// A simpler boilerplate library for getting you up and running w/ an
|
||||||
|
// automatic listener for incoming messages from Socket.io.
|
||||||
|
'linker/js/app.js',
|
||||||
|
|
||||||
|
// *-> put other dependencies here <-*
|
||||||
|
|
||||||
|
// All of the rest of your app scripts imported here
|
||||||
|
'linker/**/*.js'
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client-side HTML templates are injected using the sources below
|
||||||
|
* The ordering of these templates shouldn't matter.
|
||||||
|
* (uses Grunt-style wildcard/glob/splat expressions)
|
||||||
|
*
|
||||||
|
* By default, Sails uses JST templates and precompiles them into
|
||||||
|
* functions for you. If you want to use jade, handlebars, dust, etc.,
|
||||||
|
* edit the relevant sections below.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var templateFilesToInject = [
|
||||||
|
'linker/**/*.html'
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// DANGER:
|
||||||
|
//
|
||||||
|
// With great power comes great responsibility.
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Modify css file injection paths to use
|
||||||
|
cssFilesToInject = cssFilesToInject.map(function (path) {
|
||||||
|
return '.tmp/public/' + path;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Modify js file injection paths to use
|
||||||
|
jsFilesToInject = jsFilesToInject.map(function (path) {
|
||||||
|
return '.tmp/public/' + path;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
templateFilesToInject = templateFilesToInject.map(function (path) {
|
||||||
|
return 'assets/' + path;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Get path to core grunt dependencies from Sails
|
||||||
|
var depsPath = grunt.option('gdsrc') || 'node_modules/sails/node_modules';
|
||||||
|
grunt.loadTasks(depsPath + '/grunt-contrib-clean/tasks');
|
||||||
|
grunt.loadTasks(depsPath + '/grunt-contrib-copy/tasks');
|
||||||
|
grunt.loadTasks(depsPath + '/grunt-contrib-concat/tasks');
|
||||||
|
grunt.loadTasks(depsPath + '/grunt-sails-linker/tasks');
|
||||||
|
grunt.loadTasks(depsPath + '/grunt-contrib-jst/tasks');
|
||||||
|
grunt.loadTasks(depsPath + '/grunt-contrib-watch/tasks');
|
||||||
|
grunt.loadTasks(depsPath + '/grunt-contrib-uglify/tasks');
|
||||||
|
grunt.loadTasks(depsPath + '/grunt-contrib-cssmin/tasks');
|
||||||
|
grunt.loadTasks(depsPath + '/grunt-contrib-less/tasks');
|
||||||
|
grunt.loadTasks(depsPath + '/grunt-contrib-coffee/tasks');
|
||||||
|
|
||||||
|
// Project configuration.
|
||||||
|
grunt.initConfig({
|
||||||
|
pkg: grunt.file.readJSON('package.json'),
|
||||||
|
|
||||||
|
copy: {
|
||||||
|
dev: {
|
||||||
|
files: [
|
||||||
|
{
|
||||||
|
expand: true,
|
||||||
|
cwd: './assets',
|
||||||
|
src: ['**/*.!(coffee)'],
|
||||||
|
dest: '.tmp/public'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
files: [
|
||||||
|
{
|
||||||
|
expand: true,
|
||||||
|
cwd: '.tmp/public',
|
||||||
|
src: ['**/*'],
|
||||||
|
dest: 'www'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
clean: {
|
||||||
|
dev: ['.tmp/public/**'],
|
||||||
|
build: ['www']
|
||||||
|
},
|
||||||
|
|
||||||
|
jst: {
|
||||||
|
dev: {
|
||||||
|
|
||||||
|
// To use other sorts of templates, specify the regexp below:
|
||||||
|
// options: {
|
||||||
|
// templateSettings: {
|
||||||
|
// interpolate: /\{\{(.+?)\}\}/g
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
|
||||||
|
files: {
|
||||||
|
'.tmp/public/jst.js': templateFilesToInject
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
less: {
|
||||||
|
dev: {
|
||||||
|
files: [
|
||||||
|
{
|
||||||
|
expand: true,
|
||||||
|
cwd: 'assets/styles/',
|
||||||
|
src: ['*.less'],
|
||||||
|
dest: '.tmp/public/styles/',
|
||||||
|
ext: '.css'
|
||||||
|
}, {
|
||||||
|
expand: true,
|
||||||
|
cwd: 'assets/linker/styles/',
|
||||||
|
src: ['*.less'],
|
||||||
|
dest: '.tmp/public/linker/styles/',
|
||||||
|
ext: '.css'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
coffee: {
|
||||||
|
dev: {
|
||||||
|
options:{
|
||||||
|
bare:true
|
||||||
|
},
|
||||||
|
files: [
|
||||||
|
{
|
||||||
|
expand: true,
|
||||||
|
cwd: 'assets/js/',
|
||||||
|
src: ['**/*.coffee'],
|
||||||
|
dest: '.tmp/public/js/',
|
||||||
|
ext: '.js'
|
||||||
|
}, {
|
||||||
|
expand: true,
|
||||||
|
cwd: 'assets/linker/js/',
|
||||||
|
src: ['**/*.coffee'],
|
||||||
|
dest: '.tmp/public/linker/js/',
|
||||||
|
ext: '.js'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
concat: {
|
||||||
|
js: {
|
||||||
|
src: jsFilesToInject,
|
||||||
|
dest: '.tmp/public/concat/production.js'
|
||||||
|
},
|
||||||
|
css: {
|
||||||
|
src: cssFilesToInject,
|
||||||
|
dest: '.tmp/public/concat/production.css'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
uglify: {
|
||||||
|
dist: {
|
||||||
|
src: ['.tmp/public/concat/production.js'],
|
||||||
|
dest: '.tmp/public/min/production.js'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
cssmin: {
|
||||||
|
dist: {
|
||||||
|
src: ['.tmp/public/concat/production.css'],
|
||||||
|
dest: '.tmp/public/min/production.css'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'sails-linker': {
|
||||||
|
|
||||||
|
devJs: {
|
||||||
|
options: {
|
||||||
|
startTag: '<!--SCRIPTS-->',
|
||||||
|
endTag: '<!--SCRIPTS END-->',
|
||||||
|
fileTmpl: '<script src="%s"></script>',
|
||||||
|
appRoot: '.tmp/public'
|
||||||
|
},
|
||||||
|
files: {
|
||||||
|
'.tmp/public/**/*.html': jsFilesToInject,
|
||||||
|
'views/**/*.html': jsFilesToInject,
|
||||||
|
'views/**/*.ejs': jsFilesToInject
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
prodJs: {
|
||||||
|
options: {
|
||||||
|
startTag: '<!--SCRIPTS-->',
|
||||||
|
endTag: '<!--SCRIPTS END-->',
|
||||||
|
fileTmpl: '<script src="%s"></script>',
|
||||||
|
appRoot: '.tmp/public'
|
||||||
|
},
|
||||||
|
files: {
|
||||||
|
'.tmp/public/**/*.html': ['.tmp/public/min/production.js'],
|
||||||
|
'views/**/*.html': ['.tmp/public/min/production.js'],
|
||||||
|
'views/**/*.ejs': ['.tmp/public/min/production.js']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
devStyles: {
|
||||||
|
options: {
|
||||||
|
startTag: '<!--STYLES-->',
|
||||||
|
endTag: '<!--STYLES END-->',
|
||||||
|
fileTmpl: '<link rel="stylesheet" href="%s">',
|
||||||
|
appRoot: '.tmp/public'
|
||||||
|
},
|
||||||
|
|
||||||
|
// cssFilesToInject defined up top
|
||||||
|
files: {
|
||||||
|
'.tmp/public/**/*.html': cssFilesToInject,
|
||||||
|
'views/**/*.html': cssFilesToInject,
|
||||||
|
'views/**/*.ejs': cssFilesToInject
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
prodStyles: {
|
||||||
|
options: {
|
||||||
|
startTag: '<!--STYLES-->',
|
||||||
|
endTag: '<!--STYLES END-->',
|
||||||
|
fileTmpl: '<link rel="stylesheet" href="%s">',
|
||||||
|
appRoot: '.tmp/public'
|
||||||
|
},
|
||||||
|
files: {
|
||||||
|
'.tmp/public/index.html': ['.tmp/public/min/production.css'],
|
||||||
|
'views/**/*.html': ['.tmp/public/min/production.css'],
|
||||||
|
'views/**/*.ejs': ['.tmp/public/min/production.css']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Bring in JST template object
|
||||||
|
devTpl: {
|
||||||
|
options: {
|
||||||
|
startTag: '<!--TEMPLATES-->',
|
||||||
|
endTag: '<!--TEMPLATES END-->',
|
||||||
|
fileTmpl: '<script type="text/javascript" src="%s"></script>',
|
||||||
|
appRoot: '.tmp/public'
|
||||||
|
},
|
||||||
|
files: {
|
||||||
|
'.tmp/public/index.html': ['.tmp/public/jst.js'],
|
||||||
|
'views/**/*.html': ['.tmp/public/jst.js'],
|
||||||
|
'views/**/*.ejs': ['.tmp/public/jst.js']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************
|
||||||
|
* Jade linkers (TODO: clean this up)
|
||||||
|
*******************************************/
|
||||||
|
|
||||||
|
devJsJADE: {
|
||||||
|
options: {
|
||||||
|
startTag: '// SCRIPTS',
|
||||||
|
endTag: '// SCRIPTS END',
|
||||||
|
fileTmpl: 'script(type="text/javascript", src="%s")',
|
||||||
|
appRoot: '.tmp/public'
|
||||||
|
},
|
||||||
|
files: {
|
||||||
|
'views/**/*.jade': jsFilesToInject
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
prodJsJADE: {
|
||||||
|
options: {
|
||||||
|
startTag: '// SCRIPTS',
|
||||||
|
endTag: '// SCRIPTS END',
|
||||||
|
fileTmpl: 'script(type="text/javascript", src="%s")',
|
||||||
|
appRoot: '.tmp/public'
|
||||||
|
},
|
||||||
|
files: {
|
||||||
|
'views/**/*.jade': ['.tmp/public/min/production.js']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
devStylesJADE: {
|
||||||
|
options: {
|
||||||
|
startTag: '// STYLES',
|
||||||
|
endTag: '// STYLES END',
|
||||||
|
fileTmpl: 'link(rel="stylesheet", href="%s")',
|
||||||
|
appRoot: '.tmp/public'
|
||||||
|
},
|
||||||
|
files: {
|
||||||
|
'views/**/*.jade': cssFilesToInject
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
prodStylesJADE: {
|
||||||
|
options: {
|
||||||
|
startTag: '// STYLES',
|
||||||
|
endTag: '// STYLES END',
|
||||||
|
fileTmpl: 'link(rel="stylesheet", href="%s")',
|
||||||
|
appRoot: '.tmp/public'
|
||||||
|
},
|
||||||
|
files: {
|
||||||
|
'views/**/*.jade': ['.tmp/public/min/production.css']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Bring in JST template object
|
||||||
|
devTplJADE: {
|
||||||
|
options: {
|
||||||
|
startTag: '// TEMPLATES',
|
||||||
|
endTag: '// TEMPLATES END',
|
||||||
|
fileTmpl: 'script(type="text/javascript", src="%s")',
|
||||||
|
appRoot: '.tmp/public'
|
||||||
|
},
|
||||||
|
files: {
|
||||||
|
'views/**/*.jade': ['.tmp/public/jst.js']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/************************************
|
||||||
|
* Jade linker end
|
||||||
|
************************************/
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
api: {
|
||||||
|
|
||||||
|
// API files to watch:
|
||||||
|
files: ['api/**/*']
|
||||||
|
},
|
||||||
|
assets: {
|
||||||
|
|
||||||
|
// Assets to watch:
|
||||||
|
files: ['assets/**/*'],
|
||||||
|
|
||||||
|
// When assets are changed:
|
||||||
|
tasks: ['compileAssets', 'linkAssets']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// When Sails is lifted:
|
||||||
|
grunt.registerTask('default', [
|
||||||
|
'compileAssets',
|
||||||
|
'linkAssets',
|
||||||
|
'watch'
|
||||||
|
]);
|
||||||
|
|
||||||
|
grunt.registerTask('compileAssets', [
|
||||||
|
'clean:dev',
|
||||||
|
'jst:dev',
|
||||||
|
'less:dev',
|
||||||
|
'copy:dev',
|
||||||
|
'coffee:dev'
|
||||||
|
]);
|
||||||
|
|
||||||
|
grunt.registerTask('linkAssets', [
|
||||||
|
|
||||||
|
// Update link/script/template references in `assets` index.html
|
||||||
|
'sails-linker:devJs',
|
||||||
|
'sails-linker:devStyles',
|
||||||
|
'sails-linker:devTpl',
|
||||||
|
'sails-linker:devJsJADE',
|
||||||
|
'sails-linker:devStylesJADE',
|
||||||
|
'sails-linker:devTplJADE'
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
// Build the assets into a web accessible folder.
|
||||||
|
// (handy for phone gap apps, chrome extensions, etc.)
|
||||||
|
grunt.registerTask('build', [
|
||||||
|
'compileAssets',
|
||||||
|
'linkAssets',
|
||||||
|
'clean:build',
|
||||||
|
'copy:build'
|
||||||
|
]);
|
||||||
|
|
||||||
|
// When sails is lifted in production
|
||||||
|
grunt.registerTask('prod', [
|
||||||
|
'clean:dev',
|
||||||
|
'jst:dev',
|
||||||
|
'less:dev',
|
||||||
|
'copy:dev',
|
||||||
|
'coffee:dev',
|
||||||
|
'concat',
|
||||||
|
'uglify',
|
||||||
|
'cssmin',
|
||||||
|
'sails-linker:prodJs',
|
||||||
|
'sails-linker:prodStyles',
|
||||||
|
'sails-linker:devTpl',
|
||||||
|
'sails-linker:prodJsJADE',
|
||||||
|
'sails-linker:prodStylesJADE',
|
||||||
|
'sails-linker:devTplJADE'
|
||||||
|
]);
|
||||||
|
|
||||||
|
// When API files are changed:
|
||||||
|
// grunt.event.on('watch', function(action, filepath) {
|
||||||
|
// grunt.log.writeln(filepath + ' has ' + action);
|
||||||
|
|
||||||
|
// // Send a request to a development-only endpoint on the server
|
||||||
|
// // which will reuptake the file that was changed.
|
||||||
|
// var baseurl = grunt.option('baseurl');
|
||||||
|
// var gruntSignalRoute = grunt.option('signalpath');
|
||||||
|
// var url = baseurl + gruntSignalRoute + '?action=' + action + '&filepath=' + filepath;
|
||||||
|
|
||||||
|
// require('http').get(url)
|
||||||
|
// .on('error', function(e) {
|
||||||
|
// console.error(filepath + ' has ' + action + ', but could not signal the Sails.js server: ' + e.message);
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
};
|
||||||
2
README.bak.md
Normal file
2
README.bak.md
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# lunch
|
||||||
|
### a Sails application
|
||||||
0
api/adapters/.gitkeep
Normal file
0
api/adapters/.gitkeep
Normal file
0
api/controllers/.gitkeep
Normal file
0
api/controllers/.gitkeep
Normal file
0
api/models/.gitkeep
Normal file
0
api/models/.gitkeep
Normal file
21
api/policies/isAuthenticated.js
Normal file
21
api/policies/isAuthenticated.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* isAuthenticated
|
||||||
|
*
|
||||||
|
* @module :: Policy
|
||||||
|
* @description :: Simple policy to allow any authenticated user
|
||||||
|
* Assumes that your login action in one of your controllers sets `req.session.authenticated = true;`
|
||||||
|
* @docs :: http://sailsjs.org/#!documentation/policies
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
module.exports = function(req, res, next) {
|
||||||
|
|
||||||
|
// User is allowed, proceed to the next policy,
|
||||||
|
// or if this is the last policy, the controller
|
||||||
|
if (req.session.authenticated) {
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
|
||||||
|
// User is not allowed
|
||||||
|
// (default res.forbidden() behavior can be overridden in `config/403.js`)
|
||||||
|
return res.forbidden('You are not permitted to perform this action.');
|
||||||
|
};
|
||||||
0
api/services/.gitkeep
Normal file
0
api/services/.gitkeep
Normal file
2
app.js
Normal file
2
app.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
// Start sails and pass it command line arguments
|
||||||
|
require('sails').lift(require('optimist').argv);
|
||||||
BIN
assets/favicon.ico
Normal file
BIN
assets/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 920 B |
0
assets/images/.gitkeep
Normal file
0
assets/images/.gitkeep
Normal file
0
assets/js/.gitkeep
Normal file
0
assets/js/.gitkeep
Normal file
71
assets/js/app.js
Normal file
71
assets/js/app.js
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/**
|
||||||
|
* app.js
|
||||||
|
*
|
||||||
|
* This file contains some conventional defaults for working with Socket.io + Sails.
|
||||||
|
* It is designed to get you up and running fast, but is by no means anything special.
|
||||||
|
*
|
||||||
|
* Feel free to change none, some, or ALL of this file to fit your needs!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
(function (io) {
|
||||||
|
|
||||||
|
// as soon as this file is loaded, connect automatically,
|
||||||
|
var socket = io.connect();
|
||||||
|
if (typeof console !== 'undefined') {
|
||||||
|
log('Connecting to Sails.js...');
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.on('connect', function socketConnected() {
|
||||||
|
|
||||||
|
// Listen for Comet messages from Sails
|
||||||
|
socket.on('message', function messageReceived(message) {
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
// Replace the following with your own custom logic
|
||||||
|
// to run when a new message arrives from the Sails.js
|
||||||
|
// server.
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
log('New comet message received :: ', message);
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
// Here's where you'll want to add any custom logic for
|
||||||
|
// when the browser establishes its socket connection to
|
||||||
|
// the Sails.js server.
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
log(
|
||||||
|
'Socket is now connected and globally accessible as `socket`.\n' +
|
||||||
|
'e.g. to send a GET request to Sails, try \n' +
|
||||||
|
'`socket.get("/", function (response) ' +
|
||||||
|
'{ console.log(response); })`'
|
||||||
|
);
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Expose connected `socket` instance globally so that it's easy
|
||||||
|
// to experiment with from the browser console while prototyping.
|
||||||
|
window.socket = socket;
|
||||||
|
|
||||||
|
|
||||||
|
// Simple log function to keep the example simple
|
||||||
|
function log () {
|
||||||
|
if (typeof console !== 'undefined') {
|
||||||
|
console.log.apply(console, arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
})(
|
||||||
|
|
||||||
|
// In case you're wrapping socket.io to prevent pollution of the global namespace,
|
||||||
|
// you can replace `window.io` with your own `io` here:
|
||||||
|
window.io
|
||||||
|
|
||||||
|
);
|
||||||
166
assets/js/sails.io.js
Normal file
166
assets/js/sails.io.js
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
/**
|
||||||
|
* sails.io.js
|
||||||
|
*
|
||||||
|
* This file allows you to send and receive socket.io messages to & from Sails
|
||||||
|
* by simulating a REST client interface on top of socket.io.
|
||||||
|
*
|
||||||
|
* It models its API after the $.ajax pattern from jQuery you might be familiar with.
|
||||||
|
*
|
||||||
|
* So to switch from using AJAX to Socket.io, instead of:
|
||||||
|
* `$.post( url, [data], [cb] )`
|
||||||
|
*
|
||||||
|
* You would use:
|
||||||
|
* `socket.post( url, [data], [cb] )`
|
||||||
|
*
|
||||||
|
* For more information, visit:
|
||||||
|
* http://sailsjs.org/#documentation
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (io) {
|
||||||
|
|
||||||
|
|
||||||
|
// We'll be adding methods to `io.SocketNamespace.prototype`, the prototype for the
|
||||||
|
// Socket instance returned when the browser connects with `io.connect()`
|
||||||
|
var Socket = io.SocketNamespace;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simulate a GET request to sails
|
||||||
|
* e.g.
|
||||||
|
* `socket.get('/user/3', Stats.populate)`
|
||||||
|
*
|
||||||
|
* @param {String} url :: destination URL
|
||||||
|
* @param {Object} params :: parameters to send with the request [optional]
|
||||||
|
* @param {Function} cb :: callback function to call when finished [optional]
|
||||||
|
*/
|
||||||
|
|
||||||
|
Socket.prototype.get = function (url, data, cb) {
|
||||||
|
return this.request(url, data, cb, 'get');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simulate a POST request to sails
|
||||||
|
* e.g.
|
||||||
|
* `socket.post('/event', newMeeting, $spinner.hide)`
|
||||||
|
*
|
||||||
|
* @param {String} url :: destination URL
|
||||||
|
* @param {Object} params :: parameters to send with the request [optional]
|
||||||
|
* @param {Function} cb :: callback function to call when finished [optional]
|
||||||
|
*/
|
||||||
|
|
||||||
|
Socket.prototype.post = function (url, data, cb) {
|
||||||
|
return this.request(url, data, cb, 'post');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simulate a PUT request to sails
|
||||||
|
* e.g.
|
||||||
|
* `socket.post('/event/3', changedFields, $spinner.hide)`
|
||||||
|
*
|
||||||
|
* @param {String} url :: destination URL
|
||||||
|
* @param {Object} params :: parameters to send with the request [optional]
|
||||||
|
* @param {Function} cb :: callback function to call when finished [optional]
|
||||||
|
*/
|
||||||
|
|
||||||
|
Socket.prototype.put = function (url, data, cb) {
|
||||||
|
return this.request(url, data, cb, 'put');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simulate a DELETE request to sails
|
||||||
|
* e.g.
|
||||||
|
* `socket.delete('/event', $spinner.hide)`
|
||||||
|
*
|
||||||
|
* @param {String} url :: destination URL
|
||||||
|
* @param {Object} params :: parameters to send with the request [optional]
|
||||||
|
* @param {Function} cb :: callback function to call when finished [optional]
|
||||||
|
*/
|
||||||
|
|
||||||
|
Socket.prototype['delete'] = function (url, data, cb) {
|
||||||
|
return this.request(url, data, cb, 'delete');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simulate HTTP over Socket.io
|
||||||
|
* @api private :: but exposed for backwards compatibility w/ <= sails@~0.8
|
||||||
|
*/
|
||||||
|
|
||||||
|
Socket.prototype.request = request;
|
||||||
|
function request (url, data, cb, method) {
|
||||||
|
|
||||||
|
var socket = this;
|
||||||
|
|
||||||
|
var usage = 'Usage:\n socket.' +
|
||||||
|
(method || 'request') +
|
||||||
|
'( destinationURL, dataToSend, fnToCallWhenComplete )';
|
||||||
|
|
||||||
|
// Remove trailing slashes and spaces
|
||||||
|
url = url.replace(/^(.+)\/*\s*$/, '$1');
|
||||||
|
|
||||||
|
// If method is undefined, use 'get'
|
||||||
|
method = method || 'get';
|
||||||
|
|
||||||
|
|
||||||
|
if ( typeof url !== 'string' ) {
|
||||||
|
throw new Error('Invalid or missing URL!\n' + usage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow data arg to be optional
|
||||||
|
if ( typeof data === 'function' ) {
|
||||||
|
cb = data;
|
||||||
|
data = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build to request
|
||||||
|
var json = io.JSON.stringify({
|
||||||
|
url: url,
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Send the message over the socket
|
||||||
|
socket.emit(method, json, function afterEmitted (result) {
|
||||||
|
|
||||||
|
var parsedResult = result;
|
||||||
|
|
||||||
|
if (result && typeof result === 'string') {
|
||||||
|
try {
|
||||||
|
parsedResult = io.JSON.parse(result);
|
||||||
|
} catch (e) {
|
||||||
|
if (typeof console !== 'undefined') {
|
||||||
|
console.warn("Could not parse:", result, e);
|
||||||
|
}
|
||||||
|
throw new Error("Server response could not be parsed!\n" + result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Handle errors more effectively
|
||||||
|
if (parsedResult === 404) throw new Error("404: Not found");
|
||||||
|
if (parsedResult === 403) throw new Error("403: Forbidden");
|
||||||
|
if (parsedResult === 500) throw new Error("500: Server error");
|
||||||
|
|
||||||
|
cb && cb(parsedResult);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}) (
|
||||||
|
|
||||||
|
// In case you're wrapping socket.io to prevent pollution of the global namespace,
|
||||||
|
// you can replace `window.io` with your own `io` here:
|
||||||
|
window.io
|
||||||
|
|
||||||
|
);
|
||||||
3328
assets/js/socket.io.js
Normal file
3328
assets/js/socket.io.js
Normal file
File diff suppressed because it is too large
Load Diff
6
assets/robots.txt
Normal file
6
assets/robots.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# The robots.txt file is used to control how search engines index your live URLs.
|
||||||
|
# See http://www.robotstxt.org/wc/norobots.html for more information.
|
||||||
|
#
|
||||||
|
# To prevent search engines from seeing the site altogether, uncomment the next two lines:
|
||||||
|
# User-Agent: *
|
||||||
|
# Disallow: /
|
||||||
0
assets/styles/.gitkeep
Normal file
0
assets/styles/.gitkeep
Normal file
73
config/400.js
Normal file
73
config/400.js
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/**
|
||||||
|
* Default 400 (Bad Request) handler
|
||||||
|
*
|
||||||
|
* Sails will automatically respond using this middleware when a blueprint is requested
|
||||||
|
* with missing or invalid parameters
|
||||||
|
* (e.g. `POST /user` was used to create a user, but required parameters were missing)
|
||||||
|
*
|
||||||
|
* This middleware can also be invoked manually from a controller or policy:
|
||||||
|
* res.badRequest( [validationErrors], [redirectTo] )
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param {Array|Object|String} validationErrors
|
||||||
|
* optional errors
|
||||||
|
* usually an array of validation errors from the ORM
|
||||||
|
*
|
||||||
|
* @param {String} redirectTo
|
||||||
|
* optional URL
|
||||||
|
* (absolute or relative, e.g. google.com/foo or /bar/baz)
|
||||||
|
* of the page to redirect to. Usually only relevant for traditional HTTP requests,
|
||||||
|
* since if this was triggered from an AJAX or socket request, JSON should be sent instead.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports[400] = function badRequest(validationErrors, redirectTo, req, res) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: This function is Sails middleware-- that means that not only do `req` and `res`
|
||||||
|
* work just like their Express equivalents to handle HTTP requests, they also simulate
|
||||||
|
* the same interface for receiving socket messages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var statusCode = 400;
|
||||||
|
|
||||||
|
var result = {
|
||||||
|
status: statusCode
|
||||||
|
};
|
||||||
|
|
||||||
|
// Optional validationErrors object
|
||||||
|
if (validationErrors) {
|
||||||
|
result.validationErrors = validationErrors;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For requesters expecting JSON, everything works like you would expect-- a simple JSON response
|
||||||
|
// indicating the 400: Bad Request status with relevant information will be returned.
|
||||||
|
if (req.wantsJSON) {
|
||||||
|
return res.json(result, result.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For traditional (not-AJAX) web forms, this middleware follows best-practices
|
||||||
|
// for when a user submits invalid form data:
|
||||||
|
// i. First, a one-time-use flash variable is populated, probably a string message or an array
|
||||||
|
// of semantic validation error objects.
|
||||||
|
// ii. Then the user is redirected back to `redirectTo`, i.e. the URL where the bad request originated.
|
||||||
|
// iii. There, the controller and/or view might use the flash `errors` to either display a message or highlight
|
||||||
|
// the invalid HTML form fields.
|
||||||
|
if (redirectTo) {
|
||||||
|
|
||||||
|
// Set flash message called `errors` (one-time-use in session)
|
||||||
|
req.flash('errors', validationErrors);
|
||||||
|
|
||||||
|
// then redirect back to the `redirectTo` URL
|
||||||
|
return res.redirect(redirectTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Depending on your app's needs, you may choose to look at the Referer header here
|
||||||
|
// and redirect back. Please do so at your own risk!
|
||||||
|
// For security reasons, Sails does not provide this affordance by default.
|
||||||
|
// It's safest to provide a 'redirectTo' URL and redirect there directly.
|
||||||
|
|
||||||
|
// If `redirectTo` was not specified, just respond w/ JSON
|
||||||
|
return res.json(result, result.status);
|
||||||
|
|
||||||
|
};
|
||||||
52
config/403.js
Normal file
52
config/403.js
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* Default 403 (Forbidden) middleware
|
||||||
|
*
|
||||||
|
* This middleware can be invoked from a controller or policy:
|
||||||
|
* res.forbidden( [message] )
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param {String|Object|Array} message
|
||||||
|
* optional message to inject into view locals or JSON response
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports[403] = function badRequest(message, req, res) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: This function is Sails middleware-- that means that not only do `req` and `res`
|
||||||
|
* work just like their Express equivalents to handle HTTP requests, they also simulate
|
||||||
|
* the same interface for receiving socket messages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var viewFilePath = '403';
|
||||||
|
var statusCode = 403;
|
||||||
|
|
||||||
|
var result = {
|
||||||
|
status: statusCode
|
||||||
|
};
|
||||||
|
|
||||||
|
// Optional message
|
||||||
|
if (message) {
|
||||||
|
result.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the user-agent wants a JSON response, send json
|
||||||
|
if (req.wantsJSON) {
|
||||||
|
return res.json(result, result.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set status code and view locals
|
||||||
|
res.status(result.status);
|
||||||
|
for (var key in result) {
|
||||||
|
res.locals[key] = result[key];
|
||||||
|
}
|
||||||
|
// And render view
|
||||||
|
res.render(viewFilePath, result, function (err) {
|
||||||
|
// If the view doesn't exist, or an error occured, send json
|
||||||
|
if (err) { return res.json(result, result.status); }
|
||||||
|
|
||||||
|
// Otherwise, serve the `views/403.*` page
|
||||||
|
res.render(viewFilePath);
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
38
config/404.js
Normal file
38
config/404.js
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
* Default 404 (Not Found) handler
|
||||||
|
*
|
||||||
|
* If no route matches are found for a request, Sails will respond using this handler.
|
||||||
|
*
|
||||||
|
* This middleware can also be invoked manually from a controller or policy:
|
||||||
|
* Usage: res.notFound()
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports[404] = function pageNotFound(req, res) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: This function is Sails middleware-- that means that not only do `req` and `res`
|
||||||
|
* work just like their Express equivalents to handle HTTP requests, they also simulate
|
||||||
|
* the same interface for receiving socket messages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var viewFilePath = '404';
|
||||||
|
var statusCode = 404;
|
||||||
|
var result = {
|
||||||
|
status: statusCode
|
||||||
|
};
|
||||||
|
|
||||||
|
// If the user-agent wants a JSON response, send json
|
||||||
|
if (req.wantsJSON) {
|
||||||
|
return res.json(result, result.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(result.status);
|
||||||
|
res.render(viewFilePath, function (err) {
|
||||||
|
// If the view doesn't exist, or an error occured, send json
|
||||||
|
if (err) { return res.json(result, result.status); }
|
||||||
|
|
||||||
|
// Otherwise, serve the `views/404.*` page
|
||||||
|
res.render(viewFilePath);
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
77
config/500.js
Normal file
77
config/500.js
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/**
|
||||||
|
* Default 500 (Server Error) middleware
|
||||||
|
*
|
||||||
|
* If an error is thrown in a policy or controller,
|
||||||
|
* Sails will respond using this default error handler
|
||||||
|
*
|
||||||
|
* This middleware can also be invoked manually from a controller or policy:
|
||||||
|
* res.serverError( [errors] )
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param {Array|Object|String} errors
|
||||||
|
* optional errors
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports[500] = function serverErrorOccurred(errors, req, res) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: This function is Sails middleware-- that means that not only do `req` and `res`
|
||||||
|
* work just like their Express equivalents to handle HTTP requests, they also simulate
|
||||||
|
* the same interface for receiving socket messages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var viewFilePath = '500',
|
||||||
|
statusCode = 500,
|
||||||
|
i, errorToLog, errorToJSON;
|
||||||
|
|
||||||
|
var result = {
|
||||||
|
status: statusCode
|
||||||
|
};
|
||||||
|
|
||||||
|
// Normalize a {String|Object|Error} or array of {String|Object|Error}
|
||||||
|
// into an array of proper, readable {Error}
|
||||||
|
var errorsToDisplay = sails.util.normalizeErrors(errors);
|
||||||
|
for (i in errorsToDisplay) {
|
||||||
|
|
||||||
|
// Log error(s) as clean `stack`
|
||||||
|
// (avoids ending up with \n, etc.)
|
||||||
|
if ( errorsToDisplay[i].original ) {
|
||||||
|
errorToLog = sails.util.inspect(errorsToDisplay[i].original);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
errorToLog = errorsToDisplay[i].stack;
|
||||||
|
}
|
||||||
|
sails.log.error('Server Error (500)');
|
||||||
|
sails.log.error(errorToLog);
|
||||||
|
|
||||||
|
// Use original error if it exists
|
||||||
|
errorToJSON = errorsToDisplay[i].original || errorsToDisplay[i].message;
|
||||||
|
errorsToDisplay[i] = errorToJSON;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only include errors if application environment is set to 'development'
|
||||||
|
// In production, don't display any identifying information about the error(s)
|
||||||
|
if (sails.config.environment === 'development') {
|
||||||
|
result.errors = errorsToDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the user-agent wants JSON, respond with JSON
|
||||||
|
if (req.wantsJSON) {
|
||||||
|
return res.json(result, result.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set status code and view locals
|
||||||
|
res.status(result.status);
|
||||||
|
for (var key in result) {
|
||||||
|
res.locals[key] = result[key];
|
||||||
|
}
|
||||||
|
// And render view
|
||||||
|
res.render(viewFilePath, result, function (err) {
|
||||||
|
// If the view doesn't exist, or an error occured, just send JSON
|
||||||
|
if (err) { return res.json(result, result.status); }
|
||||||
|
|
||||||
|
// Otherwise, if it can be rendered, the `views/500.*` page is rendered
|
||||||
|
res.render(viewFilePath, result);
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
39
config/adapters.js
Normal file
39
config/adapters.js
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* Global adapter config
|
||||||
|
*
|
||||||
|
* The `adapters` configuration object lets you create different global "saved settings"
|
||||||
|
* that you can mix and match in your models. The `default` option indicates which
|
||||||
|
* "saved setting" should be used if a model doesn't have an adapter specified.
|
||||||
|
*
|
||||||
|
* Keep in mind that options you define directly in your model definitions
|
||||||
|
* will override these settings.
|
||||||
|
*
|
||||||
|
* For more information on adapter configuration, check out:
|
||||||
|
* http://sailsjs.org/#documentation
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports.adapters = {
|
||||||
|
|
||||||
|
// If you leave the adapter config unspecified
|
||||||
|
// in a model definition, 'default' will be used.
|
||||||
|
'default': 'disk',
|
||||||
|
|
||||||
|
// Persistent adapter for DEVELOPMENT ONLY
|
||||||
|
// (data is preserved when the server shuts down)
|
||||||
|
disk: {
|
||||||
|
module: 'sails-disk'
|
||||||
|
},
|
||||||
|
|
||||||
|
// MySQL is the world's most popular relational database.
|
||||||
|
// Learn more: http://en.wikipedia.org/wiki/MySQL
|
||||||
|
myLocalMySQLDatabase: {
|
||||||
|
|
||||||
|
module: 'sails-mysql',
|
||||||
|
host: 'YOUR_MYSQL_SERVER_HOSTNAME_OR_IP_ADDRESS',
|
||||||
|
user: 'YOUR_MYSQL_USER',
|
||||||
|
// Psst.. You can put your password in config/local.js instead
|
||||||
|
// so you don't inadvertently push it up if you're using version control
|
||||||
|
password: 'YOUR_MYSQL_PASSWORD',
|
||||||
|
database: 'YOUR_MYSQL_DB'
|
||||||
|
}
|
||||||
|
};
|
||||||
16
config/bootstrap.js
vendored
Normal file
16
config/bootstrap.js
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/**
|
||||||
|
* Bootstrap
|
||||||
|
*
|
||||||
|
* An asynchronous boostrap function that runs before your Sails app gets lifted.
|
||||||
|
* This gives you an opportunity to set up your data model, run jobs, or perform some special logic.
|
||||||
|
*
|
||||||
|
* For more information on bootstrapping your app, check out:
|
||||||
|
* http://sailsjs.org/#documentation
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports.bootstrap = function (cb) {
|
||||||
|
|
||||||
|
// It's very important to trigger this callack method when you are finished
|
||||||
|
// with the bootstrap! (otherwise your server will never lift, since it's waiting on the bootstrap)
|
||||||
|
cb();
|
||||||
|
};
|
||||||
169
config/controllers.js
Normal file
169
config/controllers.js
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
/**
|
||||||
|
* Controllers
|
||||||
|
*
|
||||||
|
* By default, Sails inspects your controllers, models, and configuration and binds
|
||||||
|
* certain routes automatically. These dynamically generated routes are called blueprints.
|
||||||
|
*
|
||||||
|
* These settings are for the global configuration of controllers & blueprint routes.
|
||||||
|
* You may also override these settings on a per-controller basis by defining a '_config'
|
||||||
|
* key in any of your controller files, and assigning it an object, e.g.:
|
||||||
|
* {
|
||||||
|
* // ...
|
||||||
|
* _config: { blueprints: { rest: false } }
|
||||||
|
* // ...
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* For more information on configuring controllers and blueprints, check out:
|
||||||
|
* http://sailsjs.org/#documentation
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports.controllers = {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NOTE:
|
||||||
|
* A lot of the configuration options below affect so-called "CRUD methods",
|
||||||
|
* or your controllers' `find`, `create`, `update`, and `destroy` actions.
|
||||||
|
*
|
||||||
|
* It's important to realize that, even if you haven't defined these yourself, as long as
|
||||||
|
* a model exists with the same name as the controller, Sails will respond with built-in CRUD
|
||||||
|
* logic in the form of a JSON API, including support for sort, pagination, and filtering.
|
||||||
|
*/
|
||||||
|
blueprints: {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `actions`
|
||||||
|
*
|
||||||
|
* Action blueprints speed up backend development and shorten the development workflow by
|
||||||
|
* eliminating the need to manually bind routes.
|
||||||
|
* When enabled, GET, POST, PUT, and DELETE routes will be generated for every one of a controller's actions.
|
||||||
|
*
|
||||||
|
* If an `index` action exists, additional naked routes will be created for it.
|
||||||
|
* Finally, all `actions` blueprints support an optional path parameter, `id`, for convenience.
|
||||||
|
*
|
||||||
|
* For example, assume we have an EmailController with actions `send` and `index`.
|
||||||
|
* With `actions` enabled, the following blueprint routes would be bound at runtime:
|
||||||
|
*
|
||||||
|
* `EmailController.index`
|
||||||
|
* :::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
|
* `GET /email/:id?` `GET /email/index/:id?`
|
||||||
|
* `POST /email/:id?` `POST /email/index/:id?`
|
||||||
|
* `PUT /email/:id?` `PUT /email/index/:id?`
|
||||||
|
* `DELETE /email/:id?` `DELETE /email/index/:id?`
|
||||||
|
*
|
||||||
|
* `EmailController.send`
|
||||||
|
* :::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
|
* `GET /email/send/:id?`
|
||||||
|
* `POST /email/send/:id?`
|
||||||
|
* `PUT /email/send/:id?`
|
||||||
|
* `DELETE /email/send/:id?`
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* `actions` are enabled by default, and are OK for production-- however,
|
||||||
|
* you must take great care not to inadvertently expose unsafe controller logic to GET requests.
|
||||||
|
*/
|
||||||
|
actions: true,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `rest`
|
||||||
|
*
|
||||||
|
* REST blueprints are the automatically generated routes Sails uses to expose
|
||||||
|
* a conventional REST API on top of a controller's `find`, `create`, `update`, and `destroy`
|
||||||
|
* actions.
|
||||||
|
*
|
||||||
|
* For example, a BoatController with `rest` enabled generates the following routes:
|
||||||
|
* :::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
|
* GET /boat/:id? -> BoatController.find
|
||||||
|
* POST /boat -> BoatController.create
|
||||||
|
* PUT /boat/:id -> BoatController.update
|
||||||
|
* DELETE /boat/:id -> BoatController.destroy
|
||||||
|
*
|
||||||
|
* `rest` blueprints are enabled by default, and suitable for a production scenario.
|
||||||
|
*/
|
||||||
|
rest: true,
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `shortcuts`
|
||||||
|
*
|
||||||
|
* Shortcut blueprints are simple helpers to provide access to a controller's CRUD methods
|
||||||
|
* from your browser's URL bar. When enabled, GET, POST, PUT, and DELETE routes will be generated
|
||||||
|
* for the controller's`find`, `create`, `update`, and `destroy` actions.
|
||||||
|
*
|
||||||
|
* `shortcuts` are enabled by default, but SHOULD BE DISABLED IN PRODUCTION!!!!!
|
||||||
|
*/
|
||||||
|
shortcuts: true,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `prefix`
|
||||||
|
*
|
||||||
|
* An optional mount path for all blueprint routes on a controller, including `rest`,
|
||||||
|
* `actions`, and `shortcuts`. This allows you to continue to use blueprints, even if you
|
||||||
|
* need to namespace your API methods.
|
||||||
|
*
|
||||||
|
* For example, `prefix: '/api/v2'` would make the following REST blueprint routes
|
||||||
|
* for a FooController:
|
||||||
|
*
|
||||||
|
* `GET /api/v2/foo/:id?`
|
||||||
|
* `POST /api/v2/foo`
|
||||||
|
* `PUT /api/v2/foo/:id`
|
||||||
|
* `DELETE /api/v2/foo/:id`
|
||||||
|
*
|
||||||
|
* By default, no prefix is used.
|
||||||
|
*/
|
||||||
|
prefix: '',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `pluralize`
|
||||||
|
*
|
||||||
|
* Whether to pluralize controller names in generated routes
|
||||||
|
*
|
||||||
|
* For example, REST blueprints for `FooController` with `pluralize` enabled:
|
||||||
|
* GET /foos/:id?
|
||||||
|
* POST /foos
|
||||||
|
* PUT /foos/:id?
|
||||||
|
* DELETE /foos/:id?
|
||||||
|
*/
|
||||||
|
pluralize: false
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `jsonp`
|
||||||
|
*
|
||||||
|
* If enabled, allows built-in CRUD methods to support JSONP for cross-domain requests.
|
||||||
|
*
|
||||||
|
* Example usage (REST blueprint + UserController):
|
||||||
|
* `GET /user?name=ciaran&limit=10&callback=receiveJSONPResponse`
|
||||||
|
*
|
||||||
|
* Defaults to false.
|
||||||
|
*/
|
||||||
|
jsonp: false,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `expectIntegerId`
|
||||||
|
*
|
||||||
|
* If enabled, built-in CRUD methods will only accept valid integers as an :id parameter.
|
||||||
|
*
|
||||||
|
* i.e. trigger built-in API if requests look like:
|
||||||
|
* `GET /user/8`
|
||||||
|
* but not like:
|
||||||
|
* `GET /user/a8j4g9jsd9ga4ghjasdha`
|
||||||
|
*
|
||||||
|
* Defaults to false.
|
||||||
|
*/
|
||||||
|
expectIntegerId: false
|
||||||
|
|
||||||
|
};
|
||||||
49
config/cors.js
Normal file
49
config/cors.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* Cross-Origin Resource Sharing (CORS)
|
||||||
|
*
|
||||||
|
* CORS is like a more modern version of JSONP-- it allows your server/API
|
||||||
|
* to successfully respond to requests from client-side JavaScript code
|
||||||
|
* running on some other domain (e.g. google.com)
|
||||||
|
* Unlike JSONP, it works with POST, PUT, and DELETE requests
|
||||||
|
*
|
||||||
|
* For more information on CORS, check out:
|
||||||
|
* http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
|
||||||
|
*
|
||||||
|
* Note that any of these settings (besides 'allRoutes') can be changed on a per-route basis
|
||||||
|
* by adding a "cors" object to the route configuration:
|
||||||
|
*
|
||||||
|
* '/get foo': {
|
||||||
|
* controller: 'foo',
|
||||||
|
* action: 'bar',
|
||||||
|
* cors: {
|
||||||
|
* origin: 'http://foobar.com,https://owlhoot.com'
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports.cors = {
|
||||||
|
|
||||||
|
// Allow CORS on all routes by default? If not, you must enable CORS on a
|
||||||
|
// per-route basis by either adding a "cors" configuration object
|
||||||
|
// to the route config, or setting "cors:true" in the route config to
|
||||||
|
// use the default settings below.
|
||||||
|
allRoutes: false,
|
||||||
|
|
||||||
|
// Which domains which are allowed CORS access?
|
||||||
|
// This can be a comma-delimited list of hosts (beginning with http:// or https://)
|
||||||
|
// or "*" to allow all domains CORS access.
|
||||||
|
origin: '*',
|
||||||
|
|
||||||
|
// Allow cookies to be shared for CORS requests?
|
||||||
|
credentials: true,
|
||||||
|
|
||||||
|
// Which methods should be allowed for CORS requests? This is only used
|
||||||
|
// in response to preflight requests (see article linked above for more info)
|
||||||
|
methods: 'GET, POST, PUT, DELETE, OPTIONS, HEAD',
|
||||||
|
|
||||||
|
// Which headers should be allowed for CORS requests? This is only used
|
||||||
|
// in response to preflight requests.
|
||||||
|
headers: 'content-type'
|
||||||
|
|
||||||
|
};
|
||||||
40
config/csrf.js
Normal file
40
config/csrf.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* Cross-Site Request Forgery Protection
|
||||||
|
*
|
||||||
|
* CSRF tokens are like a tracking chip. While a session tells the server that a user
|
||||||
|
* "is who they say they are", a csrf token tells the server "you are where you say you are".
|
||||||
|
*
|
||||||
|
* When enabled, all non-GET requests to the Sails server must be accompanied by
|
||||||
|
* a special token, identified as the '_csrf' parameter.
|
||||||
|
*
|
||||||
|
* This option protects your Sails app against cross-site request forgery (or CSRF) attacks.
|
||||||
|
* A would-be attacker needs not only a user's session cookie, but also this timestamped,
|
||||||
|
* secret CSRF token, which is refreshed/granted when the user visits a URL on your app's domain.
|
||||||
|
*
|
||||||
|
* This allows us to have certainty that our users' requests haven't been hijacked,
|
||||||
|
* and that the requests they're making are intentional and legitimate.
|
||||||
|
*
|
||||||
|
* This token has a short-lived expiration timeline, and must be acquired by either:
|
||||||
|
*
|
||||||
|
* (a) For traditional view-driven web apps:
|
||||||
|
* Fetching it from one of your views, where it may be accessed as
|
||||||
|
* a local variable, e.g.:
|
||||||
|
* <form>
|
||||||
|
* <input type="hidden" name="_csrf" value="<%= _csrf %>" />
|
||||||
|
* </form>
|
||||||
|
*
|
||||||
|
* or (b) For AJAX/Socket-heavy and/or single-page apps:
|
||||||
|
* Sending a GET request to the `/csrfToken` route, where it will be returned
|
||||||
|
* as JSON, e.g.:
|
||||||
|
* { _csrf: 'ajg4JD(JGdajhLJALHDa' }
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Enabling this option requires managing the token in your front-end app.
|
||||||
|
* For traditional web apps, it's as easy as passing the data from a view into a form action.
|
||||||
|
* In AJAX/Socket-heavy apps, just send a GET request to the /csrfToken route to get a valid token.
|
||||||
|
*
|
||||||
|
* For more information on CSRF, check out:
|
||||||
|
* http://en.wikipedia.org/wiki/Cross-site_request_forgery
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports.csrf = false;
|
||||||
17
config/i18n.js
Normal file
17
config/i18n.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* Internationalization / Localization Settings
|
||||||
|
*
|
||||||
|
* If your app will touch people from all over the world, i18n (or internationalization)
|
||||||
|
* may be an important part of your international strategy.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* For more information, check out:
|
||||||
|
* http://sailsjs.org/#documentation
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports.i18n = {
|
||||||
|
|
||||||
|
// Which locales are supported?
|
||||||
|
locales: ['en', 'es', 'fr', 'de']
|
||||||
|
|
||||||
|
};
|
||||||
24
config/locales/_README.md
Normal file
24
config/locales/_README.md
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Internationalization / Localization Settings
|
||||||
|
|
||||||
|
## Locale
|
||||||
|
All locale files live under `config/locales`. Here is where you can add locale data as JSON key-value pairs. The name of the file should match the language that you are supporting, which allows for automatic language detection based on the user request.
|
||||||
|
|
||||||
|
Here is an example locale stringfile for the Spanish language (`config/locales/es.json`):
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Hello!": "Hola!",
|
||||||
|
"Hello %s, how are you today?": "¿Hola %s, como estas?",
|
||||||
|
}
|
||||||
|
```
|
||||||
|
## Usage
|
||||||
|
Locales can be accessed in controllers/policies through `res.i18n()`, or in views through the `__(key)` or `i18n(key)` functions.
|
||||||
|
Remember that the keys are case sensitive and require exact key matches, e.g.
|
||||||
|
|
||||||
|
```ejs
|
||||||
|
<h1> <%= __('Welcome to PencilPals!') %> </h1>
|
||||||
|
<h2> <%= i18n('Hello %s, how are you today?', 'Pencil Maven') %> </h2>
|
||||||
|
<p> <%= i18n('That\'s right-- you can use either i18n() or __()') %> </p>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
Localization/internationalization config can be found in `config/i18n.js`, from where you can set your supported locales.
|
||||||
3
config/locales/de.json
Normal file
3
config/locales/de.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"Welcome": "Wilkommen"
|
||||||
|
}
|
||||||
3
config/locales/en.json
Normal file
3
config/locales/en.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"Welcome": "Welcome"
|
||||||
|
}
|
||||||
3
config/locales/es.json
Normal file
3
config/locales/es.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"Welcome": "Bienvenido"
|
||||||
|
}
|
||||||
3
config/locales/fr.json
Normal file
3
config/locales/fr.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"Welcome": "Bienvenue"
|
||||||
|
}
|
||||||
27
config/log.js
Normal file
27
config/log.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* Logger configuration
|
||||||
|
*
|
||||||
|
* Configure the log level for your app, as well as the transport
|
||||||
|
* (Underneath the covers, Sails uses Winston for logging, which
|
||||||
|
* allows for some pretty neat custom transports/adapters for log messages)
|
||||||
|
*
|
||||||
|
* For more information on the Sails logger, check out:
|
||||||
|
* http://sailsjs.org/#documentation
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
|
||||||
|
// Valid `level` configs:
|
||||||
|
// i.e. the minimum log level to capture with sails.log.*()
|
||||||
|
//
|
||||||
|
// 'error' : Display calls to `.error()`
|
||||||
|
// 'warn' : Display calls from `.error()` to `.warn()`
|
||||||
|
// 'debug' : Display calls from `.error()`, `.warn()` to `.debug()`
|
||||||
|
// 'info' : Display calls from `.error()`, `.warn()`, `.debug()` to `.info()`
|
||||||
|
// 'verbose': Display calls from `.error()`, `.warn()`, `.debug()`, `.info()` to `.verbose()`
|
||||||
|
//
|
||||||
|
log: {
|
||||||
|
level: 'info'
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
83
config/policies.js
Normal file
83
config/policies.js
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/**
|
||||||
|
* Policy mappings (ACL)
|
||||||
|
*
|
||||||
|
* Policies are simply Express middleware functions which run **before** your controllers.
|
||||||
|
* You can apply one or more policies to a given controller, or protect just one of its actions.
|
||||||
|
*
|
||||||
|
* Any policy file (e.g. `authenticated.js`) can be dropped into the `/policies` folder,
|
||||||
|
* at which point it can be accessed below by its filename, minus the extension, (e.g. `authenticated`)
|
||||||
|
*
|
||||||
|
* For more information on policies, check out:
|
||||||
|
* http://sailsjs.org/#documentation
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
module.exports.policies = {
|
||||||
|
|
||||||
|
// Default policy for all controllers and actions
|
||||||
|
// (`true` allows public access)
|
||||||
|
'*': true
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Here's an example of adding some policies to a controller
|
||||||
|
RabbitController: {
|
||||||
|
|
||||||
|
// Apply the `false` policy as the default for all of RabbitController's actions
|
||||||
|
// (`false` prevents all access, which ensures that nothing bad happens to our rabbits)
|
||||||
|
'*': false,
|
||||||
|
|
||||||
|
// For the action `nurture`, apply the 'isRabbitMother' policy
|
||||||
|
// (this overrides `false` above)
|
||||||
|
nurture : 'isRabbitMother',
|
||||||
|
|
||||||
|
// Apply the `isNiceToAnimals` AND `hasRabbitFood` policies
|
||||||
|
// before letting any users feed our rabbits
|
||||||
|
feed : ['isNiceToAnimals', 'hasRabbitFood']
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Here's what the `isNiceToAnimals` policy from above might look like:
|
||||||
|
* (this file would be located at `policies/isNiceToAnimals.js`)
|
||||||
|
*
|
||||||
|
* We'll make some educated guesses about whether our system will
|
||||||
|
* consider this user someone who is nice to animals.
|
||||||
|
*
|
||||||
|
* Besides protecting rabbits (while a noble cause, no doubt),
|
||||||
|
* here are a few other example use cases for policies:
|
||||||
|
*
|
||||||
|
* + cookie-based authentication
|
||||||
|
* + role-based access control
|
||||||
|
* + limiting file uploads based on MB quotas
|
||||||
|
* + OAuth
|
||||||
|
* + BasicAuth
|
||||||
|
* + or any other kind of authentication scheme you can imagine
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
module.exports = function isNiceToAnimals (req, res, next) {
|
||||||
|
|
||||||
|
// `req.session` contains a set of data specific to the user making this request.
|
||||||
|
// It's kind of like our app's "memory" of the current user.
|
||||||
|
|
||||||
|
// If our user has a history of animal cruelty, not only will we
|
||||||
|
// prevent her from going even one step further (`return`),
|
||||||
|
// we'll go ahead and redirect her to PETA (`res.redirect`).
|
||||||
|
if ( req.session.user.hasHistoryOfAnimalCruelty ) {
|
||||||
|
return res.redirect('http://PETA.org');
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the user has been seen frowning at puppies, we have to assume that
|
||||||
|
// they might end up being mean to them, so we'll
|
||||||
|
if ( req.session.user.frownsAtPuppies ) {
|
||||||
|
return res.redirect('http://www.dailypuppy.com/');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, if the user has a clean record, we'll call the `next()` function
|
||||||
|
// to let them through to the next policy or our controller
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
*/
|
||||||
166
config/routes.js
Normal file
166
config/routes.js
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
/**
|
||||||
|
* Routes
|
||||||
|
*
|
||||||
|
* Sails uses a number of different strategies to route requests.
|
||||||
|
* Here they are top-to-bottom, in order of precedence.
|
||||||
|
*
|
||||||
|
* For more information on routes, check out:
|
||||||
|
* http://sailsjs.org/#documentation
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (1) Core middleware
|
||||||
|
*
|
||||||
|
* Middleware included with `app.use` is run first, before the router
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (2) Static routes
|
||||||
|
*
|
||||||
|
* This object routes static URLs to handler functions--
|
||||||
|
* In most cases, these functions are actions inside of your controllers.
|
||||||
|
* For convenience, you can also connect routes directly to views or external URLs.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports.routes = {
|
||||||
|
|
||||||
|
// By default, your root route (aka home page) points to a view
|
||||||
|
// located at `views/home/index.ejs`
|
||||||
|
//
|
||||||
|
// (This would also work if you had a file at: `/views/home.ejs`)
|
||||||
|
'/': {
|
||||||
|
view: 'home/index'
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// But what if you want your home page to display
|
||||||
|
// a signup form located at `views/user/signup.ejs`?
|
||||||
|
'/': {
|
||||||
|
view: 'user/signup'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Let's say you're building an email client, like Gmail
|
||||||
|
// You might want your home route to serve an interface using custom logic.
|
||||||
|
// In this scenario, you have a custom controller `MessageController`
|
||||||
|
// with an `inbox` action.
|
||||||
|
'/': 'MessageController.inbox'
|
||||||
|
|
||||||
|
|
||||||
|
// Alternatively, you can use the more verbose syntax:
|
||||||
|
'/': {
|
||||||
|
controller: 'MessageController',
|
||||||
|
action: 'inbox'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// If you decided to call your action `index` instead of `inbox`,
|
||||||
|
// since the `index` action is the default, you can shortcut even further to:
|
||||||
|
'/': 'MessageController'
|
||||||
|
|
||||||
|
|
||||||
|
// Up until now, we haven't specified a specific HTTP method/verb
|
||||||
|
// The routes above will apply to ALL verbs!
|
||||||
|
// If you want to set up a route only for one in particular
|
||||||
|
// (GET, POST, PUT, DELETE, etc.), just specify the verb before the path.
|
||||||
|
// For example, if you have a `UserController` with a `signup` action,
|
||||||
|
// and somewhere else, you're serving a signup form looks like:
|
||||||
|
//
|
||||||
|
// <form action="/signup">
|
||||||
|
// <input name="username" type="text"/>
|
||||||
|
// <input name="password" type="password"/>
|
||||||
|
// <input type="submit"/>
|
||||||
|
// </form>
|
||||||
|
|
||||||
|
// You would want to define the following route to handle your form:
|
||||||
|
'post /signup': 'UserController.signup'
|
||||||
|
|
||||||
|
|
||||||
|
// What about the ever-popular "vanity URLs" aka URL slugs?
|
||||||
|
// (you might remember doing this with `mod_rewrite` in Apache)
|
||||||
|
//
|
||||||
|
// This is where you want to set up root-relative dynamic routes like:
|
||||||
|
// http://yourwebsite.com/twinkletoez
|
||||||
|
//
|
||||||
|
// NOTE:
|
||||||
|
// You'll still want to allow requests through to the static assets,
|
||||||
|
// so we need to set up this route to ignore URLs that have a trailing ".":
|
||||||
|
// (e.g. your javascript, CSS, and image files)
|
||||||
|
'get /*(^.*)': 'UserController.profile'
|
||||||
|
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (3) Action blueprints
|
||||||
|
* These routes can be disabled by setting (in `config/controllers.js`):
|
||||||
|
* `module.exports.controllers.blueprints.actions = false`
|
||||||
|
*
|
||||||
|
* All of your controllers ' actions are automatically bound to a route. For example:
|
||||||
|
* + If you have a controller, `FooController`:
|
||||||
|
* + its action `bar` is accessible at `/foo/bar`
|
||||||
|
* + its action `index` is accessible at `/foo/index`, and also `/foo`
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (4) Shortcut CRUD blueprints
|
||||||
|
*
|
||||||
|
* These routes can be disabled by setting (in config/controllers.js)
|
||||||
|
* `module.exports.controllers.blueprints.shortcuts = false`
|
||||||
|
*
|
||||||
|
* If you have a model, `Foo`, and a controller, `FooController`,
|
||||||
|
* you can access CRUD operations for that model at:
|
||||||
|
* /foo/find/:id? -> search lampshades using specified criteria or with id=:id
|
||||||
|
*
|
||||||
|
* /foo/create -> create a lampshade using specified values
|
||||||
|
*
|
||||||
|
* /foo/update/:id -> update the lampshade with id=:id
|
||||||
|
*
|
||||||
|
* /foo/destroy/:id -> delete lampshade with id=:id
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (5) REST blueprints
|
||||||
|
*
|
||||||
|
* These routes can be disabled by setting (in config/controllers.js)
|
||||||
|
* `module.exports.controllers.blueprints.rest = false`
|
||||||
|
*
|
||||||
|
* If you have a model, `Foo`, and a controller, `FooController`,
|
||||||
|
* you can access CRUD operations for that model at:
|
||||||
|
*
|
||||||
|
* get /foo/:id? -> search lampshades using specified criteria or with id=:id
|
||||||
|
*
|
||||||
|
* post /foo -> create a lampshade using specified values
|
||||||
|
*
|
||||||
|
* put /foo/:id -> update the lampshade with id=:id
|
||||||
|
*
|
||||||
|
* delete /foo/:id -> delete lampshade with id=:id
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (6) Static assets
|
||||||
|
*
|
||||||
|
* Flat files in your `assets` directory- (these are sometimes referred to as 'public')
|
||||||
|
* If you have an image file at `/assets/images/foo.jpg`, it will be made available
|
||||||
|
* automatically via the route: `/images/foo.jpg`
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (7) 404 (not found) handler
|
||||||
|
*
|
||||||
|
* Finally, if nothing else matched, the default 404 handler is triggered.
|
||||||
|
* See `config/404.js` to adjust your app's 404 logic.
|
||||||
|
*/
|
||||||
|
|
||||||
56
config/session.js
Normal file
56
config/session.js
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* Session
|
||||||
|
*
|
||||||
|
* Sails session integration leans heavily on the great work already done by Express, but also unifies
|
||||||
|
* Socket.io with the Connect session store. It uses Connect's cookie parser to normalize configuration
|
||||||
|
* differences between Express and Socket.io and hooks into Sails' middleware interpreter to allow you
|
||||||
|
* to access and auto-save to `req.session` with Socket.io the same way you would with Express.
|
||||||
|
*
|
||||||
|
* For more information on configuring the session, check out:
|
||||||
|
* http://sailsjs.org/#documentation
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports.session = {
|
||||||
|
|
||||||
|
// Session secret is automatically generated when your new app is created
|
||||||
|
// Replace at your own risk in production-- you will invalidate the cookies of your users,
|
||||||
|
// forcing them to log in again.
|
||||||
|
secret: '7c4a87c5984e13546e5ee92cef884fc3'
|
||||||
|
|
||||||
|
|
||||||
|
// In production, uncomment the following lines to set up a shared redis session store
|
||||||
|
// that can be shared across multiple Sails.js servers
|
||||||
|
// adapter: 'redis',
|
||||||
|
//
|
||||||
|
// The following values are optional, if no options are set a redis instance running
|
||||||
|
// on localhost is expected.
|
||||||
|
// Read more about options at: https://github.com/visionmedia/connect-redis
|
||||||
|
//
|
||||||
|
// host: 'localhost',
|
||||||
|
// port: 6379,
|
||||||
|
// ttl: <redis session TTL in seconds>,
|
||||||
|
// db: 0,
|
||||||
|
// pass: <redis auth password>
|
||||||
|
// prefix: 'sess:'
|
||||||
|
|
||||||
|
|
||||||
|
// Uncomment the following lines to use your Mongo adapter as a session store
|
||||||
|
// adapter: 'mongo',
|
||||||
|
//
|
||||||
|
// host: 'localhost',
|
||||||
|
// port: 27017,
|
||||||
|
// db: 'sails',
|
||||||
|
// collection: 'sessions',
|
||||||
|
//
|
||||||
|
// Optional Values:
|
||||||
|
//
|
||||||
|
// # Note: url will override other connection settings
|
||||||
|
// url: 'mongodb://user:pass@host:port/database/collection',
|
||||||
|
//
|
||||||
|
// username: '',
|
||||||
|
// password: '',
|
||||||
|
// auto_reconnect: false,
|
||||||
|
// ssl: false,
|
||||||
|
// stringify: true
|
||||||
|
|
||||||
|
};
|
||||||
223
config/sockets.js
Normal file
223
config/sockets.js
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
/**
|
||||||
|
* Socket Configuration
|
||||||
|
*
|
||||||
|
* These configuration options provide transparent access to Sails' encapsulated
|
||||||
|
* pubsub/socket server for complete customizability.
|
||||||
|
*
|
||||||
|
* For more information on using Sails with Sockets, check out:
|
||||||
|
* http://sailsjs.org/#documentation
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports.sockets = {
|
||||||
|
|
||||||
|
// This custom onConnect function will be run each time AFTER a new socket connects
|
||||||
|
// (To control whether a socket is allowed to connect, check out `authorization` config.)
|
||||||
|
// Keep in mind that Sails' RESTful simulation for sockets
|
||||||
|
// mixes in socket.io events for your routes and blueprints automatically.
|
||||||
|
onConnect: function(session, socket) {
|
||||||
|
|
||||||
|
// By default: do nothing
|
||||||
|
// This is a good place to subscribe a new socket to a room, inform other users that
|
||||||
|
// someone new has come online, or any other custom socket.io logic
|
||||||
|
},
|
||||||
|
|
||||||
|
// This custom onDisconnect function will be run each time a socket disconnects
|
||||||
|
onDisconnect: function(session, socket) {
|
||||||
|
|
||||||
|
// By default: do nothing
|
||||||
|
// This is a good place to broadcast a disconnect message, or any other custom socket.io logic
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// `transports`
|
||||||
|
//
|
||||||
|
// A array of allowed transport methods which the clients will try to use.
|
||||||
|
// The flashsocket transport is disabled by default
|
||||||
|
// You can enable flashsockets by adding 'flashsocket' to this list:
|
||||||
|
transports: [
|
||||||
|
'websocket',
|
||||||
|
'htmlfile',
|
||||||
|
'xhr-polling',
|
||||||
|
'jsonp-polling'
|
||||||
|
],
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Use this option to set the datastore socket.io will use to manage rooms/sockets/subscriptions:
|
||||||
|
// default: memory
|
||||||
|
adapter: 'memory',
|
||||||
|
|
||||||
|
|
||||||
|
// Node.js (and consequently Sails.js) apps scale horizontally.
|
||||||
|
// It's a powerful, efficient approach, but it involves a tiny bit of planning.
|
||||||
|
// At scale, you'll want to be able to copy your app onto multiple Sails.js servers
|
||||||
|
// and throw them behind a load balancer.
|
||||||
|
//
|
||||||
|
// One of the big challenges of scaling an application is that these sorts of clustered
|
||||||
|
// deployments cannot share memory, since they are on physically different machines.
|
||||||
|
// On top of that, there is no guarantee that a user will "stick" with the same server between
|
||||||
|
// requests (whether HTTP or sockets), since the load balancer will route each request to the
|
||||||
|
// Sails server with the most available resources. However that means that all room/pubsub/socket
|
||||||
|
// processing and shared memory has to be offloaded to a shared, remote messaging queue (usually Redis)
|
||||||
|
//
|
||||||
|
// Luckily, Socket.io (and consequently Sails.js) apps support Redis for sockets by default.
|
||||||
|
// To enable a remote redis pubsub server:
|
||||||
|
// adapter: 'redis',
|
||||||
|
// host: '127.0.0.1',
|
||||||
|
// port: 6379,
|
||||||
|
// db: 'sails',
|
||||||
|
// pass: '<redis auth password>'
|
||||||
|
// Worth mentioning is that, if `adapter` config is `redis`,
|
||||||
|
// but host/port is left unset, Sails will try to connect to redis
|
||||||
|
// running on localhost via port 6379
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// `authorization`
|
||||||
|
//
|
||||||
|
// Global authorization for Socket.IO access,
|
||||||
|
// this is called when the initial handshake is performed with the server.
|
||||||
|
//
|
||||||
|
// By default (`authorization: true`), when a socket tries to connect, Sails verifies
|
||||||
|
// that a valid cookie was sent with the upgrade request. If the cookie doesn't match
|
||||||
|
// any known user session, a new user session is created for it.
|
||||||
|
//
|
||||||
|
// However, in the case of cross-domain requests, it is possible to receive a connection
|
||||||
|
// upgrade request WITHOUT A COOKIE (for certain transports)
|
||||||
|
// In this case, there is no way to keep track of the requesting user between requests,
|
||||||
|
// since there is no identifying information to link him/her with a session.
|
||||||
|
//
|
||||||
|
// If you don't care about keeping track of your socket users between requests,
|
||||||
|
// you can bypass this cookie check by setting `authorization: false`
|
||||||
|
// which will disable the session for socket requests (req.session is still accessible
|
||||||
|
// in each request, but it will be empty, and any changes to it will not be persisted)
|
||||||
|
//
|
||||||
|
// On the other hand, if you DO need to keep track of user sessions,
|
||||||
|
// you can pass along a ?cookie query parameter to the upgrade url,
|
||||||
|
// which Sails will use in the absense of a proper cookie
|
||||||
|
// e.g. (when connection from the client):
|
||||||
|
// io.connect('http://localhost:1337?cookie=smokeybear')
|
||||||
|
//
|
||||||
|
// (Un)fortunately, the user's cookie is (should!) not accessible in client-side js.
|
||||||
|
// Using HTTP-only cookies is crucial for your app's security.
|
||||||
|
// Primarily because of this situation, as well as a handful of other advanced
|
||||||
|
// use cases, Sails allows you to override the authorization behavior
|
||||||
|
// with your own custom logic by specifying a function, e.g:
|
||||||
|
/*
|
||||||
|
authorization: function authorizeAttemptedSocketConnection(reqObj, cb) {
|
||||||
|
|
||||||
|
// Any data saved in `handshake` is available in subsequent requests
|
||||||
|
// from this as `req.socket.handshake.*`
|
||||||
|
|
||||||
|
//
|
||||||
|
// to allow the connection, call `cb(null, true)`
|
||||||
|
// to prevent the connection, call `cb(null, false)`
|
||||||
|
// to report an error, call `cb(err)`
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
authorization: true,
|
||||||
|
|
||||||
|
// Match string representing the origins that are allowed to connect to the Socket.IO server
|
||||||
|
origins: '*:*',
|
||||||
|
|
||||||
|
// Should we use heartbeats to check the health of Socket.IO connections?
|
||||||
|
heartbeats: true,
|
||||||
|
|
||||||
|
// When client closes connection, the # of seconds to wait before attempting a reconnect.
|
||||||
|
// This value is sent to the client after a successful handshake.
|
||||||
|
'close timeout': 60,
|
||||||
|
|
||||||
|
// The # of seconds between heartbeats sent from the client to the server
|
||||||
|
// This value is sent to the client after a successful handshake.
|
||||||
|
'heartbeat timeout': 60,
|
||||||
|
|
||||||
|
// The max # of seconds to wait for an expcted heartbeat before declaring the pipe broken
|
||||||
|
// This number should be less than the `heartbeat timeout`
|
||||||
|
'heartbeat interval': 25,
|
||||||
|
|
||||||
|
// The maximum duration of one HTTP poll-
|
||||||
|
// if it exceeds this limit it will be closed.
|
||||||
|
'polling duration': 20,
|
||||||
|
|
||||||
|
// Enable the flash policy server if the flashsocket transport is enabled
|
||||||
|
// 'flash policy server': true,
|
||||||
|
|
||||||
|
// By default the Socket.IO client will check port 10843 on your server
|
||||||
|
// to see if flashsocket connections are allowed.
|
||||||
|
// The Adobe Flash Player normally uses 843 as default port,
|
||||||
|
// but Socket.io defaults to a non root port (10843) by default
|
||||||
|
//
|
||||||
|
// If you are using a hosting provider that doesn't allow you to start servers
|
||||||
|
// other than on port 80 or the provided port, and you still want to support flashsockets
|
||||||
|
// you can set the `flash policy port` to -1
|
||||||
|
'flash policy port': 10843,
|
||||||
|
|
||||||
|
// Used by the HTTP transports. The Socket.IO server buffers HTTP request bodies up to this limit.
|
||||||
|
// This limit is not applied to websocket or flashsockets.
|
||||||
|
'destroy buffer size': '10E7',
|
||||||
|
|
||||||
|
// Do we need to destroy non-socket.io upgrade requests?
|
||||||
|
'destroy upgrade': true,
|
||||||
|
|
||||||
|
// Should Sails/Socket.io serve the `socket.io.js` client?
|
||||||
|
// (as well as WebSocketMain.swf for Flash sockets, etc.)
|
||||||
|
'browser client': true,
|
||||||
|
|
||||||
|
// Cache the Socket.IO file generation in the memory of the process
|
||||||
|
// to speed up the serving of the static files.
|
||||||
|
'browser client cache': true,
|
||||||
|
|
||||||
|
// Does Socket.IO need to send a minified build of the static client script?
|
||||||
|
'browser client minification': false,
|
||||||
|
|
||||||
|
// Does Socket.IO need to send an ETag header for the static requests?
|
||||||
|
'browser client etag': false,
|
||||||
|
|
||||||
|
// Adds a Cache-Control: private, x-gzip-ok="", max-age=31536000 header to static requests,
|
||||||
|
// but only if the file is requested with a version number like /socket.io/socket.io.v0.9.9.js.
|
||||||
|
'browser client expires': 315360000,
|
||||||
|
|
||||||
|
// Does Socket.IO need to GZIP the static files?
|
||||||
|
// This process is only done once and the computed output is stored in memory.
|
||||||
|
// So we don't have to spawn a gzip process for each request.
|
||||||
|
'browser client gzip': false,
|
||||||
|
|
||||||
|
// Optional override function to serve all static files,
|
||||||
|
// including socket.io.js et al.
|
||||||
|
// Of the form :: function (req, res) { /* serve files */ }
|
||||||
|
'browser client handler': false,
|
||||||
|
|
||||||
|
// Meant to be used when running socket.io behind a proxy.
|
||||||
|
// Should be set to true when you want the location handshake to match the protocol of the origin.
|
||||||
|
// This fixes issues with terminating the SSL in front of Node
|
||||||
|
// and forcing location to think it's wss instead of ws.
|
||||||
|
'match origin protocol': false,
|
||||||
|
|
||||||
|
// Direct access to the socket.io MQ store config
|
||||||
|
// The 'adapter' property is the preferred method
|
||||||
|
// (`undefined` indicates that Sails should defer to the 'adapter' config)
|
||||||
|
store: undefined,
|
||||||
|
|
||||||
|
// A logger instance that is used to output log information.
|
||||||
|
// (`undefined` indicates deferment to the main Sails log config)
|
||||||
|
logger: undefined,
|
||||||
|
|
||||||
|
// The amount of detail that the server should output to the logger.
|
||||||
|
// (`undefined` indicates deferment to the main Sails log config)
|
||||||
|
'log level': undefined,
|
||||||
|
|
||||||
|
// Whether to color the log type when output to the logger.
|
||||||
|
// (`undefined` indicates deferment to the main Sails log config)
|
||||||
|
'log colors': undefined,
|
||||||
|
|
||||||
|
// A Static instance that is used to serve the socket.io client and its dependencies.
|
||||||
|
// (`undefined` indicates use default)
|
||||||
|
'static': undefined,
|
||||||
|
|
||||||
|
// The entry point where Socket.IO starts looking for incoming connections.
|
||||||
|
// This should be the same between the client and the server.
|
||||||
|
resource: '/socket.io'
|
||||||
|
|
||||||
|
};
|
||||||
72
config/views.js
Normal file
72
config/views.js
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
* Views
|
||||||
|
*
|
||||||
|
* Server-sent views are a classic and effective way to get your app up and running.
|
||||||
|
* Views are normally served from controllers. Below, you can configure your
|
||||||
|
* templating language/framework of choice and configure Sails' layout support.
|
||||||
|
*
|
||||||
|
* For more information on views and layouts, check out:
|
||||||
|
* http://sailsjs.org/#documentation
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports.views = {
|
||||||
|
|
||||||
|
// View engine (aka template language)
|
||||||
|
// to use for your app's *server-side* views
|
||||||
|
//
|
||||||
|
// Sails+Express supports all view engines which implement
|
||||||
|
// TJ Holowaychuk's `consolidate.js`, including, but not limited to:
|
||||||
|
//
|
||||||
|
// ejs, jade, handlebars, mustache
|
||||||
|
// underscore, hogan, haml, haml-coffee, dust
|
||||||
|
// atpl, eco, ect, jazz, jqtpl, JUST, liquor, QEJS,
|
||||||
|
// swig, templayed, toffee, walrus, & whiskers
|
||||||
|
|
||||||
|
// For more options, check out the docs:
|
||||||
|
// https://github.com/balderdashy/sails-wiki/blob/0.9/config.views.md#engine
|
||||||
|
|
||||||
|
engine: 'ejs',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Layouts are simply top-level HTML templates you can use as wrappers
|
||||||
|
// for your server-side views. If you're using ejs or jade, you can take advantage of
|
||||||
|
// Sails' built-in `layout` support.
|
||||||
|
//
|
||||||
|
// When using a layout, when one of your views is served, it is injected into
|
||||||
|
// the `body` partial defined in the layout. This lets you reuse header
|
||||||
|
// and footer logic between views.
|
||||||
|
//
|
||||||
|
// NOTE: Layout support is only implemented for the `ejs` view engine!
|
||||||
|
// For most other engines, it is not necessary, since they implement
|
||||||
|
// partials/layouts themselves. In those cases, this config will be silently
|
||||||
|
// ignored.
|
||||||
|
//
|
||||||
|
// The `layout` setting may be set to one of:
|
||||||
|
//
|
||||||
|
// If `true`, Sails will look for the default, located at `views/layout.ejs`
|
||||||
|
// If `false`, layouts will be disabled.
|
||||||
|
// Otherwise, if a string is specified, it will be interpreted as the relative path
|
||||||
|
// to your layout from `views/` folder.
|
||||||
|
// (the file extension, e.g. ".ejs", should be omitted)
|
||||||
|
//
|
||||||
|
|
||||||
|
layout: 'layout'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Using Multiple Layouts with EJS
|
||||||
|
//
|
||||||
|
// If you're using the default engine, `ejs`, Sails supports the use of multiple
|
||||||
|
// `layout` files. To take advantage of this, before rendering a view, override
|
||||||
|
// the `layout` local in your controller by setting `res.locals.layout`.
|
||||||
|
// (this is handy if you parts of your app's UI look completely different from each other)
|
||||||
|
//
|
||||||
|
// e.g. your default might be
|
||||||
|
// layout: 'layouts/public'
|
||||||
|
//
|
||||||
|
// But you might override that in some of your controllers with:
|
||||||
|
// layout: 'layouts/internal'
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
21
package.json
Normal file
21
package.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "lunch",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"description": "a Sails application",
|
||||||
|
"dependencies": {
|
||||||
|
"sails": "0.9.9",
|
||||||
|
"grunt": "0.4.1",
|
||||||
|
"sails-disk": "~0.9.0",
|
||||||
|
"ejs": "0.8.4",
|
||||||
|
"optimist": "0.3.4"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"start": "node app.js",
|
||||||
|
"debug": "node debug app.js"
|
||||||
|
},
|
||||||
|
"main": "app.js",
|
||||||
|
"repository": "",
|
||||||
|
"author": "",
|
||||||
|
"license": ""
|
||||||
|
}
|
||||||
76
views/403.ejs
Normal file
76
views/403.ejs
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
|
||||||
|
444444444 000000000 333333333333333
|
||||||
|
4::::::::4 00:::::::::00 3:::::::::::::::33
|
||||||
|
4:::::::::4 00:::::::::::::00 3::::::33333::::::3
|
||||||
|
4::::44::::4 0:::::::000:::::::03333333 3:::::3
|
||||||
|
4::::4 4::::4 0::::::0 0::::::0 3:::::3
|
||||||
|
4::::4 4::::4 0:::::0 0:::::0 3:::::3
|
||||||
|
4::::4 4::::4 0:::::0 0:::::0 33333333:::::3
|
||||||
|
4::::444444::::4440:::::0 000 0:::::0 3:::::::::::3
|
||||||
|
4::::::::::::::::40:::::0 000 0:::::0 33333333:::::3
|
||||||
|
4444444444:::::4440:::::0 0:::::0 3:::::3
|
||||||
|
4::::4 0:::::0 0:::::0 3:::::3
|
||||||
|
4::::4 0::::::0 0::::::0 3:::::3
|
||||||
|
4::::4 0:::::::000:::::::03333333 3:::::3
|
||||||
|
44::::::44 00:::::::::::::00 3::::::33333::::::3
|
||||||
|
4::::::::4 00:::::::::00 3:::::::::::::::33
|
||||||
|
4444444444 000000000 333333333333333
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
This is the default "403: Forbidden" page.
|
||||||
|
User agents that don't "Accept" HTML will see a JSON version instead.
|
||||||
|
You can customize the control logic for your needs in `config/403.js`
|
||||||
|
|
||||||
|
You can trigger this response from one of your controllers or policies with:
|
||||||
|
`return res.forbidden( msg );`
|
||||||
|
(where `msg` is an optional error message to include in the response)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-->
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Forbidden</title>
|
||||||
|
<link href='http://sailsjs.org/styles/fonts.css' rel='stylesheet'/>
|
||||||
|
<style>
|
||||||
|
/* Styles included inline since you'll probably be deleting or replacing this page anyway */
|
||||||
|
html,body{text-align:left;font-size:1em}html,body,img,form,textarea,input,fieldset,div,p,div,ul,li,ol,dl,dt,dd,h1,h2,h3,h4,h5,h6,pre,code{margin:0;padding:0}ul,li{list-style:none}img{display:block}a img{border:0}a{text-decoration:none;font-weight:normal;font-family:inherit}*:active,*:focus{outline:0;-moz-outline-style:none}h1,h2,h3,h4,h5,h6,h7{font-weight:normal;font-size:1em}.clearfix:after{clear:both;content:".";display:block;font-size:0;height:0;line-height:0;visibility:hidden}.page .ocean{background:url('http://sailsjs.com/images/waves.png') #0c8da0 no-repeat center 0;height:315px}.page .ocean img{margin-right:auto;margin-left:auto}.page .waves{display:block;padding-top:25px;margin-right:auto;margin-left:auto}.page .main{display:block;margin-top:90px}.page .logo{width:150px;margin-top:3.5em;margin-left:auto;margin-right:auto}.page .fishy{display:block;padding-top:100px}.page .help{padding-top:2em}.page h1{font-family:"Open Sans","Myriad Pro",Arial,sans-serif;font-weight:bold;font-size:1.7em;color:#001c20;text-align:center}.page h2{font-family:"Open Sans","Myriad Pro",Arial,sans-serif;font-weight:300;font-size:1.5em;color:#001c20;text-align:center}.page p{font-family:"Open Sans","Myriad Pro",Arial,sans-serif;font-size:1.25em;color:#001c20;text-align:center}.page a{color:#118798}.page a:hover{color:#b1eef7}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="page">
|
||||||
|
<div class="ocean">
|
||||||
|
<img class="fishy" src="http://sailsjs.com/images/image_devInTub.png">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="main">
|
||||||
|
<h1>
|
||||||
|
Forbidden
|
||||||
|
</h1>
|
||||||
|
<h2>
|
||||||
|
<% if (typeof message !== 'undefined') { %>
|
||||||
|
<%= message %>
|
||||||
|
<% } else { %>
|
||||||
|
You don't have permission to see the page you're trying to reach.
|
||||||
|
<% } %>
|
||||||
|
</h2>
|
||||||
|
<p class="help">
|
||||||
|
<a href="http://en.wikipedia.org/wiki/HTTP_403">Why</a> might this be happening?
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="logo">
|
||||||
|
<a href="http://sailsjs.org">
|
||||||
|
<img src="http://sailsjs.org/images/logo.png">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
72
views/404.ejs
Normal file
72
views/404.ejs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
|
||||||
|
444444444 000000000 444444444
|
||||||
|
4::::::::4 00:::::::::00 4::::::::4
|
||||||
|
4:::::::::4 00:::::::::::::00 4:::::::::4
|
||||||
|
4::::44::::4 0:::::::000:::::::0 4::::44::::4
|
||||||
|
4::::4 4::::4 0::::::0 0::::::0 4::::4 4::::4
|
||||||
|
4::::4 4::::4 0:::::0 0:::::0 4::::4 4::::4
|
||||||
|
4::::4 4::::4 0:::::0 0:::::0 4::::4 4::::4
|
||||||
|
4::::444444::::4440:::::0 000 0:::::04::::444444::::444
|
||||||
|
4::::::::::::::::40:::::0 000 0:::::04::::::::::::::::4
|
||||||
|
4444444444:::::4440:::::0 0:::::04444444444:::::444
|
||||||
|
4::::4 0:::::0 0:::::0 4::::4
|
||||||
|
4::::4 0::::::0 0::::::0 4::::4
|
||||||
|
4::::4 0:::::::000:::::::0 4::::4
|
||||||
|
44::::::44 00:::::::::::::00 44::::::44
|
||||||
|
4::::::::4 00:::::::::00 4::::::::4
|
||||||
|
4444444444 000000000 4444444444
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
This is the default "404: Not Found" page.
|
||||||
|
User agents that don't "Accept" HTML will see a JSON version instead.
|
||||||
|
You can customize the control logic for your needs in `config/404.js`
|
||||||
|
|
||||||
|
Sails considers a request to be in a "404: Not Found" state when a user
|
||||||
|
requests a URL which doesn't match any of your app's routes or blueprints.
|
||||||
|
|
||||||
|
You can also trigger this response from one of your controllers or policies with:
|
||||||
|
`return res.notFound();`
|
||||||
|
|
||||||
|
|
||||||
|
-->
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Page Not Found</title>
|
||||||
|
<link href='http://sailsjs.org/styles/fonts.css' rel='stylesheet'/>
|
||||||
|
<style>
|
||||||
|
/* Styles included inline since you'll probably be deleting this page anyway */
|
||||||
|
html,body{text-align:left;font-size:1em}html,body,img,form,textarea,input,fieldset,div,p,div,ul,li,ol,dl,dt,dd,h1,h2,h3,h4,h5,h6,pre,code{margin:0;padding:0}ul,li{list-style:none}img{display:block}a img{border:0}a{text-decoration:none;font-weight:normal;font-family:inherit}*:active,*:focus{outline:0;-moz-outline-style:none}h1,h2,h3,h4,h5,h6,h7{font-weight:normal;font-size:1em}.clearfix:after{clear:both;content:".";display:block;font-size:0;height:0;line-height:0;visibility:hidden}.fourohfour .ocean{background:url('http://sailsjs.com/images/waves.png') #0c8da0 no-repeat center 0;height:315px}.fourohfour .ocean img{margin-right:auto;margin-left:auto}.fourohfour .waves{display:block;padding-top:25px;margin-right:auto;margin-left:auto}.fourohfour .main{display:block;margin-top:90px}.fourohfour .logo{width:150px;margin-top:3.5em;margin-left:auto;margin-right:auto}.fourohfour .fishy{display:block;padding-top:27px}.fourohfour .help{padding-top:2em}.fourohfour h1{font-family:"Open Sans","Myriad Pro",Arial,sans-serif;font-weight:bold;font-size:1.7em;color:#001c20;text-align:center}.fourohfour h2{font-family:"Open Sans","Myriad Pro",Arial,sans-serif;font-weight:300;font-size:1.5em;color:#001c20;text-align:center}.fourohfour p{font-family:"Open Sans","Myriad Pro",Arial,sans-serif;font-size:1.25em;color:#001c20;text-align:center}.fourohfour a{color:#118798}.fourohfour a:hover{color:#b1eef7}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="fourohfour">
|
||||||
|
<div class="ocean">
|
||||||
|
<img class="fishy" src="http://sailsjs.org/images/fishy4.png">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="main">
|
||||||
|
<h1>
|
||||||
|
Something's fishy here.
|
||||||
|
</h1>
|
||||||
|
<h2>
|
||||||
|
The page you were trying to reach doesn't exist.
|
||||||
|
</h2>
|
||||||
|
<p class="help">
|
||||||
|
<a href="http://en.wikipedia.org/wiki/HTTP_404">Why</a> might this be happening?
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="logo">
|
||||||
|
<a href="http://sailsjs.org">
|
||||||
|
<img src="http://sailsjs.org/images/logo.png">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
86
views/500.ejs
Normal file
86
views/500.ejs
Normal file
File diff suppressed because one or more lines are too long
93
views/home/index.ejs
Normal file
93
views/home/index.ejs
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
<!-- Default home page -->
|
||||||
|
<link type="text/css" href='http://sailsjs.org/styles/fonts.css' rel='stylesheet'/>
|
||||||
|
<style>
|
||||||
|
/* Styles included inline since you'll probably be deleting this page anyway */
|
||||||
|
html,body{text-align:left;font-size:1em}html,body,img,form,textarea,input,fieldset,div,p,div,ul,li,ol,dl,dt,dd,h1,h2,h3,h4,h5,h6,pre,code{margin:0;padding:0}ul,li{list-style:none}img{display:block}a img{border:0}a{text-decoration:none;font-weight:normal;font-family:inherit}*:active,*:focus{outline:0;-moz-outline-style:none}h1,h2,h3,h4,h5,h6{font-weight:normal}div.clear{clear:both}.clearfix:after{clear:both;content:".";display:block;font-size:0;height:0;line-height:0;visibility:hidden}body{font-family:"Open Sans",Arial,sans-serif;font-weight:300;font-size:15px}h1{color:#0c8da0;font-size:2em;font-weight:300}h2{font-size:1.5em;font-weight:300;margin-top:4%}h3{font-size:1.25em;font-weight:300;font-style:italic;margin-bottom:5px}h4{color:#0c8da0;font-weight:300;font-size:1.5em}span{font-weight:700}ul{margin-top:5%;margin-bottom:5%}a{text-decoration:none;color:inherit}p{margin-bottom:7px;font-size:.9em}.container{max-width:997px;margin:0 auto;padding:0 4%}.sprite{font-weight:normal;background:url(http://sailsjs.org/images/newapp.sprite.png) no-repeat}.top-bar{position:relative;padding-top:10px;background-color:#001c20;height:55px}.main{float:left;max-width:610px;height:555px;margin-top:50px}.steps{height:250px}.getting-started p{ margin-bottom: 30px; line-height: 26px; }.getting-started div{float:left;width:540px}.getting-started li{clear:both;height:60px;margin-top:20px;margin-bottom:20px}.getting-started .sprite{margin-left:10px;padding-left:60px;height:42px;width:0}.getting-started .one{background-position:0 0}.getting-started .two{background-position:0 -42px}.getting-started .three{background-position:0 -83px}.delete{margin-top:5%;height:52px;background:#e3f0f1;border:1px solid #118798;color:#118798;clear:both}.delete .sprite{margin-top:10px;margin-bottom:10px;margin-left:9%;padding-left:42px;padding-top:7px;height:25px;background-position:0 -126px}.delete a{color:#0c8da0;font-weight:bold;padding-left:1%}.side-bar{max-width:327px;height:555px;float:left;border-left:1px solid #0c8da0;margin-left:25px;margin-top:50px;padding-left:25px}.side-bar ul{margin-bottom:10%}.side-bar ul li{margin-top:5px;margin-bottom:.25em}.side-bar ul li a{margin-bottom:.25em}.side-bar .sprite{padding-left:25px}.side-bar .single_page{background-position:0 -199px}.side-bar .traditional{background-position:0 -219px}.side-bar .realtime{background-position:0 -179px}.side-bar .api{background-position:0 -158px}.boxy{font-family:Courier,"Courier New",sans-serif;background-color:#e4edec;border:1px solid #d0d6d6;padding-left:5px;padding-right:5px;padding-top:2px;padding-bottom:2px;font-weight:100}.sixteen{margin-right:10px}.nineteen{margin-right:7px}
|
||||||
|
.main { width: 100%; }
|
||||||
|
body { min-width: 925px; }
|
||||||
|
</style>
|
||||||
|
<!--[if IE 7]>
|
||||||
|
<style>
|
||||||
|
.getting-started li{overflow:visible;clear:both}.delete{width:690px}
|
||||||
|
</style>
|
||||||
|
<![endif]-->
|
||||||
|
|
||||||
|
<div class="top-bar">
|
||||||
|
<div class="container clearfix">
|
||||||
|
<img class="logo" src="http://sailsjs.org/images/sails-logo.jpg" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container clearfix">
|
||||||
|
<div class="main">
|
||||||
|
<h1 id="main-title"><%= __('Welcome') %></h1>
|
||||||
|
<h2>Getting started</h2>
|
||||||
|
<p>Don't worry, we've got your back.</p>
|
||||||
|
<div class="steps">
|
||||||
|
<ul class="getting-started">
|
||||||
|
<li>
|
||||||
|
<div class="sprite one"></div>
|
||||||
|
<div>
|
||||||
|
<h3>Get your API going.</h3>
|
||||||
|
<p>
|
||||||
|
Run <span class="boxy">sails generate foo</span>. This will create a model <span class="boxy">Foo</span> and controller <span class="boxy">FooController</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="sprite two"></div>
|
||||||
|
<div>
|
||||||
|
<h3>
|
||||||
|
Lift your app.
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
Run <span class="boxy">sails lift</span> to start up your app. If you visit <span class="boxy">http://localhost:1337/foo</span> in your browser, you'll see a socket.io-compatible REST API was generated for your 'Foo' model.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="sprite three"></div>
|
||||||
|
<div>
|
||||||
|
<h3>
|
||||||
|
Dive in and start building.
|
||||||
|
</h3>
|
||||||
|
<p>From here, you can modify your models, create custom controller methods as Express middleware, and create custom routes (routes are set up in <span class="boxy">config/routes.js</span>). Visit <a href="http://sailsjs.org">the Sails website</a> for more information on next steps.</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="delete">
|
||||||
|
<div class="sprite">You're looking at: <span class="boxy">views/home/index.ejs</span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="side-bar">
|
||||||
|
<h4 id="new">
|
||||||
|
New to Sails?
|
||||||
|
</h4>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="http://sailsjs.org">Visit sailsjs.org</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="http://sailsjs.org/#!documentation">Documentation</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h4>
|
||||||
|
Next Steps
|
||||||
|
</h4>
|
||||||
|
<ul>
|
||||||
|
<li class="sprite single_page">
|
||||||
|
<a target="_blank" href="http://sailsjs.org">Build a single page app</a>
|
||||||
|
</li>
|
||||||
|
<li class="sprite traditional">
|
||||||
|
<a target="_blank" href="http://sailsjs.org">Build a traditional webapp</a>
|
||||||
|
</li>
|
||||||
|
<li class="sprite realtime">
|
||||||
|
<a target="_blank" href="http://sailsjs.org">Build a realtime app</a>
|
||||||
|
</li>
|
||||||
|
<li class="sprite api">
|
||||||
|
<a target="_blank" href="http://sailsjs.org">Build an API</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
96
views/layout.ejs
Normal file
96
views/layout.ejs
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!--
|
||||||
|
For demonstration purposes, the `title` is dynamically set here based on
|
||||||
|
your `sails.config.appName` to show that you can inject data into layouts
|
||||||
|
exactly the same way as with your other view templates.
|
||||||
|
-->
|
||||||
|
<title><%- title %></title>
|
||||||
|
|
||||||
|
<!-- Viewport mobile tag for sensible mobile support -->
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Stylesheets
|
||||||
|
========================
|
||||||
|
|
||||||
|
You can link any CSS, LESS, or image files in your `assets` directory
|
||||||
|
as you would normally: using <link/> tags.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Support for LESS included by default
|
||||||
|
================================================
|
||||||
|
|
||||||
|
LESS files are automatically compiled when they change using the Gruntfile
|
||||||
|
located in the top-level of this Sails app. If you run into issues with styles
|
||||||
|
not reloading, check the Sails log output in your console for LESS compilation errors.
|
||||||
|
If necessary, shut down and then lift your app again.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<!-- Include the view file for the current controller/route -->
|
||||||
|
<%- body %>
|
||||||
|
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Client-side Javascript
|
||||||
|
========================
|
||||||
|
|
||||||
|
You can import any js files in your `assets` directory as you would
|
||||||
|
normally: using <script></script> tags.
|
||||||
|
|
||||||
|
Here's an example of importing a few dependencies, in order:
|
||||||
|
-->
|
||||||
|
<!-- Bring in the socket.io client -->
|
||||||
|
<script type="text/javascript" src="/js/socket.io.js"></script>
|
||||||
|
<!-- then beef it up with some convenience logic for talking to Sails.js -->
|
||||||
|
<script type="text/javascript" src="/js/sails.io.js"></script>
|
||||||
|
<!-- listen on socket.io for incoming messages -->
|
||||||
|
<script type="text/javascript" src="/js/app.js"></script>
|
||||||
|
|
||||||
|
<!-- Your scripts here? -->
|
||||||
|
<!-- Your scripts here? -->
|
||||||
|
<!-- Your scripts here? -->
|
||||||
|
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Looking for client-side CoffeeScript or TypeScript?
|
||||||
|
================================================
|
||||||
|
|
||||||
|
CoffeeScript and TypeScript precompilation are not installed by default,
|
||||||
|
but if you'd like to mix those features in, it is straightforward to
|
||||||
|
`npm install` the relevant grunt community modules and modify your Gruntfile
|
||||||
|
to use them.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Another way: The Asset Linker
|
||||||
|
========================
|
||||||
|
|
||||||
|
Sails supports a Grunt-based asset linker, to automatically inject
|
||||||
|
<link> and <script> tags, as well any client-side templates you're using
|
||||||
|
into your HTML layouts and views, respecting dependencies.
|
||||||
|
|
||||||
|
You created this Sails app with the asset linker disabled.
|
||||||
|
If you change your mind, check out the docs on the subject:
|
||||||
|
http://sailsjs.org/#!documentation/asset-management
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user