A simple file sharing site with an easy to use API and online panel.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

128 lignes
4.0KB

  1. const express = require('express');
  2. const router = express.Router();
  3. const config = require('config');
  4. const fs = require('fs').promises;
  5. const passport = require('passport');
  6. const canonicalize = require('../../util/auth/canonicalize');
  7. const ModelPath = '../../models/';
  8. const User = require(ModelPath + 'User.js');
  9. const Invite = require(ModelPath + 'Invite.js');
  10. const authenticate = require('../../util/auth/authenticateRequest');
  11. const verifyBody = require('../../util/verifyBody');
  12. const rateLimit = require('../../util/rateLimit');
  13. // Wraps passport.authenticate to return a promise
  14. const passportAuthenticate = (req, res, next) => {
  15. return new Promise((resolve) => {
  16. passport.authenticate('local', (err, user) => {
  17. resolve(user);
  18. })(req, res, next);
  19. });
  20. };
  21. // Wraps passport session creation to return a promise
  22. const passportLogin = (user, req) => {
  23. return new Promise((resolve) => {
  24. req.login(user, resolve);
  25. });
  26. };
  27. const registerParams = [
  28. {name: 'displayname', type: 'string', maxLength: config.get('User.Username.maxLength'), sanitize: true, restrict: new RegExp(config.get('User.Username.restrictedChars'))},
  29. {name: 'password', type: 'string'},
  30. {name: 'invite', type: 'string'}];
  31. router.post('/register',
  32. rateLimit(config.get('RateLimit.register.window'), config.get('RateLimit.register.max'), true),
  33. verifyBody(registerParams),
  34. async (req, res) => {
  35. const username = canonicalize(req.body.displayname);
  36. // Retrieve invite and username status
  37. const [invite, usernameCount] = await Promise.all([
  38. Invite.findOne({code: req.body.invite}),
  39. User.countDocuments({username: username})
  40. ]);
  41. // Validate the invite
  42. if (!invite)
  43. return res.status(422).json({message: 'Invalid invite code.'});
  44. if (invite.used)
  45. return res.status(422).json({message: 'Invite already used.'});
  46. if (invite.expires != null && invite.expires < Date.now())
  47. return res.status(422).json({message: 'Invite expired.'});
  48. // Validate the username
  49. if (usernameCount !== 0)
  50. return res.status(422).json({message: 'Username in use.'});
  51. // Create the user object
  52. await User.register({
  53. username: username,
  54. displayname: req.body.displayname,
  55. scope: invite.scope,
  56. date: Date.now()
  57. }, req.body.password);
  58. // Update the invite as used
  59. await Invite.updateOne({code: invite.code}, {recipient: username, used: Date.now()});
  60. res.status(200).json({'message': 'Registration successful.'});
  61. });
  62. const loginParams = [
  63. {name: 'displayname', type: 'string'},
  64. {name: 'password', type: 'string'}];
  65. router.post('/login',
  66. rateLimit(config.get('RateLimit.login.window'), config.get('RateLimit.login.max'), true),
  67. verifyBody(loginParams),
  68. async (req, res, next) => {
  69. req.body.username = canonicalize(req.body.displayname);
  70. // Authenticate
  71. const user = await passportAuthenticate(req, res, next);
  72. if (!user) {
  73. // Log failure
  74. await fs.appendFile('auth.log', `${new Date().toISOString()} login ${req.ip}\n`);
  75. return res.status(401).json({'message': 'Unauthorized.'});
  76. }
  77. // Create session
  78. await passportLogin(user, req);
  79. // Set session vars
  80. req.session.passport.displayname = user.displayname;
  81. req.session.passport.scope = user.scope;
  82. res.status(200).json({'message': 'Logged in.'});
  83. });
  84. router.post('/logout', (req, res) => {
  85. if (!req.isAuthenticated())
  86. return res.status(400).json({message: 'Not logged in.'});
  87. req.logout();
  88. res.status(200).json({'message': 'Logged out.'});
  89. });
  90. router.get('/whoami', authenticate(), (req, res) => {
  91. res.status(200).json({
  92. username: req.username,
  93. displayname: req.displayname,
  94. scope: req.scope,
  95. key: req.key
  96. });
  97. });
  98. module.exports = router;