diff --git a/src/components/MediaSettings/AdvancedAudioDialog.vue b/src/components/MediaSettings/AdvancedAudioDialog.vue
index a0581d146d8..aa507e2c511 100644
--- a/src/components/MediaSettings/AdvancedAudioDialog.vue
+++ b/src/components/MediaSettings/AdvancedAudioDialog.vue
@@ -14,6 +14,7 @@ import NcRadioGroupButton from '@nextcloud/vue/components/NcRadioGroupButton'
import { useDevices } from '../../composables/useDevices.js'
import { useSettingsStore } from '../../stores/settings.ts'
import { isSafari } from '../../utils/browserCheck.ts'
+import { isNoiseSuppressionModelSupported } from '../../utils/suppressNoise.ts'
import { localMediaModel } from '../../utils/webrtc/index.js'
const { container = undefined } = defineProps<{
@@ -53,7 +54,7 @@ const settingsStore = useSettingsStore()
const { audioPreviewAvailable, updateAudioStream } = useDevices()
const noiseSuppressionLevel = computed(() => {
- if (settingsStore.noiseSuppressionWithModel === 'none') {
+ if (!isNoiseSuppressionModelSupported || settingsStore.noiseSuppressionWithModel === 'none') {
return settingsStore.noiseSuppression ? NOISE_LEVEL.BASIC : NOISE_LEVEL.OFF
}
return NOISE_LEVEL.ADVANCED
@@ -145,7 +146,7 @@ function onClosing(result?: unknown) {
@update:modelValue="setNoiseSuppressionLevel">
-
+
diff --git a/src/components/NewMessage/NewMessage.vue b/src/components/NewMessage/NewMessage.vue
index 33945770401..fd583f7c4fe 100644
--- a/src/components/NewMessage/NewMessage.vue
+++ b/src/components/NewMessage/NewMessage.vue
@@ -381,6 +381,7 @@ import {
selectRange,
} from '../../utils/selectionRange.ts'
import { parseSpecialSymbols } from '../../utils/textParse.ts'
+import { mediaDevicesManager } from '../../utils/webrtc/index.js'
const supportScheduleMessages = hasTalkFeature('local', 'scheduled-messages')
@@ -670,7 +671,8 @@ export default {
},
showAudioRecorder() {
- return !this.hasText && this.canUploadFiles && !this.broadcast && !this.upload
+ return mediaDevicesManager.isSupported()
+ && !this.hasText && this.canUploadFiles && !this.broadcast && !this.upload
&& !this.messageToEdit && !this.threadCreating
&& !this.scheduleMessageTime && !this.showScheduledMessages
},
diff --git a/src/stores/upload.ts b/src/stores/upload.ts
index 2a8977e1430..51d2c8e1722 100644
--- a/src/stores/upload.ts
+++ b/src/stores/upload.ts
@@ -15,6 +15,7 @@ import { showError } from '@nextcloud/dialogs'
import { t } from '@nextcloud/l10n'
import { getUploader } from '@nextcloud/upload'
import { defineStore } from 'pinia'
+import { v4 as uuidv4 } from 'uuid'
import { reactive, ref } from 'vue'
import { useStore } from 'vuex'
import { useTemporaryMessage } from '../composables/useTemporaryMessage.ts'
@@ -469,7 +470,8 @@ export const useUploadStore = defineStore('upload', () => {
// resolves the final name (and any conflicts) when postAttachment
// moves the file out of Draft.
for (const [index] of getInitialisedUploads(uploadId)) {
- const tempName = crypto.randomUUID()
+ // crypto.randomUUID() is not available in insecure context
+ const tempName = crypto.randomUUID ? crypto.randomUUID() : uuidv4()
markFileAsPendingUpload({ uploadId, index, sharePath: '/' + draftFolderPath + '/' + tempName })
}
return
diff --git a/src/utils/e2ee/encryption.js b/src/utils/e2ee/encryption.js
index da89ea75526..9a8f6a864f6 100644
--- a/src/utils/e2ee/encryption.js
+++ b/src/utils/e2ee/encryption.js
@@ -44,6 +44,10 @@ class Encryption {
throw new Error('stream transform is not supported')
}
+ if (!window.crypto?.subtle) {
+ throw new Error('crypto.subtle is not available in this context')
+ }
+
await initializeOlm()
return true
}
diff --git a/src/utils/suppressNoise.ts b/src/utils/suppressNoise.ts
index 0a4d88322b5..51d7e1d2055 100644
--- a/src/utils/suppressNoise.ts
+++ b/src/utils/suppressNoise.ts
@@ -3,7 +3,10 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
-import { loadRnnoise, RnnoiseWorkletNode } from '@sapphi-red/web-noise-suppressor'
+import type { RnnoiseWorkletNode } from '@sapphi-red/web-noise-suppressor'
+
+// The rnnoise model relies on AudioWorkletNode, which only exists in a secure context
+export const isNoiseSuppressionModelSupported = 'isSecureContext' in window && window.isSecureContext
let audioContext: AudioContext | null = null
let rnnoiseWorklet: RnnoiseWorkletNode | null = null
@@ -31,6 +34,9 @@ export async function registerNoiseSuppressionWorklet(): Promise
}
try {
+ // Lazy load in try-catch block (AudioWorkletNode does not exist in an insecure context)
+ const { loadRnnoise, RnnoiseWorkletNode } = await import('@sapphi-red/web-noise-suppressor')
+
audioContext = new AudioContext()
const rnnoiseWasmBinary = await loadRnnoise({
url: new URL(