chore: switch to Fastify & Mercurius with auth for subscription, queries and mutations
This commit is contained in:
parent
eb3f3a8de9
commit
7dd819de7e
@ -1,9 +0,0 @@
|
|||||||
import { Controller, Get } from '@nestjs/common';
|
|
||||||
|
|
||||||
@Controller()
|
|
||||||
export class AppController {
|
|
||||||
@Get()
|
|
||||||
getHello(): string {
|
|
||||||
return 'Hello World!';
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,9 +5,7 @@ import { GraphQLModule } from "@nestjs/graphql";
|
|||||||
import { MercuriusDriver, MercuriusDriverConfig } from "@nestjs/mercurius";
|
import { MercuriusDriver, MercuriusDriverConfig } from "@nestjs/mercurius";
|
||||||
|
|
||||||
import { AppService } from "./app.service";
|
import { AppService } from "./app.service";
|
||||||
import { AuthModule } from "./auth/auth.module";
|
|
||||||
import { UserModule } from "./user/user.module";
|
import { UserModule } from "./user/user.module";
|
||||||
import { AppController } from "./app.controller";
|
|
||||||
|
|
||||||
import { GraphqlOptions } from "./graphqlOptions";
|
import { GraphqlOptions } from "./graphqlOptions";
|
||||||
|
|
||||||
@ -24,10 +22,8 @@ import { GraphqlOptions } from "./graphqlOptions";
|
|||||||
driver: MercuriusDriver,
|
driver: MercuriusDriver,
|
||||||
useClass: GraphqlOptions,
|
useClass: GraphqlOptions,
|
||||||
}),
|
}),
|
||||||
AuthModule,
|
|
||||||
UserModule,
|
UserModule,
|
||||||
],
|
],
|
||||||
providers: [AppService],
|
providers: [AppService],
|
||||||
controllers: [AppController],
|
|
||||||
})
|
})
|
||||||
export class AppModule {}
|
export class AppModule {}
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
import {
|
|
||||||
CanActivate,
|
|
||||||
ExecutionContext,
|
|
||||||
Injectable,
|
|
||||||
UnauthorizedException,
|
|
||||||
} from "@nestjs/common";
|
|
||||||
import { JwtService } from "@nestjs/jwt";
|
|
||||||
|
|
||||||
import { Request } from "express";
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class AuthGuard implements CanActivate {
|
|
||||||
constructor(private jwtService: JwtService) {}
|
|
||||||
|
|
||||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
|
||||||
const request = context.switchToHttp().getRequest();
|
|
||||||
const token = this.extractTokenFromHeader(request);
|
|
||||||
if (!token) {
|
|
||||||
throw new UnauthorizedException();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const payload = await this.jwtService.verifyAsync(token, {
|
|
||||||
secret: process.env.JWT_SECRET,
|
|
||||||
});
|
|
||||||
request["user"] = payload;
|
|
||||||
} catch {
|
|
||||||
throw new UnauthorizedException();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private extractTokenFromHeader(request: Request): string | undefined {
|
|
||||||
const [type, token] = request.headers.authorization?.split(" ") ?? [];
|
|
||||||
return type === "Bearer" ? token : undefined;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
import { Module } from '@nestjs/common';
|
|
||||||
|
|
||||||
@Module({})
|
|
||||||
export class AuthModule {}
|
|
@ -1,14 +1,46 @@
|
|||||||
|
import { Injectable, UnauthorizedException } from "@nestjs/common";
|
||||||
import { GqlOptionsFactory } from "@nestjs/graphql";
|
import { GqlOptionsFactory } from "@nestjs/graphql";
|
||||||
import { Injectable } from "@nestjs/common";
|
import { JwtService } from "@nestjs/jwt";
|
||||||
import { MercuriusDriverConfig } from "@nestjs/mercurius";
|
import { MercuriusDriverConfig } from "@nestjs/mercurius";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class GraphqlOptions implements GqlOptionsFactory {
|
export class GraphqlOptions implements GqlOptionsFactory {
|
||||||
|
constructor(private readonly jwtService: JwtService) {}
|
||||||
|
|
||||||
createGqlOptions(): Promise<MercuriusDriverConfig> | MercuriusDriverConfig {
|
createGqlOptions(): Promise<MercuriusDriverConfig> | MercuriusDriverConfig {
|
||||||
return {
|
return {
|
||||||
autoSchemaFile: "src/schema.gql",
|
autoSchemaFile: "src/schema.gql",
|
||||||
subscription: true,
|
subscription: {
|
||||||
graphiql: true,
|
context: (_connection, request) => {
|
||||||
|
const authorization = request.headers.authorization;
|
||||||
|
if (!authorization) throw new UnauthorizedException();
|
||||||
|
|
||||||
|
const token = authorization.split(" ")[1];
|
||||||
|
if (!token) throw new UnauthorizedException();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const user = this.jwtService.verify(token);
|
||||||
|
return { user };
|
||||||
|
} catch (error) {
|
||||||
|
throw new UnauthorizedException();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
graphiql: false,
|
||||||
|
context: (req) => {
|
||||||
|
const authorization = req.headers.authorization;
|
||||||
|
if (!authorization) throw new UnauthorizedException();
|
||||||
|
|
||||||
|
const token = authorization.split(" ")[1];
|
||||||
|
if (!token) throw new UnauthorizedException();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const user = this.jwtService.verify(token);
|
||||||
|
return { user };
|
||||||
|
} catch (error) {
|
||||||
|
throw new UnauthorizedException();
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ input CreateUserInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
input UpdateUserInput {
|
input UpdateUserInput {
|
||||||
username: String!
|
username: String
|
||||||
isAdmin: Boolean
|
isAdmin: Boolean
|
||||||
id: String!
|
id: String!
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,6 @@ export class UpdateUserInput extends PartialType(CreateUserInput) {
|
|||||||
@Field()
|
@Field()
|
||||||
id: string;
|
id: string;
|
||||||
|
|
||||||
@Field()
|
@Field({ nullable: true })
|
||||||
username: string;
|
username: string;
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,18 @@
|
|||||||
import { Args, Mutation, Query, Resolver, Subscription } from "@nestjs/graphql";
|
import {
|
||||||
|
Args,
|
||||||
|
Mutation,
|
||||||
|
Query,
|
||||||
|
Resolver,
|
||||||
|
Subscription
|
||||||
|
} from "@nestjs/graphql";
|
||||||
|
|
||||||
import { UserService } from "./user.service";
|
|
||||||
import { User } from "./user.entity";
|
|
||||||
import { CreateUserInput } from "./dto/create-user.input";
|
import { CreateUserInput } from "./dto/create-user.input";
|
||||||
import { UpdateUserInput } from "./dto/update-user.input";
|
|
||||||
import { SetUserPasswordInput } from "./dto/setpassword-user.input";
|
import { SetUserPasswordInput } from "./dto/setpassword-user.input";
|
||||||
|
import { UpdateUserInput } from "./dto/update-user.input";
|
||||||
|
import { User } from "./user.entity";
|
||||||
|
import { UserService } from "./user.service";
|
||||||
|
|
||||||
import { PubSub } from 'graphql-subscriptions';
|
import { PubSub } from "graphql-subscriptions";
|
||||||
|
|
||||||
const pubSub = new PubSub();
|
const pubSub = new PubSub();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user