add invite staff
This commit is contained in:
@@ -215,10 +215,7 @@ export class CenterSchema extends PothosSchema {
|
|||||||
throw new Error('Center not found');
|
throw new Error('Center not found');
|
||||||
}
|
}
|
||||||
// check if center is already approved or rejected
|
// check if center is already approved or rejected
|
||||||
if (
|
if (center.centerStatus !== CenterStatus.PENDING) {
|
||||||
center.centerStatus === CenterStatus.APPROVED ||
|
|
||||||
center.centerStatus === CenterStatus.REJECTED
|
|
||||||
) {
|
|
||||||
throw new Error('Center is already approved or rejected');
|
throw new Error('Center is already approved or rejected');
|
||||||
}
|
}
|
||||||
// find center owner and promote to staff
|
// find center owner and promote to staff
|
||||||
|
|||||||
@@ -7,12 +7,15 @@ import {
|
|||||||
} from '@smatch-corp/nestjs-pothos';
|
} from '@smatch-corp/nestjs-pothos';
|
||||||
import { Builder } from '../Graphql/graphql.builder';
|
import { Builder } from '../Graphql/graphql.builder';
|
||||||
import { PrismaService } from '../Prisma/prisma.service';
|
import { PrismaService } from '../Prisma/prisma.service';
|
||||||
|
import { MailService } from '../Mail/mail.service';
|
||||||
|
import { JwtUtils } from '../common/utils/jwt.utils';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CenterStaffSchema extends PothosSchema {
|
export class CenterStaffSchema extends PothosSchema {
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(SchemaBuilderToken) private readonly builder: Builder,
|
@Inject(SchemaBuilderToken) private readonly builder: Builder,
|
||||||
private readonly prisma: PrismaService,
|
private readonly prisma: PrismaService,
|
||||||
|
private readonly mailService: MailService,
|
||||||
|
private readonly jwtUtils: JwtUtils,
|
||||||
) {
|
) {
|
||||||
super();
|
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>;
|
generator: PrismaCrudGenerator<BuilderTypes>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extend prisma types to contain string type
|
||||||
export interface SchemaBuilderOption {
|
export interface SchemaBuilderOption {
|
||||||
Context: SchemaContext;
|
Context: SchemaContext;
|
||||||
PrismaTypes: PrismaTypes;
|
PrismaTypes: PrismaTypes;
|
||||||
|
|||||||
@@ -241,10 +241,7 @@ export class ServiceSchema extends PothosSchema {
|
|||||||
if (!service) {
|
if (!service) {
|
||||||
throw new Error('Service not found');
|
throw new Error('Service not found');
|
||||||
}
|
}
|
||||||
if (
|
if (service.status !== ServiceStatus.PENDING) {
|
||||||
service.status === ServiceStatus.APPROVED ||
|
|
||||||
service.status === ServiceStatus.REJECTED
|
|
||||||
) {
|
|
||||||
throw new Error('Service is already approved or rejected');
|
throw new Error('Service is already approved or rejected');
|
||||||
}
|
}
|
||||||
// update service status
|
// update service status
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Global, Module } from '@nestjs/common';
|
||||||
import { CommonGraphqlError } from './graphql/common.graphql.error';
|
|
||||||
|
|
||||||
|
import { CommonGraphqlError } from './graphql/common.graphql.error';
|
||||||
|
import { JwtUtils } from './utils/jwt.utils';
|
||||||
|
@Global()
|
||||||
@Module({
|
@Module({
|
||||||
imports: [],
|
imports: [],
|
||||||
providers: [CommonGraphqlError],
|
providers: [CommonGraphqlError, JwtUtils],
|
||||||
exports: [CommonGraphqlError],
|
exports: [CommonGraphqlError, JwtUtils],
|
||||||
})
|
})
|
||||||
export class CommonModule {}
|
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