Skip to content

Commit 154e1d3

Browse files
iamsivinaakashb95
authored andcommitted
chore: support PFX filetype in attachment uploads (chatwoot#14456)
# Pull Request Template ## Description This PR expands the default upload rules to support PFX certificate files (`application/x-pkcs12`, `application/pkcs12`, `.pfx`) across private notes, Website, Email, and Telegram channels. Also adds `.xls` / `.xlsx` extension fallbacks for cases where browsers upload Excel files with an empty or generic MIME type. ### Utils Repo PR: chatwoot/utils#61 Fixes https://linear.app/chatwoot/issue/CW-7085/support-more-file-types-in-private-notes-and-in-app ## Type of change - [x] New feature (non-breaking change which adds functionality) ## How Has This Been Tested? ### Screenshots <img width="330" height="218" alt="image" src="https://github.com/user-attachments/assets/80823250-893e-4509-adb9-61f845359151" /> ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --------- Co-authored-by: aakashb95 <aakashbakhle@gmail.com>
1 parent 58d0644 commit 154e1d3

7 files changed

Lines changed: 42 additions & 20 deletions

File tree

app/javascript/dashboard/components-next/icon/FileIcon.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const fileTypeIcon = computed(() => {
1818
json: 'i-woot-file-txt',
1919
odt: 'i-woot-file-doc',
2020
pdf: 'i-woot-file-pdf',
21+
pfx: 'i-woot-file-pfx',
2122
ppt: 'i-woot-file-ppt',
2223
pptx: 'i-woot-file-ppt',
2324
rar: 'i-woot-file-zip',

app/javascript/dashboard/components/widgets/WootWriter/ReplyBottomPanel.vue

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import * as ActiveStorage from 'activestorage';
77
import inboxMixin from 'shared/mixins/inboxMixin';
88
import { FEATURE_FLAGS } from 'dashboard/featureFlags';
99
import { getAllowedFileTypesByChannel } from '@chatwoot/utils';
10-
import { ALLOWED_FILE_TYPES } from 'shared/constants/messages';
1110
import VideoCallButton from '../VideoCallButton.vue';
1211
import { INBOX_TYPES } from 'dashboard/helper/inbox';
1312
import { mapGetters } from 'vuex';
@@ -166,11 +165,6 @@ export default {
166165
uploadRef,
167166
};
168167
},
169-
data() {
170-
return {
171-
ALLOWED_FILE_TYPES,
172-
};
173-
},
174168
computed: {
175169
...mapGetters({
176170
accountId: 'getCurrentAccountId',
@@ -212,13 +206,11 @@ export default {
212206
return this.conversationType === 'instagram_direct_message';
213207
},
214208
allowedFileTypes() {
215-
// Use default file types for private notes
216209
if (this.isOnPrivateNote) {
217-
return this.ALLOWED_FILE_TYPES;
210+
return getAllowedFileTypesByChannel();
218211
}
219212
220213
let channelType = this.channelType || this.inbox?.channel_type;
221-
222214
if (this.isAnInstagramChannel || this.isInstagramDM) {
223215
channelType = INBOX_TYPES.INSTAGRAM;
224216
}

app/javascript/shared/helpers/FileHelper.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { getAllowedFileTypesByChannel } from '@chatwoot/utils';
22
import { INBOX_TYPES } from 'dashboard/helper/inbox';
3-
import { ALLOWED_FILE_TYPES } from 'shared/constants/messages';
43

54
export const DEFAULT_MAXIMUM_FILE_UPLOAD_SIZE = 40;
65

@@ -58,9 +57,8 @@ export const isFileTypeAllowedForChannel = (file, options = {}) => {
5857
isOnPrivateNote,
5958
} = options;
6059

61-
// Use broader file types for private notes (matches file picker behavior)
6260
const allowedFileTypes = isOnPrivateNote
63-
? ALLOWED_FILE_TYPES
61+
? getAllowedFileTypesByChannel()
6462
: getAllowedFileTypesByChannel({
6563
channelType:
6664
isInstagramChannel || conversationType === 'instagram_direct_message'

app/models/attachment.rb

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ class Attachment < ApplicationRecord
3333
application/vnd.openxmlformats-officedocument.presentationml.presentation
3434
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
3535
application/vnd.openxmlformats-officedocument.wordprocessingml.document
36+
application/x-pkcs12 application/pkcs12
3637
].freeze
38+
ACCEPTABLE_FILE_EXTENSIONS = %w[pfx].freeze
39+
GENERIC_FILE_CONTENT_TYPES = %w[application/octet-stream].freeze
3740
belongs_to :account
3841
belongs_to :message
3942
has_one_attached :file
@@ -195,7 +198,10 @@ def acceptable_file
195198
end
196199

197200
def validate_file_content_type(file_content_type)
198-
errors.add(:file, 'type not supported') unless media_file?(file_content_type) || ACCEPTABLE_FILE_TYPES.include?(file_content_type)
201+
return if media_file?(file_content_type) || ACCEPTABLE_FILE_TYPES.include?(file_content_type)
202+
return if generic_file_content_type?(file_content_type) && ACCEPTABLE_FILE_EXTENSIONS.include?(file_extension)
203+
204+
errors.add(:file, 'type not supported')
199205
end
200206

201207
def validate_file_size(byte_size)
@@ -206,7 +212,15 @@ def validate_file_size(byte_size)
206212
end
207213

208214
def media_file?(file_content_type)
209-
file_content_type.start_with?('image/', 'video/', 'audio/')
215+
file_content_type.to_s.start_with?('image/', 'video/', 'audio/')
216+
end
217+
218+
def generic_file_content_type?(file_content_type)
219+
file_content_type.blank? || GENERIC_FILE_CONTENT_TYPES.include?(file_content_type)
220+
end
221+
222+
def file_extension
223+
File.extname(file.filename.to_s).delete_prefix('.').downcase
210224
end
211225
end
212226

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
"@breezystack/lamejs": "^1.2.7",
3636
"@chatwoot/ninja-keys": "1.2.3",
3737
"@chatwoot/prosemirror-schema": "1.3.13",
38-
"@chatwoot/utils": "^0.0.52",
38+
"@chatwoot/utils": "^0.0.55",
3939
"@formkit/core": "^1.7.2",
4040
"@formkit/vue": "^1.7.2",
4141
"@hcaptcha/vue3-hcaptcha": "^1.3.0",

pnpm-lock.yaml

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

theme/icons.js

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)