token-code.resolver.ts 4.86 KiB
import {
Args,
Context,
Mutation,
Query,
Resolver,
Subscription,
} from '@nestjs/graphql';
import { TokenCodeModel } from './models/token-code.model';
import { PrismaService } from '../prisma/prisma.service';
import { Request } from 'express';
import { Inject, NotFoundException, UseGuards } from '@nestjs/common';
import { AuthGuard } from '../auth/auth.guard';
import { AgentGuard } from '../auth/agent.guard';
import { GroupGuard } from '../auth/group.guard';
import { TokenCode } from '@prisma/client';
import { AgentFlags } from './models/agent.model';
import { PubSub } from 'graphql-subscriptions';
import { TokenCodeInputModel } from './models/token-code-input.model';
@Resolver(() => TokenCodeModel)
export class TokenCodeResolver {
constructor(
@Inject('PUBSUB')
private readonly pubSub: PubSub,
private readonly prisma: PrismaService,
) {}
@Subscription(() => TokenCodeModel, {
filter: (payload: TokenCode, variables, { req }: { req: Request }) => {
return req.agent && req.agent.id === payload.agentId;
},
})
@UseGuards(AuthGuard)
onTokenCodeUpdate() {
return this.pubSub.asyncIterator('onTokenCodeUpdate');
}
@Mutation(() => TokenCodeModel)
@UseGuards(AuthGuard, AgentGuard)
async invalidateTokenCode(
@Args('tokenCode') tokenCode: string,
@Context() { req }: { req: Request },
) {
return await this.prisma.$transaction(async (prisma) => {
const token = await prisma.tokenCode.findFirst({
where: { id: tokenCode },
});
if (!token) throw new NotFoundException();
const newToken = await prisma.tokenCode.create({
data: {
agent: {
connect: { id: req.agent.id },
},
},
include: { agent: true },
});
const oldToken = await prisma.tokenCode.delete({
where: { id: tokenCode },
include: { agent: true },
});
await this.pubSub.publish('onTokenCodeUpdate', newToken);
await this.pubSub.publish('onTokenCodeUpdate', {
id: oldToken.id,
deleted: true,
});
return newToken;
});
}
@Query(() => [TokenCodeModel])
@UseGuards(AuthGuard)
async getTokenCodes(
@Context() { req }: { req: Request },
): Promise<TokenCodeModel[]> {
if (!req.agent) return [];
if ((req.agent.flags & AgentFlags.ADMIN) === AgentFlags.ADMIN)
return await this.prisma.tokenCode.findMany({
include: {
agent: true,
},
});
else
return await this.prisma.tokenCode.findMany({
where: { agentId: req.agent.id },
include: {
agent: {
select: {
id: true,
bio: true,
name: true,
slug: false,
flags: true,
avatar: true,
},
},
},
});
}
@Mutation(() => TokenCodeModel)
@UseGuards(AuthGuard, GroupGuard)
async redeemTokenCode(
@Args('tokenCode') tokenCode: string,
@Context() { req }: { req: Request },
): Promise<TokenCodeModel> {
return this.prisma.$transaction(async (prisma) => {
const token = await prisma.tokenCode.findFirst({
where: { id: tokenCode },
include: {
agent: {
select: {
id: true,
bio: true,
name: true,
slug: false,
flags: true,
avatar: true,
},
},
},
});
if (!token) throw new NotFoundException();
const deleted = await prisma.tokenCode.delete({
where: { id: tokenCode },
});
const { tokenCodes } = await prisma.agent.update({
where: { id: token.agentId },
data: {
tokenCodes: {
create: { value: 1 },
},
},
include: { tokenCodes: true },
});
const group = await prisma.group.update({
where: { id: req.group.id },
data: {
tokens: { increment: token.value },
},
});
await this.pubSub.publish('onTokenCodeUpdate', {
id: deleted.id,
deleted: true,
});
await this.pubSub.publish('onGroupUpdate', group);
await this.pubSub.publish('onTokenCodeUpdate', tokenCodes[0]);
return token;
});
}
/*@Mutation(() => TokenCodeModel)
@UseGuards(AuthGuard, AgentGuard)
async updateTokenCode(
@Args('id') id: string,
@Args('data') data: TokenCodeInputModel,
@Context() { req }: { req: Request },
): Promise<TokenCode> {
const count = await this.prisma.tokenCode.count({
where: { id, agentId: req.agent.id },
});
if (count === 0) throw new NotFoundException();
const tokenCode = await this.prisma.tokenCode.update({
where: {
id,
},
data,
include: {
agent: {
select: {
id: true,
bio: true,
name: true,
slug: false,
flags: true,
avatar: true,
},
},
},
});
await this.pubSub.publish('onTokenCodeUpdate', tokenCode);
return tokenCode;
}*/
/*@ResolveField('agent')
async agent(@Parent() parent: TokenCodeModel): Promise<AgentModel> {
return this.prisma.agent.findFirst({
where: {
tokenCodes: {
some: { id: parent.id },
},
},
select: {
id: true,
bio: true,
name: true,
slug: false,
flags: true,
avatar: true,
},
});
}*/
}