refactor(server): move asset detail endpoint to new controller (#6636)
* refactor(server): move asset by id to new controller * chore: open api * refactor: more consolidation * refactor: asset service
This commit is contained in:
@@ -8,7 +8,6 @@ import {
|
||||
newAccessRepositoryMock,
|
||||
newAssetRepositoryMock,
|
||||
newCommunicationRepositoryMock,
|
||||
newCryptoRepositoryMock,
|
||||
newJobRepositoryMock,
|
||||
newPartnerRepositoryMock,
|
||||
newStorageRepositoryMock,
|
||||
@@ -24,7 +23,6 @@ import {
|
||||
ClientEvent,
|
||||
IAssetRepository,
|
||||
ICommunicationRepository,
|
||||
ICryptoRepository,
|
||||
IJobRepository,
|
||||
IPartnerRepository,
|
||||
IStorageRepository,
|
||||
@@ -168,7 +166,6 @@ describe(AssetService.name, () => {
|
||||
let sut: AssetService;
|
||||
let accessMock: IAccessRepositoryMock;
|
||||
let assetMock: jest.Mocked<IAssetRepository>;
|
||||
let cryptoMock: jest.Mocked<ICryptoRepository>;
|
||||
let jobMock: jest.Mocked<IJobRepository>;
|
||||
let storageMock: jest.Mocked<IStorageRepository>;
|
||||
let userMock: jest.Mocked<IUserRepository>;
|
||||
@@ -184,7 +181,6 @@ describe(AssetService.name, () => {
|
||||
accessMock = newAccessRepositoryMock();
|
||||
assetMock = newAssetRepositoryMock();
|
||||
communicationMock = newCommunicationRepositoryMock();
|
||||
cryptoMock = newCryptoRepositoryMock();
|
||||
jobMock = newJobRepositoryMock();
|
||||
storageMock = newStorageRepositoryMock();
|
||||
userMock = newUserRepositoryMock();
|
||||
@@ -194,7 +190,6 @@ describe(AssetService.name, () => {
|
||||
sut = new AssetService(
|
||||
accessMock,
|
||||
assetMock,
|
||||
cryptoMock,
|
||||
jobMock,
|
||||
configMock,
|
||||
storageMock,
|
||||
@@ -657,6 +652,59 @@ describe(AssetService.name, () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('get', () => {
|
||||
it('should allow owner access', async () => {
|
||||
accessMock.asset.checkOwnerAccess.mockResolvedValue(new Set([assetStub.image.id]));
|
||||
assetMock.getById.mockResolvedValue(assetStub.image);
|
||||
await sut.get(authStub.admin, assetStub.image.id);
|
||||
expect(accessMock.asset.checkOwnerAccess).toHaveBeenCalledWith(
|
||||
authStub.admin.user.id,
|
||||
new Set([assetStub.image.id]),
|
||||
);
|
||||
});
|
||||
|
||||
it('should allow shared link access', async () => {
|
||||
accessMock.asset.checkSharedLinkAccess.mockResolvedValue(new Set([assetStub.image.id]));
|
||||
assetMock.getById.mockResolvedValue(assetStub.image);
|
||||
await sut.get(authStub.adminSharedLink, assetStub.image.id);
|
||||
expect(accessMock.asset.checkSharedLinkAccess).toHaveBeenCalledWith(
|
||||
authStub.adminSharedLink.sharedLink?.id,
|
||||
new Set([assetStub.image.id]),
|
||||
);
|
||||
});
|
||||
|
||||
it('should allow partner sharing access', async () => {
|
||||
accessMock.asset.checkPartnerAccess.mockResolvedValue(new Set([assetStub.image.id]));
|
||||
assetMock.getById.mockResolvedValue(assetStub.image);
|
||||
await sut.get(authStub.admin, assetStub.image.id);
|
||||
expect(accessMock.asset.checkPartnerAccess).toHaveBeenCalledWith(
|
||||
authStub.admin.user.id,
|
||||
new Set([assetStub.image.id]),
|
||||
);
|
||||
});
|
||||
|
||||
it('should allow shared album access', async () => {
|
||||
accessMock.asset.checkAlbumAccess.mockResolvedValue(new Set([assetStub.image.id]));
|
||||
assetMock.getById.mockResolvedValue(assetStub.image);
|
||||
await sut.get(authStub.admin, assetStub.image.id);
|
||||
expect(accessMock.asset.checkAlbumAccess).toHaveBeenCalledWith(
|
||||
authStub.admin.user.id,
|
||||
new Set([assetStub.image.id]),
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw an error for no access', async () => {
|
||||
await expect(sut.get(authStub.admin, assetStub.image.id)).rejects.toBeInstanceOf(BadRequestException);
|
||||
expect(assetMock.getById).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should throw an error for an invalid shared link', async () => {
|
||||
await expect(sut.get(authStub.adminSharedLink, assetStub.image.id)).rejects.toBeInstanceOf(BadRequestException);
|
||||
expect(accessMock.asset.checkOwnerAccess).not.toHaveBeenCalled();
|
||||
expect(assetMock.getById).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('update', () => {
|
||||
it('should require asset write access for the id', async () => {
|
||||
await expect(sut.update(authStub.admin, 'asset-1', { isArchived: false })).rejects.toBeInstanceOf(
|
||||
|
||||
@@ -15,7 +15,6 @@ import {
|
||||
IAccessRepository,
|
||||
IAssetRepository,
|
||||
ICommunicationRepository,
|
||||
ICryptoRepository,
|
||||
IJobRepository,
|
||||
IPartnerRepository,
|
||||
IStorageRepository,
|
||||
@@ -87,7 +86,6 @@ export class AssetService {
|
||||
constructor(
|
||||
@Inject(IAccessRepository) accessRepository: IAccessRepository,
|
||||
@Inject(IAssetRepository) private assetRepository: IAssetRepository,
|
||||
@Inject(ICryptoRepository) private cryptoRepository: ICryptoRepository,
|
||||
@Inject(IJobRepository) private jobRepository: IJobRepository,
|
||||
@Inject(ISystemConfigRepository) configRepository: ISystemConfigRepository,
|
||||
@Inject(IStorageRepository) private storageRepository: IStorageRepository,
|
||||
@@ -400,6 +398,44 @@ export class AssetService {
|
||||
return this.assetRepository.getAllByDeviceId(auth.user.id, deviceId);
|
||||
}
|
||||
|
||||
async get(auth: AuthDto, id: string): Promise<AssetResponseDto | SanitizedAssetResponseDto> {
|
||||
await this.access.requirePermission(auth, Permission.ASSET_READ, id);
|
||||
|
||||
const asset = await this.assetRepository.getById(id, {
|
||||
exifInfo: true,
|
||||
tags: true,
|
||||
sharedLinks: true,
|
||||
smartInfo: true,
|
||||
owner: true,
|
||||
faces: {
|
||||
person: true,
|
||||
},
|
||||
stack: {
|
||||
exifInfo: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!asset) {
|
||||
throw new BadRequestException('Asset not found');
|
||||
}
|
||||
|
||||
if (auth.sharedLink && !auth.sharedLink.showExif) {
|
||||
return mapAsset(asset, { stripMetadata: true, withStack: true });
|
||||
}
|
||||
|
||||
const data = mapAsset(asset, { withStack: true });
|
||||
|
||||
if (auth.sharedLink) {
|
||||
delete data.owner;
|
||||
}
|
||||
|
||||
if (data.ownerId !== auth.user.id) {
|
||||
data.people = [];
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
async update(auth: AuthDto, id: string, dto: UpdateAssetDto): Promise<AssetResponseDto> {
|
||||
await this.access.requirePermission(auth, Permission.ASSET_UPDATE, id);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user