2022-02-14 17:40:41 +01:00
|
|
|
import { OnGatewayConnection, OnGatewayDisconnect, WebSocketGateway, WebSocketServer } from '@nestjs/websockets';
|
|
|
|
import { Socket, Server } from 'socket.io';
|
2022-06-25 19:53:06 +02:00
|
|
|
import { ImmichJwtService, JwtValidationResult } from '../../modules/immich-jwt/immich-jwt.service';
|
2022-02-14 17:40:41 +01:00
|
|
|
import { Logger } from '@nestjs/common';
|
|
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
2022-12-30 14:22:06 +01:00
|
|
|
import { UserEntity } from '@app/database';
|
2022-02-14 17:40:41 +01:00
|
|
|
import { Repository } from 'typeorm';
|
2022-08-27 07:53:37 +02:00
|
|
|
import cookieParser from 'cookie';
|
2022-11-15 03:24:25 +01:00
|
|
|
import { IMMICH_ACCESS_COOKIE } from '../../constants/jwt.constant';
|
|
|
|
|
2022-06-19 15:16:35 +02:00
|
|
|
@WebSocketGateway({ cors: true })
|
2022-02-14 17:40:41 +01:00
|
|
|
export class CommunicationGateway implements OnGatewayConnection, OnGatewayDisconnect {
|
|
|
|
constructor(
|
|
|
|
private immichJwtService: ImmichJwtService,
|
|
|
|
|
|
|
|
@InjectRepository(UserEntity)
|
|
|
|
private userRepository: Repository<UserEntity>,
|
|
|
|
) {}
|
|
|
|
|
2022-06-25 19:53:06 +02:00
|
|
|
@WebSocketServer() server!: Server;
|
2022-02-14 17:40:41 +01:00
|
|
|
|
|
|
|
handleDisconnect(client: Socket) {
|
|
|
|
client.leave(client.nsp.name);
|
|
|
|
|
2022-06-19 15:16:35 +02:00
|
|
|
Logger.log(`Client ${client.id} disconnected from Websocket`, 'WebsocketConnectionEvent');
|
2022-02-14 17:40:41 +01:00
|
|
|
}
|
|
|
|
|
2022-06-25 19:53:06 +02:00
|
|
|
async handleConnection(client: Socket) {
|
2022-06-19 15:16:35 +02:00
|
|
|
try {
|
|
|
|
Logger.log(`New websocket connection: ${client.id}`, 'WebsocketConnectionEvent');
|
2022-08-27 07:53:37 +02:00
|
|
|
let accessToken = '';
|
2022-02-14 17:40:41 +01:00
|
|
|
|
2022-08-27 07:53:37 +02:00
|
|
|
if (client.handshake.headers.cookie != undefined) {
|
|
|
|
const cookies = cookieParser.parse(client.handshake.headers.cookie);
|
2022-11-15 03:24:25 +01:00
|
|
|
if (cookies[IMMICH_ACCESS_COOKIE]) {
|
|
|
|
accessToken = cookies[IMMICH_ACCESS_COOKIE];
|
2022-08-27 07:53:37 +02:00
|
|
|
} else {
|
|
|
|
client.emit('error', 'unauthorized');
|
|
|
|
client.disconnect();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else if (client.handshake.headers.authorization != undefined) {
|
|
|
|
accessToken = client.handshake.headers.authorization.split(' ')[1];
|
|
|
|
} else {
|
|
|
|
client.emit('error', 'unauthorized');
|
|
|
|
client.disconnect();
|
|
|
|
return;
|
|
|
|
}
|
2022-06-19 15:16:35 +02:00
|
|
|
|
2022-06-25 19:53:06 +02:00
|
|
|
const res: JwtValidationResult = accessToken
|
|
|
|
? await this.immichJwtService.validateToken(accessToken)
|
|
|
|
: { status: false, userId: null };
|
2022-02-14 17:40:41 +01:00
|
|
|
|
2022-06-29 20:39:58 +02:00
|
|
|
if (!res.status || res.userId == null) {
|
2022-06-19 15:16:35 +02:00
|
|
|
client.emit('error', 'unauthorized');
|
|
|
|
client.disconnect();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const user = await this.userRepository.findOne({ where: { id: res.userId } });
|
|
|
|
if (!user) {
|
|
|
|
client.emit('error', 'unauthorized');
|
|
|
|
client.disconnect();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
client.join(user.id);
|
|
|
|
} catch (e) {
|
|
|
|
// Logger.error(`Error establish websocket conneciton ${e}`, 'HandleWebscoketConnection');
|
|
|
|
}
|
2022-02-14 17:40:41 +01:00
|
|
|
}
|
|
|
|
}
|