1
0
mirror of https://github.com/Foltik/Shimapan synced 2025-01-05 15:58:03 -05:00

Work on stuff...

This commit is contained in:
Jack 2017-10-11 10:15:19 -04:00
parent 659792e71b
commit 8251900309
Signed by: foltik
GPG Key ID: 303F88F996E95541
19 changed files with 311 additions and 38 deletions

2
.gitignore vendored
View File

@ -3,5 +3,7 @@ public/libs/
.idea/
.awcache/
uploads/
package-lock.json
jwt.pem

View File

@ -23,16 +23,20 @@ var UserSchema = mongoose.Schema({
UserSchema.methods.setPassword = function(password) {
this.salt = crypto.randomBytes(16).toString('hex');
this.hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64).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).toString('hex');
var hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64, 'sha256').toString('hex');
return this.hash === hash;
};
UserSchema.methods.generateJwt = function() {
var expiry = Date.now();
UserSchema.methods.genApiKey = function() {
this.apikey = crypto.randomBytes(16).toString('hex');
};
UserSchema.methods.genJwt = function() {
var expiry = new Date();
expiry.setDate(expiry.getDate() + 7);
var payload = {
@ -41,7 +45,7 @@ UserSchema.methods.generateJwt = function() {
level: this.level
};
var key = fs.readFileSync(path.join(__dirname, '/jwt.pem'), 'utf8');
var key = fs.readFileSync(path.join(__dirname, '../../jwt.pem'), 'utf8');
return jwt.sign(payload, key);
};

View File

@ -1,9 +1,28 @@
var index = require('./routes/index.js');
var upload = require('./routes/upload.js');
var view = require('./routes/view.js');
var auth = require('./routes/auth.js');
var register = require('./routes/register.js');
var fs = require('fs');
var path = require('path');
var jwt = require('express-jwt');
var jwtauth = jwt({
secret: fs.readFileSync(path.join(__dirname, '../jwt.pem'), 'utf8'),
userProperty: 'payload'
});
module.exports = function(app) {
app.use('/', index);
app.use('/v', view);
app.use('/upload', upload);
};
app.use('/api/auth', auth);
app.use('/register', register);
app.use(function(err, req, res, next) {
if (err.name === 'UnauthorizedError') {
res.status(401);
res.json({"message": err.name + ": " + err.message});
}
})
};

53
app/routes/auth.js Normal file
View File

@ -0,0 +1,53 @@
var fs = require('fs');
var path = require('path');
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var User = mongoose.model('User');
var passport = require('passport');
router.post('/register', function(req, res) {
console.log(req.body);
var user = new User();
user.username = req.body.username;
user.level = 0;
user.genApiKey();
user.setPassword(req.body.password);
user.save(function(err) {
var token;
token = user.genJwt();
res.status(200);
res.json({
"token": token
});
});
});
router.post('/login', function(req, res) {
passport.authenticate('local', function(err, user, info) {
if (err) {
res.status(404).json(err);
return;
}
var token;
if (user) {
token = user.genJwt();
res.status(200);
res.json({
"token": token
});
} else {
res.status(401).json(info);
}
})(req, res);
});
module.exports = router;

9
app/routes/register.js Normal file
View File

@ -0,0 +1,9 @@
var express = require('express');
var router = express.Router();
var path = require('path');
router.get('/', function(req, res, next) {
res.sendFile(path.join(__dirname, '../../public/views', 'register.html'));
});
module.exports = router;

View File

@ -1,8 +1,10 @@
var express = require('express');
var multer = require('multer');
var router = express.Router();
var mongoose = require('mongoose');
var Upload = require('../models/Upload.js');
var multer = require('multer');
var dest = multer({dest: 'uploads/'});
function fileNameExists(name) {
@ -22,6 +24,12 @@ function genFileName() {
}
router.post('/', dest.single('file'), function(req, res) {
//if (!req.payload._id) {
//console.log("Got unauthorized POST attempt");
//res.status(401);
//return;
//}
var entry = {
name: genFileName(),
oname: req.file.originalname,

View File

@ -1,7 +1,8 @@
var express = require('express');
var router = express.Router();
var fs = require('fs');
var Upload = require('../models/Upload.js');
var mongoose = require('mongoose');
var Upload = mongoose.model('Upload');
router.get('/:name', function(req, res, next) {
console.log('GET: ', req.params);

29
config/passport.js Normal file
View File

@ -0,0 +1,29 @@
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var mongoose = require('mongoose');
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.'
});
}
return done(null, user);
});
}
));

