fix(server): correct openapi response type for getServerLicense() (#11261)

* fix(server): correct openapi response type for getServerLicense()

* return 404 error when license doesn't exist

* update e2e test
This commit is contained in:
Michel Heusschen 2024-07-22 15:50:45 +02:00 committed by GitHub
parent 3d7a9d79da
commit 849bc6e3aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 36 additions and 14 deletions

View File

@ -254,7 +254,7 @@ describe('/server', () => {
.set('Authorization', `Bearer ${admin.accessToken}`)
.send(serverLicense);
const { status } = await request(app).get('/server/license').set('Authorization', `Bearer ${admin.accessToken}`);
expect(status).toBe(200);
expect(status).toBe(404);
});
});

View File

@ -75,7 +75,7 @@ class ServerApi {
);
}
Future<Object?> getServerLicense() async {
Future<LicenseResponseDto?> getServerLicense() async {
final response = await getServerLicenseWithHttpInfo();
if (response.statusCode >= HttpStatus.badRequest) {
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
@ -84,7 +84,7 @@ class ServerApi {
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
// FormatException when trying to decode an empty string.
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'Object',) as Object;
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'LicenseResponseDto',) as LicenseResponseDto;
}
return null;

View File

@ -5022,11 +5022,14 @@
"content": {
"application/json": {
"schema": {
"type": "object"
"$ref": "#/components/schemas/LicenseResponseDto"
}
}
},
"description": ""
},
"404": {
"description": ""
}
},
"security": [

View File

@ -880,12 +880,12 @@ export type ServerVersionResponseDto = {
minor: number;
patch: number;
};
export type LicenseKeyDto = {
export type LicenseResponseDto = {
activatedAt: string;
activationKey: string;
licenseKey: string;
};
export type LicenseResponseDto = {
activatedAt: string;
export type LicenseKeyDto = {
activationKey: string;
licenseKey: string;
};
@ -2511,7 +2511,9 @@ export function deleteServerLicense(opts?: Oazapfts.RequestOpts) {
export function getServerLicense(opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{
status: 200;
data: object;
data: LicenseResponseDto;
} | {
status: 404;
}>("/server/license", {
...opts
}));

View File

@ -1,5 +1,5 @@
import { Body, Controller, Delete, Get, Put } from '@nestjs/common';
import { ApiExcludeEndpoint, ApiTags } from '@nestjs/swagger';
import { ApiExcludeEndpoint, ApiNotFoundResponse, ApiTags } from '@nestjs/swagger';
import { LicenseKeyDto, LicenseResponseDto } from 'src/dtos/license.dto';
import {
ServerAboutResponseDto,
@ -95,7 +95,8 @@ export class ServerController {
@Get('license')
@Authenticated({ admin: true })
getServerLicense(): Promise<LicenseResponseDto | null> {
@ApiNotFoundResponse()
getServerLicense(): Promise<LicenseResponseDto> {
return this.service.getLicense();
}
}

View File

@ -1,4 +1,4 @@
import { BadRequestException, Inject, Injectable } from '@nestjs/common';
import { BadRequestException, Inject, Injectable, NotFoundException } from '@nestjs/common';
import { getBuildMetadata, getServerLicensePublicKey } from 'src/config';
import { serverVersion } from 'src/constants';
import { StorageCore, StorageFolder } from 'src/cores/storage.core';
@ -164,8 +164,12 @@ export class ServerService implements OnEvents {
await this.systemMetadataRepository.delete(SystemMetadataKey.LICENSE);
}
async getLicense(): Promise<LicenseResponseDto | null> {
return this.systemMetadataRepository.get(SystemMetadataKey.LICENSE);
async getLicense(): Promise<LicenseResponseDto> {
const license = await this.systemMetadataRepository.get(SystemMetadataKey.LICENSE);
if (!license) {
throw new NotFoundException();
}
return license;
}
async setLicense(dto: LicenseKeyDto): Promise<LicenseResponseDto> {

View File

@ -10,6 +10,7 @@
getAboutInfo,
getMyUser,
getServerLicense,
isHttpError,
type LicenseResponseDto,
} from '@immich/sdk';
import Icon from '$lib/components/elements/icon.svelte';
@ -36,7 +37,18 @@
}
if (isServerLicense && $user.isAdmin) {
serverLicenseInfo = (await getServerLicense()) as LicenseResponseDto | null;
serverLicenseInfo = await getServerLicenseInfo();
}
};
const getServerLicenseInfo = async () => {
try {
return await getServerLicense();
} catch (error) {
if (isHttpError(error) && error.status === 404) {
return null;
}
throw error;
}
};