summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/controllers/chat_room.controller.ts11
-rw-r--r--server/database/migrations/1648605030863-AddChatRoom.ts5
-rw-r--r--server/database/migrations/1648844808010-AddConnectedUsers.ts54
-rw-r--r--server/entities/chat_room.entity.ts9
-rw-r--r--server/entities/chat_room_connection.entity.ts15
-rw-r--r--server/modules/chat_room.module.ts3
-rw-r--r--server/providers/gateways/chat_room.gateway.ts40
-rw-r--r--server/providers/services/chat_room.service.ts44
8 files changed, 163 insertions, 18 deletions
diff --git a/server/controllers/chat_room.controller.ts b/server/controllers/chat_room.controller.ts
index 3917e54..9b75c1f 100644
--- a/server/controllers/chat_room.controller.ts
+++ b/server/controllers/chat_room.controller.ts
@@ -19,7 +19,11 @@ const haversine = (p1, p2) => {
};
@Controller()
export class ChatRoomController {
- constructor(private chatRoomService: ChatRoomService, private usersService: UsersService) {}
+ constructor(private chatRoomService: ChatRoomService, private usersService: UsersService) {
+ setInterval(() => {
+ console.log('Hello');
+ }, 60 * 1000);
+ }
@Get('/chat_rooms')
async get(@JwtBody() jwtBody: JwtBodyDto, @Query() query: any) {
@@ -57,6 +61,11 @@ export class ChatRoomController {
@Post('/chat_rooms')
async create(@JwtBody() jwtBody: JwtBodyDto, @Body() chatRoom: any) {
+ if (chatRoom.radius > 1000) {
+ return {
+ error: 'Radius cannot be greater than 1000 meters',
+ };
+ }
chatRoom.user = await this.usersService.find(jwtBody.userId);
return await this.chatRoomService.create(chatRoom);
}
diff --git a/server/database/migrations/1648605030863-AddChatRoom.ts b/server/database/migrations/1648605030863-AddChatRoom.ts
index 747cdd3..e50f049 100644
--- a/server/database/migrations/1648605030863-AddChatRoom.ts
+++ b/server/database/migrations/1648605030863-AddChatRoom.ts
@@ -43,6 +43,11 @@ export class AddChatRoom1648605030863 implements MigrationInterface {
type: 'varchar',
isNullable: true,
},
+ {
+ name: 'lastConnection',
+ type: 'timestamp',
+ default: 'now()',
+ },
],
}),
true,
diff --git a/server/database/migrations/1648844808010-AddConnectedUsers.ts b/server/database/migrations/1648844808010-AddConnectedUsers.ts
new file mode 100644
index 0000000..e6d16fe
--- /dev/null
+++ b/server/database/migrations/1648844808010-AddConnectedUsers.ts
@@ -0,0 +1,54 @@
+import { MigrationInterface, QueryRunner, Table, TableForeignKey } from 'typeorm';
+
+export class AddConnectedUsers1648844808010 implements MigrationInterface {
+ public async up(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.createTable(
+ new Table({
+ name: 'chat_room_connection',
+ columns: [
+ {
+ name: 'id',
+ type: 'int',
+ isPrimary: true,
+ isGenerated: true,
+ },
+ {
+ name: 'userId',
+ type: 'int',
+ isNullable: false,
+ },
+ {
+ name: 'chatRoomId',
+ type: 'text',
+ isNullable: false,
+ },
+ ],
+ }),
+ true,
+ );
+
+ await queryRunner.createForeignKey(
+ 'chat_room_connection',
+ new TableForeignKey({
+ columnNames: ['userId'],
+ referencedColumnNames: ['id'],
+ referencedTableName: 'user',
+ onDelete: 'CASCADE',
+ }),
+ );
+
+ await queryRunner.createForeignKey(
+ 'chat_room_connection',
+ new TableForeignKey({
+ columnNames: ['chatRoomId'],
+ referencedColumnNames: ['id'],
+ referencedTableName: 'chat_room',
+ onDelete: 'CASCADE',
+ }),
+ );
+ }
+
+ public async down(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.dropTable('connected_users');
+ }
+}
diff --git a/server/entities/chat_room.entity.ts b/server/entities/chat_room.entity.ts
index 2981589..36ce585 100644
--- a/server/entities/chat_room.entity.ts
+++ b/server/entities/chat_room.entity.ts
@@ -1,4 +1,5 @@
-import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from 'typeorm';
+import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany } from 'typeorm';
+import { ChatRoomConnection } from './chat_room_connection.entity';
import { User } from './user.entity';
@Entity()
@@ -18,6 +19,12 @@ export class ChatRoom {
@Column()
name: string;
+ @Column()
+ lastConnection: Date;
+
@ManyToOne(() => User, (user) => user.chatRooms)
user: User;
+
+ @OneToMany(() => ChatRoomConnection, (chatRoomConnection) => chatRoomConnection.chatRoom)
+ chatRoomConnections: ChatRoomConnection[];
}
diff --git a/server/entities/chat_room_connection.entity.ts b/server/entities/chat_room_connection.entity.ts
new file mode 100644
index 0000000..5691df1
--- /dev/null
+++ b/server/entities/chat_room_connection.entity.ts
@@ -0,0 +1,15 @@
+import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from 'typeorm';
+import { User } from './user.entity';
+import { ChatRoom } from './chat_room.entity';
+
+@Entity()
+export class ChatRoomConnection {
+ @PrimaryGeneratedColumn()
+ id: string;
+
+ @ManyToOne(() => User, (user) => user.chatRooms)
+ user: User;
+
+ @ManyToOne(() => ChatRoom, (chatRoom) => chatRoom.chatRoomConnections)
+ chatRoom: ChatRoom;
+}
diff --git a/server/modules/chat_room.module.ts b/server/modules/chat_room.module.ts
index 7acc672..4a19947 100644
--- a/server/modules/chat_room.module.ts
+++ b/server/modules/chat_room.module.ts
@@ -2,12 +2,13 @@ import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ChatRoomController } from 'server/controllers/chat_room.controller';
import { ChatRoom } from 'server/entities/chat_room.entity';
+import { ChatRoomConnection } from 'server/entities/chat_room_connection.entity';
import { ChatRoomService } from 'server/providers/services/chat_room.service';
import { UsersService } from 'server/providers/services/users.service';
import { UsersModule } from './users.module';
@Module({
- imports: [TypeOrmModule.forFeature([ChatRoom]), UsersModule],
+ imports: [TypeOrmModule.forFeature([ChatRoom, ChatRoomConnection]), UsersModule],
controllers: [ChatRoomController],
providers: [ChatRoomService, UsersService],
exports: [TypeOrmModule],
diff --git a/server/providers/gateways/chat_room.gateway.ts b/server/providers/gateways/chat_room.gateway.ts
index b565d40..bee83c5 100644
--- a/server/providers/gateways/chat_room.gateway.ts
+++ b/server/providers/gateways/chat_room.gateway.ts
@@ -14,6 +14,7 @@ import { GatewayJwtBody } from 'server/decorators/gateway_jwt_body.decorator';
import { JwtBodyDto } from 'server/dto/jwt_body.dto';
import { Server, Socket } from 'socket.io';
import { GatewayAuthGuard } from '../guards/gatewayauth.guard';
+import { ChatRoomService } from '../services/chat_room.service';
import { JwtService } from '../services/jwt.service';
import { UsersService } from '../services/users.service';
@@ -23,31 +24,40 @@ export class ChatRoomGateway implements OnGatewayInit, OnGatewayConnection, OnGa
@WebSocketServer()
server: Server;
- constructor(private jwtService: JwtService, private userService: UsersService) {}
+ constructor(
+ private jwtService: JwtService,
+ private userService: UsersService,
+ private chatRoomService: ChatRoomService,
+ ) {}
afterInit(server: Server) {
console.log('Sockets initialized');
}
- handleConnection(client: Socket) {
- // you can do things like add users to rooms
- // or emit events here.
- // IMPORTANT! The GatewayAuthGuard doesn't trigger on these handlers
- // if you need to do anything in this method you need to authenticate the JWT
- // manually.
+ async handleConnection(client: Socket) {
try {
- const jwt = client.handshake.auth.token;
- const jwtBody = this.jwtService.parseToken(jwt);
- const chatRoomId = client.handshake.query.chatRoomId;
- console.log('Client Connected: ', jwtBody.userId);
- client.join(chatRoomId);
+ const jwtBody = this.jwtService.parseToken(client.handshake.auth.token);
+ const user = await this.userService.find(jwtBody.userId);
+ const chatRoom = await this.chatRoomService.findById(client.handshake.query.chatRoomId as unknown as string);
+ await this.chatRoomService.connectUser(chatRoom, user);
+ client.join(chatRoom.id);
+ this.server.to(chatRoom.id).emit('userlist', {
+ users: await this.chatRoomService.connectedUsers(chatRoom),
+ });
} catch (e) {
- throw new WsException('Invalid token');
+ throw new WsException(e.message);
}
}
- handleDisconnect(client: Socket) {
+ async handleDisconnect(client: Socket) {
console.log('Client Disconnected');
+ const jwtBody = this.jwtService.parseToken(client.handshake.auth.token);
+ const user = await this.userService.find(jwtBody.userId);
+ const chatRoom = await this.chatRoomService.findById(client.handshake.query.chatRoomId as unknown as string);
+ await this.chatRoomService.disconnectUser(chatRoom, user);
+ this.server.to(chatRoom.id).emit('userlist', {
+ users: await this.chatRoomService.connectedUsers(chatRoom),
+ });
}
@SubscribeMessage('message')
@@ -58,7 +68,7 @@ export class ChatRoomGateway implements OnGatewayInit, OnGatewayConnection, OnGa
) {
const user = await this.userService.find(jwtBody.userId);
this.server.to(client.handshake.query.chatRoomId).emit('new-message', {
- id: user.id * Math.random() * 2048 * Date.now(),
+ id: user.id * Math.random() * Math.pow(2, 16) * Date.now(),
content: data,
userName: `${user.firstName} ${user.lastName}`,
userId: user.id,
diff --git a/server/providers/services/chat_room.service.ts b/server/providers/services/chat_room.service.ts
index 6d804e6..148ff19 100644
--- a/server/providers/services/chat_room.service.ts
+++ b/server/providers/services/chat_room.service.ts
@@ -2,12 +2,16 @@ import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ChatRoom } from 'server/entities/chat_room.entity';
+import { User } from 'server/entities/user.entity';
+import { ChatRoomConnection } from 'server/entities/chat_room_connection.entity';
@Injectable()
export class ChatRoomService {
constructor(
@InjectRepository(ChatRoom)
private chatRoomRepository: Repository<ChatRoom>,
+ @InjectRepository(ChatRoomConnection)
+ private connectedUsersRepository: Repository<ChatRoomConnection>,
) {}
create(chatRoom: ChatRoom) {
@@ -29,6 +33,46 @@ export class ChatRoomService {
return this.chatRoomRepository.findOne(id, { relations });
}
+ async connectedUsers(chatRoom: ChatRoom) {
+ return this.connectedUsersRepository
+ .find({
+ where: { chatRoom },
+ relations: ['user'],
+ })
+ .then((x) =>
+ x.map((x) => {
+ return {
+ id: x.user.id,
+ userName: `${x.user.firstName} ${x.user.lastName}`,
+ };
+ }),
+ );
+ }
+
+ connectUser = async function (chatRoom: ChatRoom, user: User) {
+ const connectedUser = await this.connectedUsersRepository.findOne({
+ where: { chatRoom, user },
+ });
+ if (connectedUser) {
+ return connectedUser;
+ }
+ const chatRoomConnection = new ChatRoomConnection();
+ chatRoomConnection.chatRoom = chatRoom;
+ chatRoomConnection.user = user;
+ await this.connectedUsersRepository.save(chatRoomConnection);
+ return this.connectedUsers(chatRoom);
+ };
+
+ disconnectUser = async function (chatRoom: ChatRoom, user: User) {
+ const connectedUser = await this.connectedUsersRepository.findOne({
+ where: { chatRoom, user },
+ });
+ if (connectedUser) {
+ return this.connectedUsersRepository.remove(connectedUser);
+ }
+ return false;
+ };
+
save(chatRoom: ChatRoom) {
return this.chatRoomRepository.save(chatRoom);
}