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:
martin
2023-10-24 17:05:42 +02:00
committed by GitHub
parent 99c6f8fb13
commit 1aae29a0b8
48 changed files with 656 additions and 100 deletions

View File

@@ -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;

View File

@@ -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 },

View File

@@ -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) {

View File

@@ -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';

View 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);
}
}