mirror of
https://github.com/KevinMidboe/immich.git
synced 2025-12-08 20:29:05 +00:00
refactor(server, web)!: store latest immich version available on the server (#3565)
* refactor: store latest immich version available on the server * don't store admins acknowledgement * merge main * fix: api * feat: custom interval * pr feedback * remove unused code * update environment-variables * pr feedback * ci: fix server tests * fix: dart number * pr feedback * remove proxy * pr feedback * feat: make stringToVersion more flexible * feat(web): disable check * feat: working version * remove env * fix: check if interval exists when updating the interval * feat: show last check * fix: tests * fix: remove availableVersion when updated * fix merge * fix: web * fix e2e tests * merge main * merge main * pr feedback * pr feedback * fix: tests * pr feedback * pr feedback * pr feedback * pr feedback * pr feedback * fix: migration * regenerate api * fix: typo * fix: compare versions * pr feedback * fix * pr feedback * fix: checkIntervalTime on startup * refactor: websockets and interval logic * chore: open api * chore: remove unused code * fix: use interval instead of cron * mobile: handle WS event data as json object --------- Co-authored-by: Jason Rasmussen <jrasm91@gmail.com> Co-authored-by: shalong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
This commit is contained in:
@@ -67,6 +67,8 @@ export enum SystemConfigKey {
|
||||
REVERSE_GEOCODING_ENABLED = 'reverseGeocoding.enabled',
|
||||
REVERSE_GEOCODING_CITIES_FILE_OVERRIDE = 'reverseGeocoding.citiesFileOverride',
|
||||
|
||||
NEW_VERSION_CHECK_ENABLED = 'newVersionCheck.enabled',
|
||||
|
||||
OAUTH_ENABLED = 'oauth.enabled',
|
||||
OAUTH_ISSUER_URL = 'oauth.issuerUrl',
|
||||
OAUTH_CLIENT_ID = 'oauth.clientId',
|
||||
@@ -219,6 +221,9 @@ export interface SystemConfig {
|
||||
quality: number;
|
||||
colorspace: Colorspace;
|
||||
};
|
||||
newVersionCheck: {
|
||||
enabled: boolean;
|
||||
};
|
||||
trash: {
|
||||
enabled: boolean;
|
||||
days: number;
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
IPartnerRepository,
|
||||
IPersonRepository,
|
||||
ISearchRepository,
|
||||
IServerInfoRepository,
|
||||
ISharedLinkRepository,
|
||||
ISmartInfoRepository,
|
||||
IStorageRepository,
|
||||
@@ -48,6 +49,7 @@ import {
|
||||
MoveRepository,
|
||||
PartnerRepository,
|
||||
PersonRepository,
|
||||
ServerInfoRepository,
|
||||
SharedLinkRepository,
|
||||
SmartInfoRepository,
|
||||
SystemConfigRepository,
|
||||
@@ -73,6 +75,7 @@ const providers: Provider[] = [
|
||||
{ provide: IPartnerRepository, useClass: PartnerRepository },
|
||||
{ provide: IPersonRepository, useClass: PersonRepository },
|
||||
{ provide: ISearchRepository, useClass: TypesenseRepository },
|
||||
{ provide: IServerInfoRepository, useClass: ServerInfoRepository },
|
||||
{ provide: ISharedLinkRepository, useClass: SharedLinkRepository },
|
||||
{ provide: ISmartInfoRepository, useClass: SmartInfoRepository },
|
||||
{ provide: IStorageRepository, useClass: FilesystemProvider },
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AuthService, CommunicationEvent, ICommunicationRepository, serverVersion } from '@app/domain';
|
||||
import { AuthService, Callback, CommunicationEvent, ICommunicationRepository } from '@app/domain';
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { OnGatewayConnection, OnGatewayDisconnect, WebSocketGateway, WebSocketServer } from '@nestjs/websockets';
|
||||
import { Server, Socket } from 'socket.io';
|
||||
@@ -6,18 +6,25 @@ import { Server, Socket } from 'socket.io';
|
||||
@WebSocketGateway({ cors: true })
|
||||
export class CommunicationRepository implements OnGatewayConnection, OnGatewayDisconnect, ICommunicationRepository {
|
||||
private logger = new Logger(CommunicationRepository.name);
|
||||
private onConnectCallbacks: Callback[] = [];
|
||||
|
||||
constructor(private authService: AuthService) {}
|
||||
|
||||
@WebSocketServer() server!: Server;
|
||||
|
||||
addEventListener(event: 'connect', callback: Callback) {
|
||||
this.onConnectCallbacks.push(callback);
|
||||
}
|
||||
|
||||
async handleConnection(client: Socket) {
|
||||
try {
|
||||
this.logger.log(`New websocket connection: ${client.id}`);
|
||||
const user = await this.authService.validate(client.request.headers, {});
|
||||
if (user) {
|
||||
await client.join(user.id);
|
||||
this.send(CommunicationEvent.SERVER_VERSION, user.id, serverVersion);
|
||||
for (const callback of this.onConnectCallbacks) {
|
||||
await callback(user.id);
|
||||
}
|
||||
} else {
|
||||
client.emit('error', 'unauthorized');
|
||||
client.disconnect();
|
||||
@@ -34,7 +41,7 @@ export class CommunicationRepository implements OnGatewayConnection, OnGatewayDi
|
||||
}
|
||||
|
||||
send(event: CommunicationEvent, userId: string, data: any) {
|
||||
this.server.to(userId).emit(event, JSON.stringify(data));
|
||||
this.server.to(userId).emit(event, data);
|
||||
}
|
||||
|
||||
broadcast(event: CommunicationEvent, data: any) {
|
||||
|
||||
@@ -14,6 +14,7 @@ export * from './metadata.repository';
|
||||
export * from './move.repository';
|
||||
export * from './partner.repository';
|
||||
export * from './person.repository';
|
||||
export * from './server-info.repository';
|
||||
export * from './shared-link.repository';
|
||||
export * from './smart-info.repository';
|
||||
export * from './system-config.repository';
|
||||
|
||||
12
server/src/infra/repositories/server-info.repository.ts
Normal file
12
server/src/infra/repositories/server-info.repository.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { GitHubRelease, IServerInfoRepository } from '@app/domain';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import axios from 'axios';
|
||||
|
||||
@Injectable()
|
||||
export class ServerInfoRepository implements IServerInfoRepository {
|
||||
getGitHubRelease(): Promise<GitHubRelease> {
|
||||
return axios
|
||||
.get<GitHubRelease>('https://api.github.com/repos/immich-app/immich/releases/latest')
|
||||
.then((response) => response.data);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user