diff --git a/package.json b/package.json index d1355e8..0b83cd8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@chatwoot/utils", - "version": "0.0.52", + "version": "0.0.55", "description": "Chatwoot utils", "private": false, "license": "MIT", diff --git a/src/fileUploadRules.ts b/src/fileUploadRules.ts index 5d887cf..7f18317 100644 --- a/src/fileUploadRules.ts +++ b/src/fileUploadRules.ts @@ -88,31 +88,36 @@ type ChannelConfigs = Partial> & { * 2. channel + "*" fallback * 3. global default */ + +const STANDARD_TEXT_MIMES = ['csv', 'plain', 'rtf', 'xml']; +const STANDARD_APPLICATION_MIMES = [ + 'json', + 'pdf', + 'xml', + 'zip', + 'x-7z-compressed', + 'vnd.rar', + 'x-tar', + 'msword', + 'vnd.ms-excel', + 'vnd.ms-powerpoint', + 'vnd.oasis.opendocument.text', + 'vnd.openxmlformats-officedocument.presentationml.presentation', + 'vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'vnd.openxmlformats-officedocument.wordprocessingml.document', +]; +const STANDARD_EXTENSIONS = ['.3gpp', '.xls', '.xlsx']; + const CHANNEL_CONFIGS: ChannelConfigs = { default: { mimeGroups: { image: ['*'], audio: ['*'], video: ['*'], - text: ['csv', 'plain', 'rtf', 'xml'], - application: [ - 'json', - 'pdf', - 'xml', - 'zip', - 'x-7z-compressed', - 'vnd.rar', - 'x-tar', - 'msword', - 'vnd.ms-excel', - 'vnd.ms-powerpoint', - 'vnd.oasis.opendocument.text', - 'vnd.openxmlformats-officedocument.presentationml.presentation', - 'vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'vnd.openxmlformats-officedocument.wordprocessingml.document', - ], + text: STANDARD_TEXT_MIMES, + application: [...STANDARD_APPLICATION_MIMES, 'x-pkcs12', 'pkcs12'], }, - extensions: ['.3gpp'], + extensions: [...STANDARD_EXTENSIONS, '.pfx'], max: 40, }, @@ -133,6 +138,7 @@ const CHANNEL_CONFIGS: ChannelConfigs = { 'vnd.openxmlformats-officedocument.presentationml.presentation', ], }, + extensions: ['.xls', '.xlsx'], maxByCategory: { image: 5, video: 16, audio: 16, document: 100 }, }, }, @@ -165,6 +171,7 @@ const CHANNEL_CONFIGS: ChannelConfigs = { 'vnd.openxmlformats-officedocument.presentationml.presentation', ], }, + extensions: ['.xls', '.xlsx'], maxByCategory: { image: 8, audio: 25, video: 25, document: 25 }, }, }, @@ -189,7 +196,17 @@ const CHANNEL_CONFIGS: ChannelConfigs = { }, [INBOX_TYPES.TWILIO]: { - sms: { max: 5 }, + sms: { + mimeGroups: { + image: ['jpeg', 'png'], + audio: ['*'], + video: ['*'], + text: STANDARD_TEXT_MIMES, + application: STANDARD_APPLICATION_MIMES, + }, + extensions: STANDARD_EXTENSIONS, + max: 5, + }, whatsapp: { mimeGroups: { image: ['png', 'jpeg'], diff --git a/test/fileUploadRules.test.ts b/test/fileUploadRules.test.ts index 8a0b8af..4d2a0ea 100644 --- a/test/fileUploadRules.test.ts +++ b/test/fileUploadRules.test.ts @@ -1,7 +1,7 @@ import { - INBOX_TYPES, getAllowedFileTypesByChannel, getMaxUploadSizeByChannel, + INBOX_TYPES, } from '../src/fileUploadRules'; describe('uploadRules helper', () => { @@ -15,6 +15,9 @@ describe('uploadRules helper', () => { expect(accept).toContain('text/plain'); expect(accept).toContain('application/json'); expect(accept).toContain('.3gpp'); + expect(accept).toContain('application/x-pkcs12'); + expect(accept).toContain('application/pkcs12'); + expect(accept).toContain('.pfx'); }); it('returns WhatsApp specific accept list', () => { @@ -33,6 +36,8 @@ describe('uploadRules helper', () => { expect(accept).not.toContain('application/json'); expect(accept).not.toContain('.3gpp'); expect(accept).not.toContain('image/gif'); + expect(accept).not.toContain('application/x-pkcs12'); + expect(accept).not.toContain('.pfx'); }); it('returns Instagram specific accept list', () => { @@ -73,13 +78,25 @@ describe('uploadRules helper', () => { expect(accept).not.toContain('audio/mp3'); }); - it('falls back to default accept list for Twilio SMS (no mimeGroups)', () => { + it('returns Twilio SMS accept list (default-aligned, excluding PFX)', () => { const accept = getAllowedFileTypesByChannel({ channelType: INBOX_TYPES.TWILIO, medium: 'sms', }); - expect(accept).toContain('image/*'); + expect(accept).toContain('image/jpeg'); + expect(accept).toContain('image/png'); + expect(accept).not.toContain('image/*'); + expect(accept).not.toContain('image/gif'); + expect(accept).toContain('audio/*'); + expect(accept).toContain('video/*'); + expect(accept).toContain('text/plain'); + expect(accept).toContain('application/pdf'); + expect(accept).toContain('application/json'); expect(accept).toContain('.3gpp'); + expect(accept).toContain('.xls'); + expect(accept).not.toContain('application/x-pkcs12'); + expect(accept).not.toContain('application/pkcs12'); + expect(accept).not.toContain('.pfx'); }); it('handles empty object parameter', () => {