From 8c27e9a566fe0cac40a3b640cfd0b0ffdd2f2269 Mon Sep 17 00:00:00 2001 From: CryptoMickle <318943357+CryptoMickle@users.noreply.github.com> Date: Tue, 1 Sep 2026 07:59:39 +0200 Subject: [PATCH 1/2] chore: harden frontend dependencies and browser policy --- frontend/next.config.ts | 79 ++++++++++- frontend/package-lock.json | 284 +++++++++++++++---------------------- frontend/package.json | 14 +- 3 files changed, 202 insertions(+), 175 deletions(-) diff --git a/frontend/next.config.ts b/frontend/next.config.ts index 1dda01c..8ecf714 100644 --- a/frontend/next.config.ts +++ b/frontend/next.config.ts @@ -1,9 +1,65 @@ import type { NextConfig } from "next"; +const isDevelopment = process.env.NODE_ENV === "development"; + +const contentSecurityPolicy = [ + "default-src 'self'", + `script-src 'self' 'unsafe-inline'${isDevelopment ? " 'unsafe-eval'" : ""} https://va.vercel-scripts.com https://vercel.live https://*.vercel.live`, + "script-src-attr 'none'", + "style-src 'self' 'unsafe-inline'", + "img-src 'self' blob: data: https:", + "font-src 'self' data:", + [ + "connect-src 'self'", + "https://dream-rpc.somnia.network", + "https://testnet.riselabs.xyz", + "wss://testnet.riselabs.xyz", + "https://*.thirdweb.com", + "wss://*.thirdweb.com", + "https://*.walletconnect.com", + "wss://*.walletconnect.com", + "https://*.walletconnect.org", + "wss://*.walletconnect.org", + "https://*.reown.com", + "wss://*.reown.com", + "https://*.metamask.io", + "wss://*.metamask.io", + "https://vitals.vercel-insights.com", + "https://vercel.live", + "https://*.vercel.live", + "wss://*.vercel.live", + ...(isDevelopment + ? [ + "http://localhost:*", + "http://127.0.0.1:*", + "ws://localhost:*", + "ws://127.0.0.1:*", + ] + : []), + ].join(" "), + [ + "frame-src 'self'", + "https://*.thirdweb.com", + "https://*.walletconnect.com", + "https://*.walletconnect.org", + "https://*.reown.com", + "https://vercel.live", + "https://*.vercel.live", + ].join(" "), + "worker-src 'self' blob:", + "media-src 'self' blob:", + "manifest-src 'self'", + "object-src 'none'", + "base-uri 'self'", + "form-action 'self'", + "frame-ancestors 'none'", + ...(isDevelopment ? [] : ["upgrade-insecure-requests"]), +].join("; "); + const securityHeaders = [ { key: "Content-Security-Policy", - value: "frame-ancestors 'none'", + value: contentSecurityPolicy, }, { key: "X-Frame-Options", @@ -21,9 +77,30 @@ const securityHeaders = [ key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=()", }, + { + key: "Strict-Transport-Security", + value: "max-age=31536000", + }, + { + key: "Cross-Origin-Opener-Policy", + value: "same-origin-allow-popups", + }, + { + key: "Origin-Agent-Cluster", + value: "?1", + }, + { + key: "X-DNS-Prefetch-Control", + value: "off", + }, + { + key: "X-Permitted-Cross-Domain-Policies", + value: "none", + }, ]; const nextConfig: NextConfig = { + poweredByHeader: false, async redirects() { return [ { diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 790e02a..87c08ca 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -22,8 +22,8 @@ "rise-wallet": "^0.3.5", "shreds": "^0.3.0", "thirdweb": "^5.121.1", - "viem": "^2.55.18", - "wagmi": "^3.7.6" + "viem": "^2.56.1", + "wagmi": "^3.7.7" }, "devDependencies": { "@tailwindcss/postcss": "^4", @@ -32,6 +32,7 @@ "@types/react-dom": "^19", "eslint": "^9", "eslint-config-next": "16.3.3", + "js-yaml": "4.3.1", "tailwindcss": "^4", "typescript": "^5" } @@ -965,29 +966,6 @@ "url": "https://github.com/sponsors/hey-api" } }, - "node_modules/@hey-api/json-schema-ref-parser/node_modules/js-yaml": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz", - "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/puzrin" - }, - { - "type": "github", - "url": "https://github.com/sponsors/nodeca" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/@hey-api/openapi-ts": { "version": "0.99.0", "resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.99.0.tgz", @@ -3745,27 +3723,6 @@ "multiformats": "^9.4.2" } }, - "node_modules/@reown/appkit-controllers/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/@reown/appkit-controllers/node_modules/zod": { "version": "3.25.76", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", @@ -4132,27 +4089,6 @@ "multiformats": "^9.4.2" } }, - "node_modules/@reown/appkit-utils/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/@reown/appkit-utils/node_modules/zod": { "version": "3.25.76", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", @@ -4471,27 +4407,6 @@ "multiformats": "^9.4.2" } }, - "node_modules/@reown/appkit/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/@reown/appkit/node_modules/zod": { "version": "3.25.76", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", @@ -6757,6 +6672,7 @@ "resolved": "https://registry.npmjs.org/@wagmi/core/-/core-3.6.4.tgz", "integrity": "sha512-YERJ+vbFZw3UI6p4KoFU5DkxkqmtzBq5lddpgVAvcu5Tz7kSicKVA3DMCWvjVAFsikNdZYIs39FIkMGWfzpSMQ==", "license": "MIT", + "peer": true, "dependencies": { "eventemitter3": "5.0.1", "mipd": "0.0.7", @@ -7132,27 +7048,6 @@ } } }, - "node_modules/@walletconnect/ethereum-provider/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/@walletconnect/ethereum-provider/node_modules/zod": { "version": "3.25.76", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", @@ -7583,27 +7478,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@walletconnect/utils/node_modules/ws": { - "version": "8.18.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", - "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/@walletconnect/utils/node_modules/zod": { "version": "3.25.76", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", @@ -7800,6 +7674,18 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/ajv": { "version": "6.15.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", @@ -8128,13 +8014,14 @@ } }, "node_modules/axios": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz", - "integrity": "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.20.0.tgz", + "integrity": "sha512-r8aOh8j9cGKpgQAqpzrUHnSIc6a59Y3Xf/cv8sy1DrHCkZHzQGEuoq1tARk6qSyDdtQGSDgpb9kFlruzPvrgwg==", "license": "MIT", "dependencies": { "follow-redirects": "^1.16.0", - "form-data": "^4.0.5", + "form-data": "^4.0.6", + "https-proxy-agent": "^5.0.1", "proxy-from-env": "^2.1.0" } }, @@ -10707,6 +10594,19 @@ "node": ">=16.9.0" } }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/idb-keyval": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.3.0.tgz", @@ -14908,27 +14808,6 @@ } } }, - "node_modules/thirdweb/node_modules/ws": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/thirdweb/node_modules/zod": { "version": "3.25.75", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.75.tgz", @@ -15581,9 +15460,9 @@ } }, "node_modules/viem": { - "version": "2.55.18", - "resolved": "https://registry.npmjs.org/viem/-/viem-2.55.18.tgz", - "integrity": "sha512-7XJtcMueFo4dQz+VK5mhY3GV9lvQkyrMbM/P/IghE0d8oZ/xbhgMXdTpc+ra4ZtDOGsLKu+0/EOD7BetVmVBsw==", + "version": "2.56.1", + "resolved": "https://registry.npmjs.org/viem/-/viem-2.56.1.tgz", + "integrity": "sha512-D+B87QRiACeWV4VOxn4Kwi4obV0fR2wGpX8bHTUlOnud3O8LTUyXvCqC83otmIww2dDv3vCl3V8a9jWApNP7KA==", "funding": [ { "type": "github", @@ -15598,7 +15477,7 @@ "@scure/bip39": "1.6.0", "abitype": "1.2.3", "isows": "1.0.7", - "ox": "0.14.33", + "ox": "0.14.34", "ws": "8.21.0" }, "peerDependencies": { @@ -15610,14 +15489,44 @@ } } }, + "node_modules/viem/node_modules/ox": { + "version": "0.14.34", + "resolved": "https://registry.npmjs.org/ox/-/ox-0.14.34.tgz", + "integrity": "sha512-12seOIk7dv8eAoGQhcWaeKZxNz304IVcDvb9U5Y7JZAEVe21Nm1YMxLjhWah+su5BD4Omx4Zz0z5x3ij9M4GYQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "dependencies": { + "@adraffy/ens-normalize": "^1.11.0", + "@noble/ciphers": "^1.3.0", + "@noble/curves": "1.9.1", + "@noble/hashes": "^1.8.0", + "@scure/bip32": "^1.7.0", + "@scure/bip39": "^1.6.0", + "abitype": "^1.2.3", + "eventemitter3": "5.0.1" + }, + "peerDependencies": { + "typescript": ">=5.4.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/wagmi": { - "version": "3.7.6", - "resolved": "https://registry.npmjs.org/wagmi/-/wagmi-3.7.6.tgz", - "integrity": "sha512-Zm/ppGHV6GYX9by3ERs1KVcNqpMZ4Vdno48Avdz9U+3QCjC5iFatOwruA9IMOl8poL7n/pJGQOcR1xj8N5c69w==", + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/wagmi/-/wagmi-3.7.7.tgz", + "integrity": "sha512-J9YTRKwOVt+L135nMiitwGALrJqpXFhLX8AZzbECWeAQ1aI9Uz8Pz0GGMqtbKe7xJtmOx838OChT7YkMs9k8OA==", "license": "MIT", "dependencies": { - "@wagmi/connectors": "8.1.0", - "@wagmi/core": "3.6.4", + "@wagmi/connectors": "8.2.0", + "@wagmi/core": "3.6.5", "use-sync-external-store": "1.4.0" }, "funding": { @@ -15704,9 +15613,9 @@ } }, "node_modules/wagmi/node_modules/@wagmi/connectors": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@wagmi/connectors/-/connectors-8.1.0.tgz", - "integrity": "sha512-ASlHXq9NC4pp617lalZdlPuPnZUhFeWNEKQfm3ngVSQKd4S2is5XXG4v3EOAhcxdLjSk1AMfGXlHgk5tX2WCZg==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@wagmi/connectors/-/connectors-8.2.0.tgz", + "integrity": "sha512-hPwdmePYjQqSWlw9JmzrzVgmw2PJ+NJsUQ/BuPBYbzBS8+cW5vWdqiaKLB4qTF9m+yr+zSp7u91KBgvOWz50og==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/wevm" @@ -15717,9 +15626,9 @@ "@metamask/connect-evm": "^2.1.0", "@safe-global/safe-apps-provider": "~0.18.6", "@safe-global/safe-apps-sdk": "^9.1.0", - "@wagmi/core": "3.6.4", + "@wagmi/core": "3.6.5", "@walletconnect/ethereum-provider": "^2.21.1", - "accounts": "~0.14", + "accounts": "~0.18", "typescript": ">=5.9.3", "viem": "2.x" }, @@ -15750,6 +15659,37 @@ } } }, + "node_modules/wagmi/node_modules/@wagmi/core": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/@wagmi/core/-/core-3.6.5.tgz", + "integrity": "sha512-zfKvLNT1V1+/RgrrUcRvteKx+V+Iv9ZHPWseIVKFA9mX5WE0H8J6zWZGWXSQCKbz5xGSUoatNFCkNFSzqQp+AA==", + "license": "MIT", + "dependencies": { + "eventemitter3": "5.0.1", + "mipd": "0.0.7", + "zustand": "5.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/wevm" + }, + "peerDependencies": { + "@tanstack/query-core": ">=5.0.0", + "accounts": "~0.18", + "typescript": ">=5.9.3", + "viem": "2.x" + }, + "peerDependenciesMeta": { + "@tanstack/query-core": { + "optional": true + }, + "accounts": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, "node_modules/wagmi/node_modules/idb-keyval": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.1.tgz", @@ -15992,9 +15932,9 @@ "license": "ISC" }, "node_modules/ws": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", - "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", + "version": "8.21.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz", + "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==", "license": "MIT", "engines": { "node": ">=10.0.0" diff --git a/frontend/package.json b/frontend/package.json index aedb70c..be35416 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -23,8 +23,8 @@ "rise-wallet": "^0.3.5", "shreds": "^0.3.0", "thirdweb": "^5.121.1", - "viem": "^2.55.18", - "wagmi": "^3.7.6" + "viem": "^2.56.1", + "wagmi": "^3.7.7" }, "devDependencies": { "@tailwindcss/postcss": "^4", @@ -33,7 +33,17 @@ "@types/react-dom": "^19", "eslint": "^9", "eslint-config-next": "16.3.3", + "js-yaml": "4.3.1", "tailwindcss": "^4", "typescript": "^5" + }, + "overrides": { + "@coinbase/cdp-sdk": { + "axios": "1.20.0" + }, + "js-yaml": "$js-yaml", + "viem": { + "ws": "8.21.3" + } } } From 210619f2b4982fd782726d2dcb46e51280ee0e72 Mon Sep 17 00:00:00 2001 From: CryptoMickle <318943357+CryptoMickle@users.noreply.github.com> Date: Tue, 1 Sep 2026 16:51:42 +0200 Subject: [PATCH 2/2] fix: strictly verify Somnia session permissions --- frontend/app/somnia-session-keys.ts | 45 ++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/frontend/app/somnia-session-keys.ts b/frontend/app/somnia-session-keys.ts index ffa271b..932017a 100644 --- a/frontend/app/somnia-session-keys.ts +++ b/frontend/app/somnia-session-keys.ts @@ -5,6 +5,7 @@ import { defineChain } from "thirdweb/chains"; import { getContract } from "thirdweb/contract"; import { getPermissionsForSigner, + isAdmin, removeSessionKey, } from "thirdweb/extensions/erc4337"; import { createWallet, type Account } from "thirdweb/wallets"; @@ -119,24 +120,48 @@ async function verifyStoredPermissions(record: SomniaSessionRecord) { chain: somniaChain, address: record.smartAccountAddress, }); - const permissions = await getPermissionsForSigner({ - contract, - signer: record.sessionKeyAddress, - }); + const [permissions, ownerIsAdmin, sessionSignerIsAdmin] = await Promise.all([ + getPermissionsForSigner({ + contract, + signer: record.sessionKeyAddress, + }), + isAdmin({ + contract, + signer: record.ownerAddress, + }), + isAdmin({ + contract, + signer: record.sessionKeyAddress, + }), + ]); const nowSeconds = BigInt(Math.floor(Date.now() / 1_000)); - const targetAllowed = permissions.approvedTargets.some( - (target) => - target.toLowerCase() === activeDeployment.dungeonAddress.toLowerCase() + const recordExpirySeconds = BigInt( + Math.floor(record.expiresAt / 1_000) + ); + const maximumPermissionDuration = BigInt( + SESSION_DURATION_SECONDS + Math.ceil(CLOCK_SKEW_MS / 1_000) ); + const targetsAreRestricted = + permissions.approvedTargets.length === 1 && + permissions.approvedTargets[0]?.toLowerCase() === + activeDeployment.dungeonAddress.toLowerCase(); + const permissionDuration = + permissions.endTimestamp - permissions.startTimestamp; if ( permissions.signer.toLowerCase() !== record.sessionKeyAddress.toLowerCase() || - !targetAllowed || + !ownerIsAdmin || + sessionSignerIsAdmin || + !targetsAreRestricted || permissions.nativeTokenLimitPerTransaction !== BigInt(0) || permissions.startTimestamp > nowSeconds || - permissions.endTimestamp <= nowSeconds + permissions.endTimestamp <= nowSeconds || + permissions.endTimestamp > recordExpirySeconds || + permissionDuration > maximumPermissionDuration ) { - throw new Error("Stored Somnia session permission is no longer active."); + throw new Error( + "Stored Somnia session permission is inactive or broader than expected." + ); } }