Fix DataCloneError when credentialRequestOptions is relayed by password-manager extensions - #1042
Open
Be-Mann wants to merge 1 commit into
Open
Fix DataCloneError when credentialRequestOptions is relayed by password-manager extensions#1042Be-Mann wants to merge 1 commit into
Be-Mann wants to merge 1 commit into
Conversation
…rd-manager extensions Fixes nextcloud#995 `credentialRequestOptions` comes from the Pinia store, so nested values (e.g. `allowCredentials[i].transports`) are still Vue-reactive `Proxy` objects when passed to `startAuthentication()`. The native `navigator.credentials.get()` handles that fine via WebIDL conversion, but password-manager extensions that intercept the call and relay it via `window.postMessage()` (structured clone) choke on the Proxies with `DataCloneError: ... could not be cloned.` — confirmed with both Bitwarden and Enpass. This unwraps the options into a plain, serializable object before handing them to `startAuthentication()`. `JSON.parse(JSON.stringify(...))` is used instead of `structuredClone()` because `structuredClone()` fails on reactive Proxies for the same reason. The options are pure JSON (base64url strings), so the round-trip is lossless. Root cause analysis and manual verification by @tschuegy and @Rumbelstilzchen in nextcloud#995. Signed-off-by: Be-Mann <25839760+Be-Mann@users.noreply.github.com>
Contributor
|
Thanks a lot, good finding 👍 I think it should also work, and if I would prefer that version, to flag the object as not reactive. Could you please give the following patch a test? Index: src/components/Challenge.vue
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/components/Challenge.vue b/src/components/Challenge.vue
--- a/src/components/Challenge.vue (revision 1ef69d077f361d17126dec3c295d86107e1fff1f)
+++ b/src/components/Challenge.vue (date 1787519209471)
@@ -94,7 +94,7 @@
let authResponse
try {
authResponse = await startAuthentication({
- optionsJSON: JSON.parse(JSON.stringify(this.credentialRequestOptions)),
+ optionsJSON: this.credentialRequestOptions,
})
} catch (error) {
switch (error.name) {
Index: src/main-challenge.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/main-challenge.js b/src/main-challenge.js
--- a/src/main-challenge.js (revision 1ef69d077f361d17126dec3c295d86107e1fff1f)
+++ b/src/main-challenge.js (date 1787519368239)
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
-import { createApp } from 'vue'
+import { createApp, markRaw } from 'vue'
import { createPinia } from 'pinia'
import Nextcloud from './mixins/Nextcloud.js'
import Challenge from './components/Challenge.vue'
@@ -14,9 +14,7 @@
const credentialRequestOptions = loadState('twofactor_webauthn', 'credential-request-options')
const mainStore = useMainStore(pinia)
-mainStore.$patch({
- credentialRequestOptions,
-})
+mainStore.credentialRequestOptions = markRaw(credentialRequestOptions)
const app = createApp(Challenge)
app.mixin(Nextcloud) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #995
credentialRequestOptionscomes from the Pinia store, so nested values (e.g.allowCredentials[i].transports) are still Vue-reactiveProxyobjects when passed tostartAuthentication(). The nativenavigator.credentials.get()handles that fine via WebIDL conversion, but password-manager extensions that intercept the call and relay it viawindow.postMessage()(structured clone) choke on the Proxies withDataCloneError: ... could not be cloned.— confirmed with both Bitwarden and Enpass.This unwraps the options into a plain, serializable object before handing them to
startAuthentication().JSON.parse(JSON.stringify(...))is used instead ofstructuredClone()becausestructuredClone()fails on reactive Proxies for the same reason. The options are pure JSON (base64url strings), so the round-trip is lossless.Root cause analysis and manual verification by @tschuegy and @Rumbelstilzchen in #995.
🤖 AI (if applicable)