Use sofa plugin
lukadriel7 opened this issue · comments
Hello, I am trying to use the sofa plugin with this library.
The swager docs works but when trying post requests (mutations) I receive an error indicating that the variables were not provided. I use a code first approach. I call the login migration.
My config is as follow :
app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AuthModule } from './auth/auth.module';
import { UsersModule } from './users/users.module';
import { PrismaModule } from './prisma/prisma.module';
import { GraphQLModule } from '@nestjs/graphql';
import { YogaDriverConfig, YogaDriver } from '@graphql-yoga/nestjs';
import { useSofaWithSwaggerUI } from '@graphql-yoga/plugin-sofa';
import { AcceptLanguageResolver, I18nModule, QueryResolver } from 'nestjs-i18n';
import { join } from 'path';
import { cwd } from 'process';
@Module({
imports: [
I18nModule.forRoot({
fallbackLanguage: 'en',
fallbacks: {
'en-*': 'en',
'fr-*': 'fr',
},
loaderOptions: {
path: join(cwd(), 'src/i18n'),
},
typesOutputPath: join(cwd(), 'src/generated/i18n.generated.ts'),
resolvers: [QueryResolver, AcceptLanguageResolver],
}),
GraphQLModule.forRoot<YogaDriverConfig>({
driver: YogaDriver,
autoSchemaFile: join(cwd(), 'src/schema.gql'),
sortSchema: true,
installSubscriptionHandlers: true,
plugins: [
useSofaWithSwaggerUI({
basePath: '/graphql/rest',
swaggerUIEndpoint: '/graphql/swagger',
servers: [
{
url: '/', // Specify Server's URL.
description: 'Development server',
},
],
info: {
title: 'Example API',
version: '1.0.0',
},
}),
],
}),
AuthModule,
UsersModule,
PrismaModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
auth.resolver.ts
import { UseGuards } from '@nestjs/common';
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
import { PasswordlessUser } from 'src/users/models/user.model';
import { AuthService } from './auth.service';
import { CurrentUser } from './decorators/current-user.decorator';
import { LoginArgs } from './dtos/login.args';
import { RegisterArgs } from './dtos/register.args';
import { GqlLocalAuthGuard } from './guards/gql-local-auth.guard';
@Resolver()
export class AuthResolver {
constructor(private readonly authService: AuthService) {}
@UseGuards(GqlLocalAuthGuard)
@Mutation(() => String)
async login(
@Args() loginArgs: LoginArgs,
@CurrentUser() user: PasswordlessUser,
) {
return this.authService.login(user);
}
@Mutation(() => String)
async register(@Args() registerArgs: RegisterArgs) {
const user = await this.authService.register(registerArgs);
return this.authService.login(user);
}
@Query(() => Boolean)
async loggedIn(@CurrentUser() user?: PasswordlessUser) {
return user ? true : false;
}
}
login.args.ts
import { ArgsType, Field } from '@nestjs/graphql';
@ArgsType()
export class LoginArgs {
@Field(() => String)
email: string;
@Field(() => String)
password: string;
}
auth.service.ts
import { Injectable } from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service';
import { JwtService } from '@nestjs/jwt';
import { User } from '@prisma/client';
import { RegisterArgs } from './dtos/register.args';
import { verify, hash } from 'argon2';
import { randomBytes } from 'crypto';
import { PasswordlessUser } from 'src/users/models/user.model';
@Injectable()
export class AuthService {
constructor(
private readonly prismaService: PrismaService,
private readonly jwtService: JwtService,
) {}
async validateUser(email: string, pass: string) {
const user = await this.prismaService.user.findUnique({
where: {
email,
},
});
if (user && verify(user.password, pass + user.salt)) {
const { password, ...userResult } = user;
return userResult;
}
return null;
}
async login(user: PasswordlessUser) {
const payload = { sub: user.id };
return this.jwtService.sign(payload);
}
async register(registerArgs: RegisterArgs) {
const salt = randomBytes(16).toString('base64');
const password = await hash(registerArgs.password + salt);
const user = await this.prismaService.user.create({
data: {
...registerArgs,
password,
salt,
},
select: {
id: true,
email: true,
firstName: true,
lastName: true,
},
});
return user;
}
}
Hey there, thanks for reporting this and sorry for the delay.
We've been working on releasing the v1 of this Nest+Yoga driver and it just shipped 🚢 !
This codebase has been moved to the official GraphQL Yoga repository, if you still need assistance, or are experiencing issues, after migrating to v1 - I kindly ask you to open an issue over there.