fix sharetoken permissions for pixels,links,boards, and failed routes
This commit is contained in:
Generated
-61
@@ -331,8 +331,6 @@ importers:
|
||||
specifier: ^4.1.6
|
||||
version: 4.1.6(@types/node@25.9.0)(jsdom@29.1.1)(msw@2.14.6(@types/node@25.9.0)(typescript@6.0.3))(vite@8.0.11(@types/node@25.9.0)(esbuild@0.28.0)(jiti@2.7.0)(terser@5.46.1)(tsx@4.22.2))
|
||||
|
||||
dist: {}
|
||||
|
||||
packages:
|
||||
|
||||
'@adobe/css-tools@4.4.4':
|
||||
@@ -624,28 +622,24 @@ packages:
|
||||
engines: {node: '>=14.21.3'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@biomejs/cli-linux-arm64@2.4.15':
|
||||
resolution: {integrity: sha512-owaAMZD/T4LrD0ELNCk0Km3qrRHuM0X6EAyVE1FSqGY0rbLoiDLrO4Us2tllm6cAeB2Ioa9C2C08NZPdr8+0Ug==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@biomejs/cli-linux-x64-musl@2.4.15':
|
||||
resolution: {integrity: sha512-CNq/9W38SYSH023lfcQ4KKU8K0YX8T//FZUhcgtMMRABDojx5XsMV7jlweAvGSl389wJQB29Qo6Zb/a+jdvt+w==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@biomejs/cli-linux-x64@2.4.15':
|
||||
resolution: {integrity: sha512-0jj7THz12GbUOLmMibktK6DZjqz2zV64KFxyBtcFTKPiiOIY0a7vns1elpO1dERvxpsZ5ik0oFfz0oGwFde1+g==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@biomejs/cli-win32-arm64@2.4.15':
|
||||
resolution: {integrity: sha512-ouhkYdlhp/1GghEJPdWwD/Vi3gQ1nFxuSpMolWsbq3Lsq3QUR4jl6UdhhscdCugKU5vOEuMiJhvKj66O0OCq+w==}
|
||||
@@ -1626,105 +1620,89 @@ packages:
|
||||
resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.2.4':
|
||||
resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-ppc64@1.2.4':
|
||||
resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-riscv64@1.2.4':
|
||||
resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.2.4':
|
||||
resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.2.4':
|
||||
resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
|
||||
resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
|
||||
resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-linux-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-arm@0.34.5':
|
||||
resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-ppc64@0.34.5':
|
||||
resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-riscv64@0.34.5':
|
||||
resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-s390x@0.34.5':
|
||||
resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-x64@0.34.5':
|
||||
resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.34.5':
|
||||
resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-wasm32@0.34.5':
|
||||
resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
|
||||
@@ -1866,28 +1844,24 @@ packages:
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@next/swc-linux-arm64-musl@16.2.6':
|
||||
resolution: {integrity: sha512-URUTu1+dMkxJsPFgm+OeEvq9wf5sujw0EvgYy80TDGHTSLTnIHeqb0Eu8A3sC95IRgjejQL+kC4mw+4yPxiAXA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@next/swc-linux-x64-gnu@16.2.6':
|
||||
resolution: {integrity: sha512-DOj182mPV8G3UkrayLoREM5YEYI+Dk5wv7Ox9xl1fFibAELEsFD0lDPfHIeILlutMMfdyhlzYPELG3peuKaurw==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@next/swc-linux-x64-musl@16.2.6':
|
||||
resolution: {integrity: sha512-HKQ5SP/V/ub73UvF7n/zeJlxk2kLmtL7Wzrg4WfmkjmNos5onJ2tKu7yZOPdL18A6Svfn3max29ym+ry7NkK4g==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@next/swc-win32-arm64-msvc@16.2.6':
|
||||
resolution: {integrity: sha512-LZXpTlPyS5v7HhSmnvsLGP3iIYgYOBnc8r8ArlT55sGHV89bR2HlDdBjWQ+PY6SJMmk8TuVGFuxalnP3k/0Dwg==}
|
||||
@@ -1960,42 +1934,36 @@ packages:
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@parcel/watcher-linux-arm-musl@2.5.6':
|
||||
resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@parcel/watcher-linux-arm64-glibc@2.5.6':
|
||||
resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@parcel/watcher-linux-arm64-musl@2.5.6':
|
||||
resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@parcel/watcher-linux-x64-glibc@2.5.6':
|
||||
resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@parcel/watcher-linux-x64-musl@2.5.6':
|
||||
resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@parcel/watcher-win32-arm64@2.5.6':
|
||||
resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==}
|
||||
@@ -2310,42 +2278,36 @@ packages:
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-arm64-musl@1.0.0-rc.18':
|
||||
resolution: {integrity: sha512-QWjdxN1HJCpBTAcZ5N5F7wju3gVPzRzSpmGzx7na0c/1qpN9CFil+xt+l9lV/1M6/gqHSNXCiqPfwhVJPeLnug==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.18':
|
||||
resolution: {integrity: sha512-ugCOyj7a4d9h3q9B+wXmf6g3a68UsjGh6dob5DHevHGMwDUbhsYNbSPxJsENcIttJZ9jv7qGM2UesLw5jqIhdg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-s390x-gnu@1.0.0-rc.18':
|
||||
resolution: {integrity: sha512-kKWRhbsotpXkGbcd5dllUWg5gEXcDAa8u5YnP9AV5DYNbvJHGzzuwv7dpmhc8NqKMJldl0a+x76IHbspEpEmdA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-x64-gnu@1.0.0-rc.18':
|
||||
resolution: {integrity: sha512-uCo8ElcCIAMyYAZyuIZ81oFkhTSIllNvUCHCAlbhlN4ji3uC28h7IIdlXyIvGO7HsuqnV9p3rD/bpH7XhIyhRw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-x64-musl@1.0.0-rc.18':
|
||||
resolution: {integrity: sha512-XNOQZtuE6yUIvx4rwGemwh8kpL1xvU41FXy/s9K7T/3JVcqGzo3NfKM2HrbrGgfPYGFW42f07Wk++aOC6B9NWA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rolldown/binding-openharmony-arm64@1.0.0-rc.18':
|
||||
resolution: {integrity: sha512-tSn/kzrfa7tNOXr7sEacDBN4YsIqTyLqh45IO0nHDwtpKIDNDJr+VFojt+4klSpChxB29JLyduSsE0MKEwa65A==}
|
||||
@@ -2492,79 +2454,66 @@ packages:
|
||||
resolution: {integrity: sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.60.4':
|
||||
resolution: {integrity: sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.60.4':
|
||||
resolution: {integrity: sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.60.4':
|
||||
resolution: {integrity: sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-loong64-gnu@4.60.4':
|
||||
resolution: {integrity: sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-loong64-musl@4.60.4':
|
||||
resolution: {integrity: sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.60.4':
|
||||
resolution: {integrity: sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-ppc64-musl@4.60.4':
|
||||
resolution: {integrity: sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.60.4':
|
||||
resolution: {integrity: sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-musl@4.60.4':
|
||||
resolution: {integrity: sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.60.4':
|
||||
resolution: {integrity: sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.60.4':
|
||||
resolution: {integrity: sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.60.4':
|
||||
resolution: {integrity: sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-openbsd-x64@4.60.4':
|
||||
resolution: {integrity: sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==}
|
||||
@@ -2753,42 +2702,36 @@ packages:
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@swc/core-linux-arm64-musl@1.15.33':
|
||||
resolution: {integrity: sha512-il7tYM+CpUNzieQbwAjFT1P8zqAhmGWNAGhQZBnxurXZ0aNn+5nqYFTEUKNZl7QibtT0uQXzTZrNGHCIj6Y1Og==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@swc/core-linux-ppc64-gnu@1.15.33':
|
||||
resolution: {integrity: sha512-ZtNBwN0Z7CFj9Il0FcPaKdjgP7URyKu/3RfH46vq+0paOBqLj4NYldD6Qo//Duif/7IOtAraUfDOmp0PLAufog==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@swc/core-linux-s390x-gnu@1.15.33':
|
||||
resolution: {integrity: sha512-De1IyajoOmhOYYjw/lx66bKlyDpHZTueqwpDrWgf5O7T6d1ODeJJO9/OqMBmrBQc5C+dNnlmIufHsp4QVCWufA==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@swc/core-linux-x64-gnu@1.15.33':
|
||||
resolution: {integrity: sha512-mGTH0YxmUN+x6vRN/I6NOk5X0ogNktkwPnJ94IMvR7QjhRDwL0O8RXEDhyUM0YtwWrryBOqaJQBX4zruxEPRGw==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@swc/core-linux-x64-musl@1.15.33':
|
||||
resolution: {integrity: sha512-hj628ZkSEJf6zMf5VMbYrG2O6QqyTIp2qwY6VlCjvIa9lAEZ5c2lfPblCLVGYubTeLJDxadLB/CxqQYOQABeEQ==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@swc/core-win32-arm64-msvc@1.15.33':
|
||||
resolution: {integrity: sha512-GV2oohtN2/5+KSccl86VULu3aT+LrISC8uzgSq0FRnikpD+Zwc+sBlXmoKQ+Db6jI57ITUOIB8jRkdGMABC29g==}
|
||||
@@ -4327,28 +4270,24 @@ packages:
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-arm64-musl@1.32.0:
|
||||
resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-linux-x64-gnu@1.32.0:
|
||||
resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-x64-musl@1.32.0:
|
||||
resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-win32-arm64-msvc@1.32.0:
|
||||
resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==}
|
||||
|
||||
@@ -3,9 +3,34 @@ import { uuid } from '@/lib/crypto';
|
||||
import { parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { pagingParams, reportSchema, reportTypeParam } from '@/lib/schema';
|
||||
import { canUpdateWebsite, canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import {
|
||||
canUpdateWebsite,
|
||||
canViewAuthenticatedWebsite,
|
||||
canViewWebsiteSection,
|
||||
} from '@/permissions';
|
||||
import type { ShareSection } from '@/permissions';
|
||||
import { createReport, getReports } from '@/queries/prisma';
|
||||
|
||||
function getReportSection(type?: z.infer<typeof reportTypeParam>): ShareSection | null {
|
||||
switch (type) {
|
||||
case 'attribution':
|
||||
case 'breakdown':
|
||||
case 'performance':
|
||||
case 'retention':
|
||||
case 'revenue':
|
||||
case 'utm':
|
||||
return type;
|
||||
case 'funnel':
|
||||
return 'funnels';
|
||||
case 'goal':
|
||||
return 'goals';
|
||||
case 'journey':
|
||||
return 'journeys';
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function GET(request: Request) {
|
||||
const schema = z.object({
|
||||
websiteId: z.uuid(),
|
||||
@@ -26,7 +51,12 @@ export async function GET(request: Request) {
|
||||
search,
|
||||
};
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
const section = getReportSection(type);
|
||||
const canView = section
|
||||
? await canViewWebsiteSection(auth, websiteId, section)
|
||||
: await canViewAuthenticatedWebsite(auth, websiteId);
|
||||
|
||||
if (!canView) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { parseEventPropertyFilters } from '@/lib/params';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { filterParams, timezoneParam, unitParam } from '@/lib/schema';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getEventDataArraySeries } from '@/queries/sql/events/getEventDataArraySeries';
|
||||
|
||||
export async function GET(
|
||||
@@ -28,7 +28,7 @@ export async function GET(
|
||||
|
||||
const { websiteId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'events'))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { parseEventPropertyFilters } from '@/lib/params';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { filterParams, timezoneParam } from '@/lib/schema';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getEventDataDateSeries } from '@/queries/sql/events/getEventDataDateSeries';
|
||||
|
||||
export async function GET(
|
||||
@@ -27,7 +27,7 @@ export async function GET(
|
||||
|
||||
const { websiteId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'events'))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { parseEventPropertyFilters } from '@/lib/params';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { filterParams, timezoneParam, unitParam } from '@/lib/schema';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getEventDataNumericSeries } from '@/queries/sql/events/getEventDataNumericSeries';
|
||||
|
||||
export async function GET(
|
||||
@@ -29,7 +29,7 @@ export async function GET(
|
||||
|
||||
const { websiteId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'events'))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { parseEventPropertyFilters } from '@/lib/params';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { filterParams } from '@/lib/schema';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getEventDataNumericStats } from '@/queries/sql/events/getEventDataNumericStats';
|
||||
|
||||
export async function GET(
|
||||
@@ -26,7 +26,7 @@ export async function GET(
|
||||
|
||||
const { websiteId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'events'))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { parseEventPropertyFilters } from '@/lib/params';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { filterParams, timezoneParam, unitParam } from '@/lib/schema';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getEventDataPropertySeries } from '@/queries/sql/events/getEventDataPropertySeries';
|
||||
|
||||
export async function GET(
|
||||
@@ -28,7 +28,7 @@ export async function GET(
|
||||
|
||||
const { websiteId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'events'))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { parseEventPropertyFilters } from '@/lib/params';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { filterParams, pagingParams, timezoneParam, unitParam } from '@/lib/schema';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getEventDataPivot } from '@/queries/sql/events/getEventDataPivot';
|
||||
|
||||
export async function GET(
|
||||
@@ -28,7 +28,7 @@ export async function GET(
|
||||
|
||||
const { websiteId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'events'))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getEventDataById } from '@/queries/sql/events/getEventDataById';
|
||||
|
||||
export async function GET(
|
||||
@@ -15,7 +15,7 @@ export async function GET(
|
||||
|
||||
const { websiteId, eventId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'events'))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { z } from 'zod';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { filterParams } from '@/lib/schema';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getEventDataEvents } from '@/queries/sql/events/getEventDataEvents';
|
||||
|
||||
export async function GET(
|
||||
@@ -23,7 +23,7 @@ export async function GET(
|
||||
|
||||
const { websiteId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'events'))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { z } from 'zod';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { filterParams } from '@/lib/schema';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getEventDataFields } from '@/queries/sql';
|
||||
|
||||
export async function GET(
|
||||
@@ -23,7 +23,7 @@ export async function GET(
|
||||
|
||||
const { websiteId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'events'))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { z } from 'zod';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { filterParams } from '@/lib/schema';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getEventDataProperties } from '@/queries/sql';
|
||||
|
||||
export async function GET(
|
||||
@@ -23,7 +23,7 @@ export async function GET(
|
||||
|
||||
const { websiteId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'events'))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { z } from 'zod';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { filterParams, pagingParams } from '@/lib/schema';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getEventData } from '@/queries/sql/events/getEventData';
|
||||
|
||||
export async function GET(
|
||||
@@ -24,7 +24,7 @@ export async function GET(
|
||||
|
||||
const { websiteId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'events'))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { z } from 'zod';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { filterParams } from '@/lib/schema';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getEventDataStats } from '@/queries/sql';
|
||||
|
||||
export async function GET(
|
||||
@@ -23,7 +23,7 @@ export async function GET(
|
||||
|
||||
const { websiteId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'events'))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { z } from 'zod';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { filterParams } from '@/lib/schema';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getEventDataValues } from '@/queries/sql';
|
||||
|
||||
export async function GET(
|
||||
@@ -26,7 +26,7 @@ export async function GET(
|
||||
|
||||
const { websiteId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'events'))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { z } from 'zod';
|
||||
import { parseRequest } from '@/lib/request';
|
||||
import { json, notFound, ok, unauthorized } from '@/lib/response';
|
||||
import { anyObjectParam, segmentTypeParam } from '@/lib/schema';
|
||||
import { canDeleteWebsite, canUpdateWebsite, canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canDeleteWebsite, canUpdateWebsite, canViewSharedWebsiteFilters } from '@/permissions';
|
||||
import { deleteSegment, getWebsiteSegment, updateSegment } from '@/queries/prisma';
|
||||
|
||||
export async function GET(
|
||||
@@ -17,7 +17,7 @@ export async function GET(
|
||||
|
||||
const { websiteId, segmentId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewSharedWebsiteFilters(auth, websiteId))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { uuid } from '@/lib/crypto';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { searchParams, segmentParamSchema, segmentTypeParam } from '@/lib/schema';
|
||||
import { canUpdateWebsite, canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canUpdateWebsite, canViewSharedWebsiteFilters } from '@/permissions';
|
||||
import { createSegment, getWebsiteSegments } from '@/queries/prisma';
|
||||
|
||||
export async function GET(
|
||||
@@ -24,7 +24,7 @@ export async function GET(
|
||||
const { websiteId } = await params;
|
||||
const { type } = query;
|
||||
|
||||
if (websiteId && !(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (websiteId && !(await canViewSharedWebsiteFilters(auth, websiteId))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { parsePropertyFilters } from '@/lib/params';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { filterParams, pagingParams, timezoneParam, unitParam } from '@/lib/schema';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getSessionDataPivot } from '@/queries/sql/sessions/getSessionDataPivot';
|
||||
|
||||
export async function GET(
|
||||
@@ -28,7 +28,7 @@ export async function GET(
|
||||
|
||||
const { websiteId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'sessions'))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { parsePropertyFilters } from '@/lib/params';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { filterParams, timezoneParam, unitParam } from '@/lib/schema';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getSessionDataArraySeries } from '@/queries/sql';
|
||||
|
||||
export async function GET(
|
||||
@@ -27,7 +27,7 @@ export async function GET(
|
||||
|
||||
const { websiteId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'sessions'))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { parsePropertyFilters } from '@/lib/params';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { filterParams, timezoneParam } from '@/lib/schema';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getSessionDataDateSeries } from '@/queries/sql';
|
||||
|
||||
export async function GET(
|
||||
@@ -26,7 +26,7 @@ export async function GET(
|
||||
|
||||
const { websiteId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'sessions'))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { parsePropertyFilters } from '@/lib/params';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { filterParams, timezoneParam, unitParam } from '@/lib/schema';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getSessionDataNumericSeries } from '@/queries/sql';
|
||||
|
||||
export async function GET(
|
||||
@@ -28,7 +28,7 @@ export async function GET(
|
||||
|
||||
const { websiteId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'sessions'))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { parsePropertyFilters } from '@/lib/params';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { filterParams, timezoneParam } from '@/lib/schema';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getSessionDataNumericStats } from '@/queries/sql';
|
||||
|
||||
export async function GET(
|
||||
@@ -26,7 +26,7 @@ export async function GET(
|
||||
|
||||
const { websiteId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'sessions'))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { parsePropertyFilters } from '@/lib/params';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { filterParams } from '@/lib/schema';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getSessionDataProperties } from '@/queries/sql';
|
||||
|
||||
export async function GET(
|
||||
@@ -25,7 +25,7 @@ export async function GET(
|
||||
|
||||
const { websiteId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'sessions'))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { parsePropertyFilters } from '@/lib/params';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { filterParams, timezoneParam, unitParam } from '@/lib/schema';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getSessionDataPropertySeries } from '@/queries/sql';
|
||||
|
||||
export async function GET(
|
||||
@@ -27,7 +27,7 @@ export async function GET(
|
||||
|
||||
const { websiteId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'sessions'))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { parsePropertyFilters } from '@/lib/params';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { filterParams, timezoneParam, unitParam } from '@/lib/schema';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getSessionDataActivityStats } from '@/queries/sql/sessions/getSessionDataActivityStats';
|
||||
|
||||
export async function GET(
|
||||
@@ -27,7 +27,7 @@ export async function GET(
|
||||
|
||||
const { websiteId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'sessions'))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { z } from 'zod';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { filterParams } from '@/lib/schema';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getSessionDataValues } from '@/queries/sql';
|
||||
|
||||
export async function GET(
|
||||
@@ -25,7 +25,7 @@ export async function GET(
|
||||
|
||||
const { websiteId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'sessions'))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { z } from 'zod';
|
||||
import { getQueryFilters, parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getSessionActivity } from '@/queries/sql';
|
||||
|
||||
export async function GET(
|
||||
@@ -21,7 +21,14 @@ export async function GET(
|
||||
|
||||
const { websiteId, sessionId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (
|
||||
!(await canViewWebsiteSection(auth, websiteId, [
|
||||
'sessions',
|
||||
'events',
|
||||
'realtime',
|
||||
'revenue',
|
||||
]))
|
||||
) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getSessionData } from '@/queries/sql';
|
||||
|
||||
export async function GET(
|
||||
@@ -15,7 +15,14 @@ export async function GET(
|
||||
|
||||
const { websiteId, sessionId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (
|
||||
!(await canViewWebsiteSection(auth, websiteId, [
|
||||
'sessions',
|
||||
'events',
|
||||
'realtime',
|
||||
'revenue',
|
||||
]))
|
||||
) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { parseRequest } from '@/lib/request';
|
||||
import { json, unauthorized } from '@/lib/response';
|
||||
import { canViewAuthenticatedWebsite } from '@/permissions';
|
||||
import { canViewWebsiteSection } from '@/permissions';
|
||||
import { getWebsiteSession } from '@/queries/sql';
|
||||
|
||||
export async function GET(
|
||||
@@ -15,7 +15,14 @@ export async function GET(
|
||||
|
||||
const { websiteId, sessionId } = await params;
|
||||
|
||||
if (!(await canViewAuthenticatedWebsite(auth, websiteId))) {
|
||||
if (
|
||||
!(await canViewWebsiteSection(auth, websiteId, [
|
||||
'sessions',
|
||||
'events',
|
||||
'realtime',
|
||||
'revenue',
|
||||
]))
|
||||
) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ export async function GET(
|
||||
|
||||
const { websiteId } = await params;
|
||||
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, 'sessions'))) {
|
||||
if (!(await canViewWebsiteSection(auth, websiteId, ['overview', 'sessions']))) {
|
||||
return unauthorized();
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { createContext, type ReactNode, useEffect } from 'react';
|
||||
import { useShareTokenQuery } from '@/components/hooks';
|
||||
import { ENTITY_TYPE } from '@/lib/constants';
|
||||
import type { ShareParameters, WhiteLabel } from '@/lib/types';
|
||||
import { setShareData, useApp } from '@/store/app';
|
||||
|
||||
export interface ShareData {
|
||||
shareId: string;
|
||||
@@ -22,6 +23,8 @@ export interface ShareData {
|
||||
|
||||
export const ShareContext = createContext<ShareData>(null);
|
||||
|
||||
const selector = (state: { shareToken: { token?: string } | null }) => state.shareToken;
|
||||
|
||||
const ALL_SECTION_IDS = [
|
||||
'overview',
|
||||
'events',
|
||||
@@ -55,8 +58,10 @@ export function ShareProvider({ slug, children }: { slug: string; children: Reac
|
||||
const { share, isLoading, isFetching } = useShareTokenQuery(slug);
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const shareToken = useApp(selector);
|
||||
const path = getSharePath(pathname);
|
||||
const isWebsiteShare = share?.shareType === ENTITY_TYPE.website;
|
||||
const isShareReady = !!share?.token && shareToken?.token === share.token;
|
||||
|
||||
const allowedSections =
|
||||
isWebsiteShare && share?.parameters
|
||||
@@ -75,11 +80,17 @@ export function ShareProvider({ slug, children }: { slug: string; children: Reac
|
||||
}
|
||||
}, [shouldRedirect, slug, allowedSections, router]);
|
||||
|
||||
if (isFetching && isLoading) {
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
setShareData(null, null);
|
||||
};
|
||||
}, [slug]);
|
||||
|
||||
if ((isFetching && isLoading) || (share && !isShareReady)) {
|
||||
return <Loading placement="absolute" />;
|
||||
}
|
||||
|
||||
if (!share || shouldRedirect) {
|
||||
if (!share || !isShareReady || shouldRedirect) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,24 @@
|
||||
import { setShareData } from '@/store/app';
|
||||
import { useEffect } from 'react';
|
||||
import { setShareData, useApp } from '@/store/app';
|
||||
import { useApi } from '../useApi';
|
||||
|
||||
export function useShareTokenQuery(slug: string) {
|
||||
const { get, useQuery } = useApi();
|
||||
const shareId = useApp(state => state.share?.shareId);
|
||||
const shareToken = useApp(state => state.shareToken?.token);
|
||||
const query = useQuery({
|
||||
queryKey: ['share', slug],
|
||||
queryFn: async () => {
|
||||
const data = await get(`/share/${slug}`);
|
||||
|
||||
setShareData(data, { token: data?.token });
|
||||
|
||||
return data;
|
||||
},
|
||||
queryFn: async () => get(`/share/${slug}`),
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
query.data?.token &&
|
||||
(shareId !== query.data.shareId || shareToken !== query.data.token)
|
||||
) {
|
||||
setShareData(query.data, { token: query.data.token });
|
||||
}
|
||||
}, [query.data, shareId, shareToken]);
|
||||
|
||||
return { share: query.data, ...query };
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useMutation, useQuery } from '@tanstack/react-query';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { useCallback } from 'react';
|
||||
import { getApiUrl } from '@/lib/api-url';
|
||||
import { getClientAuthToken } from '@/lib/client';
|
||||
@@ -7,8 +6,6 @@ import { SHARE_CONTEXT_HEADER, SHARE_TOKEN_HEADER } from '@/lib/constants';
|
||||
import { type FetchResponse, httpDelete, httpGet, httpPost, httpPut } from '@/lib/fetch';
|
||||
import { useApp } from '@/store/app';
|
||||
|
||||
const selector = (state: { shareToken: { token?: string } }) => state.shareToken;
|
||||
|
||||
async function handleResponse(res: FetchResponse): Promise<any> {
|
||||
if (!res.ok) {
|
||||
const { message, code, status } = res?.data?.error || {};
|
||||
@@ -19,13 +16,12 @@ async function handleResponse(res: FetchResponse): Promise<any> {
|
||||
}
|
||||
|
||||
export function useApi() {
|
||||
const shareToken = useApp(selector);
|
||||
const pathname = usePathname();
|
||||
const isSharePath = pathname?.startsWith('/share');
|
||||
const shareId = useApp(state => state.share?.shareId);
|
||||
const shareToken = useApp(state => state.shareToken?.token);
|
||||
|
||||
const shareHeaders =
|
||||
isSharePath && shareToken?.token
|
||||
? { [SHARE_TOKEN_HEADER]: shareToken.token, [SHARE_CONTEXT_HEADER]: '1' }
|
||||
shareId && shareToken
|
||||
? { [SHARE_TOKEN_HEADER]: shareToken, [SHARE_CONTEXT_HEADER]: '1' }
|
||||
: {};
|
||||
|
||||
const defaultHeaders = {
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
import { expect, test, vi } from 'vitest';
|
||||
import { ENTITY_TYPE } from '@/lib/constants';
|
||||
import {
|
||||
canViewSharedWebsite,
|
||||
canViewSharedWebsiteFilters,
|
||||
canViewWebsiteSection,
|
||||
} from './share';
|
||||
|
||||
vi.mock('./website', () => ({
|
||||
canViewWebsite: vi.fn(),
|
||||
}));
|
||||
|
||||
test('canViewWebsiteSection allows board shares for included websites', async () => {
|
||||
await expect(
|
||||
canViewWebsiteSection(
|
||||
{
|
||||
shareToken: {
|
||||
shareType: ENTITY_TYPE.board,
|
||||
websiteIds: ['website-1'],
|
||||
parameters: {},
|
||||
},
|
||||
},
|
||||
'website-1',
|
||||
'goals',
|
||||
),
|
||||
).resolves.toBe(true);
|
||||
});
|
||||
|
||||
test('canViewWebsiteSection respects section flags on website shares', async () => {
|
||||
await expect(
|
||||
canViewWebsiteSection(
|
||||
{
|
||||
shareToken: {
|
||||
shareType: ENTITY_TYPE.website,
|
||||
websiteId: 'website-1',
|
||||
parameters: {
|
||||
overview: true,
|
||||
goals: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
'website-1',
|
||||
'goals',
|
||||
),
|
||||
).resolves.toBe(false);
|
||||
});
|
||||
|
||||
test('canViewWebsiteSection allows any requested enabled section', async () => {
|
||||
await expect(
|
||||
canViewWebsiteSection(
|
||||
{
|
||||
shareToken: {
|
||||
shareType: ENTITY_TYPE.website,
|
||||
websiteId: 'website-1',
|
||||
parameters: {
|
||||
overview: true,
|
||||
compare: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
'website-1',
|
||||
['overview', 'compare'],
|
||||
),
|
||||
).resolves.toBe(true);
|
||||
});
|
||||
|
||||
test('canViewSharedWebsite allows board shares for included websites', async () => {
|
||||
await expect(
|
||||
canViewSharedWebsite(
|
||||
{
|
||||
shareToken: {
|
||||
shareType: ENTITY_TYPE.board,
|
||||
websiteIds: ['website-1'],
|
||||
parameters: {},
|
||||
},
|
||||
},
|
||||
'website-1',
|
||||
),
|
||||
).resolves.toBe(true);
|
||||
});
|
||||
|
||||
test('canViewSharedWebsiteFilters requires allowFilter for share tokens', async () => {
|
||||
await expect(
|
||||
canViewSharedWebsiteFilters(
|
||||
{
|
||||
shareToken: {
|
||||
shareType: ENTITY_TYPE.website,
|
||||
websiteId: 'website-1',
|
||||
parameters: {
|
||||
allowFilter: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
'website-1',
|
||||
),
|
||||
).resolves.toBe(false);
|
||||
|
||||
await expect(
|
||||
canViewSharedWebsiteFilters(
|
||||
{
|
||||
shareToken: {
|
||||
shareType: ENTITY_TYPE.website,
|
||||
websiteId: 'website-1',
|
||||
parameters: {
|
||||
allowFilter: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
'website-1',
|
||||
),
|
||||
).resolves.toBe(true);
|
||||
});
|
||||
|
||||
test('canViewWebsiteSection allows pixel shares for the shared entity id', async () => {
|
||||
await expect(
|
||||
canViewWebsiteSection(
|
||||
{
|
||||
shareToken: {
|
||||
shareType: ENTITY_TYPE.pixel,
|
||||
pixelId: 'pixel-1',
|
||||
parameters: {
|
||||
overview: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
'pixel-1',
|
||||
'overview',
|
||||
),
|
||||
).resolves.toBe(true);
|
||||
});
|
||||
|
||||
test('canViewWebsiteSection allows link shares for the shared entity id', async () => {
|
||||
await expect(
|
||||
canViewWebsiteSection(
|
||||
{
|
||||
shareToken: {
|
||||
shareType: ENTITY_TYPE.link,
|
||||
linkId: 'link-1',
|
||||
parameters: {
|
||||
overview: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
'link-1',
|
||||
'overview',
|
||||
),
|
||||
).resolves.toBe(true);
|
||||
});
|
||||
@@ -40,7 +40,14 @@ type ShareSectionInput = ShareSection | ShareSection[];
|
||||
function shareTokenIncludesWebsite(auth: Auth | null | undefined, websiteId: string) {
|
||||
const { shareToken } = auth || {};
|
||||
|
||||
return shareToken?.websiteId === websiteId || shareToken?.websiteIds?.includes(websiteId);
|
||||
return (
|
||||
shareToken?.websiteId === websiteId ||
|
||||
shareToken?.pixelId === websiteId ||
|
||||
shareToken?.linkId === websiteId ||
|
||||
shareToken?.websiteIds?.includes(websiteId) ||
|
||||
shareToken?.pixelIds?.includes(websiteId) ||
|
||||
shareToken?.linkIds?.includes(websiteId)
|
||||
);
|
||||
}
|
||||
|
||||
export async function canViewWebsiteSection(
|
||||
@@ -54,11 +61,7 @@ export async function canViewWebsiteSection(
|
||||
|
||||
const { shareToken } = auth || {};
|
||||
|
||||
if (
|
||||
!shareToken ||
|
||||
shareToken.shareType !== ENTITY_TYPE.website ||
|
||||
!shareTokenIncludesWebsite(auth, websiteId)
|
||||
) {
|
||||
if (!shareToken || !shareTokenIncludesWebsite(auth, websiteId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -79,11 +82,20 @@ export async function canViewSharedWebsite(auth: Auth | null | undefined, websit
|
||||
return canViewWebsite(auth, websiteId);
|
||||
}
|
||||
|
||||
return shareTokenIncludesWebsite(auth, websiteId);
|
||||
}
|
||||
|
||||
export async function canViewSharedWebsiteFilters(
|
||||
auth: Auth | null | undefined,
|
||||
websiteId: string,
|
||||
) {
|
||||
if (auth?.user) {
|
||||
return canViewWebsite(auth, websiteId);
|
||||
}
|
||||
|
||||
const { shareToken } = auth || {};
|
||||
|
||||
return (
|
||||
shareToken?.shareType === ENTITY_TYPE.website && shareTokenIncludesWebsite(auth, websiteId)
|
||||
);
|
||||
return shareTokenIncludesWebsite(auth, websiteId) && shareToken?.parameters?.allowFilter !== false;
|
||||
}
|
||||
|
||||
export async function canViewAuthenticatedWebsite(
|
||||
|
||||
Reference in New Issue
Block a user