Assign user to workspace on signin
This commit is contained in:
@ -13,10 +13,4 @@ describe('AppController', () => {
|
||||
|
||||
appController = app.get<AppController>(AppController);
|
||||
});
|
||||
|
||||
describe('root', () => {
|
||||
it('should return "Hello World!"', () => {
|
||||
expect(appController.health()).toBe('Healthy!');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -4,9 +4,4 @@ import { AppService } from './app.service';
|
||||
@Controller()
|
||||
export class AppController {
|
||||
constructor(private readonly appService: AppService) {}
|
||||
|
||||
@Get('/health')
|
||||
health(): string {
|
||||
return this.appService.health();
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,10 +3,20 @@ import { AppController } from './app.controller';
|
||||
import { AppService } from './app.service';
|
||||
import { HealthController } from './health.controller';
|
||||
import { TerminusModule } from '@nestjs/terminus';
|
||||
import { HasuraModule } from '@golevelup/nestjs-hasura';
|
||||
import { UserService } from './user/user.service';
|
||||
import { UserModule } from './user/user.module';
|
||||
const path = require('path');
|
||||
|
||||
@Module({
|
||||
imports: [TerminusModule],
|
||||
imports: [UserModule, TerminusModule, HasuraModule.forRoot(HasuraModule, {
|
||||
webhookConfig: {
|
||||
secretFactory: process.env.HASURA_EVENT_HANDLER_SECRET_HEADER,
|
||||
secretHeader: 'secret-header',
|
||||
},
|
||||
})
|
||||
],
|
||||
controllers: [AppController, HealthController],
|
||||
providers: [AppService],
|
||||
providers: [AppService, UserService],
|
||||
})
|
||||
export class AppModule {}
|
||||
|
||||
8
server/src/database/prisma.module.ts
Normal file
8
server/src/database/prisma.module.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { PrismaService } from './prisma.service';
|
||||
|
||||
@Module({
|
||||
providers: [PrismaService],
|
||||
exports: [PrismaService],
|
||||
})
|
||||
export class PrismaModule {}
|
||||
15
server/src/database/prisma.service.ts
Normal file
15
server/src/database/prisma.service.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { INestApplication, Injectable, OnModuleInit } from '@nestjs/common';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
@Injectable()
|
||||
export class PrismaService extends PrismaClient implements OnModuleInit {
|
||||
async onModuleInit() {
|
||||
await this.$connect();
|
||||
}
|
||||
|
||||
async enableShutdownHooks(app: INestApplication) {
|
||||
this.$on('beforeExit', async () => {
|
||||
await app.close();
|
||||
});
|
||||
}
|
||||
}
|
||||
30
server/src/database/schema.prisma
Normal file
30
server/src/database/schema.prisma
Normal file
@ -0,0 +1,30 @@
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("SERVER_DATABASE_URL")
|
||||
}
|
||||
|
||||
model WorkspaceMember {
|
||||
id Int @id @default(autoincrement())
|
||||
created_at DateTime @default(now())
|
||||
updated_at DateTime @updatedAt
|
||||
deleted_at DateTime?
|
||||
user_id String @unique
|
||||
workspace_id Int
|
||||
|
||||
@@map("workspace_members")
|
||||
}
|
||||
|
||||
model Workspace {
|
||||
id Int @id @default(autoincrement())
|
||||
created_at DateTime @default(now())
|
||||
updated_at DateTime @updatedAt
|
||||
deleted_at DateTime?
|
||||
domain_name String @unique
|
||||
display_name String
|
||||
|
||||
@@map("workspaces")
|
||||
}
|
||||
12
server/src/user/user.module.ts
Normal file
12
server/src/user/user.module.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { PrismaModule } from 'src/database/prisma.module';
|
||||
import { UserRepository } from './user.repository';
|
||||
import { UserService } from './user.service';
|
||||
import { WorkspaceRepository } from './workspace.repository';
|
||||
|
||||
@Module({
|
||||
imports: [PrismaModule],
|
||||
providers: [UserRepository, UserService, WorkspaceRepository],
|
||||
exports: [UserService, UserRepository, WorkspaceRepository],
|
||||
})
|
||||
export class UserModule {}
|
||||
23
server/src/user/user.repository.ts
Normal file
23
server/src/user/user.repository.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Prisma, WorkspaceMember } from '@prisma/client';
|
||||
import { PrismaService } from 'src/database/prisma.service';
|
||||
|
||||
@Injectable()
|
||||
export class UserRepository {
|
||||
constructor(private prisma: PrismaService) {}
|
||||
|
||||
async upsertWorkspaceMember(params: { data: Prisma.WorkspaceMemberCreateInput }): Promise<WorkspaceMember> {
|
||||
const { data } = params;
|
||||
return this.prisma.workspaceMember.upsert({
|
||||
where: {
|
||||
user_id: data.user_id,
|
||||
},
|
||||
create: {
|
||||
user_id: data.user_id,
|
||||
workspace_id: data.workspace_id,
|
||||
},
|
||||
update: {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
18
server/src/user/user.service.spec.ts
Normal file
18
server/src/user/user.service.spec.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { UserService } from './user.service';
|
||||
|
||||
describe('UserService', () => {
|
||||
let service: UserService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [UserService],
|
||||
}).compile();
|
||||
|
||||
service = module.get<UserService>(UserService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
||||
40
server/src/user/user.service.ts
Normal file
40
server/src/user/user.service.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import { HasuraInsertEvent, TrackedHasuraEventHandler } from '@golevelup/nestjs-hasura';
|
||||
import { UserRepository} from "./user.repository"
|
||||
import { Injectable, Response } from '@nestjs/common';
|
||||
import { WorkspaceRepository } from './workspace.repository';
|
||||
import { response } from 'express';
|
||||
|
||||
interface User {
|
||||
id: number;
|
||||
email: string;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
constructor(private repository: UserRepository, private workspaceRepository: WorkspaceRepository) {}
|
||||
|
||||
@TrackedHasuraEventHandler({
|
||||
triggerName: 'user-created',
|
||||
tableName: 'users',
|
||||
schema: 'auth',
|
||||
definition: { type: 'insert' },
|
||||
})
|
||||
async handleUserCreated(evt: HasuraInsertEvent<User>) {
|
||||
const workspace = await this.workspaceRepository.findWorkspaceByDomainName(
|
||||
{ where: { domain_name:evt.event.data.new.email.split('@')[1] }
|
||||
});
|
||||
|
||||
console.log(workspace)
|
||||
|
||||
if (!workspace) {
|
||||
return;
|
||||
}
|
||||
|
||||
const workspaceMember = await this.repository.upsertWorkspaceMember({
|
||||
data: {
|
||||
user_id: String(evt.event.data.new.id),
|
||||
workspace_id: workspace.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
12
server/src/user/workspace.repository.ts
Normal file
12
server/src/user/workspace.repository.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Prisma, Workspace } from '@prisma/client';
|
||||
import { PrismaService } from 'src/database/prisma.service';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceRepository {
|
||||
constructor(private prisma: PrismaService) {}
|
||||
|
||||
async findWorkspaceByDomainName(data: Prisma.WorkspaceFindUniqueArgs): Promise<Workspace> {
|
||||
return this.prisma.workspace.findUnique(data);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user