mirror of
https://github.com/immich-app/immich.git
synced 2025-12-17 09:13:17 +03:00
feat(server): user and server license endpoints (#10682)
* feat: user license endpoints * feat: server license endpoints * chore: pr feedback * chore: add more test cases * chore: add prod license public keys * chore: open-api generation
This commit is contained in:
@@ -5,6 +5,12 @@ import { app, utils } from 'src/utils';
|
||||
import request from 'supertest';
|
||||
import { beforeAll, describe, expect, it } from 'vitest';
|
||||
|
||||
const serverLicense = {
|
||||
licenseKey: 'IMSV-6ECZ-91TE-WZRM-Q7AQ-MBN4-UW48-2CPT-71X9',
|
||||
activationKey:
|
||||
'4kJUNUWMq13J14zqPFm1NodRcI6MV6DeOGvQNIgrM8Sc9nv669wyEVvFw1Nz4Kb1W7zLWblOtXEQzpRRqC4r4fKjewJxfbpeo9sEsqAVIfl4Ero-Vp1Dg21-sVdDGZEAy2oeTCXAyCT5d1JqrqR6N1qTAm4xOx9ujXQRFYhjRG8uwudw7_Q49pF18Tj5OEv9qCqElxztoNck4i6O_azsmsoOQrLIENIWPh3EynBN3ESpYERdCgXO8MlWeuG14_V1HbNjnJPZDuvYg__YfMzoOEtfm1sCqEaJ2Ww-BaX7yGfuCL4XsuZlCQQNHjfscy_WywVfIZPKCiW8QR74i0cSzQ',
|
||||
};
|
||||
|
||||
describe('/server', () => {
|
||||
let admin: LoginResponseDto;
|
||||
let nonAdmin: LoginResponseDto;
|
||||
@@ -44,6 +50,7 @@ describe('/server', () => {
|
||||
imagemagick: expect.any(String),
|
||||
libvips: expect.any(String),
|
||||
exiftool: expect.any(String),
|
||||
licensed: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -197,4 +204,104 @@ describe('/server', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /server/license', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).get('/server/license');
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should only work for admins', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.get('/server/license')
|
||||
.set('Authorization', `Bearer ${nonAdmin.accessToken}`);
|
||||
expect(status).toBe(403);
|
||||
expect(body).toEqual(errorDto.forbidden);
|
||||
});
|
||||
|
||||
it('should return the server license', async () => {
|
||||
await request(app).put('/server/license').set('Authorization', `Bearer ${admin.accessToken}`).send(serverLicense);
|
||||
const { status, body } = await request(app)
|
||||
.get('/server/license')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual({
|
||||
...serverLicense,
|
||||
activatedAt: expect.any(String),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('DELETE /server/license', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).delete('/server/license');
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should only work for admins', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.delete('/server/license')
|
||||
.set('Authorization', `Bearer ${nonAdmin.accessToken}`);
|
||||
expect(status).toBe(403);
|
||||
expect(body).toEqual(errorDto.forbidden);
|
||||
});
|
||||
|
||||
it('should delete the server license', async () => {
|
||||
await request(app)
|
||||
.delete('/server/license')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send(serverLicense);
|
||||
const { status } = await request(app).get('/server/license').set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toBe(200);
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT /server/license', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).put('/server/license');
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should only work for admins', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put('/server/license')
|
||||
.set('Authorization', `Bearer ${nonAdmin.accessToken}`);
|
||||
expect(status).toBe(403);
|
||||
expect(body).toEqual(errorDto.forbidden);
|
||||
});
|
||||
|
||||
it('should set the server license', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put('/server/license')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send(serverLicense);
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual({ ...serverLicense, activatedAt: expect.any(String) });
|
||||
const { body: licenseBody } = await request(app)
|
||||
.get('/server/license')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(licenseBody).toEqual({ ...serverLicense, activatedAt: expect.any(String) });
|
||||
});
|
||||
|
||||
it('should reject license not starting with IMSV-', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put('/server/license')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ licenseKey: 'IMCL-ABCD-ABCD-ABCD-ABCD-ABCD-ABCD-ABCD-ABCD', activationKey: 'activationKey' });
|
||||
expect(status).toBe(400);
|
||||
expect(body.message).toBe('Invalid license key');
|
||||
});
|
||||
|
||||
it('should reject license with invalid activation key', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put('/server/license')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({ licenseKey: serverLicense.licenseKey, activationKey: `invalid${serverLicense.activationKey}` });
|
||||
expect(status).toBe(400);
|
||||
expect(body.message).toBe('Invalid license key');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user