-
Steve Reis authoredd8f77d4c
auth.resolver.ts 3.04 KiB
import {
Inject,
InternalServerErrorException,
Logger,
UseGuards,
} from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { Args, Mutation, Resolver } from '@nestjs/graphql';
import { Response, Request } from 'express';
import { GQLRequest } from 'src/common/decorators/gql-request.decoractor';
import { GQLResponse } from '../common/decorators/gql-response.decoractor';
import { parseToBoolean } from '../common/utilities';
import {
ENGINE_MODULE_OPTIONS,
ENGINE_SERVICE,
} from '../engine/engine.constants';
import { IEngineOptions, IEngineService } from '../engine/engine.interfaces';
import { User } from '../users/models/user.model';
import { authConstants } from './auth-constants';
import { AuthService } from './auth.service';
import { CurrentUser } from './decorators/user.decorator';
import { JwtAuthGuard } from './guards/jwt-auth.guard';
import { LocalAuthGuard } from './guards/local-auth.guard';
import { AuthenticationInput } from './inputs/authentication.input';
import { AuthenticationOutput } from './outputs/authentication.output';
//Custom defined type because Pick<CookieOptions, 'sameSite'> does not work
type SameSiteType = boolean | 'lax' | 'strict' | 'none' | undefined;
@Resolver()
export class AuthResolver {
private readonly logger = new Logger(AuthResolver.name);
constructor(
@Inject(ENGINE_SERVICE) private readonly engineService: IEngineService,
@Inject(ENGINE_MODULE_OPTIONS)
private readonly engineOptions: IEngineOptions,
private readonly authService: AuthService,
private readonly configService: ConfigService,
) {}
@Mutation(() => AuthenticationOutput)
@UseGuards(LocalAuthGuard)
async login(
@GQLResponse() res: Response,
@CurrentUser() user: User,
@Args('variables') inputs: AuthenticationInput,
): Promise<AuthenticationOutput> {
this.logger.verbose(`${inputs.username} logged in`);
const data = await this.authService.login(user);
if (!data)
throw new InternalServerErrorException(
`Error during the authentication process`,
);
res.cookie(authConstants.cookie.name, data.accessToken, {
httpOnly: parseToBoolean(
this.configService.get(authConstants.cookie.httpOnly, 'true'),
),
sameSite: this.configService.get<SameSiteType>(
authConstants.cookie.sameSite,
'strict',
),
secure: parseToBoolean(
this.configService.get(authConstants.cookie.secure, 'true'),
),
});
return {
accessToken: data.accessToken,
};
}
@Mutation(() => Boolean)
@UseGuards(JwtAuthGuard)
logout(
@GQLRequest() req: Request,
@GQLResponse() res: Response,
@CurrentUser() user: User,
): boolean {
if (user) {
this.logger.verbose(`${user.username} logged out`);
try {
this.engineService.logout?.(req);
} catch (e) {
this.logger.debug(
`Service ${this.engineOptions.type} produce an error when logging out ${user.username}`,
);
}
}
res.clearCookie(authConstants.cookie.name);
return true;
}
}