Skip to content
Snippets Groups Projects
tokenCode.resolver.ts 3.16 KiB
Newer Older
import { UseGuards, NotFoundException } from "@nestjs/common";
import { Args, Context, Mutation, Parent, ResolveField, Resolver, Subscription } from "@nestjs/graphql";
import { GraphQLString, GraphQLInt } from 'graphql';
import { Request } from "express";
import { GroupAuthGuard } from "../auth/graphql-auth.guard";
import { PrismaService } from "../prisma/prisma.service";
import { TokenCode } from "./models/tokenCode.model";
import { AgentAuthGuard } from "../auth/agent-auth.guard";
import { pubSub } from "../pubSub.instance";

@Resolver(() => TokenCode)
export class TokenCodeResolver {
    constructor(private prismaService: PrismaService) {}

    // TODO: protect subscription
    @Subscription(() => TokenCode, {
        filter: (payload, variables) =>
            payload.newTokenCode.agent.id === variables.id,
    })
    newTokenCode(@Args('id') id: string){
        return pubSub.asyncIterator('newTokenCode');
    }

    @UseGuards(AgentAuthGuard)
    @Mutation(() => TokenCode)
    async tokenCode(@Context() { req }: { req: Request }) {
        let tokenCode = await this.prismaService.tokenCode.findFirst({
            where: {
                id: req.agent.tokenCodeId,
            },
        });

        if (!tokenCode) {
            tokenCode = await this.prismaService.tokenCode.create({
                data: {
                    value: 1,
                    agent: {
                        connect: { id: req.agent.id },
                    },
                },
            });
            
            pubSub.publish('newTokenCode', {
                newTokenCode: tokenCode
            });
        }

        return tokenCode;
    }

    @UseGuards(GroupAuthGuard)
    @Mutation(() => GraphQLInt)
    async redeemCode(
        @Args({ name: 'code', type: () => GraphQLString }) code: string,
        @Context() { req }: { req: Request },
    ) {
        const tokenCode = await this.prismaService.tokenCode.findFirst({
            where: { id: code },
            include: {
                agent: true,
            }
        });

        if (!tokenCode)
            throw new NotFoundException();

        
        const newTokenCode = await this.prismaService.tokenCode.create({
            data: {
                value: 1,
                agent: {
                    connect: { id: tokenCode.agent.id },
                },
            },
            include: {
                agent: true,
            }
        });

        pubSub.publish('newTokenCode', {
            newTokenCode: newTokenCode,
        });

        await this.prismaService.tokenCode.delete({
            where: { id: tokenCode.id },
        });

        req.group = await this.prismaService.group.update({
            where: { id: req.group.id },
            data: {
                tokens: {
                    increment: tokenCode.value,
                },
            },
        });

        pubSub.publish('updateToken', {
            updateToken: req.group,
        });

        return tokenCode.value;
    }

    @ResolveField('agent')
    agent(@Parent() token: TokenCode) {
        return this.prismaService.agent.findFirst({
            where: {
                tokenCodeId: token.id,
            },
        });
    }

}