56 lines
2.7 KiB
TypeScript
56 lines
2.7 KiB
TypeScript
import { Kysely } from 'kysely';
|
|
import { randomBytes } from 'node:crypto';
|
|
import { AssetType, SharedLinkType } from 'src/enum.js';
|
|
import { AccessRepository } from 'src/repositories/access.repository.js';
|
|
import { LoggingRepository } from 'src/repositories/logging.repository.js';
|
|
import { SharedLinkRepository } from 'src/repositories/shared-link.repository.js';
|
|
import { DB } from 'src/schema/index.js';
|
|
import { BaseService } from 'src/services/base.service.js';
|
|
import { newMediumService } from 'test/medium.factory.js';
|
|
import { factory } from 'test/small.factory.js';
|
|
import { getKyselyDB } from 'test/utils.js';
|
|
|
|
let db: Kysely<DB>;
|
|
|
|
beforeAll(async () => {
|
|
db = await getKyselyDB();
|
|
});
|
|
|
|
afterAll(async () => {
|
|
await db.destroy();
|
|
});
|
|
|
|
describe('shared link asset access', () => {
|
|
for (const type of [SharedLinkType.Album, SharedLinkType.Individual]) {
|
|
it(`${type}: permits the photo and its Live Photo video, but excludes unrelated and trashed assets`, async () => {
|
|
const { ctx } = newMediumService(BaseService, { database: db, real: [], mock: [LoggingRepository] });
|
|
const { user } = await ctx.newUser();
|
|
const { asset: video } = await ctx.newAsset({ ownerId: user.id, type: AssetType.Video });
|
|
const { asset: photo } = await ctx.newAsset({ ownerId: user.id, livePhotoVideoId: video.id });
|
|
const { asset: unrelated } = await ctx.newAsset({ ownerId: user.id });
|
|
const { asset: trashed } = await ctx.newAsset({ ownerId: user.id, deletedAt: new Date().toISOString() });
|
|
const { album } = await ctx.newAlbum({ ownerId: user.id });
|
|
await ctx.newAlbumAsset({ albumId: album.id, assetId: photo.id });
|
|
await ctx.newAlbumAsset({ albumId: album.id, assetId: trashed.id });
|
|
const link = await ctx.get(SharedLinkRepository).create({
|
|
id: factory.uuid(),
|
|
key: randomBytes(16),
|
|
userId: user.id,
|
|
allowUpload: false,
|
|
type,
|
|
...(type === SharedLinkType.Album ? { albumId: album.id } : { assetIds: [photo.id, trashed.id] }),
|
|
});
|
|
const access = ctx.get(AccessRepository).asset;
|
|
const requested = new Set([photo.id, video.id, unrelated.id, trashed.id]);
|
|
await expect(access.checkSharedLinkAccess(link.id, requested)).resolves.toEqual(new Set([photo.id, video.id]));
|
|
await expect(access.checkSharedLinkAccess(factory.uuid(), requested)).resolves.toEqual(new Set());
|
|
await expect(access.checkSharedLinkAccess(link.id, new Set())).resolves.toEqual(new Set());
|
|
if (type !== SharedLinkType.Album) {
|
|
return;
|
|
}
|
|
await db.updateTable('album').set({ deletedAt: new Date().toISOString() }).where('id', '=', album.id).execute();
|
|
await expect(access.checkSharedLinkAccess(link.id, requested)).resolves.toEqual(new Set());
|
|
});
|
|
}
|
|
});
|