View File

@ -5,13 +5,16 @@
"angular-messages": "^1.6.6",
"body-parser": "^1.18.2",
"express": "latest",
"express-jwt": "^5.3.0",
"gulp": "latest",
"jsonwebtoken": "^8.1.0",
"jwt-sign": "^0.1.0",
"method-override": "latest",
"mongoose": "latest",
"multer": "^1.3.0",
"ng-file-upload": "^12.2.13"
"ng-file-upload": "^12.2.13",
"passport": "^0.4.0",
"passport-local": "^1.0.0"
},
"description": "A simple file sharing website.",
"main": "index.js",

View File

@ -119,6 +119,13 @@ h1 {
outline: none;
}
.list-err {
font-family: 'Roboto Mono', monospace;
margin-left: auto;
color: #ff6666;
vertical-align: super;
}
nav > ul,

View File

@ -1 +1 @@
angular.module('shimapan', ['ngFileUpload', 'ngclipboard', 'UploadCtrl']);
angular.module('shimapan', ['ngFileUpload', 'ngclipboard', 'UploadComp', 'RegisterComp']);

View File

@ -0,0 +1,16 @@
function RegisterController($scope, AuthService) {
$scope.register = function() {
AuthService.register({
username: $scope.username,
password: $scope.password
}).then(function() {
alert('Registered');
});
};
}
angular.module('RegisterComp', ['AuthSvc']).component('registerComponent', {
templateUrl: '/views/register-form.html',
controller: RegisterController,
controllerAs: 'vm'
});

View File

