mirror of
https://github.com/hexastack/hexabot
synced 2025-06-26 18:27:28 +00:00
feat: rename enum instead of string
This commit is contained in:
@@ -39,6 +39,7 @@ import { attachment, attachmentFile } from '../mocks/attachment.mock';
|
||||
import { AttachmentRepository } from '../repositories/attachment.repository';
|
||||
import { Attachment, AttachmentModel } from '../schemas/attachment.schema';
|
||||
import { AttachmentService } from '../services/attachment.service';
|
||||
import { AttachmentResourceRef } from '../types';
|
||||
|
||||
import { AttachmentController } from './attachment.controller';
|
||||
|
||||
@@ -110,7 +111,7 @@ describe('AttachmentController', () => {
|
||||
file: [],
|
||||
},
|
||||
{} as Request,
|
||||
{ resourceRef: 'block_attachment' },
|
||||
{ resourceRef: AttachmentResourceRef.BlockAttachment },
|
||||
);
|
||||
await expect(promiseResult).rejects.toThrow(
|
||||
new BadRequestException('No file was selected'),
|
||||
@@ -128,7 +129,7 @@ describe('AttachmentController', () => {
|
||||
{
|
||||
session: { passport: { user: { id: '9'.repeat(24) } } },
|
||||
} as unknown as Request,
|
||||
{ resourceRef: 'block_attachment' },
|
||||
{ resourceRef: AttachmentResourceRef.BlockAttachment },
|
||||
);
|
||||
const [name] = attachmentFile.filename.split('.');
|
||||
expect(attachmentService.create).toHaveBeenCalledWith({
|
||||
@@ -136,7 +137,7 @@ describe('AttachmentController', () => {
|
||||
type: attachmentFile.mimetype,
|
||||
name: attachmentFile.originalname,
|
||||
location: expect.stringMatching(new RegExp(`^/${name}`)),
|
||||
resourceRef: 'block_attachment',
|
||||
resourceRef: AttachmentResourceRef.BlockAttachment,
|
||||
access: 'public',
|
||||
createdByRef: 'User',
|
||||
createdBy: '9'.repeat(24),
|
||||
@@ -145,7 +146,7 @@ describe('AttachmentController', () => {
|
||||
[
|
||||
{
|
||||
...attachment,
|
||||
resourceRef: 'block_attachment',
|
||||
resourceRef: AttachmentResourceRef.BlockAttachment,
|
||||
createdByRef: 'User',
|
||||
createdBy: '9'.repeat(24),
|
||||
},
|
||||
|
||||
@@ -18,6 +18,7 @@ import { Action } from '@/user/types/action.type';
|
||||
import { attachment } from '../mocks/attachment.mock';
|
||||
import { Attachment } from '../schemas/attachment.schema';
|
||||
import { AttachmentService } from '../services/attachment.service';
|
||||
import { AttachmentResourceRef } from '../types';
|
||||
|
||||
import { AttachmentGuard } from './attachment-ability.guard';
|
||||
|
||||
@@ -55,7 +56,7 @@ describe('AttachmentGuard', () => {
|
||||
describe('canActivate', () => {
|
||||
it('should allow GET requests with valid ref', async () => {
|
||||
const mockUser = { roles: ['admin-id'] } as any;
|
||||
const mockRef = ['user_avatar'];
|
||||
const mockRef = [AttachmentResourceRef.UserAvatar];
|
||||
|
||||
jest.spyOn(modelService, 'findOne').mockImplementation((criteria) => {
|
||||
return typeof criteria === 'string' ||
|
||||
@@ -120,7 +121,7 @@ describe('AttachmentGuard', () => {
|
||||
? Promise.reject('Invalid ID')
|
||||
: Promise.resolve({
|
||||
id: '9'.repeat(24),
|
||||
resourceRef: `user_avatar`,
|
||||
resourceRef: AttachmentResourceRef.UserAvatar,
|
||||
} as Attachment);
|
||||
});
|
||||
|
||||
@@ -191,7 +192,7 @@ describe('AttachmentGuard', () => {
|
||||
const mockExecutionContext = {
|
||||
switchToHttp: jest.fn().mockReturnValue({
|
||||
getRequest: jest.fn().mockReturnValue({
|
||||
query: { resourceRef: 'block_attachment' },
|
||||
query: { resourceRef: AttachmentResourceRef.BlockAttachment },
|
||||
method: 'POST',
|
||||
user: mockUser,
|
||||
}),
|
||||
|
||||
@@ -26,7 +26,7 @@ import { Action } from '@/user/types/action.type';
|
||||
import { TModel } from '@/user/types/model.type';
|
||||
|
||||
import { AttachmentService } from '../services/attachment.service';
|
||||
import { TAttachmentResourceRef } from '../types';
|
||||
import { AttachmentResourceRef, TAttachmentResourceRef } from '../types';
|
||||
import {
|
||||
isAttachmentResourceRef,
|
||||
isAttachmentResourceRefArray,
|
||||
@@ -46,46 +46,46 @@ export class AttachmentGuard implements CanActivate {
|
||||
> = {
|
||||
// Read attachments by ref
|
||||
[Action.READ]: {
|
||||
setting_attachment: [
|
||||
[AttachmentResourceRef.SettingAttachment]: [
|
||||
['setting', Action.READ],
|
||||
['attachment', Action.READ],
|
||||
],
|
||||
user_avatar: [['user', Action.READ]],
|
||||
block_attachment: [
|
||||
[AttachmentResourceRef.UserAvatar]: [['user', Action.READ]],
|
||||
[AttachmentResourceRef.BlockAttachment]: [
|
||||
['block', Action.READ],
|
||||
['attachment', Action.READ],
|
||||
],
|
||||
content_attachment: [
|
||||
[AttachmentResourceRef.ContentAttachment]: [
|
||||
['content', Action.READ],
|
||||
['attachment', Action.READ],
|
||||
],
|
||||
subscriber_avatar: [['subscriber', Action.READ]],
|
||||
message_attachment: [
|
||||
[AttachmentResourceRef.SubscriberAvatar]: [['subscriber', Action.READ]],
|
||||
[AttachmentResourceRef.MessageAttachment]: [
|
||||
['message', Action.READ],
|
||||
['attachment', Action.READ],
|
||||
],
|
||||
},
|
||||
// Create attachments by ref
|
||||
[Action.CREATE]: {
|
||||
setting_attachment: [
|
||||
[AttachmentResourceRef.SettingAttachment]: [
|
||||
['setting', Action.UPDATE],
|
||||
['attachment', Action.CREATE],
|
||||
],
|
||||
user_avatar: [
|
||||
[AttachmentResourceRef.UserAvatar]: [
|
||||
// Not authorized, done via /user/:id/edit endpoint
|
||||
],
|
||||
block_attachment: [
|
||||
[AttachmentResourceRef.BlockAttachment]: [
|
||||
['block', Action.UPDATE],
|
||||
['attachment', Action.CREATE],
|
||||
],
|
||||
content_attachment: [
|
||||
[AttachmentResourceRef.ContentAttachment]: [
|
||||
['content', Action.UPDATE],
|
||||
['attachment', Action.CREATE],
|
||||
],
|
||||
subscriber_avatar: [
|
||||
[AttachmentResourceRef.SubscriberAvatar]: [
|
||||
// Not authorized, done programmatically by the channel
|
||||
],
|
||||
message_attachment: [
|
||||
[AttachmentResourceRef.MessageAttachment]: [
|
||||
// Unless we're in case of a handover, done programmatically by the channel
|
||||
['message', Action.CREATE],
|
||||
['attachment', Action.CREATE],
|
||||
@@ -93,36 +93,36 @@ export class AttachmentGuard implements CanActivate {
|
||||
},
|
||||
// Delete attachments by ref
|
||||
[Action.DELETE]: {
|
||||
setting_attachment: [
|
||||
[AttachmentResourceRef.SettingAttachment]: [
|
||||
['setting', Action.UPDATE],
|
||||
['attachment', Action.DELETE],
|
||||
],
|
||||
user_avatar: [
|
||||
[AttachmentResourceRef.UserAvatar]: [
|
||||
// Not authorized
|
||||
],
|
||||
block_attachment: [
|
||||
[AttachmentResourceRef.BlockAttachment]: [
|
||||
['block', Action.UPDATE],
|
||||
['attachment', Action.DELETE],
|
||||
],
|
||||
content_attachment: [
|
||||
[AttachmentResourceRef.ContentAttachment]: [
|
||||
['content', Action.UPDATE],
|
||||
['attachment', Action.DELETE],
|
||||
],
|
||||
subscriber_avatar: [
|
||||
[AttachmentResourceRef.SubscriberAvatar]: [
|
||||
// Not authorized, done programmatically by the channel
|
||||
],
|
||||
message_attachment: [
|
||||
[AttachmentResourceRef.MessageAttachment]: [
|
||||
// Not authorized
|
||||
],
|
||||
},
|
||||
// Update attachments is not possible
|
||||
[Action.UPDATE]: {
|
||||
setting_attachment: [],
|
||||
user_avatar: [],
|
||||
block_attachment: [],
|
||||
content_attachment: [],
|
||||
subscriber_avatar: [],
|
||||
message_attachment: [],
|
||||
[AttachmentResourceRef.SettingAttachment]: [],
|
||||
[AttachmentResourceRef.UserAvatar]: [],
|
||||
[AttachmentResourceRef.BlockAttachment]: [],
|
||||
[AttachmentResourceRef.ContentAttachment]: [],
|
||||
[AttachmentResourceRef.SubscriberAvatar]: [],
|
||||
[AttachmentResourceRef.MessageAttachment]: [],
|
||||
},
|
||||
};
|
||||
|
||||
@@ -163,7 +163,7 @@ export class AttachmentGuard implements CanActivate {
|
||||
*
|
||||
* @param action - The action on the attachment.
|
||||
* @param user - The current user.
|
||||
* @param resourceRef - The resource ref of the attachment (e.g., user_avatar, setting_attachment).
|
||||
* @param resourceRef - The resource ref of the attachment (e.g., [AttachmentResourceRef.UserAvatar], [AttachmentResourceRef.SettingAttachment]).
|
||||
* @returns A promise that resolves to `true` if the user has the required upload permission, otherwise `false`.
|
||||
*/
|
||||
private async isAuthorized(
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
import { Stream } from 'node:stream';
|
||||
|
||||
import { Attachment } from '../schemas/attachment.schema';
|
||||
import { AttachmentResourceRef } from '../types';
|
||||
|
||||
export const attachment: Attachment = {
|
||||
name: 'Screenshot from 2022-03-11 08-41-27-2a9799a8b6109c88fd9a7a690c1101934c.png',
|
||||
@@ -16,7 +17,7 @@ export const attachment: Attachment = {
|
||||
size: 343370,
|
||||
location:
|
||||
'/Screenshot from 2022-03-11 08-41-27-2a9799a8b6109c88fd9a7a690c1101934c.png',
|
||||
resourceRef: 'block_attachment',
|
||||
resourceRef: AttachmentResourceRef.BlockAttachment,
|
||||
access: 'public',
|
||||
id: '65940d115178607da65c82b6',
|
||||
createdAt: new Date(),
|
||||
@@ -47,7 +48,7 @@ export const attachments: Attachment[] = [
|
||||
location:
|
||||
'/app/src/attachment/uploads/Screenshot from 2022-03-11 08-41-27-2a9799a8b6109c88fd9a7a690c1101934c.png',
|
||||
channel: { ['some-channel']: {} },
|
||||
resourceRef: 'block_attachment',
|
||||
resourceRef: AttachmentResourceRef.BlockAttachment,
|
||||
access: 'public',
|
||||
id: '65940d115178607da65c82b7',
|
||||
createdAt: new Date(),
|
||||
@@ -62,7 +63,7 @@ export const attachments: Attachment[] = [
|
||||
location:
|
||||
'/app/src/attachment/uploads/Screenshot from 2022-03-18 08-58-15-af61e7f71281f9fd3f1ad7ad10107741c.png',
|
||||
channel: { ['some-channel']: {} },
|
||||
resourceRef: 'block_attachment',
|
||||
resourceRef: AttachmentResourceRef.BlockAttachment,
|
||||
access: 'public',
|
||||
id: '65940d115178607da65c82b8',
|
||||
createdAt: new Date(),
|
||||
|
||||
@@ -30,7 +30,7 @@ import { BaseService } from '@/utils/generics/base-service';
|
||||
import { AttachmentMetadataDto } from '../dto/attachment.dto';
|
||||
import { AttachmentRepository } from '../repositories/attachment.repository';
|
||||
import { Attachment } from '../schemas/attachment.schema';
|
||||
import { TAttachmentResourceRef } from '../types';
|
||||
import { AttachmentResourceRef, TAttachmentResourceRef } from '../types';
|
||||
import {
|
||||
fileExists,
|
||||
generateUniqueFilename,
|
||||
@@ -164,7 +164,8 @@ export class AttachmentService extends BaseService<Attachment> {
|
||||
* @returns The root directory path
|
||||
*/
|
||||
getRootDirByResourceRef(ref: TAttachmentResourceRef) {
|
||||
return ref === 'subscriber_avatar' || ref === 'user_avatar'
|
||||
return ref === AttachmentResourceRef.SubscriberAvatar ||
|
||||
ref === AttachmentResourceRef.UserAvatar
|
||||
? config.parameters.avatarDir
|
||||
: config.parameters.uploadDir;
|
||||
}
|
||||
|
||||
@@ -24,12 +24,12 @@ export type TAttachmentCreatedByRef = `${AttachmentCreatedByRef}`;
|
||||
* These resource references influence how the attachment is uploaded, stored, and accessed:
|
||||
*/
|
||||
export enum AttachmentResourceRef {
|
||||
SettingAttachment = 'setting_attachment', // Attachments related to app settings, restricted to users with specific permissions.
|
||||
UserAvatar = 'user_avatar', // Avatar files for users, only the current user can upload, accessible to those with appropriate permissions.
|
||||
SubscriberAvatar = 'subscriber_avatar', // Avatar files for subscribers, uploaded programmatically, accessible to authorized users.
|
||||
BlockAttachment = 'block_attachment', // Files sent by the bot, public or private based on the channel and user authentication.
|
||||
ContentAttachment = 'content_attachment', // Files in the knowledge base, usually public but could vary based on specific needs.
|
||||
MessageAttachment = 'message_attachment', // Files sent or received via messages, uploaded programmatically, accessible to users with inbox permissions.;
|
||||
SettingAttachment = 'Setting', // Attachments related to app settings, restricted to users with specific permissions.
|
||||
UserAvatar = 'User', // Avatar files for users, only the current user can upload, accessible to those with appropriate permissions.
|
||||
SubscriberAvatar = 'Subscriber', // Avatar files for subscribers, uploaded programmatically, accessible to authorized users.
|
||||
BlockAttachment = 'Block', // Files sent by the bot, public or private based on the channel and user authentication.
|
||||
ContentAttachment = 'Content', // Files in the knowledge base, usually public but could vary based on specific needs.
|
||||
MessageAttachment = 'Message', // Files sent or received via messages, uploaded programmatically, accessible to users with inbox permissions.;
|
||||
}
|
||||
|
||||
export type TAttachmentResourceRef = `${AttachmentResourceRef}`;
|
||||
|
||||
Reference in New Issue
Block a user