Update server dependencies
[oweals/peertube.git] / server / middlewares / oauth.ts
index 07bbded57d636d3a5999c46cc7b94621981c4c72..b1149174bfbf633c0ba7314718b997fa8f9ab451 100644 (file)
@@ -1,34 +1,74 @@
-import OAuthServer = require('express-oauth-server')
+import * as express from 'express'
+import { logger } from '../helpers/logger'
+import { Socket } from 'socket.io'
+import { getAccessToken } from '../lib/oauth-model'
+import { oAuthServer } from '@server/lib/auth'
 
-import { OAUTH_LIFETIME } from '../initializers'
-import { logger } from '../helpers'
+function authenticate (req: express.Request, res: express.Response, next: express.NextFunction, authenticateInQuery = false) {
+  const options = authenticateInQuery ? { allowBearerTokensInQueryString: true } : {}
 
-const oAuthServer = new OAuthServer({
-  accessTokenLifetime: OAUTH_LIFETIME.ACCESS_TOKEN,
-  refreshTokenLifetime: OAUTH_LIFETIME.REFRESH_TOKEN,
-  model: require('../lib/oauth-model')
-})
-
-function authenticate (req, res, next) {
-  oAuthServer.authenticate()(req, res, function (err) {
+  oAuthServer.authenticate(options)(req, res, err => {
     if (err) {
-      logger.error('Cannot authenticate.', { error: err })
-      return res.sendStatus(500)
-    }
+      logger.warn('Cannot authenticate.', { err })
 
-    if (res.statusCode === 401 || res.statusCode === 400 || res.statusCode === 503) return res.end()
+      return res.status(err.status)
+        .json({
+          error: 'Token is invalid.',
+          code: err.name
+        })
+        .end()
+    }
 
     return next()
   })
 }
 
-function token (req, res, next) {
-  return oAuthServer.token()(req, res, next)
+function authenticateSocket (socket: Socket, next: (err?: any) => void) {
+  const accessToken = socket.handshake.query.accessToken
+
+  logger.debug('Checking socket access token %s.', accessToken)
+
+  if (!accessToken) return next(new Error('No access token provided'))
+
+  getAccessToken(accessToken)
+    .then(tokenDB => {
+      const now = new Date()
+
+      if (!tokenDB || tokenDB.accessTokenExpiresAt < now || tokenDB.refreshTokenExpiresAt < now) {
+        return next(new Error('Invalid access token.'))
+      }
+
+      socket.handshake.query.user = tokenDB.User
+
+      return next()
+    })
+    .catch(err => logger.error('Cannot get access token.', { err }))
+}
+
+function authenticatePromiseIfNeeded (req: express.Request, res: express.Response, authenticateInQuery = false) {
+  return new Promise(resolve => {
+    // Already authenticated? (or tried to)
+    if (res.locals.oauth?.token.User) return resolve()
+
+    if (res.locals.authenticated === false) return res.sendStatus(401)
+
+    authenticate(req, res, () => resolve(), authenticateInQuery)
+  })
+}
+
+function optionalAuthenticate (req: express.Request, res: express.Response, next: express.NextFunction) {
+  if (req.header('authorization')) return authenticate(req, res, next)
+
+  res.locals.authenticated = false
+
+  return next()
 }
 
 // ---------------------------------------------------------------------------
 
 export {
   authenticate,
-  token
+  authenticateSocket,
+  authenticatePromiseIfNeeded,
+  optionalAuthenticate
 }