@ -1,11 +1,14 @@
angular.module('UploadCtrl', ['ngFileUpload']).controller('UploadController', ['$scope', 'Upload', '$timeout', function ($scope, Upload, $timeout) {
$scope.uploadFiles = function (files, errorFiles) {
if (!$scope.files)
$scope.files = files;
function UploadController($scope, Upload, $timeout) {
$scope.errToString = function(err) {
if (err === 'maxSize')
return "File too large.";
else
$scope.files = $scope.files.concat(files);
return err;
};
$scope.errorFiles = errorFiles;
$scope.uploadFiles = function(files, errorFiles) {
$scope.files = $scope.files ? $scope.files.concat(files) : files;
$scope.errorFiles = $scope.errorFiles ? $scope.errorFiles.concat(errorFiles) : errorFiles;
angular.forEach(files, function (file) {
file.upload = Upload.upload({
@ -31,4 +34,10 @@ angular.module('UploadCtrl', ['ngFileUpload']).controller('UploadController', ['
);
});
};
}]);
}
angular.module('UploadComp', ['ngFileUpload']).component('uploadComponent', {
templateUrl: '/views/upload-form.html',
controller: UploadController,
controllerAs: 'vm'
});

View File

@ -0,0 +1,66 @@
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.login = function(user) {
return $http({
method: 'POST',
url: '/api/auth/login',
headers: {'Content-Type': 'x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
for (var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data: user
}).then(function(res) {
saveToken(res.data.token);
})
};
this.logout = function() {
$window.localStorage.removeItem('shimapan-token');
};
this.isLoggedIn = function() {
var payload = decodeToken(getToken());
return payload.exp > Date.now() / 1000;
};
this.register = function(user) {
return $http({
method: 'POST',
url: '/api/auth/register',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
for (var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data: user
}).then(function(res) {
saveToken(res.data.token);
});
};
this.currentUser = function() {
var payload = decodeToken(getToken());
return payload.username;
};
}]);

View File

@ -14,30 +14,15 @@
<script src="https://cdn.rawgit.com/zenorocha/clipboard.js/master/dist/clipboard.min.js"></script>
<script src="/libs/ngclipboard/src/ngclipboard.js"></script>
<script src="/js/controllers/UploadCtrl.js"></script>
<script src="/js/components/UploadComp.js"></script>
<script src="/js/components/RegisterComp.js"></script>
<script src="/js/services/AuthSvc.js"></script>
<script src="/js/app.js"></script>
</head>
<body ng-app="shimapan">
<div id="container">
<h1>Shimapan~</h1>
<div class="upload" ng-controller="UploadController">
<form id="upload-form" ng-submit="submit()">
<button id="upload-btn" class="btn" ngf-select="uploadFiles($files, $invalidFiles)" multiple>Select or drop file(s)</button>
</form>
<ul id="upload-filelist">
<li ng-repeat="file in files">
<span class="list-name" ng-bind="file.name"></span>
<progress class="list-progress" max="100" value="{{file.progress}}" ng-hide="file.progress == 100"></progress>
<span class="list-url">
<a href="https://shimapan.rocks/v/{{file.result.name}}" ng-hide="file.progress < 100">https://shimapan.rocks/v/{{file.result.name}}</a>
<button class="list-url-clipboard-btn" ngclipboard data-clipboard-text="https://shimapan.rocks/v/{{file.result.name}}">
<img src="/img/glyphicons-512-copy.png"/>
</button>
</span>
</li>
<li ng-repeat="file in errorFiles">{{file.name}} {{file.$error}} {{file.$errorParam}}</li>
</ul>
</div>
<upload-component></upload-component>
<nav>
<ul>
<li><a href="/">Shimapan</a></li>

View File

@ -0,0 +1,11 @@
<form ng-submit="register()">
<div class="form-group">
<label for="username">Username</label>
<input id="username" class="form-control" type="text" ng-model="username"/>
</div>
<div class="form-group">
<label for="password">Password</label>
<input id="password" class="form-control" type="password" ng-model="password"/>
</div>
<button type="submit" class="btn">Register</button>
</form>

View File

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<base href="/register"/>
<title>Register</title>
<script src="/libs/angular/angular.min.js"></script>
<script src="/libs/ng-file-upload/ng-file-upload-all.min.js"></script>
<script src="https://cdn.rawgit.com/zenorocha/clipboard.js/master/dist/clipboard.min.js"></script>
<script src="/libs/ngclipboard/src/ngclipboard.js"></script>
<script src="/js/components/UploadComp.js"></script>
<script src="/js/components/RegisterComp.js"></script>
<script src="/js/services/AuthSvc.js"></script>
<script src="/js/app.js"></script>
</head>
<body ng-app="shimapan">
<div id="container" ng-controller="RegisterController">
<register-component></register-component>
</div>
</body>
</html>

View File

@ -0,0 +1,21 @@
<div class="upload">
<form id="upload-form" ng-submit="submit()">
<button id="upload-btn" class="btn" ngf-select="uploadFiles($files, $invalidFiles)" ngf-max-size="128MB" multiple>Select or drop file(s)</button>
</form>
<ul id="upload-filelist">
<li ng-repeat="file in files">
<span class="list-name" ng-bind="file.name"></span>
<progress class="list-progress" max="100" value="{{file.progress}}" ng-hide="file.progress == 100"></progress>
<span class="list-url">
<a href="https://shimapan.rocks/v/{{file.result.name}}" ng-hide="file.progress < 100">https://shimapan.rocks/v/{{file.result.name}}</a>
<button class="list-url-clipboard-btn" ngclipboard data-clipboard-text="https://shimapan.rocks/v/{{file.result.name}}">
<img src="/img/glyphicons-512-copy.png"/>
</button>
</span>
</li>
<li ng-repeat="file in errorFiles">
<span class="list-name" ng-bind="file.name"></span>
<span class="list-err">Error: {{errToString(file.$error)}}</span>
</li>
</ul>
</div>

View File

@ -2,12 +2,12 @@ var express = require('express');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var mongoose = require('mongoose');
var passport = require('passport');
var app = express();
mongoose.connect('mongodb://localhost/shimapan', {useMongoClient: true});
var db = mongoose.connection;
db.on('error', function(err) {
if (err)
console.log('MongoDB Connection Error: ', err);
@ -15,16 +15,22 @@ db.on('error', function(err) {
console.log('MongoDB Connection Established');
});
db.once('open', function() {
console.log('MongoDB Connection Open')
});
require('./config/passport.js');
app.use(bodyParser.json());
app.use(bodyParser.json({ type: 'application/vnd.api+json' }));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(passport.initialize());
app.use(methodOverride('X-HTTP-Method-Override'));
app.get('/secret', passport.authenticate('local', { session: false }), function(req, res) {
res.json("You cannot see this without a token!");
});
// Set /public to document root
app.use(express.static(__dirname + '/public'));
require('./app/routes')(app);