summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/app.module.ts5
-rw-r--r--server/controllers/chat_room.controller.ts51
-rw-r--r--server/controllers/users.controller.ts1
-rw-r--r--server/database/migrations/1648605030863-AddChatRoom.ts20
-rw-r--r--server/database/migrations/1648669551959-AddDistanceFunction.ts45
-rw-r--r--server/entities/chat_room.entity.ts9
-rw-r--r--server/entities/user.entity.ts4
-rw-r--r--server/modules/chat_room.module.ts8
-rw-r--r--server/modules/users.module.ts3
-rw-r--r--server/providers/services/chat_room.service.ts18
10 files changed, 144 insertions, 20 deletions
diff --git a/server/app.module.ts b/server/app.module.ts
index bbc3c1c..5fc4654 100644
--- a/server/app.module.ts
+++ b/server/app.module.ts
@@ -3,17 +3,19 @@ import { APP_GUARD } from '@nestjs/core';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { config } from './database/config';
+import { ChatRoomModule } from './modules/chat_room.module';
import { UsersModule } from './modules/users.module';
import { PingGateway } from './providers/gateways/ping.gateway';
import { AuthGuard } from './providers/guards/auth.guard';
import { RolesGuard } from './providers/guards/roles.guard';
+import { ChatRoomService } from './providers/services/chat_room.service';
import { JwtService } from './providers/services/jwt.service';
import { RolesService } from './providers/services/roles.service';
import { UsersService } from './providers/services/users.service';
import { GuardUtil } from './providers/util/guard.util';
@Module({
- imports: [TypeOrmModule.forRoot(config), UsersModule],
+ imports: [TypeOrmModule.forRoot(config), UsersModule, ChatRoomModule],
controllers: [AppController],
providers: [
PingGateway,
@@ -21,6 +23,7 @@ import { GuardUtil } from './providers/util/guard.util';
RolesService,
JwtService,
GuardUtil,
+ ChatRoomService,
{ provide: APP_GUARD, useClass: AuthGuard }, // auth guard should come before roles guard
{ provide: APP_GUARD, useClass: RolesGuard }, // otherwise users won't be authenticated before roles check
],
diff --git a/server/controllers/chat_room.controller.ts b/server/controllers/chat_room.controller.ts
index 5a8da66..bd9ba4a 100644
--- a/server/controllers/chat_room.controller.ts
+++ b/server/controllers/chat_room.controller.ts
@@ -1,12 +1,55 @@
-import { Controller, Get } from '@nestjs/common';
+import { Body, Controller, Delete, Get, Param, Post, Put, Query } from '@nestjs/common';
+import { JwtBody } from 'server/decorators/jwt_body.decorator';
+import { JwtBodyDto } from 'server/dto/jwt_body.dto';
import { ChatRoomService } from 'server/providers/services/chat_room.service';
+import { UsersService } from 'server/providers/services/users.service';
@Controller()
export class ChatRoomController {
- constructor(private chatRoomService: ChatRoomService) {}
+ constructor(private chatRoomService: ChatRoomService, private usersService: UsersService) {}
@Get('/chat_rooms')
- async get() {
- return await this.chatRoomService.all();
+ async get(@Query() query: any) {
+ console.log(query);
+ return await this.chatRoomService.near(query);
+ }
+
+ @Post('/chat_rooms')
+ async create(@JwtBody() jwtBody: JwtBodyDto, @Body() chatRoom: any) {
+ chatRoom.user = await this.usersService.find(jwtBody.userId);
+ console.log(jwtBody);
+ return await this.chatRoomService.create(chatRoom);
+ }
+
+ private async authorized(jwtBody: JwtBodyDto, chatRoom: any) {
+ const user = await this.usersService.find(jwtBody.userId);
+ if (user.id !== chatRoom.user.id) {
+ return {
+ error: 'You are not the owner of this chat room',
+ };
+ }
+ return true;
+ }
+
+ @Put('/chat_rooms/:id')
+ async update(@JwtBody() jwtBody: JwtBodyDto, @Param('id') id: number, @Body() chatRoom: any) {
+ console.log(id);
+ const chat_room = await this.chatRoomService.findById(id, ['user']);
+ if (!(await this.authorized(jwtBody, chat_room))) {
+ return chat_room;
+ }
+ chat_room.latitude = chatRoom.latitude;
+ chat_room.longitude = chatRoom.longitude;
+ chat_room.radius = chatRoom.radius;
+ return await this.chatRoomService.save(chat_room);
+ }
+
+ @Delete('/chat_rooms/:id')
+ async delete(@JwtBody() jwtBody: JwtBodyDto, @Param('id') id: number) {
+ const chat_room = await this.chatRoomService.findById(id, ['user']);
+ if (!(await this.authorized(jwtBody, chat_room))) {
+ return false;
+ }
+ return await this.chatRoomService.remove(chat_room);
}
}
diff --git a/server/controllers/users.controller.ts b/server/controllers/users.controller.ts
index 652b5b6..82d6215 100644
--- a/server/controllers/users.controller.ts
+++ b/server/controllers/users.controller.ts
@@ -35,6 +35,7 @@ export class UsersController {
@Get('/users/me')
async getCurrentUser(@JwtBody() jwtBody: JwtBodyDto) {
const user = await this.usersService.find(jwtBody.userId);
+ delete user.passwordHash;
return { user };
}
diff --git a/server/database/migrations/1648605030863-AddChatRoom.ts b/server/database/migrations/1648605030863-AddChatRoom.ts
index d8eed52..e4b5ca9 100644
--- a/server/database/migrations/1648605030863-AddChatRoom.ts
+++ b/server/database/migrations/1648605030863-AddChatRoom.ts
@@ -1,10 +1,10 @@
-import { MigrationInterface, QueryRunner, Table } from 'typeorm';
+import { MigrationInterface, QueryRunner, Table, TableForeignKey } from 'typeorm';
export class AddChatRoom1648605030863 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.createTable(
new Table({
- name: 'chatroom',
+ name: 'chat_room',
columns: [
{
name: 'id',
@@ -13,8 +13,8 @@ export class AddChatRoom1648605030863 implements MigrationInterface {
isGenerated: true,
},
{
- name: 'name',
- type: 'text',
+ name: 'userId',
+ type: 'int',
isNullable: false,
},
{
@@ -35,9 +35,19 @@ export class AddChatRoom1648605030863 implements MigrationInterface {
],
}),
);
+
+ await queryRunner.createForeignKey(
+ 'chat_room',
+ new TableForeignKey({
+ columnNames: ['userId'],
+ referencedColumnNames: ['id'],
+ referencedTableName: 'user',
+ onDelete: 'CASCADE',
+ }),
+ );
}
public async down(queryRunner: QueryRunner): Promise<void> {
- await queryRunner.dropTable('chatroom');
+ await queryRunner.dropTable('chat_room');
}
}
diff --git a/server/database/migrations/1648669551959-AddDistanceFunction.ts b/server/database/migrations/1648669551959-AddDistanceFunction.ts
new file mode 100644
index 0000000..0890936
--- /dev/null
+++ b/server/database/migrations/1648669551959-AddDistanceFunction.ts
@@ -0,0 +1,45 @@
+import { MigrationInterface, QueryRunner } from 'typeorm';
+
+export class AddDistanceFunction1648669551959 implements MigrationInterface {
+ public async up(queryRunner: QueryRunner): Promise<void> {
+ // From https://stackoverflow.com/questions/61135374/postgresql-calculate-distance-between-two-points-without-using-postgis
+ await queryRunner.query(`
+CREATE OR REPLACE FUNCTION calculate_distance(lat1 float, lon1 float, lat2 float, lon2 float, units varchar)
+ RETURNS float AS $dist$
+ DECLARE
+ dist float = 0;
+ radlat1 float;
+ radlat2 float;
+ theta float;
+ radtheta float;
+ BEGIN
+ IF lat1 = lat2 OR lon1 = lon2
+ THEN RETURN dist;
+ ELSE
+ radlat1 = pi() * lat1 / 180;
+ radlat2 = pi() * lat2 / 180;
+ theta = lon1 - lon2;
+ radtheta = pi() * theta / 180;
+ dist = sin(radlat1) * sin(radlat2) + cos(radlat1) * cos(radlat2) * cos(radtheta);
+
+ IF dist > 1 THEN dist = 1; END IF;
+
+ dist = acos(dist);
+ dist = dist * 180 / pi();
+ dist = dist * 60 * 1.1515;
+
+ IF units = 'K' THEN dist = dist * 1.609344; END IF;
+ IF units = 'N' THEN dist = dist * 0.8684; END IF;
+
+ RETURN dist;
+ END IF;
+ END;
+ $dist$ LANGUAGE plpgsql;`);
+ }
+
+ public async down(queryRunner: QueryRunner): Promise<void> {
+ await queryRunner.query(
+ `DROP FUNCTION IF EXISTS calculate_distance(lat1 float, lon1 float, lat2 float, lon2 float, units varchar);`,
+ );
+ }
+}
diff --git a/server/entities/chat_room.entity.ts b/server/entities/chat_room.entity.ts
index 9550d26..6f46c97 100644
--- a/server/entities/chat_room.entity.ts
+++ b/server/entities/chat_room.entity.ts
@@ -1,4 +1,5 @@
-import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
+import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from 'typeorm';
+import { User } from './user.entity';
@Entity()
export class ChatRoom {
@@ -6,9 +7,6 @@ export class ChatRoom {
id: number;
@Column()
- name: string;
-
- @Column()
latitude: number;
@Column()
@@ -16,4 +14,7 @@ export class ChatRoom {
@Column()
radius: number;
+
+ @ManyToOne(() => User, (user) => user.chatRooms)
+ user: User;
}
diff --git a/server/entities/user.entity.ts b/server/entities/user.entity.ts
index aeef107..c3ece96 100644
--- a/server/entities/user.entity.ts
+++ b/server/entities/user.entity.ts
@@ -1,4 +1,5 @@
import { Entity, Column, PrimaryGeneratedColumn, OneToMany } from 'typeorm';
+import { ChatRoom } from './chat_room.entity';
import { RefreshToken } from './refresh_token.entity';
import { UserRole } from './user_role.entity';
@@ -24,4 +25,7 @@ export class User {
@OneToMany(() => UserRole, (userRole) => userRole.user, { cascade: true })
userRoles: UserRole[];
+
+ @OneToMany(() => ChatRoom, (chatRoom) => chatRoom.user)
+ chatRooms: ChatRoom[];
}
diff --git a/server/modules/chat_room.module.ts b/server/modules/chat_room.module.ts
index 07b2553..7acc672 100644
--- a/server/modules/chat_room.module.ts
+++ b/server/modules/chat_room.module.ts
@@ -3,11 +3,13 @@ import { TypeOrmModule } from '@nestjs/typeorm';
import { ChatRoomController } from 'server/controllers/chat_room.controller';
import { ChatRoom } from 'server/entities/chat_room.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])],
+ imports: [TypeOrmModule.forFeature([ChatRoom]), UsersModule],
controllers: [ChatRoomController],
- providers: [ChatRoomService],
+ providers: [ChatRoomService, UsersService],
exports: [TypeOrmModule],
})
-export class UsersModule {}
+export class ChatRoomModule {}
diff --git a/server/modules/users.module.ts b/server/modules/users.module.ts
index 69c533b..5b5b2ff 100644
--- a/server/modules/users.module.ts
+++ b/server/modules/users.module.ts
@@ -11,9 +11,10 @@ import { RefreshTokensController } from 'server/controllers/refresh_tokens.contr
import { Role } from 'server/entities/role.entity';
import { RolesService } from 'server/providers/services/roles.service';
import { UserRole } from 'server/entities/user_role.entity';
+import { ChatRoom } from 'server/entities/chat_room.entity';
@Module({
- imports: [TypeOrmModule.forFeature([User, RefreshToken, Role, UserRole])],
+ imports: [TypeOrmModule.forFeature([User, RefreshToken, Role, UserRole, ChatRoom])],
controllers: [SessionsController, UsersController, RefreshTokensController],
providers: [UsersService, RolesService, RefreshTokensService, JwtService],
exports: [TypeOrmModule],
diff --git a/server/providers/services/chat_room.service.ts b/server/providers/services/chat_room.service.ts
index 6c87539..a6af023 100644
--- a/server/providers/services/chat_room.service.ts
+++ b/server/providers/services/chat_room.service.ts
@@ -18,7 +18,21 @@ export class ChatRoomService {
return this.chatRoomRepository.find();
}
- findById(id: number) {
- return this.chatRoomRepository.findOne(id);
+ near({ lat, lng }: { lat: number; lng: number }) {
+ return this.chatRoomRepository.query(
+ `SELECT * FROM chat_room WHERE calculate_distance(latitude, longitude, ${lat}, ${lng}, 'M') < 5`,
+ );
+ }
+
+ findById(id: number, relations: string[] = []) {
+ return this.chatRoomRepository.findOne(id, { relations });
+ }
+
+ save(chatRoom: ChatRoom) {
+ return this.chatRoomRepository.save(chatRoom);
+ }
+
+ remove(chatRoom: ChatRoom) {
+ return this.chatRoomRepository.remove(chatRoom);
}
}