X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Flib%2Fauth%2Foauth.ts;h=bc0d4301f082519a02a666d279c0e6bf5ad8c431;hb=37ff5005b47b9df2933a0b8812609a6c41faa170;hp=47bc8c05566774098671fec01393457e97ed2707;hpb=06aad80165d09a8863ab8103149a8ff518b10641;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/lib/auth/oauth.ts b/server/lib/auth/oauth.ts index 47bc8c055..bc0d4301f 100644 --- a/server/lib/auth/oauth.ts +++ b/server/lib/auth/oauth.ts @@ -1,5 +1,5 @@ import express from 'express' -import { +import OAuth2Server, { InvalidClientError, InvalidGrantError, InvalidRequestError, @@ -7,20 +7,31 @@ import { Response, UnauthorizedClientError, UnsupportedGrantTypeError -} from 'oauth2-server' -import { sha1 } from '@shared/core-utils/crypto' +} from '@node-oauth/oauth2-server' import { randomBytesPromise } from '@server/helpers/core-utils' +import { isOTPValid } from '@server/helpers/otp' import { MOAuthClient } from '@server/types/models' -import { OAUTH_LIFETIME } from '../../initializers/constants' +import { sha1 } from '@shared/extra-utils' +import { HttpStatusCode } from '@shared/models' +import { OAUTH_LIFETIME, OTP } from '../../initializers/constants' import { BypassLogin, getClient, getRefreshToken, getUser, revokeToken, saveToken } from './oauth-model' +class MissingTwoFactorError extends Error { + code = HttpStatusCode.UNAUTHORIZED_401 + name = 'missing_two_factor' +} + +class InvalidTwoFactorError extends Error { + code = HttpStatusCode.BAD_REQUEST_400 + name = 'invalid_two_factor' +} + /** * * Reimplement some functions of OAuth2Server to inject external auth methods * */ - -const oAuthServer = new (require('oauth2-server'))({ +const oAuthServer = new OAuth2Server({ accessTokenLifetime: OAUTH_LIFETIME.ACCESS_TOKEN, refreshTokenLifetime: OAUTH_LIFETIME.REFRESH_TOKEN, @@ -84,17 +95,15 @@ async function handleOAuthToken (req: express.Request, options: { refreshTokenAu function handleOAuthAuthenticate ( req: express.Request, - res: express.Response, - authenticateInQuery = false + res: express.Response ) { - const options = authenticateInQuery - ? { allowBearerTokensInQueryString: true } - : {} - - return oAuthServer.authenticate(new Request(req), new Response(res), options) + return oAuthServer.authenticate(new Request(req), new Response(res)) } export { + MissingTwoFactorError, + InvalidTwoFactorError, + handleOAuthToken, handleOAuthAuthenticate } @@ -119,6 +128,16 @@ async function handlePasswordGrant (options: { const user = await getUser(request.body.username, request.body.password, bypassLogin) if (!user) throw new InvalidGrantError('Invalid grant: user credentials are invalid') + if (user.otpSecret) { + if (!request.headers[OTP.HEADER_NAME]) { + throw new MissingTwoFactorError('Missing two factor header') + } + + if (await isOTPValid({ encryptedSecret: user.otpSecret, token: request.headers[OTP.HEADER_NAME] }) !== true) { + throw new InvalidTwoFactorError('Invalid two factor header') + } + } + const token = await buildToken() return saveToken(token, client, user, { bypassLogin })