add invite staff
This commit is contained in:
@@ -215,10 +215,7 @@ export class CenterSchema extends PothosSchema {
|
||||
throw new Error('Center not found');
|
||||
}
|
||||
// check if center is already approved or rejected
|
||||
if (
|
||||
center.centerStatus === CenterStatus.APPROVED ||
|
||||
center.centerStatus === CenterStatus.REJECTED
|
||||
) {
|
||||
if (center.centerStatus !== CenterStatus.PENDING) {
|
||||
throw new Error('Center is already approved or rejected');
|
||||
}
|
||||
// find center owner and promote to staff
|
||||
|
||||
@@ -7,12 +7,15 @@ import {
|
||||
} from '@smatch-corp/nestjs-pothos';
|
||||
import { Builder } from '../Graphql/graphql.builder';
|
||||
import { PrismaService } from '../Prisma/prisma.service';
|
||||
|
||||
import { MailService } from '../Mail/mail.service';
|
||||
import { JwtUtils } from '../common/utils/jwt.utils';
|
||||
@Injectable()
|
||||
export class CenterStaffSchema extends PothosSchema {
|
||||
constructor(
|
||||
@Inject(SchemaBuilderToken) private readonly builder: Builder,
|
||||
private readonly prisma: PrismaService,
|
||||
private readonly mailService: MailService,
|
||||
private readonly jwtUtils: JwtUtils,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -121,6 +124,45 @@ export class CenterStaffSchema extends PothosSchema {
|
||||
});
|
||||
},
|
||||
}),
|
||||
inviteCenterStaff: t.prismaField({
|
||||
type: this.centerStaff(),
|
||||
description: 'Invite a new center staff member.',
|
||||
args: {
|
||||
email: t.arg({ type: 'String', required: true }),
|
||||
},
|
||||
resolve: async (query, root, args, ctx, info) => {
|
||||
return this.prisma.$transaction(async (prisma) => {
|
||||
// get centerId by user id from context
|
||||
const userId = ctx.me.id;
|
||||
if (!userId) {
|
||||
throw new Error('User ID is required');
|
||||
}
|
||||
// get centerId by user id
|
||||
const center = await prisma.center.findUnique({
|
||||
where: { centerOwnerId: userId },
|
||||
});
|
||||
if (!center) {
|
||||
throw new Error('Center not found');
|
||||
}
|
||||
// build signature
|
||||
const token = this.jwtUtils.signTokenRS256(
|
||||
{ centerId: center.id, email: args.email },
|
||||
'1d',
|
||||
);
|
||||
// build invite url
|
||||
const inviteUrl = `${process.env.CENTER_BASE_URL}/invite?token=${token}`;
|
||||
// mail to user with params centerId, email
|
||||
await this.mailService.sendEmail(
|
||||
args.email,
|
||||
'Invite to center',
|
||||
`You are invited to join the center ${center.name}.
|
||||
Please click the link below to join the center:
|
||||
${inviteUrl}`,
|
||||
);
|
||||
return null;
|
||||
});
|
||||
},
|
||||
}),
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ export interface SchemaContext {
|
||||
generator: PrismaCrudGenerator<BuilderTypes>;
|
||||
}
|
||||
|
||||
// extend prisma types to contain string type
|
||||
export interface SchemaBuilderOption {
|
||||
Context: SchemaContext;
|
||||
PrismaTypes: PrismaTypes;
|
||||
|
||||
@@ -241,10 +241,7 @@ export class ServiceSchema extends PothosSchema {
|
||||
if (!service) {
|
||||
throw new Error('Service not found');
|
||||
}
|
||||
if (
|
||||
service.status === ServiceStatus.APPROVED ||
|
||||
service.status === ServiceStatus.REJECTED
|
||||
) {
|
||||
if (service.status !== ServiceStatus.PENDING) {
|
||||
throw new Error('Service is already approved or rejected');
|
||||
}
|
||||
// update service status
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { CommonGraphqlError } from './graphql/common.graphql.error';
|
||||
import { Global, Module } from '@nestjs/common';
|
||||
|
||||
import { CommonGraphqlError } from './graphql/common.graphql.error';
|
||||
import { JwtUtils } from './utils/jwt.utils';
|
||||
@Global()
|
||||
@Module({
|
||||
imports: [],
|
||||
providers: [CommonGraphqlError],
|
||||
exports: [CommonGraphqlError],
|
||||
providers: [CommonGraphqlError, JwtUtils],
|
||||
exports: [CommonGraphqlError, JwtUtils],
|
||||
})
|
||||
export class CommonModule {}
|
||||
|
||||
29
src/common/utils/jwt.utils.ts
Normal file
29
src/common/utils/jwt.utils.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { sign, verify } from 'jsonwebtoken';
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
export class JwtUtils {
|
||||
signToken(payload: string, expiresIn: string) {
|
||||
return sign(payload, process.env.JWT_SECRET!, { expiresIn });
|
||||
}
|
||||
//eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
signTokenRS256(payload: any, expiresIn: string) {
|
||||
const privateKey = process.env.JWT_RS256_PRIVATE_KEY!;
|
||||
return sign(payload, privateKey, {
|
||||
algorithm: 'RS256',
|
||||
expiresIn,
|
||||
});
|
||||
}
|
||||
|
||||
verifyTokenRS256(token: string) {
|
||||
const publicKey = process.env.JWT_RS256_PUBLIC_KEY!;
|
||||
return verify(token, publicKey, {
|
||||
algorithms: ['RS256'],
|
||||
});
|
||||
}
|
||||
|
||||
verifyToken(token: string) {
|
||||
return verify(token, process.env.JWT_SECRET!);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user