mirror of
https://github.com/Foltik/Shimapan
synced 2025-01-05 15:58:03 -05:00
Work on stuff...
This commit is contained in:
parent
659792e71b
commit
8251900309
2
.gitignore
vendored
2
.gitignore
vendored
@ -3,5 +3,7 @@ public/libs/
|
||||
.idea/
|
||||
.awcache/
|
||||
|
||||
uploads/
|
||||
|
||||
package-lock.json
|
||||
jwt.pem
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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
53
app/routes/auth.js
Normal 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
9
app/routes/register.js
Normal 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;
|
@ -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,
|
||||
|
@ -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
29
config/passport.js
Normal 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);
|
||||
});
|
||||
}
|
||||
));
|
@ -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",
|
||||
|
@ -119,6 +119,13 @@ h1 {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.list-err {
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
margin-left: auto;
|
||||
color: #ff6666;
|
||||
vertical-align: super;
|
||||
}
|
||||
|
||||
|
||||
|
||||
nav > ul,
|
||||
|
@ -1 +1 @@
|
||||
angular.module('shimapan', ['ngFileUpload', 'ngclipboard', 'UploadCtrl']);
|
||||
angular.module('shimapan', ['ngFileUpload', 'ngclipboard', 'UploadComp', 'RegisterComp']);
|
16
public/js/components/RegisterComp.js
Normal file
16
public/js/components/RegisterComp.js
Normal 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'
|
||||
});
|
@ -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'
|
||||
});
|
66
public/js/services/AuthSvc.js
Normal file
66
public/js/services/AuthSvc.js
Normal 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;
|
||||
};
|
||||
}]);
|
@ -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>
|
||||
|
11
public/views/register-form.html
Normal file
11
public/views/register-form.html
Normal 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>
|
24
public/views/register.html
Normal file
24
public/views/register.html
Normal 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>
|
||||
|
21
public/views/upload-form.html
Normal file
21
public/views/upload-form.html
Normal 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>
|
10
server.js
10
server.js
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user