Skip to content

Commit

Permalink
feat: add more checks to invite service
Browse files Browse the repository at this point in the history
  • Loading branch information
gregfrasco committed Feb 27, 2024
1 parent 8dcf323 commit acbc896
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 18 deletions.
3 changes: 2 additions & 1 deletion packages/server/src/invite/invite.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import { UserModule } from '../user/user.module';
import { NotificationModule } from '../notification/notification.module';
import { AuthModule } from '../auth/auth.module';
import { JwtModule } from '../jwt/jwt.module';
import { ProjectModule } from '../project/project.module';

@Module({
imports: [UserModule, NotificationModule, AuthModule, JwtModule],
imports: [UserModule, NotificationModule, AuthModule, JwtModule, ProjectModule],
providers: [InviteService, InviteResolver, PrismaService],
exports: [InviteService]
})
Expand Down
16 changes: 12 additions & 4 deletions packages/server/src/invite/invite.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { ConfigService } from '@nestjs/config';
import { InviteModel } from './model/invite.model';
import { isPast } from 'date-fns';
import { AuthService } from '../auth/auth.service';
import { ProjectService } from '../project/project.service';

@Injectable()
export class InviteService {
Expand All @@ -19,7 +20,8 @@ export class InviteService {
private readonly userService: UserService,
private readonly auth: AuthService,
private readonly notification: NotificationService,
private readonly config: ConfigService
private readonly config: ConfigService,
private readonly projectService: ProjectService
) {}

/**
Expand All @@ -39,6 +41,12 @@ export class InviteService {
if (await this.findInviteByEmail(projectId, newInvite.email)) {
throw new HttpException('Invite already exists for this user', HttpStatus.FORBIDDEN);
}

// get project
const project = await this.projectService.getProject(projectId);
if (!project) {
throw new HttpException(`Project ${projectId} not found`, HttpStatus.NOT_FOUND);
}
// Generate a random invite code
const inviteCode = randomBytes(4).toString('hex');
const hashInviteCode = await hash(inviteCode, 10);
Expand All @@ -56,7 +64,7 @@ export class InviteService {
}
});
// Send the invitation email
await this.sendInviteEmail(invite, inviteCode);
await this.sendInviteEmail(invite, inviteCode, project);
return invite;
}

Expand Down Expand Up @@ -304,10 +312,10 @@ export class InviteService {
* @param {string} inviteCode - The invite code to include in the email invitation.
* @returns {Promise<any>} - A promise that resolves when the email is sent.
*/
private async sendInviteEmail(invite: Invite, inviteCode: string): Promise<any> {
private async sendInviteEmail(invite: Invite, inviteCode: string, project?: Partial<Project>): Promise<any> {
// Construct the invite URL and send the invitation email
const inviteUrl = `${this.config.get('BASE_URL')}/invite/${invite.id}?inviteCode=${inviteCode}`;
return this.notification.sendInviteEmail(invite.projectId, invite.email, inviteUrl);
return this.notification.sendInviteEmail(invite.email, inviteUrl, project);
}

/**
Expand Down
27 changes: 14 additions & 13 deletions packages/server/src/notification/notification.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { HttpStatus, Injectable, Logger, HttpException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { HttpService } from '@nestjs/axios';
import { ProjectService } from '../project/project.service';
import { Project } from '@prisma/client';

export interface Email {
to: string[];
Expand All @@ -22,8 +23,8 @@ export class NotificationService {
this.notificationUrl = this.configService.getOrThrow('NOTIFICATION_SERVICE_URL');
}

private async sendEmail(email: Email, projectId: string): Promise<any> {
if (projectId) {
private async sendEmail(email: Email, projectId?: string): Promise<any> {
if (projectId && !email.templateData.project) {
const project = await this.projectService.getProject(projectId);
email.templateData.project = project;
}
Expand Down Expand Up @@ -63,16 +64,16 @@ export class NotificationService {
);
}

async sendInviteEmail(email: string, projectId: string, link: string): Promise<any> {
return this.sendEmail(
{
to: [email],
subject: `You have been invited to join ${projectId}`,
message: `Click this link to join: ${link}`,
template: 'auth/invite',
templateData: {}
},
projectId
);
async sendInviteEmail(email: string, link: string, project: Partial<Project>): Promise<any> {
return this.sendEmail({
to: [email],
subject: `You have been invited to join ${project.name}`,
message: `Click this link to join: ${link}`,
template: 'auth/invite',
templateData: {
link,
project
}
});
}
}

0 comments on commit acbc896

Please sign in to comment.