1
0
mirror of https://github.com/immich-app/immich.git synced 2024-12-25 10:43:13 +02:00

fix(web,server): web socket auth (for web) (#4632)

This commit is contained in:
Jason Rasmussen 2023-10-24 18:07:24 -04:00 committed by GitHub
parent 3021eca8e5
commit 0fb1d33f17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 39 additions and 24 deletions

View File

@ -147,7 +147,7 @@ export class AuthService {
return mapAdminSignupResponse(admin);
}
async validate(headers: IncomingHttpHeaders, params: Record<string, string>): Promise<AuthUserDto | null> {
async validate(headers: IncomingHttpHeaders, params: Record<string, string>): Promise<AuthUserDto> {
const shareKey = (headers['x-immich-share-key'] || params.key) as string;
const userToken = (headers['x-immich-user-token'] ||
params.userToken ||

View File

@ -99,11 +99,6 @@ export class AppGuard implements CanActivate {
const req = context.switchToHttp().getRequest<AuthRequest>();
const authDto = await this.authService.validate(req.headers, req.query as Record<string, string>);
if (!authDto) {
this.logger.warn(`Denied access to authenticated route: ${req.path}`);
return false;
}
if (authDto.isPublicUser && !isSharedRoute) {
this.logger.warn(`Denied access to non-shared route: ${req.path}`);
return false;

View File

@ -18,26 +18,22 @@ export class CommunicationRepository implements OnGatewayConnection, OnGatewayDi
async handleConnection(client: Socket) {
try {
this.logger.log(`New websocket connection: ${client.id}`);
this.logger.log(`Websocket Connect: ${client.id}`);
const user = await this.authService.validate(client.request.headers, {});
if (user) {
await client.join(user.id);
for (const callback of this.onConnectCallbacks) {
await callback(user.id);
}
} else {
client.emit('error', 'unauthorized');
client.disconnect();
await client.join(user.id);
for (const callback of this.onConnectCallbacks) {
await callback(user.id);
}
} catch (e) {
} catch (error: Error | any) {
this.logger.error(`Websocket connection error: ${error}`, error?.stack);
client.emit('error', 'unauthorized');
client.disconnect();
}
}
async handleDisconnect(client: Socket) {
this.logger.log(`Websocket Disconnect: ${client.id}`);
await client.leave(client.nsp.name);
this.logger.log(`Client ${client.id} disconnected from Websocket`);
}
send(event: CommunicationEvent, userId: string, data: any) {

View File

@ -1,5 +1,5 @@
import type { AssetResponseDto, ServerVersionResponseDto } from '@api';
import { io } from 'socket.io-client';
import { Socket, io } from 'socket.io-client';
import { writable } from 'svelte/store';
import { loadConfig } from './server-config.store';
@ -20,9 +20,15 @@ export const websocketStore = {
onRelease: writable<ReleaseEvent>(),
};
let websocket: Socket | null = null;
export const openWebsocketConnection = () => {
try {
const websocket = io('', {
if (websocket) {
return;
}
websocket = io('', {
path: '/api/socket.io',
reconnection: true,
forceNew: true,
@ -40,9 +46,14 @@ export const openWebsocketConnection = () => {
.on('on_config_update', () => loadConfig())
.on('on_new_release', (data) => websocketStore.onRelease.set(data))
.on('error', (e) => console.log('Websocket Error', e));
return () => websocket?.close();
} catch (e) {
console.log('Cannot connect to websocket ', e);
}
};
export const closeWebsocketConnection = () => {
if (websocket) {
websocket.close();
}
websocket = null;
};

View File

@ -18,7 +18,7 @@
import { handleError } from '$lib/utils/handle-error';
import { dragAndDropFilesStore } from '$lib/stores/drag-and-drop-files.store';
import { api } from '@api';
import { openWebsocketConnection } from '$lib/stores/websocket';
import { closeWebsocketConnection, openWebsocketConnection } from '$lib/stores/websocket';
let showNavigationLoadingBar = false;
export let data: LayoutData;
@ -28,7 +28,18 @@
api.setKey($page.params.key);
}
beforeNavigate(() => {
beforeNavigate(({ from, to }) => {
const fromRoute = from?.route?.id || '';
const toRoute = to?.route?.id || '';
if (fromRoute.startsWith('/auth') && !toRoute.startsWith('/auth')) {
openWebsocketConnection();
}
if (!fromRoute.startsWith('/auth') && toRoute.startsWith('/auth')) {
closeWebsocketConnection();
}
showNavigationLoadingBar = true;
});
@ -37,7 +48,9 @@
});
onMount(async () => {
openWebsocketConnection();
if ($page.route.id?.startsWith('/auth') === false) {
openWebsocketConnection();
}
try {
await loadConfig();