You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
2.8 KiB

  1. const express = require('express');
  2. const mustacheExpress = require('mustache-express');
  3. const portfinder = require('portfinder');
  4. const session = require('express-session');
  5. const jwt = require('jsonwebtoken');
  6. const config = require('./config');
  7. const fs = require('fs');
  8. const setupExpress = (port) => {
  9. const app = express();
  10. app.engine('mustache', mustacheExpress());
  11. app.set('view engine', 'mustache');
  12. app.set('views', __dirname + '/views');
  13. app.set('trust proxy', 1);
  14. app.use(session({
  15. secret: 'somesecret',
  16. resave: false,
  17. saveUninitialized: true,
  18. cookie: { secure: false }
  19. }));
  20. app.use(express.static('public'));
  21. app.use(express.urlencoded({ extended: false }));
  22. setupRoutes(app);
  23. app.listen(port, () => console.log(`Tiny Drive starter project is now available at: http://localhost:${port}/`));
  24. };
  25. const setupRoutes = (app) => {
  26. app.get('/', (req, res) => {
  27. res.render('index');
  28. });
  29. app.get('/editor', (req, res) => {
  30. if (req.session.user) {
  31. res.render('editor', { apiKey: config.apiKey, fullname: req.session.user.fullname });
  32. } else {
  33. res.redirect('/');
  34. }
  35. });
  36. app.get('/logout', (req, res) => {
  37. req.session.destroy();
  38. res.redirect('/');
  39. });
  40. app.post('/jwt', (req, res) => {
  41. const user = req.session.user;
  42. if (user) {
  43. const payload = {
  44. sub: user.username, // Unique user id string
  45. name: user.fullname, // Full name of user
  46. exp: Math.floor(Date.now() / 1000) + (60 * 10) // 10 minutes expiration
  47. };
  48. // When this is set the user will only be able to manage and see files in the specified root
  49. // directory. This makes it possible to have a dedicated home directory for each user.
  50. if (config.scopeUser) {
  51. payload['https://claims.tiny.cloud/drive/root'] = `/${user.username}`;
  52. }
  53. try {
  54. const privateKey = fs.readFileSync(config.privateKeyFile).toString();
  55. const token = jwt.sign(payload, privateKey, { algorithm: 'RS256'});
  56. res.json({ token });
  57. } catch (e) {
  58. res.status(500);
  59. res.send('Failed generate jwt token.');
  60. console.error(e.message);
  61. }
  62. } else {
  63. res.status(401);
  64. res.send('Could not produce a jwt token since the user is not logged in.');
  65. }
  66. });
  67. app.post('/', (req, res) => {
  68. const user = config.users.find(({ username, password }) => username === req.body.username && password === req.body.password);
  69. if (user) {
  70. req.session.user = user;
  71. res.redirect('/editor');
  72. } else {
  73. res.render('index', { error: 'Incorrect username or password.' })
  74. }
  75. });
  76. };
  77. portfinder.getPort({
  78. port: 3000,
  79. stopPort: 4000
  80. }, (err, port) => {
  81. if (err) {
  82. console.error('Error:', err.message);
  83. process.exit(-1);
  84. } else {
  85. setupExpress(port);
  86. }
  87. });