mirror of
https://github.com/samsonjs/immich.git
synced 2026-04-27 15:07:45 +00:00
fix(server): api key update checks (#25363)
This commit is contained in:
parent
1ada7a8340
commit
b123beae38
2 changed files with 80 additions and 0 deletions
|
|
@ -107,6 +107,78 @@ describe(ApiKeyService.name, () => {
|
||||||
permissions: newPermissions,
|
permissions: newPermissions,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('api key auth', () => {
|
||||||
|
it('should prevent adding Permission.all', async () => {
|
||||||
|
const permissions = [Permission.ApiKeyCreate, Permission.ApiKeyUpdate, Permission.AssetRead];
|
||||||
|
const auth = factory.auth({ apiKey: { permissions } });
|
||||||
|
const apiKey = factory.apiKey({ userId: auth.user.id, permissions });
|
||||||
|
|
||||||
|
mocks.apiKey.getById.mockResolvedValue(apiKey);
|
||||||
|
|
||||||
|
await expect(sut.update(auth, apiKey.id, { permissions: [Permission.All] })).rejects.toThrow(
|
||||||
|
'Cannot grant permissions you do not have',
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(mocks.apiKey.update).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should prevent adding a new permission', async () => {
|
||||||
|
const permissions = [Permission.ApiKeyCreate, Permission.ApiKeyUpdate, Permission.AssetRead];
|
||||||
|
const auth = factory.auth({ apiKey: { permissions } });
|
||||||
|
const apiKey = factory.apiKey({ userId: auth.user.id, permissions });
|
||||||
|
|
||||||
|
mocks.apiKey.getById.mockResolvedValue(apiKey);
|
||||||
|
|
||||||
|
await expect(sut.update(auth, apiKey.id, { permissions: [Permission.AssetCopy] })).rejects.toThrow(
|
||||||
|
'Cannot grant permissions you do not have',
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(mocks.apiKey.update).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow removing permissions', async () => {
|
||||||
|
const auth = factory.auth({ apiKey: { permissions: [Permission.ApiKeyUpdate, Permission.AssetRead] } });
|
||||||
|
const apiKey = factory.apiKey({
|
||||||
|
userId: auth.user.id,
|
||||||
|
permissions: [Permission.AssetRead, Permission.AssetDelete],
|
||||||
|
});
|
||||||
|
|
||||||
|
mocks.apiKey.getById.mockResolvedValue(apiKey);
|
||||||
|
mocks.apiKey.update.mockResolvedValue(apiKey);
|
||||||
|
|
||||||
|
// remove Permission.AssetDelete
|
||||||
|
await sut.update(auth, apiKey.id, { permissions: [Permission.AssetRead] });
|
||||||
|
|
||||||
|
expect(mocks.apiKey.update).toHaveBeenCalledWith(
|
||||||
|
auth.user.id,
|
||||||
|
apiKey.id,
|
||||||
|
expect.objectContaining({ permissions: [Permission.AssetRead] }),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow adding new permissions', async () => {
|
||||||
|
const auth = factory.auth({
|
||||||
|
apiKey: { permissions: [Permission.ApiKeyUpdate, Permission.AssetRead, Permission.AssetUpdate] },
|
||||||
|
});
|
||||||
|
const apiKey = factory.apiKey({ userId: auth.user.id, permissions: [Permission.AssetRead] });
|
||||||
|
|
||||||
|
mocks.apiKey.getById.mockResolvedValue(apiKey);
|
||||||
|
mocks.apiKey.update.mockResolvedValue(apiKey);
|
||||||
|
|
||||||
|
// add Permission.AssetUpdate
|
||||||
|
await sut.update(auth, apiKey.id, {
|
||||||
|
name: apiKey.name,
|
||||||
|
permissions: [Permission.AssetRead, Permission.AssetUpdate],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(mocks.apiKey.update).toHaveBeenCalledWith(
|
||||||
|
auth.user.id,
|
||||||
|
apiKey.id,
|
||||||
|
expect.objectContaining({ permissions: [Permission.AssetRead, Permission.AssetUpdate] }),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('delete', () => {
|
describe('delete', () => {
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,14 @@ export class ApiKeyService extends BaseService {
|
||||||
throw new BadRequestException('API Key not found');
|
throw new BadRequestException('API Key not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
auth.apiKey &&
|
||||||
|
dto.permissions &&
|
||||||
|
!isGranted({ requested: dto.permissions, current: auth.apiKey.permissions })
|
||||||
|
) {
|
||||||
|
throw new BadRequestException('Cannot grant permissions you do not have');
|
||||||
|
}
|
||||||
|
|
||||||
const key = await this.apiKeyRepository.update(auth.user.id, id, { name: dto.name, permissions: dto.permissions });
|
const key = await this.apiKeyRepository.update(auth.user.id, id, { name: dto.name, permissions: dto.permissions });
|
||||||
|
|
||||||
return this.map(key);
|
return this.map(key);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue