@@ -0,0 +1,22 @@ | |||||
var mongoose = require('mongoose'); | |||||
var KeySchema = mongoose.Schema({ | |||||
key: String, | |||||
identifier: { | |||||
type: String, | |||||
required: true | |||||
}, | |||||
scope: [String], | |||||
uploadCount: { | |||||
type: Number, | |||||
default: 0 | |||||
}, | |||||
uploadSize: { | |||||
type: Number, | |||||
default: 0 | |||||
}, | |||||
username: String, | |||||
date: Date | |||||
}); | |||||
module.exports = mongoose.model('Key', KeySchema); |
@@ -1,30 +0,0 @@ | |||||
var fs = require('fs'); | |||||
var path = require('path'); | |||||
var mongoose = require('mongoose'); | |||||
var jwt = require('jsonwebtoken'); | |||||
var jwtsign = require('jwt-sign'); | |||||
var TokenSchema = mongoose.Schema({ | |||||
scope: [String], | |||||
issuer: String, | |||||
issued: Date, | |||||
exp: Date | |||||
}); | |||||
TokenSchema.methods.genJwt = function(expiry) { | |||||
var exp = new Date(); | |||||
exp.setDate(exp.getDate() + expiry); | |||||
var payload = { | |||||
_id: this._id, | |||||
username: this.username, | |||||
scope: this.scope, | |||||
exp: parseInt(exp.getTime() / 1000) | |||||
}; | |||||
var key = fs.readFilySync(path.join(__dirname, '../../jwt.pem'), 'utf8'); | |||||
return jwt.sign(payload, key); | |||||
}; | |||||
module.exports = mongoose.model('Token', TokenSchema); |
@@ -1,9 +1,5 @@ | |||||
var fs = require('fs'); | |||||
var path = require('path'); | |||||
var mongoose = require('mongoose'); | var mongoose = require('mongoose'); | ||||
var crypto = require('crypto'); | |||||
var jwt = require('jsonwebtoken'); | |||||
var jwtsign = require('jwt-sign'); | |||||
var passportLocalMongoose = require('passport-local-mongoose'); | |||||
var UserSchema = mongoose.Schema({ | var UserSchema = mongoose.Schema({ | ||||
username: { | username: { | ||||
@@ -11,6 +7,7 @@ var UserSchema = mongoose.Schema({ | |||||
unique: true, | unique: true, | ||||
required: true | required: true | ||||
}, | }, | ||||
scope: [String], | |||||
uploadCount: { | uploadCount: { | ||||
type: Number, | type: Number, | ||||
default: 0 | default: 0 | ||||
@@ -19,36 +16,9 @@ var UserSchema = mongoose.Schema({ | |||||
type: Number, | type: Number, | ||||
default: 0 | default: 0 | ||||
}, | }, | ||||
scope: [String], | |||||
hash: String, | |||||
salt: String, | |||||
date: Date | date: Date | ||||
}); | }); | ||||
UserSchema.methods.setPassword = function(password) { | |||||
this.salt = crypto.randomBytes(16).toString('hex'); | |||||
this.hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64, 'sha256').toString('hex'); | |||||
}; | |||||
UserSchema.methods.validatePassword = function(password) { | |||||
var hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64, 'sha256').toString('hex'); | |||||
return this.hash === hash; | |||||
}; | |||||
UserSchema.methods.genJwt = function() { | |||||
var expiry = new Date(); | |||||
expiry.setDate(expiry.getDate() + 7); | |||||
var payload = { | |||||
_id: this._id, | |||||
username: this.username, | |||||
scope: this.scope, | |||||
exp: parseInt(expiry.getTime() / 1000) | |||||
}; | |||||
var key = fs.readFileSync(path.join(__dirname, '../../jwt.pem'), 'utf8'); | |||||
return jwt.sign(payload, key); | |||||
}; | |||||
UserSchema.plugin(passportLocalMongoose); | |||||
module.exports = mongoose.model('User', UserSchema); | module.exports = mongoose.model('User', UserSchema); |
@@ -5,43 +5,34 @@ var view = require('./routes/view.js'); | |||||
var auth = require('./routes/auth.js'); | var auth = require('./routes/auth.js'); | ||||
var register = require('./routes/register.js'); | var register = require('./routes/register.js'); | ||||
var login = require('./routes/login.js'); | var login = require('./routes/login.js'); | ||||
var panel = require('./routes/panel'); | |||||
var panel = require('./routes/panel.js'); | |||||
var keys = require('./routes/keys.js'); | |||||
var fs = require('fs'); | var fs = require('fs'); | ||||
var path = require('path'); | var path = require('path'); | ||||
var jwt = require('express-jwt'); | |||||
var jwtauth = jwt({ | |||||
secret: fs.readFileSync(path.join(__dirname, '../jwt.pem'), 'utf8'), | |||||
userProperty: 'payload', | |||||
getToken: function(req) { | |||||
if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') { | |||||
// First check Authorization header | |||||
return req.headers.authorization.split(' ')[1]; | |||||
} else if (req.cookies && req.cookies['shimapan-token']) { | |||||
// Get from cookies as fallback | |||||
return req.cookies['shimapan-token']; | |||||
} | |||||
// no token received | |||||
return null; | |||||
} | |||||
}); | |||||
var requireLogin = function(req, res, next) { | |||||
if (!req.session.passport.user) | |||||
res.redirect('/login'); | |||||
else | |||||
next(); | |||||
}; | |||||
module.exports = function(app) { | module.exports = function(app) { | ||||
app.use('/', index); | app.use('/', index); | ||||
app.use('/home', jwtauth, home); | |||||
app.use('/home', requireLogin, home); | |||||
app.use('/v', view); | app.use('/v', view); | ||||
app.use('/api/upload', jwtauth, upload); | |||||
app.use('/api/upload', upload); | |||||
app.use('/api/auth', auth); | app.use('/api/auth', auth); | ||||
app.use('/api/keys', requireLogin, keys); | |||||
app.use('/register', register); | app.use('/register', register); | ||||
app.use('/login', login); | app.use('/login', login); | ||||
app.use('/panel', jwtauth, panel); | |||||
app.use('/panel*', jwtauth, panel); | |||||
app.use('/panel', requireLogin, panel); | |||||
app.use('/panel*', requireLogin, panel); | |||||
app.use(function(err, req, res, next) { | app.use(function(err, req, res, next) { | ||||
if (err.name === 'UnauthorizedError') { | if (err.name === 'UnauthorizedError') { | ||||
res.status(401); | res.status(401); | ||||
res.redirect('/login'); | |||||
res.json({"message": err.name + ": " + err.message}); | res.json({"message": err.name + ": " + err.message}); | ||||
} | } | ||||
}) | }) |
@@ -3,25 +3,12 @@ var path = require('path'); | |||||
var express = require('express'); | var express = require('express'); | ||||
var router = express.Router(); | var router = express.Router(); | ||||
var async = require('async'); | |||||
var User = require('../models/User.js'); | var User = require('../models/User.js'); | ||||
var Invite = require('../models/Invite.js'); | var Invite = require('../models/Invite.js'); | ||||
var passport = require('passport'); | var passport = require('passport'); | ||||
var striptags = require('striptags'); | |||||
function checkUsername(username, callback) { | |||||
if (username.length > 30) return callback(null, false); | |||||
if (striptags(username) !== username) return callback(null, false); | |||||
User.find({username: username}).limit(1).count(function (err, count) { | |||||
if (err) return callback(err); | |||||
(count === 0) ? callback(null, true) : callback(null, false); | |||||
}); | |||||
} | |||||
function checkInvite(code, callback) { | function checkInvite(code, callback) { | ||||
Invite.findOne({code: code}, function (err, invite) { | Invite.findOne({code: code}, function (err, invite) { | ||||
if (err) return callback(err); | if (err) return callback(err); | ||||
@@ -33,75 +20,62 @@ function checkInvite(code, callback) { | |||||
} | } | ||||
function useInvite(code, username) { | function useInvite(code, username) { | ||||
Invite.updateOne({code: code}, {recipient: username, used: new Date()}, function (err, res) { | |||||
Invite.updateOne({code: code}, {recipient: username, used: new Date()}, function (err) { | |||||
if (err) throw err; | if (err) throw err; | ||||
}); | }); | ||||
} | } | ||||
router.post('/register', function (req, res) { | |||||
// Validate the parameters | |||||
async.parallel({ | |||||
userCheck: function (callback) { | |||||
checkUsername(req.body.username, function (err, valid) { | |||||
callback(err, valid); | |||||
}); | |||||
}, | |||||
inviteCheck: function (callback) { | |||||
checkInvite(req.body.invite, function (err, valid, invite) { | |||||
callback(err, {valid: valid, invite: invite}); | |||||
}); | |||||
} | |||||
}, function (err, result) { | |||||
if (!result.userCheck) { | |||||
res.status(401).json({'message': 'Invalid username.'}); | |||||
} else if (!result.inviteCheck.valid) { | |||||
res.status(401).json({'message': 'Invalid invite code.'}); | |||||
} else { | |||||
useInvite(req.body.invite, req.body.username); | |||||
var user = new User(); | |||||
user.username = req.body.username; | |||||
user.scope = result.inviteCheck.invite.scope; | |||||
user.date = new Date(); | |||||
user.setPassword(req.body.password); | |||||
user.save(function (err) { | |||||
if (err) { | |||||
res.status(500).json({'message': 'Internal server error.'}); | |||||
} else { | |||||
res.status(200) | |||||
.cookie('shimapan-token', user.genJwt(), { | |||||
expires: new Date(Date.now() + 604800000), | |||||
httpOnly: true | |||||
}) | |||||
.json({'token': user.genJwt()}); | |||||
router.post('/register', function (req, res, next) { | |||||
// Validate the invite code, then hand off to passport | |||||
checkInvite(req.body.invite, function (err, valid, invite) { | |||||
if (valid) { | |||||
User.register( | |||||
new User({username: req.body.username, scope: invite.scope, date: Date.now()}), | |||||
req.body.password, | |||||
function (err) { | |||||
if (err) return res.status(403).json({'message': err.message}); | |||||
passport.authenticate('local')(req, res, function () { | |||||
req.session.save(function(err) { | |||||
if (err) return next(err); | |||||
useInvite(req.body.invite, req.body.username); | |||||
res.status(200).json({'message': 'Registered.'}); | |||||
}); | |||||
}); | |||||
} | } | ||||
}); | |||||
); | |||||
} else { | |||||
res.status(401).json({'message': 'Invalid invite code.'}); | |||||
} | } | ||||
}); | }); | ||||
}); | }); | ||||
router.post('/login', function (req, res) { | |||||
passport.authenticate('local', function (err, user, info) { | |||||
if (err) { | |||||
res.status(500).json(err); | |||||
} else if (user) { | |||||
res.status(200) | |||||
.cookie('shimapan-token', user.genJwt(), { | |||||
expires: new Date(Date.now() + 604800000), | |||||
httpOnly: true | |||||
}) | |||||
.json({'token': user.genJwt()}); | |||||
} else { | |||||
res.status(401).json(info); | |||||
} | |||||
})(req, res); | |||||
router.post('/login', function (req, res, next) { | |||||
passport.authenticate('local', function(err, user, info) { | |||||
if (err) return next(err); | |||||
if (!user) return res.status(401).json({'message': info}); | |||||
req.logIn(user, function(err) { | |||||
if (err) return next(err); | |||||
res.status(200).json({'message': 'Logged in.'}); | |||||
}); | |||||
})(req, res, next); | |||||
}); | }); | ||||
router.get('/logout', function(req, res) { | |||||
res.clearCookie('shimapan-token'); | |||||
res.status(200).json({'message': 'Successfully logged out.'}); | |||||
router.get('/logout', function (req, res) { | |||||
req.logout(); | |||||
res.status(200).json({'message': 'Logged out.'}); | |||||
}); | }); | ||||
router.get('/session', function(req, res) { | |||||
if (req.session.passport.user) { | |||||
User.findOne({username: req.session.passport.user}, function(err, user) { | |||||
res.status(200).json({ | |||||
user: user.username, | |||||
scope: user.scope | |||||
}); | |||||
}); | |||||
} else { | |||||
res.status(401).json({'message': 'Unauthorized.'}); | |||||
} | |||||
}); | |||||
module.exports = router; | module.exports = router; |
@@ -0,0 +1,67 @@ | |||||
var express = require('express'); | |||||
var router = express.Router(); | |||||
var crypto = require('crypto'); | |||||
var Key = require('../models/Key.js'); | |||||
router.post('/create', function (req, res) { | |||||
if (!req.body.identifier || !req.body.scope) { | |||||
res.status(400).json({'message': 'Bad request.'}); | |||||
return; | |||||
} | |||||
Key.count({'username': req.session.passport.user}, function (err, count) { | |||||
if (count >= 10) { | |||||
res.status(403).json({'message': 'Key limit reached.'}); | |||||
return; | |||||
} | |||||
var scope; | |||||
try { | |||||
scope = JSON.parse(req.body.scope); | |||||
} catch (e) { | |||||
res.status(400).json({'message': e.name + ': ' + e.message}); | |||||
return; | |||||
} | |||||
var id = req.sanitize(req.body.identifier); | |||||
if (id.length === 0) id = "err"; | |||||
var entry = { | |||||
key: crypto.randomBytes(32).toString('hex'), | |||||
identifier: id, | |||||
scope: scope, | |||||
username: req.session.passport.user, | |||||
date: Date.now() | |||||
}; | |||||
Key.create(entry, function (err) { | |||||
if (err) { | |||||
throw err; | |||||
} else { | |||||
res.status(200).json({ | |||||
key: entry.key, | |||||
identifier: entry.identifier, | |||||
scope: entry.scope | |||||
}); | |||||
} | |||||
}) | |||||
}) | |||||
}); | |||||
router.get('/get', function (req, res, next) { | |||||
var query = {username: req.session.passport.user}; | |||||
if (req.body.identifier) | |||||
query.identifier = req.body.identifier; | |||||
Key.find(query, function (err, keys) { | |||||
if (err) { | |||||
next(err); | |||||
} else { | |||||
res.status(200).json(keys); | |||||
} | |||||
}) | |||||
}); | |||||
module.exports = router; |
@@ -14,11 +14,9 @@ function fileNameExists(name) { | |||||
}); | }); | ||||
} | } | ||||
function updateStats(user, size) { | |||||
User.updateOne({username: user}, { $inc: { uploadCount: 1, uploadSize: size } }, function(err, res) { | |||||
if (err) { | |||||
throw err; | |||||
} | |||||
function updateUserStats(user, size) { | |||||
User.updateOne({username: user}, {$inc: {uploadCount: 1, uploadSize: size}}, function (err, res) { | |||||
if (err) throw err; | |||||
}); | }); | ||||
} | } | ||||
@@ -33,22 +31,17 @@ function genFileName() { | |||||
} | } | ||||
router.post('/', dest.single('file'), function (req, res) { | router.post('/', dest.single('file'), function (req, res) { | ||||
if (req.payload.scope.indexOf('file.upload') === -1) { | |||||
res.status(403).json({'message': 'Permission error.'}); | |||||
return; | |||||
} | |||||
// Size must be below 128 Megabytes (1024*1024*128 Bytes) | // Size must be below 128 Megabytes (1024*1024*128 Bytes) | ||||
if (req.file.size >= 134217728) { | if (req.file.size >= 134217728) { | ||||
res.status(413).json({'message': 'File too large.'}); | res.status(413).json({'message': 'File too large.'}); | ||||
return; | return; | ||||
} | } | ||||
updateStats(req.payload.username, req.file.size); | |||||
updateUserStats(req.session.passport.user, req.file.size); | |||||
var entry = { | var entry = { | ||||
name: genFileName(), | name: genFileName(), | ||||
uploader: req.payload.username, | |||||
uploader: req.session.passport.user, | |||||
created: Date.now(), | created: Date.now(), | ||||
file: req.file | file: req.file | ||||
}; | }; | ||||
@@ -1,29 +1,7 @@ | |||||
var passport = require('passport'); | var passport = require('passport'); | ||||
var LocalStrategy = require('passport-local').Strategy; | |||||
var mongoose = require('mongoose'); | |||||
var User = require('../app/models/User.js'); | var User = require('../app/models/User.js'); | ||||
passport.use(new LocalStrategy({ | |||||
usernameField: 'username' | |||||
}, | |||||
function(username, password, done) { | |||||
User.findOne({username: username}, function(err, user) { | |||||
if (err) return done(err); | |||||
if (!user) { | |||||
return done(null, false, { | |||||
message: 'Invalid username.' | |||||
}); | |||||
} | |||||
if (!user.validatePassword(password)) { | |||||
return done(null, false, { | |||||
message: 'Invalid password.' | |||||
}); | |||||
} | |||||
passport.use(User.createStrategy()); | |||||
passport.serializeUser(User.serializeUser()); | |||||
passport.deserializeUser(User.deserializeUser()); | |||||
return done(null, user); | |||||
}); | |||||
} | |||||
)); |
@@ -7,11 +7,12 @@ | |||||
"async": "^2.5.0", | "async": "^2.5.0", | ||||
"body-parser": "^1.18.2", | "body-parser": "^1.18.2", | ||||
"config": "^1.26.2", | "config": "^1.26.2", | ||||
"connect-mongo": "^2.0.0", | |||||
"cookie-parser": "^1.4.3", | "cookie-parser": "^1.4.3", | ||||
"express": "^4.16.2", | "express": "^4.16.2", | ||||
"express-jwt": "^5.3.0", | |||||
"jsonwebtoken": "^8.1.0", | |||||
"jwt-sign": "^0.1.0", | |||||
"express-sanitizer": "^1.0.2", | |||||
"express-session": "^1.15.6", | |||||
"helmet": "^3.9.0", | |||||
"method-override": "latest", | "method-override": "latest", | ||||
"mongoose": "^4.12.1", | "mongoose": "^4.12.1", | ||||
"morgan": "^1.9.0", | "morgan": "^1.9.0", | ||||
@@ -19,6 +20,7 @@ | |||||
"ng-file-upload": "^12.2.13", | "ng-file-upload": "^12.2.13", | ||||
"passport": "^0.4.0", | "passport": "^0.4.0", | ||||
"passport-local": "^1.0.0", | "passport-local": "^1.0.0", | ||||
"passport-local-mongoose": "^4.2.1", | |||||
"striptags": "^3.1.0" | "striptags": "^3.1.0" | ||||
}, | }, | ||||
"description": "A simple file sharing website.", | "description": "A simple file sharing website.", | ||||
@@ -98,3 +98,43 @@ body { | |||||
box-shadow: inset 5px 0 0 #2A9FD6, inset 6px 0 0 #222; | box-shadow: inset 5px 0 0 #2A9FD6, inset 6px 0 0 #222; | ||||
background: #444; | background: #444; | ||||
} | } | ||||
.inner { | |||||
display: flex; | |||||
flex-direction: column; | |||||
} | |||||
.keys { | |||||
display: flex; | |||||
flex-direction: row; | |||||
} | |||||
.key { | |||||
background: #555; | |||||
border: 3px solid #2a9fd6; | |||||
border-radius: 5px; | |||||
box-shadow: 5px 5px 10px #000; | |||||
margin: 10px; | |||||
width: 300px; | |||||
height: 100px; | |||||
} | |||||
.add-key { | |||||
cursor: pointer; | |||||
display: flex; | |||||
justify-content: flex-start; | |||||
flex-direction: row; | |||||
} | |||||
.add-key i { | |||||
font-size: 48px; | |||||
margin: auto 0 auto 20px; | |||||
} | |||||
.add-key span { | |||||
font-size: 36px; | |||||
vertical-align: center; | |||||
margin: auto; | |||||
-moz-user-select: none; | |||||
user-select: none; | |||||
} |
@@ -0,0 +1,20 @@ | |||||
angular.module('ApiSvc', []).service('ApiService', ['$http', '$window', function ($http, $window) { | |||||
this.getKey = function (identifier, cb) { | |||||
$http({ | |||||
method: 'GET', | |||||
url: '/api/keys/get', | |||||
params: {identifier: identifier} | |||||
}).then(function (res) { | |||||
cb(res.data); | |||||
}); | |||||
}; | |||||
this.getAll = function (cb) { | |||||
$http({ | |||||
method: 'GET', | |||||
url: '/api/keys/get' | |||||
}).then(function (res) { | |||||
cb(res.data); | |||||
}); | |||||
}; | |||||
}]); |
@@ -1,28 +1,4 @@ | |||||
angular.module('AuthSvc', []).service('AuthService', ['$http', '$window', function($http, $window) { | angular.module('AuthSvc', []).service('AuthService', ['$http', '$window', function($http, $window) { | ||||
function decodeToken(token) { | |||||
if (token) { | |||||
var payload = token.split('.')[1]; | |||||
payload = $window.atob(payload); | |||||
payload = JSON.parse(payload); | |||||
return payload; | |||||
} else { | |||||
return {}; | |||||
} | |||||
} | |||||
function saveToken(token) { | |||||
$window.localStorage['shimapan-token'] = token; | |||||
} | |||||
function getToken() { | |||||
return $window.localStorage['shimapan-token']; | |||||
} | |||||
this.getAuthHeader = function() { | |||||
return 'Bearer ' + getToken(); | |||||
}; | |||||
this.login = function(user) { | this.login = function(user) { | ||||
return $http({ | return $http({ | ||||
method: 'POST', | method: 'POST', | ||||
@@ -36,23 +12,19 @@ angular.module('AuthSvc', []).service('AuthService', ['$http', '$window', functi | |||||
}, | }, | ||||
data: user | data: user | ||||
}).then(function(res) { | }).then(function(res) { | ||||
saveToken(res.data.token); | |||||
if (res.status === 401) return false; | |||||
$window.location.href = '/home'; | $window.location.href = '/home'; | ||||
}) | }) | ||||
}; | }; | ||||
this.logout = function() { | this.logout = function() { | ||||
$window.localStorage.removeItem('shimapan-token'); | |||||
$http({ | $http({ | ||||
method: 'GET', | method: 'GET', | ||||
url: '/api/auth/logout' | url: '/api/auth/logout' | ||||
}).then(function(res) { | |||||
}).then(function() { | |||||
$window.location.href = '/'; | $window.location.href = '/'; | ||||
}); | }); | ||||
}; | }; | ||||
this.isLoggedIn = function() { | |||||
var payload = decodeToken(getToken()); | |||||
return payload.exp > Date.now() / 1000; | |||||
}; | |||||
this.register = function(user) { | this.register = function(user) { | ||||
return $http({ | return $http({ | ||||
@@ -67,18 +39,18 @@ angular.module('AuthSvc', []).service('AuthService', ['$http', '$window', functi | |||||
}, | }, | ||||
data: user | data: user | ||||
}).then(function(res) { | }).then(function(res) { | ||||
saveToken(res.data.token); | |||||
if (res.status === 401) return false; | |||||
$window.location.href = '/home'; | $window.location.href = '/home'; | ||||
}); | }); | ||||
}; | }; | ||||
this.currentUser = function() { | |||||
var payload = decodeToken(getToken()); | |||||
return payload.username; | |||||
}; | |||||
this.currentScope = function() { | |||||
var payload = decodeToken(getToken()); | |||||
return payload.scope; | |||||
this.currentUser = function(cb) { | |||||
return $http({ | |||||
method: 'GET', | |||||
url: '/api/auth/session', | |||||
headers: {'Content-Type': 'application/json'} | |||||
}).then(function(res) { | |||||
cb(res.data); | |||||
}); | |||||
} | } | ||||
}]); | }]); |
@@ -0,0 +1,8 @@ | |||||
angular.module('ApiCtrl', ['ApiSvc', 'AuthSvc']).controller('ApiController', ['$scope', 'ApiService', 'AuthService', function($scope, ApiService, AuthService) { | |||||
$scope.getKeys = function() { | |||||
ApiService.getAll(function(keys) { | |||||
$scope.keys = keys; | |||||
}); | |||||
console.log($scope.keys); | |||||
}; | |||||
}]); |
@@ -1,12 +1,14 @@ | |||||
angular.module('NavCtrl', ['AuthSvc']).controller('NavController', ['$scope', '$window', 'AuthService', function($scope, $window, AuthService) { | angular.module('NavCtrl', ['AuthSvc']).controller('NavController', ['$scope', '$window', 'AuthService', function($scope, $window, AuthService) { | ||||
$scope.isLoggedIn = AuthService.isLoggedIn(); | |||||
$scope.currentUser = AuthService.currentUser(); | |||||
$scope.currentScope = AuthService.currentScope(); | |||||
$scope.user = {}; | |||||
AuthService.currentUser(function(user) { | |||||
$scope.user = user; | |||||
}); | |||||
$scope.logout = AuthService.logout; | $scope.logout = AuthService.logout; | ||||
$scope.hasPermission = function(permission) { | $scope.hasPermission = function(permission) { | ||||
if (!$scope.currentScope) return false; | |||||
return $scope.currentScope.indexOf(permission) !== -1; | |||||
if (!$scope.user.scope) return false; | |||||
return $scope.user.scope.indexOf(permission) !== -1; | |||||
}; | }; | ||||
}]); | }]); |
@@ -6,7 +6,7 @@ angular.module('PanelRoutes', ['ui.router']).config(['$stateProvider', '$urlRout | |||||
$stateProvider | $stateProvider | ||||
.state('dashboard', { | .state('dashboard', { | ||||
url: '/panel', | url: '/panel', | ||||
templateUrl: '/views/shimapan-panel/panel-home.html' | |||||
templateUrl: '/views/shimapan-panel/panel-dash.html' | |||||
}).state('search', { | }).state('search', { | ||||
url: '/panel/search', | url: '/panel/search', | ||||
templateUrl: '/views/shimapan-panel/panel-search.html' | templateUrl: '/views/shimapan-panel/panel-search.html' | ||||
@@ -1,4 +1,4 @@ | |||||
var app = angular.module('shimapan-panel', ['ui.router', 'NavCtrl', 'PanelRoutes']); | |||||
var app = angular.module('shimapan-panel', ['ui.router', 'AuthSvc', 'ApiSvc', 'ApiCtrl', 'NavCtrl', 'PanelRoutes']); | |||||
app.run(['$rootScope', '$state', '$stateParams', function($rootScope, $state, $stateParams) { | app.run(['$rootScope', '$state', '$stateParams', function($rootScope, $state, $stateParams) { | ||||
$rootScope.$state = $state; | $rootScope.$state = $state; | ||||
@@ -16,9 +16,6 @@ angular.module('UploadComp', ['ngFileUpload', 'AuthSvc']).component('uploadCompo | |||||
file.upload = Upload.upload({ | file.upload = Upload.upload({ | ||||
url: '/api/upload', | url: '/api/upload', | ||||
method: 'POST', | method: 'POST', | ||||
headers: { | |||||
'Authorization': AuthService.getAuthHeader() | |||||
}, | |||||
file: file | file: file | ||||
}); | }); | ||||
@@ -1 +1,11 @@ | |||||
<h1>Panel api hurr durr</h1> | |||||
<div class="inner"> | |||||
<p ng-hide="keys">Loading...</p> | |||||
<div class="keys" ng-controller="ApiController" ng-init="getKeys()"> | |||||
<div class="key" ng-repeat="key in keys"> | |||||
</div> | |||||
<div class="key add-key"> | |||||
<i class="fa fa-plus"></i> | |||||
<span>Create</span> | |||||
</div> | |||||
</div> | |||||
</div> |
@@ -0,0 +1 @@ | |||||
<h1>Dashboard</h1> |
@@ -1,2 +0,0 @@ | |||||
<h1>This is yer home</h1> | |||||
<p>This is a pargragraph</p> |
@@ -5,6 +5,9 @@ var mongoose = require('mongoose'); | |||||
var morgan = require('morgan'); | var morgan = require('morgan'); | ||||
var passport = require('passport'); | var passport = require('passport'); | ||||
var cookieParser = require('cookie-parser'); | var cookieParser = require('cookie-parser'); | ||||
var session = require('express-session'); | |||||
var sanitizer = require('express-sanitizer'); | |||||
var helmet = require('helmet'); | |||||
var app = express(); | var app = express(); | ||||
@@ -19,20 +22,46 @@ var db = mongoose.connection; | |||||
db.on('error', function(err) { | db.on('error', function(err) { | ||||
if (err) console.log('MongoDB Connection Error: ', err); | if (err) console.log('MongoDB Connection Error: ', err); | ||||
}); | }); | ||||
var MongoStore = require('connect-mongo')(session); | |||||
var mongoStore = new MongoStore({ | |||||
url: config.dbHost | |||||
}); | |||||
require('./config/passport.js'); | |||||
app.use(helmet()); | |||||
app.set('trust proxy', 1); | |||||
app.use(session({ | |||||
secret: 'secret', | |||||
name: 'session.id', | |||||
resave: false, | |||||
saveUninitialized: false, | |||||
store: mongoStore, | |||||
cookie: { | |||||
//secure: true, | |||||
httpOnly: true, | |||||
//domain: 'shimapan.rocks', | |||||
maxAge: 1000 * 60 * 60 | |||||
} | |||||
})); | |||||
app.use(passport.initialize()); | |||||
app.use(passport.session()); | |||||
app.use(cookieParser()); | app.use(cookieParser()); | ||||
app.use(bodyParser.json()); | app.use(bodyParser.json()); | ||||
app.use(bodyParser.json({ type: 'application/json' })); | |||||
app.use(bodyParser.json({ type: 'application/*+json' })) | |||||
app.use(bodyParser.urlencoded({ extended: true })); | app.use(bodyParser.urlencoded({ extended: true })); | ||||
app.use(bodyParser.text()); | app.use(bodyParser.text()); | ||||
app.use(sanitizer()); | |||||
app.use(methodOverride('X-HTTP-Method-Override')); | app.use(methodOverride('X-HTTP-Method-Override')); | ||||
app.use(passport.initialize()); | app.use(passport.initialize()); | ||||
// Set /public to document root | |||||
//app.use(favicon(__dirname + '/public/img/favicon.ico')); | |||||
app.use(express.static(__dirname + '/public')); | app.use(express.static(__dirname + '/public')); | ||||
require('./app/routes')(app); | require('./app/routes')(app); | ||||
require('./config/passport.js'); | |||||
// Start app | // Start app | ||||
var port = process.env.PORT || 8080; | var port = process.env.PORT || 8080; | ||||
@@ -6,7 +6,6 @@ var mongoose = require('mongoose'); | |||||
var User = require('../app/models/User.js'); | var User = require('../app/models/User.js'); | ||||
var Invite = require('../app/models/Invite.js'); | var Invite = require('../app/models/Invite.js'); | ||||
var Upload = require('../app/models/Upload.js'); | var Upload = require('../app/models/Upload.js'); | ||||
var Token = require('../app/models/Token.js'); | |||||
var chai = require('chai'); | var chai = require('chai'); | ||||
var should = chai.should(); | var should = chai.should(); | ||||
@@ -6,7 +6,6 @@ var mongoose = require('mongoose'); | |||||
var User = require('../app/models/User.js'); | var User = require('../app/models/User.js'); | ||||
var Invite = require('../app/models/Invite.js'); | var Invite = require('../app/models/Invite.js'); | ||||
var Upload = require('../app/models/Upload.js'); | var Upload = require('../app/models/Upload.js'); | ||||
var Token = require('../app/models/Token.js'); | |||||
var chai = require('chai'); | var chai = require('chai'); | ||||
var http = require('chai-http'); | var http = require('chai-http'); | ||||
@@ -24,7 +23,7 @@ chai.use(http); | |||||
var resetDatabase = function(callback) { | var resetDatabase = function(callback) { | ||||
db.once('open', function() { | db.once('open', function() { | ||||
async.each([ | async.each([ | ||||
User, Invite, Upload, Token | |||||
User, Invite, Upload, | |||||
], function(schema, cb) { | ], function(schema, cb) { | ||||
schema.remove({}, function(err) { | schema.remove({}, function(err) { | ||||
cb(err); | cb(err); | ||||
@@ -73,8 +72,6 @@ var register = function(user, cb) { | |||||
var verifySuccessfulRegister = function(user, done) { | var verifySuccessfulRegister = function(user, done) { | ||||
register(user, function (err, res) { | register(user, function (err, res) { | ||||
res.should.have.status(200); | res.should.have.status(200); | ||||
res.body.should.be.a('object'); | |||||
res.body.should.have.property('token'); | |||||
done(); | done(); | ||||
}); | }); | ||||
}; | }; | ||||
@@ -111,8 +108,6 @@ var login = function(user, cb) { | |||||
var verifySuccessfulLogin = function(user, done) { | var verifySuccessfulLogin = function(user, done) { | ||||
login(user, function (err, res) { | login(user, function (err, res) { | ||||
res.should.have.status(200); | res.should.have.status(200); | ||||
res.body.should.be.a('object'); | |||||
res.body.should.have.property('token'); | |||||
done(); | done(); | ||||
}); | }); | ||||
}; | }; | ||||