oauth.ts 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import * as express from 'express'
  2. import * as OAuthServer from 'express-oauth-server'
  3. import { OAUTH_LIFETIME } from '../initializers/constants'
  4. import { logger } from '../helpers/logger'
  5. import { Socket } from 'socket.io'
  6. import { getAccessToken } from '../lib/oauth-model'
  7. const oAuthServer = new OAuthServer({
  8. useErrorHandler: true,
  9. accessTokenLifetime: OAUTH_LIFETIME.ACCESS_TOKEN,
  10. refreshTokenLifetime: OAUTH_LIFETIME.REFRESH_TOKEN,
  11. continueMiddleware: true,
  12. model: require('../lib/oauth-model')
  13. })
  14. function authenticate (req: express.Request, res: express.Response, next: express.NextFunction, authenticateInQuery = false) {
  15. const options = authenticateInQuery ? { allowBearerTokensInQueryString: true } : {}
  16. oAuthServer.authenticate(options)(req, res, err => {
  17. if (err) {
  18. logger.warn('Cannot authenticate.', { err })
  19. return res.status(err.status)
  20. .json({
  21. error: 'Token is invalid.',
  22. code: err.name
  23. })
  24. .end()
  25. }
  26. return next()
  27. })
  28. }
  29. function authenticateSocket (socket: Socket, next: (err?: any) => void) {
  30. const accessToken = socket.handshake.query.accessToken
  31. logger.debug('Checking socket access token %s.', accessToken)
  32. if (!accessToken) return next(new Error('No access token provided'))
  33. getAccessToken(accessToken)
  34. .then(tokenDB => {
  35. const now = new Date()
  36. if (!tokenDB || tokenDB.accessTokenExpiresAt < now || tokenDB.refreshTokenExpiresAt < now) {
  37. return next(new Error('Invalid access token.'))
  38. }
  39. socket.handshake.query.user = tokenDB.User
  40. return next()
  41. })
  42. }
  43. function authenticatePromiseIfNeeded (req: express.Request, res: express.Response, authenticateInQuery = false) {
  44. return new Promise(resolve => {
  45. // Already authenticated? (or tried to)
  46. if (res.locals.oauth && res.locals.oauth.token.User) return resolve()
  47. if (res.locals.authenticated === false) return res.sendStatus(401)
  48. authenticate(req, res, () => resolve(), authenticateInQuery)
  49. })
  50. }
  51. function optionalAuthenticate (req: express.Request, res: express.Response, next: express.NextFunction) {
  52. if (req.header('authorization')) return authenticate(req, res, next)
  53. res.locals.authenticated = false
  54. return next()
  55. }
  56. function token (req: express.Request, res: express.Response, next: express.NextFunction) {
  57. return oAuthServer.token()(req, res, err => {
  58. if (err) {
  59. return res.status(err.status)
  60. .json({
  61. error: err.message,
  62. code: err.name
  63. })
  64. .end()
  65. }
  66. return next()
  67. })
  68. }
  69. // ---------------------------------------------------------------------------
  70. export {
  71. authenticate,
  72. authenticateSocket,
  73. authenticatePromiseIfNeeded,
  74. optionalAuthenticate,
  75. token
  76. }