diff --git a/packages/api-gateway/src/Controller/AuthMiddleware.ts b/packages/api-gateway/src/Controller/AuthMiddleware.ts index 10579330b..ca15d3125 100644 --- a/packages/api-gateway/src/Controller/AuthMiddleware.ts +++ b/packages/api-gateway/src/Controller/AuthMiddleware.ts @@ -17,7 +17,7 @@ export abstract class AuthMiddleware extends BaseMiddleware { private crossServiceTokenCacheTTL: number, private crossServiceTokenCache: CrossServiceTokenCacheInterface, private timer: TimerInterface, - private logger: Logger, + protected logger: Logger, ) { super() } diff --git a/packages/api-gateway/src/Controller/RequiredCrossServiceTokenMiddleware.ts b/packages/api-gateway/src/Controller/RequiredCrossServiceTokenMiddleware.ts index 62ab18c7d..54e0dc9c8 100644 --- a/packages/api-gateway/src/Controller/RequiredCrossServiceTokenMiddleware.ts +++ b/packages/api-gateway/src/Controller/RequiredCrossServiceTokenMiddleware.ts @@ -42,6 +42,8 @@ export class RequiredCrossServiceTokenMiddleware extends AuthMiddleware { _next: NextFunction, ): boolean { if (!authHeaderValue) { + this.logger.debug('Missing auth header') + response.status(401).send({ error: { tag: 'invalid-auth', diff --git a/packages/auth/src/Domain/UseCase/AuthenticateRequest.ts b/packages/auth/src/Domain/UseCase/AuthenticateRequest.ts index acad1e48a..d3e44c691 100644 --- a/packages/auth/src/Domain/UseCase/AuthenticateRequest.ts +++ b/packages/auth/src/Domain/UseCase/AuthenticateRequest.ts @@ -16,6 +16,8 @@ export class AuthenticateRequest implements UseCaseInterface { async execute(dto: AuthenticateRequestDTO): Promise { if (!dto.authorizationHeader) { + this.logger.debug('Authorization header not provided.') + return { success: false, responseCode: 401, diff --git a/packages/auth/src/Domain/UseCase/AuthenticateUser.spec.ts b/packages/auth/src/Domain/UseCase/AuthenticateUser.spec.ts index a0a4da31e..571d122c4 100644 --- a/packages/auth/src/Domain/UseCase/AuthenticateUser.spec.ts +++ b/packages/auth/src/Domain/UseCase/AuthenticateUser.spec.ts @@ -7,6 +7,7 @@ import { AuthenticateUser } from './AuthenticateUser' import { RevokedSession } from '../Session/RevokedSession' import { AuthenticationMethodResolverInterface } from '../Auth/AuthenticationMethodResolverInterface' import { TimerInterface } from '@standardnotes/time' +import { Logger } from 'winston' describe('AuthenticateUser', () => { let user: User @@ -14,11 +15,15 @@ describe('AuthenticateUser', () => { let revokedSession: RevokedSession let authenticationMethodResolver: AuthenticationMethodResolverInterface let timer: TimerInterface + let logger: Logger const accessTokenAge = 3600 - const createUseCase = () => new AuthenticateUser(authenticationMethodResolver, timer, accessTokenAge) + const createUseCase = () => new AuthenticateUser(authenticationMethodResolver, timer, accessTokenAge, logger) beforeEach(() => { + logger = {} as jest.Mocked + logger.debug = jest.fn() + user = {} as jest.Mocked user.supportsSessions = jest.fn().mockReturnValue(false) diff --git a/packages/auth/src/Domain/UseCase/AuthenticateUser.ts b/packages/auth/src/Domain/UseCase/AuthenticateUser.ts index d5169f3e7..17bcbb2e9 100644 --- a/packages/auth/src/Domain/UseCase/AuthenticateUser.ts +++ b/packages/auth/src/Domain/UseCase/AuthenticateUser.ts @@ -9,6 +9,7 @@ import { Session } from '../Session/Session' import { AuthenticateUserDTO } from './AuthenticateUserDTO' import { AuthenticateUserResponse } from './AuthenticateUserResponse' import { UseCaseInterface } from './UseCaseInterface' +import { Logger } from 'winston' @injectable() export class AuthenticateUser implements UseCaseInterface { @@ -17,11 +18,14 @@ export class AuthenticateUser implements UseCaseInterface { private authenticationMethodResolver: AuthenticationMethodResolverInterface, @inject(TYPES.Auth_Timer) private timer: TimerInterface, @inject(TYPES.Auth_ACCESS_TOKEN_AGE) private accessTokenAge: number, + @inject(TYPES.Auth_Logger) private logger: Logger, ) {} async execute(dto: AuthenticateUserDTO): Promise { const authenticationMethod = await this.authenticationMethodResolver.resolve(dto.token) if (!authenticationMethod) { + this.logger.debug('No authentication method found for token.') + return { success: false, failureType: 'INVALID_AUTH', @@ -37,6 +41,8 @@ export class AuthenticateUser implements UseCaseInterface { const user = authenticationMethod.user if (!user) { + this.logger.debug('No user found for authentication method.') + return { success: false, failureType: 'INVALID_AUTH', @@ -44,6 +50,8 @@ export class AuthenticateUser implements UseCaseInterface { } if (authenticationMethod.type == 'jwt' && user.supportsSessions()) { + this.logger.debug('User supports sessions but is trying to authenticate with a JWT.') + return { success: false, failureType: 'INVALID_AUTH', @@ -56,6 +64,8 @@ export class AuthenticateUser implements UseCaseInterface { const encryptedPasswordDigest = crypto.createHash('sha256').update(user.encryptedPassword).digest('hex') if (!pwHash || !crypto.timingSafeEqual(Buffer.from(pwHash), Buffer.from(encryptedPasswordDigest))) { + this.logger.debug('Password hash does not match.') + return { success: false, failureType: 'INVALID_AUTH', @@ -66,6 +76,8 @@ export class AuthenticateUser implements UseCaseInterface { case 'session_token': { const session = authenticationMethod.session if (!session) { + this.logger.debug('No session found for authentication method.') + return { success: false, failureType: 'INVALID_AUTH', @@ -73,6 +85,8 @@ export class AuthenticateUser implements UseCaseInterface { } if (session.refreshExpiration < this.timer.getUTCDate()) { + this.logger.debug('Session refresh token has expired.') + return { success: false, failureType: 'INVALID_AUTH', diff --git a/packages/syncing-server/src/Infra/InversifyExpressUtils/Middleware/InversifyExpressAuthMiddleware.ts b/packages/syncing-server/src/Infra/InversifyExpressUtils/Middleware/InversifyExpressAuthMiddleware.ts index 5803e9770..c494c37d6 100644 --- a/packages/syncing-server/src/Infra/InversifyExpressUtils/Middleware/InversifyExpressAuthMiddleware.ts +++ b/packages/syncing-server/src/Infra/InversifyExpressUtils/Middleware/InversifyExpressAuthMiddleware.ts @@ -13,6 +13,8 @@ export class InversifyExpressAuthMiddleware extends BaseMiddleware { async handler(request: Request, response: Response, next: NextFunction): Promise { try { if (!request.header('X-Auth-Token')) { + this.logger.debug('Missing X-Auth-Token header') + return this.sendInvalidAuthResponse(response) }