UNPKG

nodulator

Version:

Complete NodeJS Framework for Restfull APIs

177 lines (125 loc) 4.61 kB
_ = require 'underscore' async = require 'async' cookieParser = require 'cookie-parser' passport = require 'passport' LocalStrategy = require('passport-local').Strategy module.exports = (N) -> N.authApp = true N.passport = passport # Init do -> if N.consoleMode return if not N.app? N.Route._InitServer() N.app.use N.passport.initialize() N.app.use N.passport.session() class AccountResource extends N '_account', {abstract: true} @userField: usernameField: 'username' passwordField: 'password' @_InitPassport: -> N.passport.serializeUser (user, done) => done null, user.id N.passport.deserializeUser (id, done) => @Fetch id, (err, user) -> return done null, false if err? and err.status is 'not_found' return done 'Error deserialize user', null if err? done null, user N.passport.use new LocalStrategy @userField, (username, password, done) => constraints = {} constraints[@userField.usernameField] = username @Fetch constraints, (err, user) => # @[@methodName] username, (err, user) => return done err if err? and err.status isnt 'not_found' return done null, false, {message: 'Incorrect Username/password'} if err? or !(user?) or user[@userField.passwordField] isnt password return done null, user @_InitLoginRoutes: (resName) -> @app = N.app @app.post '/api/1/' + resName + 's' + '/login', N.passport.authenticate('local'), (req, res) => if @config? and @config.loginCallback? @config.loginCallback req, -> res.sendStatus(200) else res.sendStatus(200) @app.post '/api/1/' + resName + 's' + '/logout', (req, res) => if @config? and @config.logoutCallback? @config.logoutCallback req, -> req.logout() res.sendStatus(200) else req.logout() res.sendStatus(200) @_InjectUser: (req, res) -> userObject = '<script>var __user = ' + (JSON.stringify(req.user?.ToJSON() || {})) + ';</script>\n' #FIXME: dirty userObject ToJSON: -> blob = super() delete blob[AccountResource.userField.passwordField] blob AccountResource.Init() if N.assets? N.ExtendBeforeRender AccountResource._InjectUser N.ExtendAfterRender (req, res) => rend = 'auth' if req.user? rend = 'index' res.render rend # Returning false breaks the render loop return false N.AccountResource = (args...) -> if @resources[args[0]]? return @resources[args[0]] res = AccountResource.Extend.apply AccountResource, args if res.config? and res.config.fields? res.userField = res.config.fields res._InitPassport() res._InitLoginRoutes args[0] res N.AccountResource._AccountResource = AccountResource N.Route.Auth = () -> (req, res, next) -> return res.sendStatus(403) if not req.user? next() N.Route.HasProperty = (obj) -> (req, res, next) => return res.sendStatus(403) if not req.user? for key, item of obj if not req.user[key]? or req.user[key] isnt item return res.sendStatus(403) next() N.Route.IsOwn = (key) -> (req, res, next) => return next() if not req.params[key]? return res.sendStatus(403) if not req.user? return res.sendStatus(403) if parseInt(req.params[key]) isnt req.user.id next() # N.Route.IsOwnObject = (key) -> # (req, res, next) => # return res.sendStatus(403) if not req.user? # #FIXME: dirty # toSearch = {} # toSearch[key] = req.user.id # @resource.FetchBy toSearch, (err, instance) -> # return res.status(403).send err if err? # if # return res.sendStatus(403) if not req.params[key]? or parseInt(req.params[key]) isnt req.user.id # next() N.Route.prototype.Auth = (args...) -> N.Route.Auth args... N.Route.prototype.HasProperty = (args...) -> N.Route.HasProperty args... N.Route.prototype.IsOwn = (args...) -> N.Route.IsOwn args... #Used to wrap _Add call to allow global permissions restrictions on Route _AddBack = N.Route.prototype._Add N.Route.prototype._Add = (args...) -> if not @config? return _AddBack.apply @, args done = args.splice(args.length - 1, 1)[0] if @config.restrict? and typeof(@config.restrict) is 'function' args.push @config.restrict args.push done _AddBack.apply @, args {name: 'Account'}