mirror of
https://github.com/hexastack/hexabot
synced 2025-01-22 10:35:37 +00:00
refactor: use enums
This commit is contained in:
parent
4fac5d4fc9
commit
359049ff3d
@ -39,7 +39,11 @@ import { attachment, attachmentFile } from '../mocks/attachment.mock';
|
|||||||
import { AttachmentRepository } from '../repositories/attachment.repository';
|
import { AttachmentRepository } from '../repositories/attachment.repository';
|
||||||
import { Attachment, AttachmentModel } from '../schemas/attachment.schema';
|
import { Attachment, AttachmentModel } from '../schemas/attachment.schema';
|
||||||
import { AttachmentService } from '../services/attachment.service';
|
import { AttachmentService } from '../services/attachment.service';
|
||||||
import { AttachmentResourceRef } from '../types';
|
import {
|
||||||
|
AttachmentAccess,
|
||||||
|
AttachmentCreatedByRef,
|
||||||
|
AttachmentResourceRef,
|
||||||
|
} from '../types';
|
||||||
|
|
||||||
import { AttachmentController } from './attachment.controller';
|
import { AttachmentController } from './attachment.controller';
|
||||||
|
|
||||||
@ -138,8 +142,8 @@ describe('AttachmentController', () => {
|
|||||||
name: attachmentFile.originalname,
|
name: attachmentFile.originalname,
|
||||||
location: expect.stringMatching(new RegExp(`^/${name}`)),
|
location: expect.stringMatching(new RegExp(`^/${name}`)),
|
||||||
resourceRef: AttachmentResourceRef.BlockAttachment,
|
resourceRef: AttachmentResourceRef.BlockAttachment,
|
||||||
access: 'public',
|
access: AttachmentAccess.Public,
|
||||||
createdByRef: 'User',
|
createdByRef: AttachmentCreatedByRef.User,
|
||||||
createdBy: '9'.repeat(24),
|
createdBy: '9'.repeat(24),
|
||||||
});
|
});
|
||||||
expect(result).toEqualPayload(
|
expect(result).toEqualPayload(
|
||||||
@ -147,7 +151,7 @@ describe('AttachmentController', () => {
|
|||||||
{
|
{
|
||||||
...attachment,
|
...attachment,
|
||||||
resourceRef: AttachmentResourceRef.BlockAttachment,
|
resourceRef: AttachmentResourceRef.BlockAttachment,
|
||||||
createdByRef: 'User',
|
createdByRef: AttachmentCreatedByRef.User,
|
||||||
createdBy: '9'.repeat(24),
|
createdBy: '9'.repeat(24),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -46,6 +46,7 @@ import {
|
|||||||
import { AttachmentGuard } from '../guards/attachment-ability.guard';
|
import { AttachmentGuard } from '../guards/attachment-ability.guard';
|
||||||
import { Attachment } from '../schemas/attachment.schema';
|
import { Attachment } from '../schemas/attachment.schema';
|
||||||
import { AttachmentService } from '../services/attachment.service';
|
import { AttachmentService } from '../services/attachment.service';
|
||||||
|
import { AttachmentAccess, AttachmentCreatedByRef } from '../types';
|
||||||
|
|
||||||
@UseInterceptors(CsrfInterceptor)
|
@UseInterceptors(CsrfInterceptor)
|
||||||
@Controller('attachment')
|
@Controller('attachment')
|
||||||
@ -131,7 +132,10 @@ export class AttachmentController extends BaseController<Attachment> {
|
|||||||
@UploadedFiles() files: { file: Express.Multer.File[] },
|
@UploadedFiles() files: { file: Express.Multer.File[] },
|
||||||
@Req() req: Request,
|
@Req() req: Request,
|
||||||
@Query()
|
@Query()
|
||||||
{ resourceRef, access = 'public' }: AttachmentContextParamDto,
|
{
|
||||||
|
resourceRef,
|
||||||
|
access = AttachmentAccess.Public,
|
||||||
|
}: AttachmentContextParamDto,
|
||||||
): Promise<Attachment[]> {
|
): Promise<Attachment[]> {
|
||||||
if (!files || !Array.isArray(files?.file) || files.file.length === 0) {
|
if (!files || !Array.isArray(files?.file) || files.file.length === 0) {
|
||||||
throw new BadRequestException('No file was selected');
|
throw new BadRequestException('No file was selected');
|
||||||
@ -153,7 +157,7 @@ export class AttachmentController extends BaseController<Attachment> {
|
|||||||
resourceRef,
|
resourceRef,
|
||||||
access,
|
access,
|
||||||
createdBy: userId,
|
createdBy: userId,
|
||||||
createdByRef: 'User',
|
createdByRef: AttachmentCreatedByRef.User,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (attachment) {
|
if (attachment) {
|
||||||
|
@ -27,9 +27,6 @@ import {
|
|||||||
AttachmentAccess,
|
AttachmentAccess,
|
||||||
AttachmentCreatedByRef,
|
AttachmentCreatedByRef,
|
||||||
AttachmentResourceRef,
|
AttachmentResourceRef,
|
||||||
TAttachmentAccess,
|
|
||||||
TAttachmentCreatedByRef,
|
|
||||||
TAttachmentResourceRef,
|
|
||||||
} from '../types';
|
} from '../types';
|
||||||
|
|
||||||
export class AttachmentMetadataDto {
|
export class AttachmentMetadataDto {
|
||||||
@ -76,7 +73,7 @@ export class AttachmentMetadataDto {
|
|||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@IsIn(Object.values(AttachmentResourceRef))
|
@IsIn(Object.values(AttachmentResourceRef))
|
||||||
resourceRef: TAttachmentResourceRef;
|
resourceRef: AttachmentResourceRef;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attachment Owner Type
|
* Attachment Owner Type
|
||||||
@ -88,7 +85,7 @@ export class AttachmentMetadataDto {
|
|||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@IsIn(Object.values(AttachmentCreatedByRef))
|
@IsIn(Object.values(AttachmentCreatedByRef))
|
||||||
createdByRef: TAttachmentCreatedByRef;
|
createdByRef: AttachmentCreatedByRef;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attachment Access
|
* Attachment Access
|
||||||
@ -100,7 +97,7 @@ export class AttachmentMetadataDto {
|
|||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@IsIn(Object.values(AttachmentAccess))
|
@IsIn(Object.values(AttachmentAccess))
|
||||||
access: TAttachmentAccess;
|
access: AttachmentAccess;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attachment Owner : Subscriber or User ID
|
* Attachment Owner : Subscriber or User ID
|
||||||
@ -147,7 +144,7 @@ export class AttachmentContextParamDto {
|
|||||||
@IsString()
|
@IsString()
|
||||||
@IsIn(Object.values(AttachmentResourceRef))
|
@IsIn(Object.values(AttachmentResourceRef))
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
resourceRef: TAttachmentResourceRef;
|
resourceRef: AttachmentResourceRef;
|
||||||
|
|
||||||
@ApiPropertyOptional({
|
@ApiPropertyOptional({
|
||||||
description: 'Attachment Access',
|
description: 'Attachment Access',
|
||||||
@ -156,5 +153,5 @@ export class AttachmentContextParamDto {
|
|||||||
@IsString()
|
@IsString()
|
||||||
@IsIn(Object.values(AttachmentAccess))
|
@IsIn(Object.values(AttachmentAccess))
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
access?: TAttachmentAccess;
|
access?: AttachmentAccess;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ import { Action } from '@/user/types/action.type';
|
|||||||
import { TModel } from '@/user/types/model.type';
|
import { TModel } from '@/user/types/model.type';
|
||||||
|
|
||||||
import { AttachmentService } from '../services/attachment.service';
|
import { AttachmentService } from '../services/attachment.service';
|
||||||
import { AttachmentResourceRef, TAttachmentResourceRef } from '../types';
|
import { AttachmentResourceRef } from '../types';
|
||||||
import {
|
import {
|
||||||
isAttachmentResourceRef,
|
isAttachmentResourceRef,
|
||||||
isAttachmentResourceRefArray,
|
isAttachmentResourceRefArray,
|
||||||
@ -42,7 +42,7 @@ export class AttachmentGuard implements CanActivate {
|
|||||||
|
|
||||||
private permissionMap: Record<
|
private permissionMap: Record<
|
||||||
Action,
|
Action,
|
||||||
Record<TAttachmentResourceRef, [TModel, Action][]>
|
Record<AttachmentResourceRef, [TModel, Action][]>
|
||||||
> = {
|
> = {
|
||||||
// Read attachments by ref
|
// Read attachments by ref
|
||||||
[Action.READ]: {
|
[Action.READ]: {
|
||||||
@ -169,7 +169,7 @@ export class AttachmentGuard implements CanActivate {
|
|||||||
private async isAuthorized(
|
private async isAuthorized(
|
||||||
action: Action,
|
action: Action,
|
||||||
user: Express.User & User,
|
user: Express.User & User,
|
||||||
resourceRef: TAttachmentResourceRef,
|
resourceRef: AttachmentResourceRef,
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
if (!action) {
|
if (!action) {
|
||||||
throw new TypeError('Invalid action');
|
throw new TypeError('Invalid action');
|
||||||
|
@ -9,7 +9,11 @@
|
|||||||
import { Stream } from 'node:stream';
|
import { Stream } from 'node:stream';
|
||||||
|
|
||||||
import { Attachment } from '../schemas/attachment.schema';
|
import { Attachment } from '../schemas/attachment.schema';
|
||||||
import { AttachmentResourceRef } from '../types';
|
import {
|
||||||
|
AttachmentAccess,
|
||||||
|
AttachmentCreatedByRef,
|
||||||
|
AttachmentResourceRef,
|
||||||
|
} from '../types';
|
||||||
|
|
||||||
export const attachment: Attachment = {
|
export const attachment: Attachment = {
|
||||||
name: 'Screenshot from 2022-03-11 08-41-27-2a9799a8b6109c88fd9a7a690c1101934c.png',
|
name: 'Screenshot from 2022-03-11 08-41-27-2a9799a8b6109c88fd9a7a690c1101934c.png',
|
||||||
@ -18,12 +22,12 @@ export const attachment: Attachment = {
|
|||||||
location:
|
location:
|
||||||
'/Screenshot from 2022-03-11 08-41-27-2a9799a8b6109c88fd9a7a690c1101934c.png',
|
'/Screenshot from 2022-03-11 08-41-27-2a9799a8b6109c88fd9a7a690c1101934c.png',
|
||||||
resourceRef: AttachmentResourceRef.BlockAttachment,
|
resourceRef: AttachmentResourceRef.BlockAttachment,
|
||||||
access: 'public',
|
access: AttachmentAccess.Public,
|
||||||
id: '65940d115178607da65c82b6',
|
id: '65940d115178607da65c82b6',
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
createdBy: '1',
|
createdBy: '1',
|
||||||
createdByRef: 'User',
|
createdByRef: AttachmentCreatedByRef.User,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const attachmentFile: Express.Multer.File = {
|
export const attachmentFile: Express.Multer.File = {
|
||||||
@ -49,12 +53,12 @@ export const attachments: Attachment[] = [
|
|||||||
'/app/src/attachment/uploads/Screenshot from 2022-03-11 08-41-27-2a9799a8b6109c88fd9a7a690c1101934c.png',
|
'/app/src/attachment/uploads/Screenshot from 2022-03-11 08-41-27-2a9799a8b6109c88fd9a7a690c1101934c.png',
|
||||||
channel: { ['some-channel']: {} },
|
channel: { ['some-channel']: {} },
|
||||||
resourceRef: AttachmentResourceRef.BlockAttachment,
|
resourceRef: AttachmentResourceRef.BlockAttachment,
|
||||||
access: 'public',
|
access: AttachmentAccess.Public,
|
||||||
id: '65940d115178607da65c82b7',
|
id: '65940d115178607da65c82b7',
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
createdBy: '1',
|
createdBy: '1',
|
||||||
createdByRef: 'User',
|
createdByRef: AttachmentCreatedByRef.User,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Screenshot from 2022-03-18 08-58-15-af61e7f71281f9fd3f1ad7ad10107741c.png',
|
name: 'Screenshot from 2022-03-18 08-58-15-af61e7f71281f9fd3f1ad7ad10107741c.png',
|
||||||
@ -64,11 +68,11 @@ export const attachments: Attachment[] = [
|
|||||||
'/app/src/attachment/uploads/Screenshot from 2022-03-18 08-58-15-af61e7f71281f9fd3f1ad7ad10107741c.png',
|
'/app/src/attachment/uploads/Screenshot from 2022-03-18 08-58-15-af61e7f71281f9fd3f1ad7ad10107741c.png',
|
||||||
channel: { ['some-channel']: {} },
|
channel: { ['some-channel']: {} },
|
||||||
resourceRef: AttachmentResourceRef.BlockAttachment,
|
resourceRef: AttachmentResourceRef.BlockAttachment,
|
||||||
access: 'public',
|
access: AttachmentAccess.Public,
|
||||||
id: '65940d115178607da65c82b8',
|
id: '65940d115178607da65c82b8',
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
createdBy: '1',
|
createdBy: '1',
|
||||||
createdByRef: 'User',
|
createdByRef: AttachmentCreatedByRef.User,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -27,9 +27,6 @@ import {
|
|||||||
AttachmentAccess,
|
AttachmentAccess,
|
||||||
AttachmentCreatedByRef,
|
AttachmentCreatedByRef,
|
||||||
AttachmentResourceRef,
|
AttachmentResourceRef,
|
||||||
TAttachmentAccess,
|
|
||||||
TAttachmentCreatedByRef,
|
|
||||||
TAttachmentResourceRef,
|
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import { MIME_REGEX } from '../utilities';
|
import { MIME_REGEX } from '../utilities';
|
||||||
|
|
||||||
@ -94,19 +91,19 @@ export class AttachmentStub extends BaseSchema {
|
|||||||
* Type of the createdBy (depending on the createdBy type)
|
* Type of the createdBy (depending on the createdBy type)
|
||||||
*/
|
*/
|
||||||
@Prop({ type: String, enum: Object.values(AttachmentCreatedByRef) })
|
@Prop({ type: String, enum: Object.values(AttachmentCreatedByRef) })
|
||||||
createdByRef: TAttachmentCreatedByRef;
|
createdByRef: AttachmentCreatedByRef;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resource reference of the attachment
|
* Resource reference of the attachment
|
||||||
*/
|
*/
|
||||||
@Prop({ type: String, enum: Object.values(AttachmentResourceRef) })
|
@Prop({ type: String, enum: Object.values(AttachmentResourceRef) })
|
||||||
resourceRef: TAttachmentResourceRef;
|
resourceRef: AttachmentResourceRef;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Access level of the attachment
|
* Access level of the attachment
|
||||||
*/
|
*/
|
||||||
@Prop({ type: String, enum: Object.values(AttachmentAccess) })
|
@Prop({ type: String, enum: Object.values(AttachmentAccess) })
|
||||||
access: TAttachmentAccess;
|
access: AttachmentAccess;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional property representing the URL of the attachment.
|
* Optional property representing the URL of the attachment.
|
||||||
|
@ -30,7 +30,7 @@ import { BaseService } from '@/utils/generics/base-service';
|
|||||||
import { AttachmentMetadataDto } from '../dto/attachment.dto';
|
import { AttachmentMetadataDto } from '../dto/attachment.dto';
|
||||||
import { AttachmentRepository } from '../repositories/attachment.repository';
|
import { AttachmentRepository } from '../repositories/attachment.repository';
|
||||||
import { Attachment } from '../schemas/attachment.schema';
|
import { Attachment } from '../schemas/attachment.schema';
|
||||||
import { AttachmentResourceRef, TAttachmentResourceRef } from '../types';
|
import { AttachmentResourceRef } from '../types';
|
||||||
import {
|
import {
|
||||||
fileExists,
|
fileExists,
|
||||||
generateUniqueFilename,
|
generateUniqueFilename,
|
||||||
@ -163,7 +163,7 @@ export class AttachmentService extends BaseService<Attachment> {
|
|||||||
* @param ref The attachment resource reference
|
* @param ref The attachment resource reference
|
||||||
* @returns The root directory path
|
* @returns The root directory path
|
||||||
*/
|
*/
|
||||||
getRootDirByResourceRef(ref: TAttachmentResourceRef) {
|
getRootDirByResourceRef(ref: AttachmentResourceRef) {
|
||||||
return ref === AttachmentResourceRef.SubscriberAvatar ||
|
return ref === AttachmentResourceRef.SubscriberAvatar ||
|
||||||
ref === AttachmentResourceRef.UserAvatar
|
ref === AttachmentResourceRef.UserAvatar
|
||||||
? config.parameters.avatarDir
|
? config.parameters.avatarDir
|
||||||
|
@ -17,8 +17,6 @@ export enum AttachmentCreatedByRef {
|
|||||||
Subscriber = 'Subscriber',
|
Subscriber = 'Subscriber',
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TAttachmentCreatedByRef = `${AttachmentCreatedByRef}`;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the various resource references in which an attachment can exist.
|
* Defines the various resource references in which an attachment can exist.
|
||||||
* These resource references influence how the attachment is uploaded, stored, and accessed:
|
* These resource references influence how the attachment is uploaded, stored, and accessed:
|
||||||
@ -32,15 +30,11 @@ export enum AttachmentResourceRef {
|
|||||||
MessageAttachment = 'Message', // Files sent or received via messages, uploaded programmatically, accessible to users with inbox permissions.;
|
MessageAttachment = 'Message', // Files sent or received via messages, uploaded programmatically, accessible to users with inbox permissions.;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TAttachmentResourceRef = `${AttachmentResourceRef}`;
|
|
||||||
|
|
||||||
export enum AttachmentAccess {
|
export enum AttachmentAccess {
|
||||||
Public = 'public',
|
Public = 'public',
|
||||||
Private = 'private',
|
Private = 'private',
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TAttachmentAccess = `${AttachmentAccess}`;
|
|
||||||
|
|
||||||
export class AttachmentFile {
|
export class AttachmentFile {
|
||||||
/**
|
/**
|
||||||
* File original file name
|
* File original file name
|
||||||
|
@ -15,7 +15,7 @@ import { v4 as uuidv4 } from 'uuid';
|
|||||||
|
|
||||||
import { config } from '@/config';
|
import { config } from '@/config';
|
||||||
|
|
||||||
import { AttachmentResourceRef, TAttachmentResourceRef } from '../types';
|
import { AttachmentResourceRef } from '../types';
|
||||||
|
|
||||||
export const MIME_REGEX = /^[a-z-]+\/[0-9a-z\-.]+$/gm;
|
export const MIME_REGEX = /^[a-z-]+\/[0-9a-z\-.]+$/gm;
|
||||||
|
|
||||||
@ -84,13 +84,13 @@ export const generateUniqueFilename = (originalname: string) => {
|
|||||||
/**
|
/**
|
||||||
* Checks if the given ref is of type TAttachmentResourceRef.
|
* Checks if the given ref is of type TAttachmentResourceRef.
|
||||||
*
|
*
|
||||||
* @param ref - The ref to check.
|
* @param resourceRef - The ref to check.
|
||||||
* @returns True if the ref is of type TAttachmentResourceRef, otherwise false.
|
* @returns True if the ref is of type TAttachmentResourceRef, otherwise false.
|
||||||
*/
|
*/
|
||||||
export const isAttachmentResourceRef = (
|
export const isAttachmentResourceRef = (
|
||||||
ref: any,
|
resourceRef: any,
|
||||||
): ref is TAttachmentResourceRef => {
|
): resourceRef is AttachmentResourceRef => {
|
||||||
return Object.values(AttachmentResourceRef).includes(ref);
|
return Object.values(AttachmentResourceRef).includes(resourceRef);
|
||||||
};
|
};
|
||||||
AttachmentResourceRef;
|
AttachmentResourceRef;
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ AttachmentResourceRef;
|
|||||||
*/
|
*/
|
||||||
export const isAttachmentResourceRefArray = (
|
export const isAttachmentResourceRefArray = (
|
||||||
refList: any,
|
refList: any,
|
||||||
): refList is TAttachmentResourceRef[] => {
|
): refList is AttachmentResourceRef[] => {
|
||||||
return (
|
return (
|
||||||
Array.isArray(refList) &&
|
Array.isArray(refList) &&
|
||||||
refList.length > 0 &&
|
refList.length > 0 &&
|
||||||
|
@ -23,7 +23,12 @@ import { v4 as uuidv4 } from 'uuid';
|
|||||||
|
|
||||||
import { Attachment } from '@/attachment/schemas/attachment.schema';
|
import { Attachment } from '@/attachment/schemas/attachment.schema';
|
||||||
import { AttachmentService } from '@/attachment/services/attachment.service';
|
import { AttachmentService } from '@/attachment/services/attachment.service';
|
||||||
import { AttachmentFile, AttachmentResourceRef } from '@/attachment/types';
|
import {
|
||||||
|
AttachmentAccess,
|
||||||
|
AttachmentCreatedByRef,
|
||||||
|
AttachmentFile,
|
||||||
|
AttachmentResourceRef,
|
||||||
|
} from '@/attachment/types';
|
||||||
import { SubscriberCreateDto } from '@/chat/dto/subscriber.dto';
|
import { SubscriberCreateDto } from '@/chat/dto/subscriber.dto';
|
||||||
import { AttachmentRef } from '@/chat/schemas/types/attachment';
|
import { AttachmentRef } from '@/chat/schemas/types/attachment';
|
||||||
import {
|
import {
|
||||||
@ -260,8 +265,8 @@ export default abstract class ChannelHandler<
|
|||||||
type,
|
type,
|
||||||
size,
|
size,
|
||||||
resourceRef: AttachmentResourceRef.MessageAttachment,
|
resourceRef: AttachmentResourceRef.MessageAttachment,
|
||||||
access: 'private',
|
access: AttachmentAccess.Private,
|
||||||
createdByRef: 'Subscriber',
|
createdByRef: AttachmentCreatedByRef.Subscriber,
|
||||||
createdBy: subscriber.id,
|
createdBy: subscriber.id,
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
@ -327,7 +332,7 @@ export default abstract class ChannelHandler<
|
|||||||
* @return True, if requester is authorized to download the attachment
|
* @return True, if requester is authorized to download the attachment
|
||||||
*/
|
*/
|
||||||
public async hasDownloadAccess(attachment: Attachment, _req: Request) {
|
public async hasDownloadAccess(attachment: Attachment, _req: Request) {
|
||||||
return attachment.access === 'public';
|
return attachment.access === AttachmentAccess.Public;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,7 +7,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Attachment } from '@/attachment/schemas/attachment.schema';
|
import { Attachment } from '@/attachment/schemas/attachment.schema';
|
||||||
import { AttachmentResourceRef } from '@/attachment/types';
|
import {
|
||||||
|
AttachmentAccess,
|
||||||
|
AttachmentCreatedByRef,
|
||||||
|
AttachmentResourceRef,
|
||||||
|
} from '@/attachment/types';
|
||||||
import { ButtonType } from '@/chat/schemas/types/button';
|
import { ButtonType } from '@/chat/schemas/types/button';
|
||||||
import {
|
import {
|
||||||
FileType,
|
FileType,
|
||||||
@ -90,8 +94,8 @@ const attachment: Attachment = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
resourceRef: AttachmentResourceRef.BlockAttachment,
|
resourceRef: AttachmentResourceRef.BlockAttachment,
|
||||||
access: 'public',
|
access: AttachmentAccess.Public,
|
||||||
createdByRef: 'User',
|
createdByRef: AttachmentCreatedByRef.User,
|
||||||
createdBy: null,
|
createdBy: null,
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
|
@ -12,7 +12,11 @@ import mime from 'mime';
|
|||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
import { AttachmentService } from '@/attachment/services/attachment.service';
|
import { AttachmentService } from '@/attachment/services/attachment.service';
|
||||||
import { AttachmentResourceRef } from '@/attachment/types';
|
import {
|
||||||
|
AttachmentAccess,
|
||||||
|
AttachmentCreatedByRef,
|
||||||
|
AttachmentResourceRef,
|
||||||
|
} from '@/attachment/types';
|
||||||
import EventWrapper from '@/channel/lib/EventWrapper';
|
import EventWrapper from '@/channel/lib/EventWrapper';
|
||||||
import { config } from '@/config';
|
import { config } from '@/config';
|
||||||
import { HelperService } from '@/helper/helper.service';
|
import { HelperService } from '@/helper/helper.service';
|
||||||
@ -282,8 +286,8 @@ export class ChatService {
|
|||||||
size,
|
size,
|
||||||
type,
|
type,
|
||||||
resourceRef: AttachmentResourceRef.SubscriberAvatar,
|
resourceRef: AttachmentResourceRef.SubscriberAvatar,
|
||||||
access: 'private',
|
access: AttachmentAccess.Private,
|
||||||
createdByRef: 'Subscriber',
|
createdByRef: AttachmentCreatedByRef.Subscriber,
|
||||||
createdBy: subscriber.id,
|
createdBy: subscriber.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -15,7 +15,11 @@ import { v4 as uuidv4 } from 'uuid';
|
|||||||
|
|
||||||
import { Attachment } from '@/attachment/schemas/attachment.schema';
|
import { Attachment } from '@/attachment/schemas/attachment.schema';
|
||||||
import { AttachmentService } from '@/attachment/services/attachment.service';
|
import { AttachmentService } from '@/attachment/services/attachment.service';
|
||||||
import { AttachmentResourceRef } from '@/attachment/types';
|
import {
|
||||||
|
AttachmentAccess,
|
||||||
|
AttachmentCreatedByRef,
|
||||||
|
AttachmentResourceRef,
|
||||||
|
} from '@/attachment/types';
|
||||||
import { ChannelService } from '@/channel/channel.service';
|
import { ChannelService } from '@/channel/channel.service';
|
||||||
import ChannelHandler from '@/channel/lib/Handler';
|
import ChannelHandler from '@/channel/lib/Handler';
|
||||||
import { ChannelName } from '@/channel/types';
|
import { ChannelName } from '@/channel/types';
|
||||||
@ -627,8 +631,8 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
size: Buffer.byteLength(data.file),
|
size: Buffer.byteLength(data.file),
|
||||||
type: data.type,
|
type: data.type,
|
||||||
resourceRef: AttachmentResourceRef.MessageAttachment,
|
resourceRef: AttachmentResourceRef.MessageAttachment,
|
||||||
access: 'private',
|
access: AttachmentAccess.Private,
|
||||||
createdByRef: 'Subscriber',
|
createdByRef: AttachmentCreatedByRef.Subscriber,
|
||||||
createdBy: req.session?.web?.profile?.id,
|
createdBy: req.session?.web?.profile?.id,
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -694,8 +698,8 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
size: file.size,
|
size: file.size,
|
||||||
type: file.mimetype,
|
type: file.mimetype,
|
||||||
resourceRef: AttachmentResourceRef.MessageAttachment,
|
resourceRef: AttachmentResourceRef.MessageAttachment,
|
||||||
access: 'private',
|
access: AttachmentAccess.Private,
|
||||||
createdByRef: 'Subscriber',
|
createdByRef: AttachmentCreatedByRef.Subscriber,
|
||||||
createdBy: req.session.web.profile?.id,
|
createdBy: req.session.web.profile?.id,
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -1355,7 +1359,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
*/
|
*/
|
||||||
public async hasDownloadAccess(attachment: Attachment, req: Request) {
|
public async hasDownloadAccess(attachment: Attachment, req: Request) {
|
||||||
const subscriberId = req.session?.web?.profile?.id as string;
|
const subscriberId = req.session?.web?.profile?.id as string;
|
||||||
if (attachment.access === 'public') {
|
if (attachment.access === AttachmentAccess.Public) {
|
||||||
return true;
|
return true;
|
||||||
} else if (!subscriberId) {
|
} else if (!subscriberId) {
|
||||||
this.logger.warn(
|
this.logger.warn(
|
||||||
@ -1363,7 +1367,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
} else if (
|
} else if (
|
||||||
attachment.createdByRef === 'Subscriber' &&
|
attachment.createdByRef === AttachmentCreatedByRef.Subscriber &&
|
||||||
subscriberId === attachment.createdBy
|
subscriberId === attachment.createdBy
|
||||||
) {
|
) {
|
||||||
// Either subscriber wants to access the attachment he sent
|
// Either subscriber wants to access the attachment he sent
|
||||||
|
@ -16,6 +16,7 @@ import attachmentSchema, {
|
|||||||
Attachment,
|
Attachment,
|
||||||
} from '@/attachment/schemas/attachment.schema';
|
} from '@/attachment/schemas/attachment.schema';
|
||||||
import {
|
import {
|
||||||
|
AttachmentAccess,
|
||||||
AttachmentCreatedByRef,
|
AttachmentCreatedByRef,
|
||||||
AttachmentResourceRef,
|
AttachmentResourceRef,
|
||||||
} from '@/attachment/types';
|
} from '@/attachment/types';
|
||||||
@ -619,8 +620,8 @@ const migrateAttachmentContents = async (
|
|||||||
$set: {
|
$set: {
|
||||||
resourceRef: AttachmentResourceRef.ContentAttachment,
|
resourceRef: AttachmentResourceRef.ContentAttachment,
|
||||||
createdBy: adminUser.id,
|
createdBy: adminUser.id,
|
||||||
createdByRef: 'User',
|
createdByRef: AttachmentCreatedByRef.User,
|
||||||
access: 'public',
|
access: AttachmentAccess.Public,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -682,8 +683,10 @@ const migrateAndPopulateAttachmentMessages = async ({
|
|||||||
msg.message.attachment.payload.attachment_id as string,
|
msg.message.attachment.payload.attachment_id as string,
|
||||||
{
|
{
|
||||||
resourceRef: AttachmentResourceRef.MessageAttachment,
|
resourceRef: AttachmentResourceRef.MessageAttachment,
|
||||||
access: 'private',
|
access: AttachmentAccess.Private,
|
||||||
createdByRef: msg.sender ? 'Subscriber' : 'User',
|
createdByRef: msg.sender
|
||||||
|
? AttachmentCreatedByRef.Subscriber
|
||||||
|
: AttachmentCreatedByRef.User,
|
||||||
createdBy: msg.sender ? msg.sender : adminUser.id,
|
createdBy: msg.sender ? msg.sender : adminUser.id,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -715,9 +718,13 @@ const migrateAndPopulateAttachmentMessages = async ({
|
|||||||
type: response.headers['content-type'],
|
type: response.headers['content-type'],
|
||||||
channel: {},
|
channel: {},
|
||||||
resourceRef: AttachmentResourceRef.MessageAttachment,
|
resourceRef: AttachmentResourceRef.MessageAttachment,
|
||||||
access: msg.sender ? 'private' : 'public',
|
access: msg.sender
|
||||||
|
? AttachmentAccess.Private
|
||||||
|
: AttachmentAccess.Public,
|
||||||
createdBy: msg.sender ? msg.sender : adminUser.id,
|
createdBy: msg.sender ? msg.sender : adminUser.id,
|
||||||
createdByRef: msg.sender ? 'Subscriber' : 'User',
|
createdByRef: msg.sender
|
||||||
|
? AttachmentCreatedByRef.Subscriber
|
||||||
|
: AttachmentCreatedByRef.User,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (attachment) {
|
if (attachment) {
|
||||||
|
@ -31,7 +31,11 @@ import { Session as ExpressSession } from 'express-session';
|
|||||||
import { diskStorage, memoryStorage } from 'multer';
|
import { diskStorage, memoryStorage } from 'multer';
|
||||||
|
|
||||||
import { AttachmentService } from '@/attachment/services/attachment.service';
|
import { AttachmentService } from '@/attachment/services/attachment.service';
|
||||||
import { AttachmentResourceRef } from '@/attachment/types';
|
import {
|
||||||
|
AttachmentAccess,
|
||||||
|
AttachmentCreatedByRef,
|
||||||
|
AttachmentResourceRef,
|
||||||
|
} from '@/attachment/types';
|
||||||
import { config } from '@/config';
|
import { config } from '@/config';
|
||||||
import { CsrfInterceptor } from '@/interceptors/csrf.interceptor';
|
import { CsrfInterceptor } from '@/interceptors/csrf.interceptor';
|
||||||
import { LoggerService } from '@/logger/logger.service';
|
import { LoggerService } from '@/logger/logger.service';
|
||||||
@ -296,8 +300,8 @@ export class ReadWriteUserController extends ReadOnlyUserController {
|
|||||||
size: avatarFile.size,
|
size: avatarFile.size,
|
||||||
type: avatarFile.mimetype,
|
type: avatarFile.mimetype,
|
||||||
resourceRef: AttachmentResourceRef.UserAvatar,
|
resourceRef: AttachmentResourceRef.UserAvatar,
|
||||||
access: 'private',
|
access: AttachmentAccess.Private,
|
||||||
createdByRef: 'User',
|
createdByRef: AttachmentCreatedByRef.User,
|
||||||
createdBy: req.user.id,
|
createdBy: req.user.id,
|
||||||
})
|
})
|
||||||
: undefined;
|
: undefined;
|
||||||
|
14
api/src/utils/test/fixtures/attachment.ts
vendored
14
api/src/utils/test/fixtures/attachment.ts
vendored
@ -10,7 +10,11 @@ import mongoose from 'mongoose';
|
|||||||
|
|
||||||
import { AttachmentCreateDto } from '@/attachment/dto/attachment.dto';
|
import { AttachmentCreateDto } from '@/attachment/dto/attachment.dto';
|
||||||
import { AttachmentModel } from '@/attachment/schemas/attachment.schema';
|
import { AttachmentModel } from '@/attachment/schemas/attachment.schema';
|
||||||
import { AttachmentResourceRef } from '@/attachment/types';
|
import {
|
||||||
|
AttachmentAccess,
|
||||||
|
AttachmentCreatedByRef,
|
||||||
|
AttachmentResourceRef,
|
||||||
|
} from '@/attachment/types';
|
||||||
|
|
||||||
export const attachmentFixtures: AttachmentCreateDto[] = [
|
export const attachmentFixtures: AttachmentCreateDto[] = [
|
||||||
{
|
{
|
||||||
@ -24,8 +28,8 @@ export const attachmentFixtures: AttachmentCreateDto[] = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
resourceRef: AttachmentResourceRef.ContentAttachment,
|
resourceRef: AttachmentResourceRef.ContentAttachment,
|
||||||
access: 'public',
|
access: AttachmentAccess.Public,
|
||||||
createdByRef: 'User',
|
createdByRef: AttachmentCreatedByRef.User,
|
||||||
createdBy: '9'.repeat(24),
|
createdBy: '9'.repeat(24),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -39,8 +43,8 @@ export const attachmentFixtures: AttachmentCreateDto[] = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
resourceRef: AttachmentResourceRef.ContentAttachment,
|
resourceRef: AttachmentResourceRef.ContentAttachment,
|
||||||
access: 'public',
|
access: AttachmentAccess.Public,
|
||||||
createdByRef: 'User',
|
createdByRef: AttachmentCreatedByRef.User,
|
||||||
createdBy: '9'.repeat(24),
|
createdBy: '9'.repeat(24),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -13,7 +13,7 @@ import { forwardRef } from "react";
|
|||||||
import { useGet } from "@/hooks/crud/useGet";
|
import { useGet } from "@/hooks/crud/useGet";
|
||||||
import { useHasPermission } from "@/hooks/useHasPermission";
|
import { useHasPermission } from "@/hooks/useHasPermission";
|
||||||
import { EntityType } from "@/services/types";
|
import { EntityType } from "@/services/types";
|
||||||
import { IAttachment, TAttachmentResourceRef } from "@/types/attachment.types";
|
import { AttachmentResourceRef, IAttachment } from "@/types/attachment.types";
|
||||||
import { PermissionAction } from "@/types/permission.types";
|
import { PermissionAction } from "@/types/permission.types";
|
||||||
|
|
||||||
import AttachmentThumbnail from "./AttachmentThumbnail";
|
import AttachmentThumbnail from "./AttachmentThumbnail";
|
||||||
@ -29,7 +29,7 @@ type AttachmentThumbnailProps = {
|
|||||||
onChange?: (id: string | null, mimeType: string | null) => void;
|
onChange?: (id: string | null, mimeType: string | null) => void;
|
||||||
error?: boolean;
|
error?: boolean;
|
||||||
helperText?: string;
|
helperText?: string;
|
||||||
resourceRef: TAttachmentResourceRef;
|
resourceRef: AttachmentResourceRef;
|
||||||
};
|
};
|
||||||
|
|
||||||
const AttachmentInput = forwardRef<HTMLDivElement, AttachmentThumbnailProps>(
|
const AttachmentInput = forwardRef<HTMLDivElement, AttachmentThumbnailProps>(
|
||||||
|
@ -17,7 +17,7 @@ import { getDisplayDialogs, useDialog } from "@/hooks/useDialog";
|
|||||||
import { useToast } from "@/hooks/useToast";
|
import { useToast } from "@/hooks/useToast";
|
||||||
import { useTranslate } from "@/hooks/useTranslate";
|
import { useTranslate } from "@/hooks/useTranslate";
|
||||||
import { EntityType } from "@/services/types";
|
import { EntityType } from "@/services/types";
|
||||||
import { IAttachment, TAttachmentResourceRef } from "@/types/attachment.types";
|
import { AttachmentResourceRef, IAttachment } from "@/types/attachment.types";
|
||||||
|
|
||||||
import { AttachmentDialog } from "./AttachmentDialog";
|
import { AttachmentDialog } from "./AttachmentDialog";
|
||||||
import AttachmentThumbnail from "./AttachmentThumbnail";
|
import AttachmentThumbnail from "./AttachmentThumbnail";
|
||||||
@ -68,7 +68,7 @@ export type FileUploadProps = {
|
|||||||
enableMediaLibrary?: boolean;
|
enableMediaLibrary?: boolean;
|
||||||
onChange?: (data?: IAttachment | null) => void;
|
onChange?: (data?: IAttachment | null) => void;
|
||||||
onUploadComplete?: () => void;
|
onUploadComplete?: () => void;
|
||||||
resourceRef: TAttachmentResourceRef;
|
resourceRef: AttachmentResourceRef;
|
||||||
};
|
};
|
||||||
|
|
||||||
const AttachmentUploader: FC<FileUploadProps> = ({
|
const AttachmentUploader: FC<FileUploadProps> = ({
|
||||||
|
@ -12,7 +12,7 @@ import { forwardRef, useState } from "react";
|
|||||||
|
|
||||||
import { useHasPermission } from "@/hooks/useHasPermission";
|
import { useHasPermission } from "@/hooks/useHasPermission";
|
||||||
import { EntityType } from "@/services/types";
|
import { EntityType } from "@/services/types";
|
||||||
import { IAttachment, TAttachmentResourceRef } from "@/types/attachment.types";
|
import { AttachmentResourceRef, IAttachment } from "@/types/attachment.types";
|
||||||
import { PermissionAction } from "@/types/permission.types";
|
import { PermissionAction } from "@/types/permission.types";
|
||||||
|
|
||||||
import AttachmentThumbnail from "./AttachmentThumbnail";
|
import AttachmentThumbnail from "./AttachmentThumbnail";
|
||||||
@ -28,7 +28,7 @@ type MultipleAttachmentInputProps = {
|
|||||||
onChange?: (ids: string[]) => void;
|
onChange?: (ids: string[]) => void;
|
||||||
error?: boolean;
|
error?: boolean;
|
||||||
helperText?: string;
|
helperText?: string;
|
||||||
resourceRef: TAttachmentResourceRef;
|
resourceRef: AttachmentResourceRef;
|
||||||
};
|
};
|
||||||
|
|
||||||
const MultipleAttachmentInput = forwardRef<
|
const MultipleAttachmentInput = forwardRef<
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
import { useMutation, useQueryClient } from "react-query";
|
import { useMutation, useQueryClient } from "react-query";
|
||||||
|
|
||||||
import { QueryType, TMutationOptions } from "@/services/types";
|
import { QueryType, TMutationOptions } from "@/services/types";
|
||||||
import { TAttachmentResourceRef } from "@/types/attachment.types";
|
import { AttachmentResourceRef } from "@/types/attachment.types";
|
||||||
import { IBaseSchema, IDynamicProps, TType } from "@/types/base.types";
|
import { IBaseSchema, IDynamicProps, TType } from "@/types/base.types";
|
||||||
|
|
||||||
import { useEntityApiClient } from "../useApiClient";
|
import { useEntityApiClient } from "../useApiClient";
|
||||||
@ -27,7 +27,7 @@ export const useUpload = <
|
|||||||
TMutationOptions<
|
TMutationOptions<
|
||||||
TBasic,
|
TBasic,
|
||||||
Error,
|
Error,
|
||||||
{ file: File; resourceRef: TAttachmentResourceRef },
|
{ file: File; resourceRef: AttachmentResourceRef },
|
||||||
TBasic
|
TBasic
|
||||||
>,
|
>,
|
||||||
"mutationFn" | "mutationKey"
|
"mutationFn" | "mutationKey"
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
import { AxiosInstance, AxiosResponse } from "axios";
|
import { AxiosInstance, AxiosResponse } from "axios";
|
||||||
|
|
||||||
import { TAttachmentResourceRef } from "@/types/attachment.types";
|
import { AttachmentResourceRef } from "@/types/attachment.types";
|
||||||
import { ILoginAttributes } from "@/types/auth/login.types";
|
import { ILoginAttributes } from "@/types/auth/login.types";
|
||||||
import { IUserPermissions } from "@/types/auth/permission.types";
|
import { IUserPermissions } from "@/types/auth/permission.types";
|
||||||
import { StatsType } from "@/types/bot-stat.types";
|
import { StatsType } from "@/types/bot-stat.types";
|
||||||
@ -302,7 +302,7 @@ export class EntityApiClient<TAttr, TBasic, TFull> extends ApiClient {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
async upload(file: File, resourceRef?: TAttachmentResourceRef) {
|
async upload(file: File, resourceRef?: AttachmentResourceRef) {
|
||||||
const { _csrf } = await this.getCsrf();
|
const { _csrf } = await this.getCsrf();
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
|
|
||||||
|
@ -22,8 +22,6 @@ export enum AttachmentCreatedByRef {
|
|||||||
Subscriber = "Subscriber",
|
Subscriber = "Subscriber",
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TAttachmentCreatedByRef = `${AttachmentCreatedByRef}`;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the various resource references in which an attachment can exist.
|
* Defines the various resource references in which an attachment can exist.
|
||||||
* These references influence how the attachment is uploaded, stored, and accessed:
|
* These references influence how the attachment is uploaded, stored, and accessed:
|
||||||
@ -37,7 +35,10 @@ export enum AttachmentResourceRef {
|
|||||||
MessageAttachment = "Message", // Files sent or received via messages, uploaded programmatically, accessible to users with inbox permissions.;
|
MessageAttachment = "Message", // Files sent or received via messages, uploaded programmatically, accessible to users with inbox permissions.;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TAttachmentResourceRef = `${AttachmentResourceRef}`;
|
export enum AttachmentAccess {
|
||||||
|
Public = "public",
|
||||||
|
Private = "private",
|
||||||
|
}
|
||||||
|
|
||||||
export interface IAttachmentAttributes {
|
export interface IAttachmentAttributes {
|
||||||
name: string;
|
name: string;
|
||||||
@ -46,8 +47,9 @@ export interface IAttachmentAttributes {
|
|||||||
location: string;
|
location: string;
|
||||||
url: string;
|
url: string;
|
||||||
channel?: Record<string, any>;
|
channel?: Record<string, any>;
|
||||||
resourceRef: TAttachmentResourceRef;
|
resourceRef: AttachmentResourceRef;
|
||||||
createdByRef: TAttachmentCreatedByRef;
|
access: AttachmentAccess;
|
||||||
|
createdByRef: AttachmentCreatedByRef;
|
||||||
createdBy: string | null;
|
createdBy: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user