mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-23 19:47:03 -04:00
Add GET /me/media
Returns all media files uploaded by the authenticated user. Signed-off-by: Yannick Bungers <git@innay.de>
This commit is contained in:
parent
b67ec817e6
commit
ef352a1313
7 changed files with 174 additions and 10 deletions
|
@ -23,7 +23,10 @@ import { HistoryEntry } from '../../../history/history-entry.entity';
|
|||
import { NoteGroupPermission } from '../../../permissions/note-group-permission.entity';
|
||||
import { NoteUserPermission } from '../../../permissions/note-user-permission.entity';
|
||||
import { Group } from '../../../groups/group.entity';
|
||||
import { MediaModule } from '../../../media/media.module';
|
||||
import { MediaUpload } from '../../../media/media-upload.entity';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
import mediaConfigMock from '../../../config/media.config.mock';
|
||||
import appConfigMock from '../../../config/app.config.mock';
|
||||
|
||||
describe('Me Controller', () => {
|
||||
|
@ -33,14 +36,19 @@ describe('Me Controller', () => {
|
|||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [MeController],
|
||||
imports: [
|
||||
UsersModule,
|
||||
HistoryModule,
|
||||
NotesModule,
|
||||
LoggerModule,
|
||||
ConfigModule.forRoot({
|
||||
isGlobal: true,
|
||||
load: [mediaConfigMock],
|
||||
}),
|
||||
ConfigModule.forRoot({
|
||||
isGlobal: true,
|
||||
load: [appConfigMock],
|
||||
}),
|
||||
UsersModule,
|
||||
HistoryModule,
|
||||
NotesModule,
|
||||
LoggerModule,
|
||||
MediaModule,
|
||||
],
|
||||
})
|
||||
.overrideProvider(getRepositoryToken(User))
|
||||
|
@ -67,6 +75,8 @@ describe('Me Controller', () => {
|
|||
.useValue({})
|
||||
.overrideProvider(getRepositoryToken(Group))
|
||||
.useValue({})
|
||||
.overrideProvider(getRepositoryToken(MediaUpload))
|
||||
.useValue({})
|
||||
.compile();
|
||||
|
||||
controller = module.get<MeController>(MeController);
|
||||
|
|
|
@ -28,6 +28,9 @@ import { HistoryEntryDto } from '../../../history/history-entry.dto';
|
|||
import { UserInfoDto } from '../../../users/user-info.dto';
|
||||
import { NotInDBError } from '../../../errors/errors';
|
||||
import { Request } from 'express';
|
||||
import { MediaService } from '../../../media/media.service';
|
||||
import { MediaUploadUrlDto } from '../../../media/media-upload-url.dto';
|
||||
import { MediaUploadDto } from '../../../media/media-upload.dto';
|
||||
|
||||
@ApiTags('me')
|
||||
@ApiSecurity('token')
|
||||
|
@ -38,6 +41,7 @@ export class MeController {
|
|||
private usersService: UsersService,
|
||||
private historyService: HistoryService,
|
||||
private notesService: NotesService,
|
||||
private mediaService: MediaService,
|
||||
) {
|
||||
this.logger.setContext(MeController.name);
|
||||
}
|
||||
|
@ -129,4 +133,11 @@ export class MeController {
|
|||
(await notes).map((note) => this.notesService.toNoteMetadataDto(note)),
|
||||
);
|
||||
}
|
||||
|
||||
@UseGuards(TokenAuthGuard)
|
||||
@Get('media')
|
||||
async getMyMedia(@Req() req: Request): Promise<MediaUploadDto[]> {
|
||||
const media = await this.mediaService.listUploadsByUser(req.user);
|
||||
return media.map((media) => this.mediaService.toMediaUploadDto(media));
|
||||
}
|
||||
}
|
||||
|
|
37
src/media/media-upload.dto.ts
Normal file
37
src/media/media-upload.dto.ts
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { IsDate, IsString } from 'class-validator';
|
||||
|
||||
export class MediaUploadDto {
|
||||
/**
|
||||
* The link to the media file.
|
||||
* @example "https://example.com/uploads/testfile123.jpg"
|
||||
*/
|
||||
@IsString()
|
||||
url: string;
|
||||
|
||||
/**
|
||||
* The noteId of the note to which the uploaded file is linked to.
|
||||
* @example "noteId" TODO how looks a note id?
|
||||
*/
|
||||
@IsString()
|
||||
noteId: string;
|
||||
|
||||
/**
|
||||
* The date when the upload objects was created.
|
||||
* @example "2020-12-01 12:23:34"
|
||||
*/
|
||||
@IsDate()
|
||||
createdAt: Date;
|
||||
|
||||
/**
|
||||
* The userName of the user which uploaded the media file.
|
||||
* @example "testuser5"
|
||||
*/
|
||||
@IsString()
|
||||
userName: string;
|
||||
}
|
|
@ -229,4 +229,39 @@ describe('MediaService', () => {
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('listUploadsByUser', () => {
|
||||
describe('works', () => {
|
||||
it('with one upload from user', async () => {
|
||||
const mockMediaUploadEntry = {
|
||||
id: 'testMediaUpload',
|
||||
backendData: 'testBackendData',
|
||||
user: {
|
||||
userName: 'hardcoded',
|
||||
} as User,
|
||||
} as MediaUpload;
|
||||
jest
|
||||
.spyOn(mediaRepo, 'find')
|
||||
.mockResolvedValueOnce([mockMediaUploadEntry]);
|
||||
expect(
|
||||
await service.listUploadsByUser({ userName: 'hardcoded' } as User),
|
||||
).toEqual([mockMediaUploadEntry]);
|
||||
});
|
||||
|
||||
it('without uploads from user', async () => {
|
||||
jest.spyOn(mediaRepo, 'find').mockResolvedValueOnce([]);
|
||||
const mediaList = await service.listUploadsByUser({
|
||||
userName: 'hardcoded',
|
||||
} as User);
|
||||
expect(mediaList).toEqual([]);
|
||||
});
|
||||
it('with error (undefined as return value of find)', async () => {
|
||||
jest.spyOn(mediaRepo, 'find').mockResolvedValueOnce(undefined);
|
||||
const mediaList = await service.listUploadsByUser({
|
||||
userName: 'hardcoded',
|
||||
} as User);
|
||||
expect(mediaList).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -22,6 +22,8 @@ import { MediaUploadUrlDto } from './media-upload-url.dto';
|
|||
import { S3Backend } from './backends/s3-backend';
|
||||
import { AzureBackend } from './backends/azure-backend';
|
||||
import { ImgurBackend } from './backends/imgur-backend';
|
||||
import { User } from '../users/user.entity';
|
||||
import { MediaUploadDto } from './media-upload.dto';
|
||||
|
||||
@Injectable()
|
||||
export class MediaService {
|
||||
|
@ -157,6 +159,23 @@ export class MediaService {
|
|||
return mediaUpload;
|
||||
}
|
||||
|
||||
/**
|
||||
* @async
|
||||
* List all uploads by a specific user
|
||||
* @param {User} user - the specific user
|
||||
* @return {MediaUpload[]} arary of media uploads owned by the user
|
||||
*/
|
||||
async listUploadsByUser(user: User): Promise<MediaUpload[]> {
|
||||
const mediaUploads = await this.mediaUploadRepository.find({
|
||||
where: { user: user },
|
||||
relations: ['user', 'note'],
|
||||
});
|
||||
if (mediaUploads === undefined) {
|
||||
return [];
|
||||
}
|
||||
return mediaUploads;
|
||||
}
|
||||
|
||||
private chooseBackendType(): BackendType {
|
||||
switch (this.mediaConfig.backend.use) {
|
||||
case 'filesystem':
|
||||
|
@ -183,6 +202,15 @@ export class MediaService {
|
|||
}
|
||||
}
|
||||
|
||||
toMediaUploadDto(mediaUpload: MediaUpload): MediaUploadDto {
|
||||
return {
|
||||
url: mediaUpload.fileUrl,
|
||||
noteId: mediaUpload.note.id,
|
||||
createdAt: mediaUpload.createdAt,
|
||||
userName: mediaUpload.user.userName,
|
||||
};
|
||||
}
|
||||
|
||||
toMediaUploadUrlDto(url: string): MediaUploadUrlDto {
|
||||
return {
|
||||
link: url,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue