tauri-apps / tauri

Build smaller, faster, and more secure desktop applications with a web frontend.
https://tauri.app
Apache License 2.0
81.61k stars 2.44k forks source link

[bug] TypeError: Cannot assign to read only property '__TAURI_IPC__' of object 'window' #10347

Open muwoo opened 1 month ago

muwoo commented 1 month ago

Describe the bug

The steps to trigger this error are as follows:

  1. There are multiple local iframe subpages embedded in my main page
  2. My iframe subpage also needs to access the tauri api
  3. However, Tauri does not actively inject some global variables into each sub-iframe, such as __TAURI_IPC__
  4. Therefore, I will manually rewrite window.__TAURI_IPC__ in the sub-iframe to point to the parent window:
    // child iframe
    window.__TAURI_IPC__ = (args) => {
    // Handle callback callback
    window.parent[`_${args.callback}`] = window[`_${args.callback}`];
    window.parent[`_${args.error}`] = window[`_${args.error}`];
    // Handle listeners listener callback
    const handler = args?.message?.handler || args?.handle;
    if (handler) {
    window.parent[`_${handler}`] = window[`_${handler}`];
    }
    window.parent.__TAURI_IPC__(args);
    };

    However, this code runs normally on macos, but an error will be reported on windows:

    TypeError: Cannot assign to read only property '__TAURI_IPC__' of object 'window'

    So, can we allow the modification of the __TAURI_IPC__ variable in the source code?

Source code location: https://github.com/tauri-apps/tauri/blob/1.x/core/tauri/scripts/ipc.js#L93

Change to this:

Object.defineProperty(window, '__TAURI_IPC__', {
  // todo: JSDoc this function
  value: Object.freeze( (message) => {
    // ...
  }),
  writable: true,
})

If possible, I will submit a PR to fix this issue, looking forward to your reply

Reproduction

No response

Expected behavior

No response

Full tauri info output

[✔] Environment                 
    - OS: Windows 10.0.19045 X64
    ✔ WebView2: 126.0.2592.113  
    ✔ MSVC: Visual Studio ���ɹ��� 2022
    ✔ rustc: 1.76.0 (07dca489a 2024-02-04)
    ✔ cargo: 1.76.0 (c84b36747 2024-01-18)
    ✔ rustup: 1.27.1 (54dd3d00f 2024-04-24)
    ✔ Rust toolchain: stable-x86_64-pc-windows-msvc (default)
    - node: 20.11.1
    - pnpm: 7.33.7
    - yarn: 1.22.22
    - npm: 10.2.4

[-] Packages
    - tauri [RUST]: 1.6.8
    - tauri-build [RUST]: 1.5.2
    - wry [RUST]: 0.24.10
    - tao [RUST]: 0.16.9
    - @tauri-apps/api [NPM]: 1.5.6
    - @tauri-apps/cli [NPM]: 1.5.14

[-] App
    - build-type: bundle
    - CSP: unset
    - distDir: ../dist
    - devPath: http://localhost:1420/
    - framework: Vue.js
    - bundler: Vite

Stack trace

No response

Additional context

No response

FabianLars commented 1 month ago

I highly doubt the security team would be okay with writable: true, but i guess i could extend https://github.com/tauri-apps/tauri/pull/10300 into the other injected scripts (if that PR is actually ok to be merged). Then it should match macos/linux.

muwoo commented 1 month ago

@FabianLars Thank you for your feedback. Your idea is right. If the tauri api cannot be used in the iframe, it should not be injected.

But in addition to window.__TAURI_API__, there are two other places that need to be adjusted:

https://github.com/tauri-apps/tauri/blob/1.x/core/tauri/scripts/core.js#L11

https://github.com/tauri-apps/tauri/blob/1.x/core/tauri/src/manager.rs#L470

FabianLars commented 1 month ago

But in addition to window.__TAURI_API__, there are two other places that need to be adjusted:

Exactly, that's what i meant with extending the PR :)