From 7a59572f110ddcf2b9fd4b7859231635fccf90e1 Mon Sep 17 00:00:00 2001 From: Yukino_fox Date: Sun, 29 Mar 2026 19:30:27 +0800 Subject: [PATCH] =?UTF-8?q?feat(auth):=20=E6=B7=BB=E5=8A=A0=20SECTL=20Auth?= =?UTF-8?q?=20OAuth=20=E7=99=BB=E5=BD=95=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 OAuth 登录组件和回调页面 - 集成 Tauri 深度链接插件处理 OAuth 回调 - 添加账户设置页面显示登录信息 - 更新 CI 配置添加 OAuth 环境变量 - 扩展 API 接口支持 OAuth 相关操作 - 添加国际化支持 --- .eslintcache | 1 + .github/workflows/build.yml | 19 + AGENTS.md | 2 + AUTH/API.MD | 922 ++++++++ AUTH/AUTH.MD | 482 ++++ AUTH/OAUTH_FLOW.MD | 311 +++ AUTH/TROUBLESHOOTING.md | 476 ++++ package.json | 2 + pnpm-lock.yaml | 50 +- resources/看板SQL生成提示词.md | 33 + src-tauri/Cargo.lock | 98 + src-tauri/Cargo.toml | 2 + src-tauri/data.sql | Bin 0 -> 110592 bytes src-tauri/gen/schemas/acl-manifests.json | 1 + src-tauri/gen/schemas/capabilities.json | 1 + src-tauri/gen/schemas/desktop-schema.json | 2618 +++++++++++++++++++++ src-tauri/gen/schemas/windows-schema.json | 2618 +++++++++++++++++++++ src-tauri/src/commands/auth.rs | 137 ++ src-tauri/src/lib.rs | 26 + src-tauri/tauri.conf.json | 8 + src/App.tsx | 72 +- src/components/BoardManager.tsx | 42 +- src/components/ContentArea.tsx | 5 +- src/components/Home.tsx | 276 +-- src/components/OAuthCallback.tsx | 49 + src/components/OAuthLogin.tsx | 183 ++ src/components/Settings.tsx | 127 +- src/components/StudentManager.tsx | 36 +- src/i18n/locales/en-US.json | 11 + src/i18n/locales/zh-CN.json | 11 + src/main.tsx | 2 +- src/preload/types.ts | 55 +- src/shared/mobileNavigation.ts | 1 + 33 files changed, 8477 insertions(+), 200 deletions(-) create mode 100644 .eslintcache create mode 100644 AUTH/API.MD create mode 100644 AUTH/AUTH.MD create mode 100644 AUTH/OAUTH_FLOW.MD create mode 100644 AUTH/TROUBLESHOOTING.md create mode 100644 src-tauri/data.sql create mode 100644 src-tauri/gen/schemas/acl-manifests.json create mode 100644 src-tauri/gen/schemas/capabilities.json create mode 100644 src-tauri/gen/schemas/desktop-schema.json create mode 100644 src-tauri/gen/schemas/windows-schema.json create mode 100644 src/components/OAuthCallback.tsx create mode 100644 src/components/OAuthLogin.tsx diff --git a/.eslintcache b/.eslintcache new file mode 100644 index 0000000..28d825a --- /dev/null +++ b/.eslintcache @@ -0,0 +1 @@ +[{"E:\\Document\\Coding\\SecScore\\eslint.config.mjs":"1","E:\\Document\\Coding\\SecScore\\src\\App.tsx":"2","E:\\Document\\Coding\\SecScore\\src\\ClientContext.ts":"3","E:\\Document\\Coding\\SecScore\\src\\components\\BoardManager.tsx":"4","E:\\Document\\Coding\\SecScore\\src\\components\\ContentArea.tsx":"5","E:\\Document\\Coding\\SecScore\\src\\components\\EventHistory.tsx":"6","E:\\Document\\Coding\\SecScore\\src\\components\\Home.tsx":"7","E:\\Document\\Coding\\SecScore\\src\\components\\Leaderboard.tsx":"8","E:\\Document\\Coding\\SecScore\\src\\components\\OAuthCallback.tsx":"9","E:\\Document\\Coding\\SecScore\\src\\components\\OAuthLogin.tsx":"10","E:\\Document\\Coding\\SecScore\\src\\components\\OOBE\\OOBE.tsx":"11","E:\\Document\\Coding\\SecScore\\src\\components\\OOBE\\OOBEBackground.tsx":"12","E:\\Document\\Coding\\SecScore\\src\\components\\ReasonManager.tsx":"13","E:\\Document\\Coding\\SecScore\\src\\components\\RewardExchange.tsx":"14","E:\\Document\\Coding\\SecScore\\src\\components\\RewardSettings.tsx":"15","E:\\Document\\Coding\\SecScore\\src\\components\\ScoreManager.tsx":"16","E:\\Document\\Coding\\SecScore\\src\\components\\Settings.tsx":"17","E:\\Document\\Coding\\SecScore\\src\\components\\SettlementHistory.tsx":"18","E:\\Document\\Coding\\SecScore\\src\\components\\Sidebar.tsx":"19","E:\\Document\\Coding\\SecScore\\src\\components\\StudentManager.tsx":"20","E:\\Document\\Coding\\SecScore\\src\\components\\TagEditorDialog.tsx":"21","E:\\Document\\Coding\\SecScore\\src\\components\\ThemeEditor.tsx":"22","E:\\Document\\Coding\\SecScore\\src\\components\\ThemeQuickSettings.tsx":"23","E:\\Document\\Coding\\SecScore\\src\\components\\TitleBar.tsx":"24","E:\\Document\\Coding\\SecScore\\src\\components\\Versions.tsx":"25","E:\\Document\\Coding\\SecScore\\src\\components\\WindowControls.tsx":"26","E:\\Document\\Coding\\SecScore\\src\\components\\Wizard.tsx":"27","E:\\Document\\Coding\\SecScore\\src\\contexts\\ServiceContext.tsx":"28","E:\\Document\\Coding\\SecScore\\src\\contexts\\ThemeContext.tsx":"29","E:\\Document\\Coding\\SecScore\\src\\contexts\\ThemeEditorContext.tsx":"30","E:\\Document\\Coding\\SecScore\\src\\env.d.ts":"31","E:\\Document\\Coding\\SecScore\\src\\hooks\\useResponsive.ts":"32","E:\\Document\\Coding\\SecScore\\src\\i18n\\index.ts":"33","E:\\Document\\Coding\\SecScore\\src\\main.tsx":"34","E:\\Document\\Coding\\SecScore\\src\\preload\\types.ts":"35","E:\\Document\\Coding\\SecScore\\src\\react-19-patch.ts":"36","E:\\Document\\Coding\\SecScore\\src\\services\\StudentService.ts":"37","E:\\Document\\Coding\\SecScore\\src\\shared\\kernel.ts":"38","E:\\Document\\Coding\\SecScore\\src\\shared\\mobileNavigation.ts":"39","E:\\Document\\Coding\\SecScore\\src\\utils\\color.ts":"40","E:\\Document\\Coding\\SecScore\\src\\utils\\studentAvatar.ts":"41","E:\\Document\\Coding\\SecScore\\src\\workers\\xlsxWorker.ts":"42","E:\\Document\\Coding\\SecScore\\vite.config.ts":"43"},{"size":1413,"mtime":1774084765386,"results":"44","hashOfConfig":"45"},{"size":38217,"mtime":1774773410827,"results":"46","hashOfConfig":"47"},{"size":124,"mtime":1774084765537,"results":"48","hashOfConfig":"47"},{"size":47714,"mtime":1774704827018,"results":"49","hashOfConfig":"47"},{"size":12490,"mtime":1774773413504,"results":"50","hashOfConfig":"47"},{"size":2044,"mtime":1774084765557,"results":"51","hashOfConfig":"47"},{"size":90881,"mtime":1774704827750,"results":"52","hashOfConfig":"47"},{"size":8101,"mtime":1774084765561,"results":"53","hashOfConfig":"47"},{"size":1047,"mtime":1774772479779,"results":"54","hashOfConfig":"47"},{"size":4948,"mtime":1774780673579,"results":"55","hashOfConfig":"47"},{"size":36271,"mtime":1774176288912,"results":"56","hashOfConfig":"47"},{"size":4203,"mtime":1774084765566,"results":"57","hashOfConfig":"47"},{"size":5983,"mtime":1774084765569,"results":"58","hashOfConfig":"47"},{"size":9360,"mtime":1774084765571,"results":"59","hashOfConfig":"47"},{"size":6151,"mtime":1774084765572,"results":"60","hashOfConfig":"47"},{"size":12301,"mtime":1774084765573,"results":"61","hashOfConfig":"47"},{"size":55529,"mtime":1774779133310,"results":"62","hashOfConfig":"47"},{"size":5950,"mtime":1774084765578,"results":"63","hashOfConfig":"47"},{"size":10335,"mtime":1774675242424,"results":"64","hashOfConfig":"47"},{"size":79058,"mtime":1774704830361,"results":"65","hashOfConfig":"47"},{"size":6331,"mtime":1774084765584,"results":"66","hashOfConfig":"47"},{"size":8079,"mtime":1774084765586,"results":"67","hashOfConfig":"47"},{"size":10954,"mtime":1774084765587,"results":"68","hashOfConfig":"47"},{"size":3858,"mtime":1774084765589,"results":"69","hashOfConfig":"47"},{"size":431,"mtime":1774084765590,"results":"70","hashOfConfig":"47"},{"size":2367,"mtime":1774084765592,"results":"71","hashOfConfig":"47"},{"size":1560,"mtime":1774084765594,"results":"72","hashOfConfig":"47"},{"size":362,"mtime":1774084765604,"results":"73","hashOfConfig":"47"},{"size":5985,"mtime":1774084765606,"results":"74","hashOfConfig":"47"},{"size":2824,"mtime":1774084765608,"results":"75","hashOfConfig":"47"},{"size":38,"mtime":1774084765611,"results":"76","hashOfConfig":"47"},{"size":2097,"mtime":1774084765613,"results":"77","hashOfConfig":"47"},{"size":1533,"mtime":1774084765616,"results":"78","hashOfConfig":"47"},{"size":6919,"mtime":1774704831300,"results":"79","hashOfConfig":"47"},{"size":17900,"mtime":1774779134852,"results":"80","hashOfConfig":"47"},{"size":1150,"mtime":1774084765630,"results":"81","hashOfConfig":"47"},{"size":667,"mtime":1774084765638,"results":"82","hashOfConfig":"47"},{"size":3061,"mtime":1774176077013,"results":"83","hashOfConfig":"47"},{"size":1716,"mtime":1774772796302,"results":"84","hashOfConfig":"47"},{"size":3256,"mtime":1774084765655,"results":"85","hashOfConfig":"47"},{"size":1115,"mtime":1774084765658,"results":"86","hashOfConfig":"47"},{"size":947,"mtime":1774084765660,"results":"87","hashOfConfig":"47"},{"size":709,"mtime":1774665241507,"results":"88","hashOfConfig":"47"},{"filePath":"89","messages":"90","suppressedMessages":"91","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"oyxevq",{"filePath":"92","messages":"93","suppressedMessages":"94","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"f6a32r",{"filePath":"95","messages":"96","suppressedMessages":"97","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"98","messages":"99","suppressedMessages":"100","errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"101","messages":"102","suppressedMessages":"103","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"104","messages":"105","suppressedMessages":"106","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"107","messages":"108","suppressedMessages":"109","errorCount":3,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"110","messages":"111","suppressedMessages":"112","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"113","messages":"114","suppressedMessages":"115","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"116","messages":"117","suppressedMessages":"118","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"119","messages":"120","suppressedMessages":"121","errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"122","messages":"123","suppressedMessages":"124","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"125","messages":"126","suppressedMessages":"127","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"128","messages":"129","suppressedMessages":"130","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"131","messages":"132","suppressedMessages":"133","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"134","messages":"135","suppressedMessages":"136","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"137","messages":"138","suppressedMessages":"139","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"140","messages":"141","suppressedMessages":"142","errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"143","messages":"144","suppressedMessages":"145","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"146","messages":"147","suppressedMessages":"148","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"149","messages":"150","suppressedMessages":"151","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"152","messages":"153","suppressedMessages":"154","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"155","messages":"156","suppressedMessages":"157","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"158","messages":"159","suppressedMessages":"160","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"161","messages":"162","suppressedMessages":"163","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"164","messages":"165","suppressedMessages":"166","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"167","messages":"168","suppressedMessages":"169","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"170","messages":"171","suppressedMessages":"172","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"173","messages":"174","suppressedMessages":"175","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"176","messages":"177","suppressedMessages":"178","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"179","messages":"180","suppressedMessages":"181","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"182","messages":"183","suppressedMessages":"184","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"185","messages":"186","suppressedMessages":"187","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"188","messages":"189","suppressedMessages":"190","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"191","messages":"192","suppressedMessages":"193","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"194","messages":"195","suppressedMessages":"196","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"197","messages":"198","suppressedMessages":"199","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"200","messages":"201","suppressedMessages":"202","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"203","messages":"204","suppressedMessages":"205","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"206","messages":"207","suppressedMessages":"208","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"209","messages":"210","suppressedMessages":"211","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"212","messages":"213","suppressedMessages":"214","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"215","messages":"216","suppressedMessages":"217","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"E:\\Document\\Coding\\SecScore\\eslint.config.mjs",[],[],"E:\\Document\\Coding\\SecScore\\src\\App.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\ClientContext.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\BoardManager.tsx",["218","219"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\ContentArea.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\EventHistory.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\Home.tsx",["220","221","222","223","224","225"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\Leaderboard.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\OAuthCallback.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\OAuthLogin.tsx",["226"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\OOBE\\OOBE.tsx",["227","228"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\OOBE\\OOBEBackground.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\ReasonManager.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\RewardExchange.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\RewardSettings.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\ScoreManager.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\Settings.tsx",["229"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\SettlementHistory.tsx",["230","231"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\Sidebar.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\StudentManager.tsx",["232"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\TagEditorDialog.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\ThemeEditor.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\ThemeQuickSettings.tsx",["233"],[],"E:\\Document\\Coding\\SecScore\\src\\components\\TitleBar.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\Versions.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\WindowControls.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\components\\Wizard.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\contexts\\ServiceContext.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\contexts\\ThemeContext.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\contexts\\ThemeEditorContext.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\env.d.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\hooks\\useResponsive.ts",["234"],[],"E:\\Document\\Coding\\SecScore\\src\\i18n\\index.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\main.tsx",[],[],"E:\\Document\\Coding\\SecScore\\src\\preload\\types.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\react-19-patch.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\services\\StudentService.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\shared\\kernel.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\shared\\mobileNavigation.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\utils\\color.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\utils\\studentAvatar.ts",[],[],"E:\\Document\\Coding\\SecScore\\src\\workers\\xlsxWorker.ts",[],[],"E:\\Document\\Coding\\SecScore\\vite.config.ts",[],[],{"ruleId":"235","severity":1,"message":"236","line":626,"column":6,"nodeType":"237","endLine":626,"endColumn":44,"suggestions":"238"},{"ruleId":"235","severity":1,"message":"236","line":634,"column":6,"nodeType":"237","endLine":634,"endColumn":59,"suggestions":"239"},{"ruleId":"235","severity":1,"message":"240","line":532,"column":6,"nodeType":"237","endLine":532,"endColumn":76,"suggestions":"241"},{"ruleId":"242","severity":2,"message":"243","line":544,"column":34,"nodeType":null,"endLine":556,"endColumn":4},{"ruleId":"242","severity":2,"message":"243","line":544,"column":34,"nodeType":null,"endLine":556,"endColumn":4},{"ruleId":"235","severity":1,"message":"244","line":556,"column":6,"nodeType":"237","endLine":556,"endColumn":15,"suggestions":"245"},{"ruleId":"242","severity":2,"message":"246","line":1627,"column":5,"nodeType":null,"endLine":1650,"endColumn":6},{"ruleId":"235","severity":1,"message":"247","line":1710,"column":6,"nodeType":"237","endLine":1710,"endColumn":8,"suggestions":"248"},{"ruleId":"235","severity":1,"message":"249","line":119,"column":6,"nodeType":"237","endLine":119,"endColumn":8,"suggestions":"250"},{"ruleId":"235","severity":1,"message":"251","line":160,"column":6,"nodeType":"237","endLine":160,"endColumn":20,"suggestions":"252"},{"ruleId":"235","severity":1,"message":"253","line":334,"column":5,"nodeType":"237","endLine":334,"endColumn":27,"suggestions":"254"},{"ruleId":"235","severity":1,"message":"255","line":239,"column":6,"nodeType":"237","endLine":239,"endColumn":8,"suggestions":"256"},{"ruleId":"235","severity":1,"message":"257","line":54,"column":6,"nodeType":"237","endLine":54,"endColumn":18,"suggestions":"258"},{"ruleId":"235","severity":1,"message":"244","line":106,"column":5,"nodeType":"237","endLine":106,"endColumn":7,"suggestions":"259"},{"ruleId":"235","severity":1,"message":"260","line":1351,"column":6,"nodeType":"237","endLine":1351,"endColumn":50,"suggestions":"261"},{"ruleId":"235","severity":1,"message":"251","line":100,"column":6,"nodeType":"237","endLine":100,"endColumn":20,"suggestions":"262"},{"ruleId":"235","severity":1,"message":"263","line":25,"column":9,"nodeType":"264","endLine":25,"endColumn":70},"react-hooks/exhaustive-deps","React Hook useEffect has a missing dependency: 'activeBoard'. Either include it or remove the dependency array.","ArrayExpression",["265"],["266"],"React Hook useMemo has an unnecessary dependency: 'layoutType'. Either exclude it or remove the dependency array.",["267"],"react-hooks/preserve-manual-memoization","Compilation Skipped: Existing memoization could not be preserved\n\nReact Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected. The inferred dependency was `t`, but the source dependencies were [reasons]. Inferred different dependency than source.\n\nE:\\Document\\Coding\\SecScore\\src\\components\\Home.tsx:544:34\n 542 | }, [groupedStudents])\n 543 |\n> 544 | const groupedReasons = useMemo(() => {\n | ^^^^^^^\n> 545 | const groups: Record = {}\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n> 546 | reasons.forEach((r) => {\n …\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n> 555 | })\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n> 556 | }, [reasons])\n | ^^^^ Could not preserve existing manual memoization\n 557 |\n 558 | const selectedStudents = useMemo(() => {\n 559 | if (selectedStudentIds.length === 0) return []","React Hook useMemo has a missing dependency: 't'. Either include it or remove the dependency array.",["268"],"Compilation Skipped: Existing memoization could not be preserved\n\nReact Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. This value was memoized in source but not in compilation output.\n\nE:\\Document\\Coding\\SecScore\\src\\components\\Home.tsx:1627:5\n 1625 |\n 1626 | const handleNavAction = useCallback(\n> 1627 | (clientY: number) => {\n | ^^^^^^^^^^^^^^^^^^^^^^\n> 1628 | if (!navContainerRef.current) return\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n> 1629 | const rect = navContainerRef.current.getBoundingClientRect()\n …\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n> 1649 | }\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n> 1650 | },\n | ^^^^^^ Could not preserve existing memoization\n 1651 | [groupedStudents, quickNavLayout.itemSize, quickNavLayout.paddingY, triggerNavHaptic]\n 1652 | )\n 1653 |","React Hook useEffect has missing dependencies: 'onGlobalMouseMove' and 'onGlobalMouseUp'. Either include them or remove the dependency array.",["269"],"React Hook useEffect has a missing dependency: 'handleDeepLink'. Either include it or remove the dependency array.",["270"],"React Hook useEffect has a missing dependency: 't'. Either include it or remove the dependency array.",["271"],"React Hook useCallback has missing dependencies: 'showOobeMessage' and 't'. Either include them or remove the dependency array.",["272"],"React Hook useEffect has a missing dependency: 'loadAll'. Either include it or remove the dependency array.",["273"],"React Hook useCallback has a missing dependency: 't'. Either include it or remove the dependency array.",["274"],["275"],"React Hook useMemo has missing dependencies: 'handleDelete', 'handleOpenAvatarEditor', 'handleOpenGroupEditor', and 'handleOpenTagEditor'. Either include them or remove the dependency array.",["276"],["277"],"The 'breakpoints' object makes the dependencies of useEffect Hook (at line 49) change on every render. Move it inside the useEffect callback. Alternatively, wrap the initialization of 'breakpoints' in its own useMemo() Hook.","VariableDeclarator",{"desc":"278","fix":"279"},{"desc":"280","fix":"281"},{"desc":"282","fix":"283"},{"desc":"284","fix":"285"},{"desc":"286","fix":"287"},{"desc":"288","fix":"289"},{"desc":"290","fix":"291"},{"desc":"292","fix":"293"},{"desc":"294","fix":"295"},{"desc":"296","fix":"297"},{"desc":"298","fix":"299"},{"desc":"300","fix":"301"},{"desc":"290","fix":"302"},"Update the dependencies array to be: [activeBoard, activeBoard.id, activeBoard.layout]",{"range":"303","text":"304"},"Update the dependencies array to be: [activeBoard, activeBoard.id, listConfigSignature, runAllInBoard]",{"range":"305","text":"306"},"Update the dependencies array to be: [sortedStudents, sortType, searchKeyword, getGroupName, t]",{"range":"307","text":"308"},"Update the dependencies array to be: [reasons, t]",{"range":"309","text":"310"},"Update the dependencies array to be: [onGlobalMouseMove, onGlobalMouseUp]",{"range":"311","text":"312"},"Update the dependencies array to be: [handleDeepLink]",{"range":"313","text":"314"},"Update the dependencies array to be: [currentTheme, t]",{"range":"315","text":"316"},"Update the dependencies array to be: [students, showOobeMessage, t]",{"range":"317","text":"318"},"Update the dependencies array to be: [loadAll]",{"range":"319","text":"320"},"Update the dependencies array to be: [messageApi, t]",{"range":"321","text":"322"},"Update the dependencies array to be: [t]",{"range":"323","text":"324"},"Update the dependencies array to be: [t, isMobile, canEdit, handleOpenTagEditor, handleOpenGroupEditor, handleOpenAvatarEditor, handleDelete]",{"range":"325","text":"326"},{"range":"327","text":"316"},[18048,18086],"[activeBoard, activeBoard.id, activeBoard.layout]",[18296,18349],"[activeBoard, activeBoard.id, listConfigSignature, runAllInBoard]",[16069,16139],"[sortedStudents, sortType, searchKeyword, getGroupName, t]",[16914,16923],"[reasons, t]",[53173,53175],"[onGlobalMouseMove, onGlobalMouseUp]",[3088,3090],"[handleDeepLink]",[4674,4688],"[currentTheme, t]",[10389,10411],"[students, showOobeMessage, t]",[7646,7648],"[loadAll]",[1697,1709],"[messageApi, t]",[3343,3345],"[t]",[45580,45624],"[t, isMobile, canEdit, handleOpenTagEditor, handleOpenGroupEditor, handleOpenAvatarEditor, handleDelete]",[3185,3199]] \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dc05b22..5741f99 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -72,6 +72,13 @@ jobs: - name: 应用版本号 run: node scripts/ci/apply-version.mjs ${{ needs.parse.outputs.version }} + - name: 设置 OAuth 环境变量 + run: | + echo "VITE_OAUTH_PLATFORM_ID=${{ secrets.OAUTH_PLATFORM_ID }}" >> $env:GITHUB_ENV + echo "VITE_OAUTH_PLATFORM_SECRET=${{ secrets.OAUTH_PLATFORM_SECRET }}" >> $env:GITHUB_ENV + echo "VITE_OAUTH_CALLBACK_URL=secscore://oauth/callback" >> $env:GITHUB_ENV + shell: pwsh + - name: 安装依赖 run: pnpm install --frozen-lockfile @@ -108,6 +115,12 @@ jobs: - name: 应用版本号 run: node scripts/ci/apply-version.mjs ${{ needs.parse.outputs.version }} + - name: 设置 OAuth 环境变量 + run: | + echo "VITE_OAUTH_PLATFORM_ID=${{ secrets.OAUTH_PLATFORM_ID }}" >> $GITHUB_ENV + echo "VITE_OAUTH_PLATFORM_SECRET=${{ secrets.OAUTH_PLATFORM_SECRET }}" >> $GITHUB_ENV + echo "VITE_OAUTH_CALLBACK_URL=secscore://oauth/callback" >> $GITHUB_ENV + - name: 安装依赖 run: pnpm install --frozen-lockfile @@ -149,6 +162,12 @@ jobs: - name: 应用版本号 run: node scripts/ci/apply-version.mjs ${{ needs.parse.outputs.version }} + - name: 设置 OAuth 环境变量 + run: | + echo "VITE_OAUTH_PLATFORM_ID=${{ secrets.OAUTH_PLATFORM_ID }}" >> $GITHUB_ENV + echo "VITE_OAUTH_PLATFORM_SECRET=${{ secrets.OAUTH_PLATFORM_SECRET }}" >> $GITHUB_ENV + echo "VITE_OAUTH_CALLBACK_URL=secscore://oauth/callback" >> $GITHUB_ENV + - name: 安装依赖 run: pnpm install --frozen-lockfile diff --git a/AGENTS.md b/AGENTS.md index 0b1dd8a..4d73c8a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,10 +1,12 @@ # AGENTS 协作规范 ## 代码规范 + - 所有代码必须符合 Rust 语言规范。 - 所有代码跑`pnpm run typecheck` or `cargo typecheck` 必须通过。 ## 提交与推送要求 + - 每次代码修改后,除非用户说明进行一次 Git 提交(commit)并推送(git push)否则不进行。 - 用户只说 `cp` 时,表示执行一次 Git 提交(commit)并推送(git push)。 - 提交信息必须使用中文。 diff --git a/AUTH/API.MD b/AUTH/API.MD new file mode 100644 index 0000000..fc62a7f --- /dev/null +++ b/AUTH/API.MD @@ -0,0 +1,922 @@ +# SECTL Auth API 参考 + +本文档详细说明 SECTL Auth 提供的所有 API 接口。 + +## 基础信息 + +- **基础 URL**: `https://sectl.top` +- **认证方式**: OAuth 2.0 + Bearer Token +- **数据格式**: JSON + +## 接口概览 + +| 接口 | 方法 | 说明 | 对应页面 | +| ----------------------- | ---- | ------------------- | ------------------------ | +| `/oauth/authorize` | GET | 获取授权码 | OAuthAuthorizeView.vue | +| `/api/oauth/token` | POST | 换取/刷新令牌 | AuthCallbackView.vue | +| `/api/oauth/userinfo` | GET | 获取用户信息 | PlatformUsersView.vue | +| `/api/oauth/config` | POST | 配置 Token 过期时间 | PlatformSettingsView.vue | +| `/api/oauth/revoke` | POST | 撤销令牌 | SecurityView.vue | +| `/api/oauth/introspect` | POST | 验证令牌 | - | + +--- + +## OAuth 接口 + +### 1. 获取授权码 + +引导用户跳转到授权页面。 + +```http +GET /oauth/authorize +``` + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------------- | ------ | ---- | ---------------- | +| client_id | string | ✅ | 平台 ID | +| redirect_uri | string | ✅ | 回调 URL | +| response_type | string | ✅ | 固定值 `code` | +| state | string | ❌ | 防 CSRF 状态参数 | + +**示例请求:** + +``` +https://sectl.top/oauth/authorize?client_id=pf_AHmIhAiptyLFxk8x&redirect_uri=http://localhost:5000/callback&response_type=code +``` + +**成功响应:** + +- 重定向到 `redirect_uri?code={authorization_code}&state={state}` + +**错误响应:** + +- 重定向到 `redirect_uri?error={error_code}&error_description={description}` + +**错误码:** + +| 错误码 | 说明 | +| ------------------------- | ------------------ | +| invalid_request | 请求参数缺失或无效 | +| unauthorized_client | 客户端未授权 | +| access_denied | 用户拒绝授权 | +| unsupported_response_type | 不支持的响应类型 | +| invalid_scope | 无效的权限范围 | +| server_error | 服务器内部错误 | + +**相关页面:** + +- [OAuthAuthorizeView.vue](../../src/views/OAuthAuthorizeView.vue) - 授权页面 +- [LoginView.vue](../../src/views/LoginView.vue) - 登录页面 + +--- + +### 2. 获取访问令牌 + +使用授权码换取访问令牌。 + +```http +POST /api/oauth/token +``` + +**请求头:** + +``` +Content-Type: application/json +``` + +**请求体:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------------- | ------ | ---- | ------------------------------------------------ | +| grant_type | string | ✅ | `authorization_code` 或 `refresh_token` | +| code | string | 条件 | 授权码(grant_type=authorization_code 时必填) | +| refresh_token | string | 条件 | 刷新令牌(grant_type=refresh_token 时必填) | +| client_id | string | ✅ | 平台 ID | +| client_secret | string | ✅ | 平台密钥 | +| redirect_uri | string | 条件 | 回调地址(grant_type=authorization_code 时必填) | + +**授权码模式示例:** + +```json +{ + "grant_type": "authorization_code", + "code": "NjliNDIyOTYwMDE4znLUNeWM6J8ye0MC", + "client_id": "pf_AHmIhAiptyLFxk8x", + "client_secret": "sk_UyMHuFf6oKXh8ZcHSb7lfOSgzumoOeg1", + "redirect_uri": "http://localhost:5000/callback" +} +``` + +**刷新令牌模式示例:** + +```json +{ + "grant_type": "refresh_token", + "refresh_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "client_id": "pf_AHmIhAiptyLFxk8x", + "client_secret": "sk_UyMHuFf6oKXh8ZcHSb7lfOSgzumoOeg1" +} +``` + +**成功响应:** + +```json +{ + "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "refresh_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "token_type": "Bearer", + "expires_in": 3600 +} +``` + +**响应字段:** + +| 字段 | 类型 | 说明 | +| ------------- | ------ | ----------------------- | +| access_token | string | 访问令牌(JWT) | +| refresh_token | string | 刷新令牌 | +| token_type | string | 令牌类型,固定为 Bearer | +| expires_in | number | 过期时间(秒) | + +**错误响应:** + +```json +{ + "error": "invalid_grant", + "error_description": "Authorization code has expired" +} +``` + +**错误码:** + +| 错误码 | HTTP 状态 | 说明 | +| ---------------------- | --------- | ------------------------ | +| invalid_request | 400 | 请求格式错误 | +| invalid_client | 401 | 客户端认证失败 | +| invalid_grant | 400 | 授权码无效或过期 | +| unauthorized_client | 400 | 客户端无权使用此授权类型 | +| unsupported_grant_type | 400 | 不支持的授权类型 | +| invalid_scope | 400 | 无效的权限范围 | + +**相关页面:** + +- [AuthCallbackView.vue](../../src/views/AuthCallbackView.vue) - 回调处理 + +--- + +### 3. 获取用户信息 + +使用访问令牌获取用户信息。 + +```http +GET /api/oauth/userinfo +``` + +**请求头:** + +``` +Authorization: Bearer {access_token} +``` + +**成功响应:** + +```json +{ + "user_id": "69bd422960018cf4d0e5", + "email": "user@example.com", + "name": "张三", + "github_username": "zhangsan", + "permission": 1 +} +``` + +**响应字段:** + +| 字段 | 类型 | 说明 | +| --------------- | ------ | --------------------- | +| user_id | string | 用户唯一标识 | +| email | string | 用户邮箱 | +| name | string | 用户名称 | +| github_username | string | GitHub 用户名(如有) | +| permission | number | 用户权限等级 | + +**错误响应:** + +```json +{ + "error": "invalid_token", + "error_description": "The access token is invalid or has expired" +} +``` + +**相关页面:** + +- [PlatformUsersView.vue](../../src/views/dashboard/manage/PlatformUsersView.vue) - 平台用户列表 + +--- + +### 4. 配置 Token 过期时间 + +配置平台的 access_token 过期时间(需要管理员权限)。 + +```http +POST /api/oauth/config +``` + +**请求头:** + +``` +Content-Type: application/json +``` + +**请求体:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------------ | ------ | ---- | ------------------------------------------- | +| platform_id | string | ✅ | 平台 ID | +| expires_in | number | ✅ | 过期时间(秒),-1 表示永不过期,最小 60 秒 | +| admin_secret | string | ✅ | 管理员密钥 | + +**请求示例:** + +```json +{ + "platform_id": "pf_AHmIhAiptyLFxk8x", + "expires_in": 86400, + "admin_secret": "your-admin-secret" +} +``` + +**成功响应:** + +```json +{ + "success": true, + "message": "Token expiration time updated", + "expires_in": 86400 +} +``` + +**错误响应:** + +```json +{ + "error": "unauthorized", + "error_description": "Invalid admin secret" +} +``` + +**相关页面:** + +- [PlatformSettingsView.vue](../../src/views/dashboard/other/PlatformSettingsView.vue) - 平台设置 + +--- + +### 5. 撤销令牌 + +撤销指定的访问令牌或刷新令牌。 + +```http +POST /api/oauth/revoke +``` + +**请求头:** + +``` +Content-Type: application/json +``` + +**请求体:** + +| 参数名 | 类型 | 必填 | 说明 | +| --------------- | ------ | ---- | --------------------------------- | +| token | string | ✅ | 要撤销的令牌 | +| token_type_hint | string | ❌ | `access_token` 或 `refresh_token` | +| client_id | string | ✅ | 平台 ID | +| client_secret | string | ✅ | 平台密钥 | + +**请求示例:** + +```json +{ + "token": "eyJhbGciOiJIUzI1NiIs...", + "token_type_hint": "access_token", + "client_id": "pf_AHmIhAiptyLFxk8x", + "client_secret": "sk_UyMHuFf6oKXh8ZcHSb7lfOSgzumoOeg1" +} +``` + +**成功响应:** + +```json +{ + "success": true, + "message": "Token revoked successfully" +} +``` + +**相关页面:** + +- [SecurityView.vue](../../src/views/dashboard/other/SecurityView.vue) - 安全设置 +- [LoginPlatformsView.vue](../../src/views/dashboard/list/LoginPlatformsView.vue) - 登录平台列表 + +--- + +### 6. 验证令牌 + +验证访问令牌的有效性和获取令牌信息。 + +```http +POST /api/oauth/introspect +``` + +**请求头:** + +``` +Content-Type: application/json +``` + +**请求体:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------------- | ------ | ---- | ------------ | +| token | string | ✅ | 要验证的令牌 | +| client_id | string | ✅ | 平台 ID | +| client_secret | string | ✅ | 平台密钥 | + +**请求示例:** + +```json +{ + "token": "eyJhbGciOiJIUzI1NiIs...", + "client_id": "pf_AHmIhAiptyLFxk8x", + "client_secret": "sk_UyMHuFf6oKXh8ZcHSb7lfOSgzumoOeg1" +} +``` + +**活跃令牌响应:** + +```json +{ + "active": true, + "user_id": "69bd422960018cf4d0e5", + "client_id": "pf_AHmIhAiptyLFxk8x", + "exp": 1704783600, + "iat": 1704780000 +} +``` + +**非活跃令牌响应:** + +```json +{ + "active": false +} +``` + +**响应字段:** + +| 字段 | 类型 | 说明 | +| --------- | ------- | ------------------------ | +| active | boolean | 令牌是否有效 | +| user_id | string | 用户 ID(仅活跃令牌) | +| client_id | string | 平台 ID(仅活跃令牌) | +| exp | number | 过期时间戳(仅活跃令牌) | +| iat | number | 签发时间戳(仅活跃令牌) | + +--- + +## 平台管理 API + +以下 API 用于管理平台信息,需要通过 Appwrite SDK 调用。 + +### 获取平台列表 + +```javascript +// 使用 Appwrite SDK +const result = await databases.listDocuments({ + databaseId: "69bd89d8000304c37368", + collectionId: "platforms", + queries: [Query.orderDesc("$createdAt"), Query.limit(100)], +}) +``` + +**相关页面:** + +- [PlatformManagementView.vue](../../src/views/dashboard/manage/PlatformManagementView.vue) + +### 获取平台详情 + +```javascript +const platform = await databases.getDocument({ + databaseId: "69bd89d8000304c37368", + collectionId: "platforms", + documentId: "platform-document-id", +}) +``` + +**相关页面:** + +- [PlatformDetailView.vue](../../src/views/dashboard/detail/PlatformDetailView.vue) + +### 更新平台信息 + +```javascript +await databases.updateDocument({ + databaseId: "69bd89d8000304c37368", + collectionId: "platforms", + documentId: "platform-document-id", + data: { + callback_url: "http://new-callback.com", + token_expires_in: 7200, + }, +}) +``` + +**相关页面:** + +- [PlatformSettingsView.vue](../../src/views/dashboard/other/PlatformSettingsView.vue) + +### 申请创建平台 + +```javascript +await databases.createDocument({ + databaseId: "69bd89d8000304c37368", + collectionId: "platform_applications", + documentId: ID.unique(), + data: { + name: "我的应用", + description: "应用描述", + callback_url: "http://localhost:5000/callback", + owner_id: currentUser.$id, + status: "pending", + created_at: new Date().toISOString(), + }, +}) +``` + +**相关页面:** + +- [PlatformApplyView.vue](../../src/views/dashboard/form/PlatformApplyView.vue) + +--- + +## 用户管理 API + +### 获取用户授权的平台列表 + +```javascript +const result = await databases.listDocuments({ + databaseId: "69bd89d8000304c37368", + collectionId: "oauth_tokens", + queries: [Query.equal("user_id", currentUser.$id), Query.equal("revoked", false)], +}) +``` + +**相关页面:** + +- [LoginPlatformsView.vue](../../src/views/dashboard/list/LoginPlatformsView.vue) + +### 获取平台授权用户列表 + +```javascript +const result = await databases.listDocuments({ + databaseId: "69bd89d8000304c37368", + collectionId: "oauth_tokens", + queries: [Query.equal("platform_id", "pf_xxx"), Query.equal("revoked", false)], +}) +``` + +**相关页面:** + +- [PlatformUsersView.vue](../../src/views/dashboard/manage/PlatformUsersView.vue) + +--- + +## 云存储 API + +云存储 API 提供文件上传、下载、管理等功能。需要通过 OAuth access_token 进行认证。 + +### 接口概览 + +| 接口 | 方法 | 说明 | SDK 方法 | +| ------------------------------- | ------ | ------------------------ | ------------------------------- | +| `/api/cloud/upload` | POST | 上传文件 | `uploadFile()` | +| `/api/cloud/files/{file_id}` | GET | 获取文件信息 | `getFile()` | +| `/api/cloud/download/{file_id}` | GET | 获取下载链接 | `downloadFile()` | +| `/api/cloud/view/{file_id}` | GET | 查看文件内容 | `viewFile()` | +| `/api/cloud/preview/{file_id}` | GET | 预览文件(支持图片处理) | `previewFile()` | +| `/api/cloud/info` | GET | 获取存储信息 | `getStorageInfo()` | +| `/api/cloud/files` | GET | 列出/搜索文件 | `listFiles()` / `searchFiles()` | +| `/api/cloud/files/{file_id}` | PUT | 更新文件(重命名) | `updateFile()` | +| `/api/cloud/files/{file_id}` | DELETE | 删除文件 | `deleteFile()` | + +--- + +### 1. 上传文件 + +上传文件到云存储,系统会自动验证文件格式和检查存储容量。 + +```http +POST /api/cloud/upload +``` + +**请求头:** + +``` +Authorization: Bearer {access_token} +Content-Type: multipart/form-data +``` + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ----------- | ------ | ---- | ------------ | +| file | File | ✅ | 要上传的文件 | +| platform_id | string | ✅ | 平台 ID | + +**请求示例(JavaScript):** + +```javascript +const formData = new FormData() +formData.append("file", fileInput.files[0]) +formData.append("platform_id", "pf_AHmIhAiptyLFxk8x") + +const response = await fetch("https://sectl.top/api/cloud/upload", { + method: "POST", + headers: { + Authorization: "Bearer eyJhbGciOiJIUzI1NiIs...", + }, + body: formData, +}) +``` + +**成功响应:** + +```json +{ + "success": true, + "file_id": "cf_xxxxxxxx", + "filename": "example.jpg", + "size": 1024567, + "url": "https://cloud.appwrite.io/v1/storage/buckets/69c869010007b752a9b1/files/xxx/view", + "storage": { + "used": "50MB", + "limit": "100MB", + "available": "50MB", + "percentage": 50 + } +} +``` + +**错误响应 - 格式不允许:** + +```json +{ + "error": "invalid_format", + "error_description": "File format 'exe' is not allowed", + "allowed_formats": ["jpg", "png", "pdf"] +} +``` + +**错误响应 - 超出容量:** + +```json +{ + "error": "storage_exceeded", + "error_description": "Upload would exceed storage limit", + "storage": { + "used": "95MB", + "limit": "100MB", + "available": "5MB", + "requested": "10MB" + } +} +``` + +**相关页面:** + +- [CloudServiceView.vue](../../src/views/dashboard/CloudServiceView.vue) - 云服务总览 + +--- + +### 2. 下载文件 + +获取文件的下载链接。 + +```http +GET /api/cloud/download/{file_id} +``` + +**请求头:** + +``` +Authorization: Bearer {access_token} +``` + +**路径参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------- | ------ | ---- | ------- | +| file_id | string | ✅ | 文件 ID | + +**成功响应:** + +```json +{ + "success": true, + "file_id": "cf_xxxxxxxx", + "filename": "example.jpg", + "download_url": "https://cloud.appwrite.io/v1/storage/buckets/69c869010007b752a9b1/files/xxx/download", + "expires_at": "2025-01-01T01:00:00Z" +} +``` + +--- + +### 3. 获取存储信息 + +获取用户在该平台的存储使用情况和配置信息。 + +```http +GET /api/cloud/info?platform_id={platform_id} +``` + +**请求头:** + +``` +Authorization: Bearer {access_token} +``` + +**查询参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ----------- | ------ | ---- | ------- | +| platform_id | string | ✅ | 平台 ID | + +**成功响应:** + +```json +{ + "success": true, + "platform_id": "pf_xxx", + "tier": "free", + "storage": { + "used": 52428800, + "used_formatted": "50MB", + "limit": 104857600, + "limit_formatted": "100MB", + "available": 52428800, + "available_formatted": "50MB", + "percentage": 50 + }, + "allowed_formats": ["jpg", "png", "pdf"], + "max_file_size": 10485760 +} +``` + +--- + +### 4. 列出文件 + +获取用户在该平台的文件列表。 + +```http +GET /api/cloud/files?platform_id={platform_id}&limit=20&offset=0 +``` + +**请求头:** + +``` +Authorization: Bearer {access_token} +``` + +**查询参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ----------- | ------ | ---- | ----------------- | +| platform_id | string | ✅ | 平台 ID | +| limit | number | ❌ | 每页数量,默认 20 | +| offset | number | ❌ | 偏移量,默认 0 | + +**成功响应:** + +```json +{ + "success": true, + "files": [ + { + "file_id": "cf_xxx", + "filename": "example.jpg", + "size": 1024567, + "size_formatted": "1MB", + "created_at": "2025-01-01T00:00:00Z" + } + ], + "total": 10, + "limit": 20, + "offset": 0 +} +``` + +--- + +### 5. 删除文件 + +删除指定的文件。 + +```http +DELETE /api/cloud/files/{file_id} +``` + +**请求头:** + +``` +Authorization: Bearer {access_token} +``` + +**路径参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------- | ------ | ---- | ------- | +| file_id | string | ✅ | 文件 ID | + +**成功响应:** + +```json +{ + "success": true, + "message": "File deleted successfully", + "storage": { + "used": "45MB", + "limit": "100MB", + "available": "55MB" + } +} +``` + +--- + +## 云存储 SDK + +我们提供了 JavaScript SDK 简化云存储 API 的调用。 + +### 安装 + +```html + +``` + +或使用 ES6 模块: + +```javascript +import CloudStorage from "./cloud-storage.js" +``` + +### 初始化 + +```javascript +const cloud = new CloudStorage({ + baseUrl: "https://sectl.top", + platformId: "your_platform_id", + accessToken: "your_access_token", +}) +``` + +### 使用示例 + +```javascript +// 上传文件 +try { + const result = await cloud.uploadFile(fileInput.files[0]) + console.log("文件上传成功:", result.file_id) + console.log("存储使用情况:", result.storage.percentage + "%") +} catch (error) { + if (error.code === "invalid_format") { + console.error("不支持的文件格式:", error.data.allowed_formats) + } else if (error.code === "storage_exceeded") { + console.error("存储空间不足") + } +} + +// 获取存储信息 +const info = await cloud.getStorageInfo() +console.log("已用空间:", info.storage.used_formatted) +console.log("允许格式:", info.allowed_formats) + +// 列出文件 +const files = await cloud.listFiles({ limit: 10 }) +files.files.forEach((file) => { + console.log(file.filename, file.size_formatted) +}) + +// 下载文件 +const download = await cloud.downloadFile("cf_xxx") +window.location.href = download.download_url + +// 删除文件 +await cloud.deleteFile("cf_xxx") +``` + +**相关文件:** + +- [cloud-storage.js](../../platform-sdk/cloud-storage.js) - SDK 源码 + +--- + +## 远程退登 API + +### 创建退登事件 + +当用户退出登录时,系统会自动创建退登事件。 + +```javascript +await databases.createDocument({ + databaseId: "69bd89d8000304c37368", + collectionId: "logout_events", + documentId: ID.unique(), + data: { + user_id: currentUser.$id, + platform_id: null, // null 表示全局退出 + global: true, + created_at: new Date().toISOString(), + }, +}) +``` + +### 订阅退登事件 + +使用 Appwrite Realtime 订阅退登事件: + +```javascript +import { Client } from "appwrite" + +const client = new Client() + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject("your-project-id") + +const unsubscribe = client.subscribe( + "databases.69bd89d8000304c37368.collections.logout_events.documents", + (response) => { + const event = response.payload + if (event.user_id === currentUserId) { + // 执行本地退出 + localLogout() + } + } +) +``` + +**相关页面:** + +- [SecurityView.vue](../../src/views/dashboard/other/SecurityView.vue) + +--- + +## 错误处理 + +### HTTP 状态码 + +| 状态码 | 说明 | +| ------ | ------------------ | +| 200 | 请求成功 | +| 400 | 请求参数错误 | +| 401 | 未授权,认证失败 | +| 403 | 禁止访问,权限不足 | +| 404 | 资源不存在 | +| 500 | 服务器内部错误 | + +### 错误响应格式 + +```json +{ + "error": "error_code", + "error_description": "详细的错误描述", + "error_uri": "https://docs.example.com/error/error_code" +} +``` + +--- + +## 安全建议 + +1. **使用 HTTPS** - 所有 API 通信必须使用 HTTPS +2. **保护密钥** - 不要在客户端代码中暴露 client_secret +3. **验证回调地址** - 确保 redirect_uri 与注册时一致 +4. **使用状态参数** - 添加 state 参数防止 CSRF 攻击 +5. **安全存储令牌** - Token 应安全存储,避免泄露 +6. **及时撤销** - 用户退出时及时撤销令牌 + +--- + +## 相关页面 + +- [OAuthAuthorizeView.vue](../../src/views/OAuthAuthorizeView.vue) - OAuth 授权页面 +- [AuthCallbackView.vue](../../src/views/AuthCallbackView.vue) - 认证回调 +- [PlatformManagementView.vue](../../src/views/dashboard/manage/PlatformManagementView.vue) - 平台管理 +- [PlatformDetailView.vue](../../src/views/dashboard/detail/PlatformDetailView.vue) - 平台详情 +- [PlatformSettingsView.vue](../../src/views/dashboard/other/PlatformSettingsView.vue) - 平台设置 +- [SecurityView.vue](../../src/views/dashboard/other/SecurityView.vue) - 安全设置 +- [LoginPlatformsView.vue](../../src/views/dashboard/list/LoginPlatformsView.vue) - 登录平台列表 diff --git a/AUTH/AUTH.MD b/AUTH/AUTH.MD new file mode 100644 index 0000000..d77c64b --- /dev/null +++ b/AUTH/AUTH.MD @@ -0,0 +1,482 @@ +# 平台接入指南 + +本文档介绍如何将第三方平台与 SECTL Auth 集成,实现统一认证和远程退登功能。 + +## 目录 + +- [概述](#概述) +- [快速开始](#快速开始) +- [管理后台功能](#管理后台功能) +- [OAuth 集成](#oauth-集成) +- [远程退登](#远程退登) +- [代码示例](#代码示例) +- [常见问题](#常见问题) + +## 概述 + +SECTL Auth 提供以下核心功能: + +1. **统一认证** - 用户使用 SECTL Auth 账号登录第三方平台 +2. **远程退登** - 用户在 SECTL Auth 中心退出后,平台自动退出 +3. **用户管理** - 查看已授权用户、统计信息等 + +### 工作流程 + +``` +┌─────────────┐ 登录请求 ┌─────────────┐ +│ 用户 │ ─────────────> │ SECTL Auth │ +│ │ │ │ +│ 平台A │ <───────────── │ 认证中心 │ +│ │ Access Token │ │ +└──────┬──────┘ └──────┬──────┘ + │ │ + │ 远程退登通知 │ + │ <─────────────────────────── │ + │ (Realtime) │ + ▼ ▼ + 自动退出登录 用户点击退出 +``` + +## 快速开始 + +### 1. 注册平台 + +在 SECTL Auth 平台管理页面 ([PlatformManagementView.vue](../../src/views/dashboard/manage/PlatformManagementView.vue)) 申请接入,获取: + +| 参数 | 说明 | 示例 | +| -------------- | ------------ | ------------------------------------- | +| platform_id | 平台唯一标识 | `pf_AHmIhAiptyLFxk8x` | +| platform_token | 平台认证密钥 | `sk_UyMHuFf6oKXh8ZcHSb7lfOSgzumoOeg1` | +| callback_url | 回调地址 | `http://localhost:5000/callback` | + +### 2. 平台状态说明 + +平台在管理后台有以下状态: + +| 状态 | 说明 | 可操作 | +| -------- | ------ | -------- | +| active | 运行中 | 正常授权 | +| pending | 审核中 | 等待审核 | +| disabled | 已停用 | 无法授权 | + +### 3. 查看统计信息 + +在平台管理页面可以查看: + +- **总平台数** - 已创建的平台数量 +- **运行中** - 活跃平台数量 +- **审核中** - 待审核申请数量 +- **总用户数** - 授权用户总数 + +## 管理后台功能 + +### 平台列表 ([PlatformManagementView.vue](../../src/views/dashboard/manage/PlatformManagementView.vue)) + +平台管理页面提供以下功能: + +#### 1. 平台卡片展示 + +每个平台显示: + +- 平台名称和描述 +- 状态标签(运行中/审核中/已停用) +- 创建时间 +- 授权用户数 +- 管理按钮 + +#### 2. 搜索和过滤 + +- 按名称搜索平台 +- 按状态过滤 +- 分页展示 + +#### 3. 快捷操作 + +- **新建平台** - 跳转到申请页面 +- **我的申请** - 查看自己的平台申请 +- **审核申请** - 审核其他用户的申请(需 >=18 权限) + +### 平台详情 ([PlatformDetailView.vue](../../src/views/dashboard/detail/PlatformDetailView.vue)) + +查看平台详细信息: + +#### 基本信息 + +- 平台 ID (Client ID) +- 平台密钥 (Client Secret) +- 回调地址 +- 创建时间 + +#### 安全设置 + +- Token 过期时间配置 +- 密钥重置 +- 回调地址修改 + +#### 用户统计 + +- 授权用户列表 +- 登录时间 +- 最后活跃时间 + +### 平台申请 ([PlatformApplyView.vue](../../src/views/dashboard/form/PlatformApplyView.vue)) + +申请创建新平台: + +```javascript +// 申请参数 +{ + name: "我的应用", // 平台名称 + description: "应用描述", // 平台描述 + callback_url: "http://..." // 回调地址 +} +``` + +申请后状态为 `pending`,等待管理员审核。 + +### 申请审核 ([PlatformApplicationsView.vue](../../src/views/dashboard/manage/PlatformApplicationsView.vue)) + +管理员审核平台申请: + +- 查看申请详情 +- 批准申请(状态变为 `active`) +- 拒绝申请(状态变为 `disabled`) + +## OAuth 集成 + +### 授权流程 + +#### 1. 引导用户到授权页面 + +``` +GET https://sectl.top/oauth/authorize +``` + +**参数:** + +| 参数名 | 必填 | 说明 | +| ------------- | ---- | ------------- | +| client_id | ✅ | 平台 ID | +| redirect_uri | ✅ | 回调地址 | +| response_type | ✅ | 固定值 `code` | + +**示例:** + +``` +https://sectl.top/oauth/authorize?client_id=pf_xxx&redirect_uri=http://localhost:5000/callback&response_type=code +``` + +#### 2. 处理回调 + +用户授权后,会重定向到: + +``` +{callback_url}?code={authorization_code} +``` + +#### 3. 换取访问令牌 + +```http +POST https://sectl.top/api/oauth/token +Content-Type: application/json + +{ + "grant_type": "authorization_code", + "code": "授权码", + "client_id": "pf_xxx", + "client_secret": "sk_xxx", + "redirect_uri": "http://localhost:5000/callback" +} +``` + +**响应:** + +```json +{ + "access_token": "eyJhbGciOiJIUzI1NiIs...", + "refresh_token": "xxx", + "token_type": "Bearer", + "expires_in": 3600 +} +``` + +#### 4. 获取用户信息 + +```http +GET https://sectl.top/api/oauth/userinfo +Authorization: Bearer {access_token} +``` + +**响应:** + +```json +{ + "user_id": "69bd422960018cf4d0e5", + "email": "user@example.com", + "name": "张三", + "github_username": "zhangsan" +} +``` + +## 远程退登 + +### 实现原理 + +1. 用户在 SECTL Auth 点击退出登录 +2. 系统创建 `logout_events` 文档 +3. 第三方应用通过 Appwrite Realtime 订阅该集合 +4. 收到匹配的事件后执行本地退出 + +### 集成步骤 + +#### 1. 安装 Appwrite SDK + +**C#** + +```bash +dotnet add package Appwrite +``` + +**Python** + +```bash +pip install appwrite +``` + +#### 2. 配置 Realtime 订阅 + +**C# 示例:** + +```csharp +using Appwrite; +using Appwrite.Services; + +var client = new Client() + .SetEndpoint("https://cloud.appwrite.io/v1") + .SetProject("your-project-id"); + +var realtime = new Realtime(client); + +// 订阅 logout_events 集合 +realtime.Subscribe("databases.{databaseId}.collections.logout_events.documents", + callback: (message) => { + var logoutEvent = message.Payload; + if (logoutEvent.UserId == currentUserId) { + // 执行本地退出 + LocalLogout(); + } + }); +``` + +**Python 示例:** + +```python +from appwrite.client import Client +from appwrite.services.realtime import Realtime + +client = Client() +client.set_endpoint('https://cloud.appwrite.io/v1') +client.set_project('your-project-id') + +realtime = Realtime(client) + +def on_logout_event(message): + event = message['payload'] + if event['user_id'] == current_user_id: + # 执行本地退出 + local_logout() + +# 订阅 logout_events 集合 +realtime.subscribe( + 'databases.{database_id}.collections.logout_events.documents', + callback=on_logout_event +) +``` + +### 数据结构 + +**logout_events 集合字段:** + +| 字段 | 类型 | 说明 | +| ----------- | ------- | ------------------ | +| user_id | String | 退出登录的用户ID | +| platform_id | String | 特定平台ID(可选) | +| global | Boolean | 是否全局退出 | +| created_at | String | 创建时间 | + +## 代码示例 + +### C# 完整示例 + +详见 [csharp-example](./csharp-example/) 目录。 + +```csharp +// SectlAuthClient.cs +public class SectlAuthClient +{ + private readonly string _platformId; + private readonly string _platformSecret; + private readonly string _callbackUrl; + private readonly HttpClient _httpClient; + + public SectlAuthClient(string platformId, string platformSecret, string callbackUrl) + { + _platformId = platformId; + _platformSecret = platformSecret; + _callbackUrl = callbackUrl; + _httpClient = new HttpClient(); + } + + // 获取授权 URL + public string GetAuthorizationUrl() + { + return $"https://sectl.top/oauth/authorize?" + + $"client_id={_platformId}&" + + $"redirect_uri={Uri.EscapeDataString(_callbackUrl)}&" + + $"response_type=code"; + } + + // 换取访问令牌 + public async Task ExchangeCodeAsync(string code) + { + var request = new + { + grant_type = "authorization_code", + code = code, + client_id = _platformId, + client_secret = _platformSecret, + redirect_uri = _callbackUrl + }; + + var response = await _httpClient.PostAsJsonAsync( + "https://sectl.top/api/oauth/token", request); + + return await response.Content.ReadFromJsonAsync(); + } + + // 获取用户信息 + public async Task GetUserInfoAsync(string accessToken) + { + _httpClient.DefaultRequestHeaders.Authorization = + new AuthenticationHeaderValue("Bearer", accessToken); + + var response = await _httpClient.GetAsync( + "https://sectl.top/api/oauth/userinfo"); + + return await response.Content.ReadFromJsonAsync(); + } +} +``` + +### Python 完整示例 + +详见 [python-example](./python-example/) 目录。 + +```python +# sectl_auth/client.py +import requests + +class SectlAuthClient: + BASE_URL = "https://sectl.top" + AUTH_URL = "https://sectl.top" + + def __init__(self, platform_id: str, platform_secret: str, callback_url: str): + self.platform_id = platform_id + self.platform_secret = platform_secret + self.callback_url = callback_url + + def get_authorization_url(self) -> str: + """获取授权 URL""" + return ( + f"{self.AUTH_URL}/oauth/authorize?" + f"client_id={self.platform_id}&" + f"redirect_uri={self.callback_url}&" + f"response_type=code" + ) + + def exchange_code(self, code: str) -> dict: + """用授权码换取访问令牌""" + response = requests.post( + f"{self.BASE_URL}/api/oauth/token", + json={ + "grant_type": "authorization_code", + "code": code, + "client_id": self.platform_id, + "client_secret": self.platform_secret, + "redirect_uri": self.callback_url + } + ) + response.raise_for_status() + return response.json() + + def get_user_info(self, access_token: str) -> dict: + """获取用户信息""" + response = requests.get( + f"{self.BASE_URL}/api/oauth/userinfo", + headers={"Authorization": f"Bearer {access_token}"} + ) + response.raise_for_status() + return response.json() +``` + +## 常见问题 + +### Q: 如何获取 platform_id 和 platform_token? + +A: 在 SECTL Auth 平台管理页面申请创建平台,审核通过后会获得: + +- platform_id (Client ID) +- platform_token (Client Secret) + +### Q: 授权码有效期多久? + +A: 授权码有效期为 10 分钟,且只能使用一次。 + +### Q: Access Token 过期后怎么办? + +A: 使用 refresh_token 换取新的 access_token: + +```http +POST /api/oauth/token +{ + "grant_type": "refresh_token", + "refresh_token": "your-refresh-token", + "client_id": "your-platform-id", + "client_secret": "your-platform-secret" +} +``` + +### Q: 如何配置 Token 过期时间? + +A: 在平台设置页面 ([PlatformSettingsView.vue](../../src/views/dashboard/other/PlatformSettingsView.vue)) 可以配置: + +- access_token 过期时间(默认 3600 秒) +- 设置为 -1 表示永不过期 + +### Q: 远程退登不生效怎么办? + +A: 检查以下几点: + +1. 是否正确订阅了 `logout_events` 集合 +2. 检查 user_id 是否匹配 +3. 确认 Appwrite Realtime 连接正常 +4. 查看浏览器控制台是否有错误 + +### Q: 平台状态显示"审核中"怎么办? + +A: 新创建的平台需要管理员审核。审核通过后状态会变为 `active`。 + +## 相关页面 + +- [PlatformManagementView.vue](../../src/views/dashboard/manage/PlatformManagementView.vue) - 平台管理 +- [PlatformDetailView.vue](../../src/views/dashboard/detail/PlatformDetailView.vue) - 平台详情 +- [PlatformApplyView.vue](../../src/views/dashboard/form/PlatformApplyView.vue) - 申请平台 +- [PlatformApplicationsView.vue](../../src/views/dashboard/manage/PlatformApplicationsView.vue) - 审核申请 +- [PlatformSettingsView.vue](../../src/views/dashboard/other/PlatformSettingsView.vue) - 平台设置 +- [LoginPlatformsView.vue](../../src/views/dashboard/list/LoginPlatformsView.vue) - 登录平台列表 + +## 参考文档 + +- [OAuth 2.0 流程](./OAUTH_FLOW.MD) +- [API 参考](./API_REFERENCE.md) +- [故障排查](../oauth-flow/TROUBLESHOOTING.md) diff --git a/AUTH/OAUTH_FLOW.MD b/AUTH/OAUTH_FLOW.MD new file mode 100644 index 0000000..b3279b6 --- /dev/null +++ b/AUTH/OAUTH_FLOW.MD @@ -0,0 +1,311 @@ +# OAuth 2.0 授权流程文档 + +本文档详细说明 SECTL Auth 的 OAuth 2.0 授权流程,帮助第三方应用开发者接入统一认证服务。 + +## 概述 + +SECTL Auth 实现了标准的 OAuth 2.0 授权码流程(Authorization Code Flow),允许第三方应用使用 SECTL Auth 账户进行用户认证。 + +### 流程特点 + +- **安全性高** - 使用授权码模式,避免 Token 暴露在浏览器端 +- **标准化** - 遵循 OAuth 2.0 RFC 6749 规范 +- **远程退登** - 支持通过 Realtime 实现跨平台同步退出 +- **可配置** - 支持自定义 Token 过期时间 + +## 授权流程 + +### 流程图 + +``` +┌─────────┐ ┌─────────────┐ +│ 用户 │ │ 第三方应用 │ +└────┬────┘ └──────┬──────┘ + │ │ + │ 1. 访问应用 │ + │───────────────────────────────────────────────>│ + │ │ + │ 2. 重定向到授权页面 │ + │<───────────────────────────────────────────────│ + │ │ + │ 3. 登录并授权 (LoginView.vue / OAuthAuthorizeView.vue) + │───────────────────────────────────────────────>│ + │ │ + │ 4. 返回授权码 │ + │<───────────────────────────────────────────────│ + │ │ + │ 5. 用授权码换取 Token │ + │ │──────┐ + │ │ │ + │ 6. 返回 Access Token │<─────┘ + │ │ + │ 7. 使用 Token 访问用户资源 │ + │<───────────────────────────────────────────────│ +``` + +## 详细步骤 + +### 1. 引导用户到授权页面 + +当用户需要登录时,第三方应用应将用户重定向到 SECTL Auth 的授权页面。 + +**请求地址:** + +``` +GET https://sectl.top/oauth/authorize +``` + +**请求参数:** + +| 参数名 | 必填 | 类型 | 说明 | +| ------------- | ---- | ------ | --------------------------------- | +| client_id | ✅ | string | 平台 ID,如 `pf_AHmIhAiptyLFxk8x` | +| redirect_uri | ✅ | string | 回调地址,必须与平台设置匹配 | +| response_type | ✅ | string | 固定值 `code` | + +**示例 URL:** + +``` +https://sectl.top/oauth/authorize?client_id=pf_AHmIhAiptyLFxk8x&redirect_uri=http://localhost:5000/callback&response_type=code +``` + +**相关代码:** [OAuthAuthorizeView.vue](../../src/views/OAuthAuthorizeView.vue) + +### 2. 用户登录与授权 + +用户将被引导至 SECTL Auth 登录页面(如果未登录): + +1. **登录页面** ([LoginView.vue](../../src/views/LoginView.vue)) + - 用户输入邮箱密码或使用 GitHub 登录 + - 支持记住我功能 + - 检测 OAuth 参数,登录后自动跳转授权页 + +2. **授权确认页** ([OAuthAuthorizeView.vue](../../src/views/OAuthAuthorizeView.vue)) + - 显示应用名称和图标 + - 列出请求的权限范围 + - 用户可选择"授权"或"拒绝" + +**权限范围:** + +- 访问用户基本信息(用户名、邮箱、头像) +- 验证用户身份 + +### 3. 获取授权码 + +用户授权后,页面将重定向到指定的回调地址: + +``` +{redirect_uri}?code={authorization_code} +``` + +**示例:** + +``` +http://localhost:5000/callback?code=NjliNDIyOTYwMDE4znLUNeWM6J8ye0MC +``` + +**授权码特性:** + +- 有效期:10 分钟 +- 一次性使用 +- 与 `redirect_uri` 绑定 + +### 4. 换取访问令牌 + +第三方应用后端使用授权码向 SECTL Auth 换取访问令牌。 + +**请求地址:** + +``` +POST https://sectl.top/api/oauth/token +``` + +**请求头:** + +``` +Content-Type: application/json +``` + +**请求体:** + +```json +{ + "grant_type": "authorization_code", + "code": "NjliNDIyOTYwMDE4znLUNeWM6J8ye0MC", + "client_id": "pf_AHmIhAiptyLFxk8x", + "client_secret": "sk_UyMHuFf6oKXh8ZcHSb7lfOSgzumoOeg1", + "redirect_uri": "http://localhost:5000/callback" +} +``` + +**参数说明:** + +| 参数名 | 必填 | 说明 | +| ------------- | ---- | --------------------------- | +| grant_type | ✅ | 固定值 `authorization_code` | +| code | ✅ | 上一步获取的授权码 | +| client_id | ✅ | 平台 ID | +| client_secret | ✅ | 平台密钥 | +| redirect_uri | ✅ | 必须与授权时一致 | + +**成功响应:** + +```json +{ + "access_token": "eyJhbGciOiJIUzI1NiIs...", + "refresh_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "token_type": "Bearer", + "expires_in": 3600 +} +``` + +**Token 信息:** + +| 字段 | 说明 | +| ------------- | ----------------------------------- | +| access_token | 访问令牌,用于调用 API | +| refresh_token | 刷新令牌,用于获取新的 access_token | +| token_type | 令牌类型,固定为 Bearer | +| expires_in | 过期时间(秒) | + +### 5. 使用访问令牌 + +获取 access_token 后,可用于调用 SECTL Auth API 获取用户信息。 + +**获取用户信息:** + +```http +GET https://sectl.top/api/oauth/userinfo +Authorization: Bearer {access_token} +``` + +**响应示例:** + +```json +{ + "user_id": "69bd422960018cf4d0e5", + "email": "user@example.com", + "name": "张三", + "github_username": "zhangsan" +} +``` + +## Token 管理 + +### 过期时间配置 + +平台可配置 Token 过期时间: + +| 令牌类型 | 默认有效期 | 说明 | +| ------------- | --------------- | ---------------------- | +| access_token | 3600 秒 (1小时) | 短期有效,用于访问资源 | +| refresh_token | 长期有效 | 用于刷新 access_token | +| 授权码 | 600 秒 (10分钟) | 一次性使用 | + +**修改过期时间:** + +```http +POST https://sectl.top/api/oauth/config +Content-Type: application/json + +{ + "expires_in": 86400, + "admin_secret": "your-admin-secret" +} +``` + +### 刷新 Token + +当 access_token 过期时,使用 refresh_token 获取新的令牌: + +```http +POST https://sectl.top/api/oauth/token +Content-Type: application/json + +{ + "grant_type": "refresh_token", + "refresh_token": "your-refresh-token", + "client_id": "your-platform-id", + "client_secret": "your-platform-secret" +} +``` + +## 远程退登 + +SECTL Auth 支持远程退登功能,当用户在 SECTL Auth 中心退出登录时,已授权的第三方应用会收到通知。 + +### 实现原理 + +1. 用户在 SECTL Auth 点击退出登录 +2. 系统创建 `logout_events` 文档 +3. 第三方应用通过 Appwrite Realtime 订阅该集合 +4. 收到退登事件后,应用执行本地退出操作 + +### 集成方式 + +详见 [平台接入指南](../platform-integration/README.md)。 + +## 错误处理 + +### 授权错误 + +当授权失败时,将重定向到回调地址并附带错误信息: + +``` +{redirect_uri}?error=access_denied&error_description=user+denied+authorization +``` + +**常见错误码:** + +| 错误码 | 说明 | +| ------------------------- | ------------------ | +| invalid_request | 请求参数缺失或无效 | +| unauthorized_client | 客户端未授权 | +| access_denied | 用户拒绝授权 | +| unsupported_response_type | 不支持的响应类型 | +| invalid_scope | 无效的权限范围 | +| server_error | 服务器内部错误 | + +### Token 错误 + +换取 Token 时的错误响应: + +```json +{ + "error": "invalid_grant", + "error_description": "Authorization code has expired" +} +``` + +**常见错误码:** + +| 错误码 | 说明 | +| ---------------------- | ------------------------ | +| invalid_request | 请求格式错误 | +| invalid_client | 客户端认证失败 | +| invalid_grant | 授权码无效或过期 | +| unauthorized_client | 客户端无权使用此授权类型 | +| unsupported_grant_type | 不支持的授权类型 | +| invalid_scope | 无效的权限范围 | + +## 安全建议 + +1. **使用 HTTPS** - 所有 OAuth 通信必须使用 HTTPS +2. **保护 client_secret** - 不要在客户端代码中暴露 client_secret +3. **验证 redirect_uri** - 确保回调地址与注册时一致 +4. **使用状态参数** - 建议添加 `state` 参数防止 CSRF 攻击 +5. **及时清理** - 使用后的授权码应立即作废 +6. **安全存储** - Token 应安全存储,避免泄露 + +## 相关页面 + +- [LoginView.vue](../../src/views/LoginView.vue) - 登录页面 +- [OAuthAuthorizeView.vue](../../src/views/OAuthAuthorizeView.vue) - OAuth 授权页面 +- [AuthCallbackView.vue](../../src/views/AuthCallbackView.vue) - 认证回调处理 +- [LoginPlatformsView.vue](../../src/views/dashboard/list/LoginPlatformsView.vue) - 登录平台列表 + +## 参考文档 + +- [平台接入指南](../platform-integration/README.md) +- [API 参考](../platform-integration/API_REFERENCE.md) +- [故障排查](./TROUBLESHOOTING.md) diff --git a/AUTH/TROUBLESHOOTING.md b/AUTH/TROUBLESHOOTING.md new file mode 100644 index 0000000..c24753a --- /dev/null +++ b/AUTH/TROUBLESHOOTING.md @@ -0,0 +1,476 @@ +# OAuth 流程故障排查指南 + +本文档汇总了 SECTL Auth OAuth 流程中的常见问题及解决方案。 + +## 目录 + +- [授权阶段问题](#授权阶段问题) +- [Token 换取问题](#token-换取问题) +- [用户信息获取问题](#用户信息获取问题) +- [远程退登问题](#远程退登问题) +- [平台管理问题](#平台管理问题) +- [网络与 CORS 问题](#网络与-cors-问题) + +--- + +## 授权阶段问题 + +### 1. 授权页面无法打开 + +**现象:** 访问授权 URL 返回 404 或空白页面 + +**排查步骤:** + +1. 检查 URL 格式是否正确 + ``` + https://auth.sectl.top/oauth/authorize?client_id=xxx&redirect_uri=xxx&response_type=code + ``` +2. 确认必要参数是否齐全 + - `client_id` - 平台 ID + - `redirect_uri` - 回调地址 + - `response_type` - 固定值 `code` +3. 检查平台是否存在且状态为 `active` + - 登录 SECTL Auth 管理后台 + - 查看 [PlatformManagementView.vue](../../src/views/dashboard/manage/PlatformManagementView.vue) + - 确认平台状态不是 `pending` 或 `disabled` + +**相关页面:** + +- [OAuthAuthorizeView.vue](../../src/views/OAuthAuthorizeView.vue) +- [PlatformManagementView.vue](../../src/views/dashboard/manage/PlatformManagementView.vue) + +--- + +### 2. 授权后没有记录到登录平台 + +**现象:** 用户授权后,在"登录平台"页面 ([LoginPlatformsView.vue](../../src/views/dashboard/list/LoginPlatformsView.vue)) 看不到记录 + +**排查步骤:** + +1. 检查浏览器控制台是否有错误 +2. 检查 `user_data` 集合是否有该用户的记录 +3. 检查 `user_data.login_platforms` 字段是否正确更新 +4. 检查 `oauth_tokens` 集合是否有对应的令牌记录 + +**可能原因:** + +- 用户未登录 SECTL Auth +- `user_data` 集合权限问题 +- 网络请求失败 +- 平台状态为 `disabled` + +**相关页面:** + +- [LoginPlatformsView.vue](../../src/views/dashboard/list/LoginPlatformsView.vue) +- [SecurityView.vue](../../src/views/dashboard/other/SecurityView.vue) + +--- + +### 3. 用户已登录但授权页面仍要求登录 + +**现象:** 用户已登录 SECTL Auth,但授权页面仍跳转到登录页 + +**排查步骤:** + +1. 检查登录状态是否正确保持 +2. 检查浏览器 Cookie 是否被阻止 +3. 检查是否跨域问题 + +**解决方案:** + +- 确保浏览器允许第三方 Cookie +- 检查 `rememberMe` 选项是否勾选 +- 查看 [LoginView.vue](../../src/views/LoginView.vue) 中的登录逻辑 + +--- + +## Token 换取问题 + +### 1. 换取 token 时提示 "Invalid authorization code" + +**现象:** 用 code 换取 token 返回 400 错误 + +```json +{ + "error": "invalid_grant", + "error_description": "Invalid authorization code" +} +``` + +**排查步骤:** + +1. 检查 code 是否已过期(10分钟有效期) +2. 检查 code 是否已被使用过 +3. 检查 `redirect_uri` 是否与授权时一致 +4. 检查 `client_id` 和 `client_secret` 是否正确 + +**可能原因:** + +- Code 已过期 +- Code 已被使用(一次性) +- 回调地址不匹配 +- 平台密钥错误 + +**相关代码:** [AuthCallbackView.vue](../../src/views/AuthCallbackView.vue) + +--- + +### 2. 换取 token 时提示 "Invalid client" + +**现象:** 返回 401 错误 + +```json +{ + "error": "invalid_client", + "error_description": "Client authentication failed" +} +``` + +**排查步骤:** + +1. 确认 `client_id` 正确 +2. 确认 `client_secret` 正确且未泄露 +3. 检查平台状态是否为 `active` + +**解决方案:** + +- 在 [PlatformManagementView.vue](../../src/views/dashboard/manage/PlatformManagementView.vue) 查看平台信息 +- 如密钥泄露,在 [PlatformSettingsView.vue](../../src/views/dashboard/other/PlatformSettingsView.vue) 重置密钥 + +--- + +### 3. Access Token 过期后无法刷新 + +**现象:** 使用 refresh_token 换取新 token 失败 + +**排查步骤:** + +1. 检查 refresh_token 是否有效 +2. 检查 refresh_token 是否被撤销 +3. 检查平台是否被禁用 + +**请求示例:** + +```http +POST /api/oauth/token +{ + "grant_type": "refresh_token", + "refresh_token": "your-refresh-token", + "client_id": "your-platform-id", + "client_secret": "your-platform-secret" +} +``` + +--- + +## 用户信息获取问题 + +### 1. 获取用户信息返回 401 + +**现象:** 调用 `/api/oauth/userinfo` 返回未授权错误 + +**排查步骤:** + +1. 检查 access_token 是否过期 +2. 检查 Authorization 头格式是否正确 + ``` + Authorization: Bearer {access_token} + ``` +3. 检查 token 是否被撤销 + +**解决方案:** + +- 使用 refresh_token 获取新的 access_token +- 重新走授权流程 + +**相关页面:** [PlatformUsersView.vue](../../src/views/dashboard/manage/PlatformUsersView.vue) + +--- + +### 2. 用户信息字段缺失 + +**现象:** 返回的用户信息缺少某些字段 + +**排查步骤:** + +1. 检查用户是否设置了该字段 +2. 检查数据库中 `user_data` 集合是否有该字段 + +**响应示例:** + +```json +{ + "user_id": "69bd422960018cf4d0e5", + "email": "user@example.com", + "name": "张三", + "github_username": "zhangsan", + "permission": 1 +} +``` + +--- + +## 远程退登问题 + +### 1. 远程退登不生效 + +**现象:** 用户在 SECTL Auth 退出后,第三方平台没有自动退出 + +**排查步骤:** + +1. 检查是否正确订阅了 `logout_events` 集合 +2. 检查 user_id 是否匹配 +3. 确认 Appwrite Realtime 连接正常 +4. 查看浏览器控制台是否有错误 + +**订阅代码示例:** + +```javascript +client.subscribe( + "databases.69bd89d8000304c37368.collections.logout_events.documents", + (response) => { + const event = response.payload + if (event.user_id === currentUserId) { + localLogout() + } + } +) +``` + +**相关页面:** + +- [SecurityView.vue](../../src/views/dashboard/other/SecurityView.vue) +- [PlatformManagementView.vue](../../src/views/dashboard/manage/PlatformManagementView.vue) + +--- + +### 2. Realtime 连接断开 + +**现象:** 退登事件偶尔收不到 + +**排查步骤:** + +1. 检查网络连接稳定性 +2. 检查是否有心跳机制保持连接 +3. 检查浏览器是否进入休眠状态 + +**解决方案:** + +- 实现重连机制 +- 定期检查连接状态 +- 使用 Service Worker 保持后台连接 + +--- + +## 平台管理问题 + +### 1. 平台管理的"登录用户"为空 + +**现象:** 在平台管理页面查看登录用户,显示为空 + +**排查步骤:** + +1. 检查 `oauth_tokens` 集合是否有记录 +2. 检查记录是否有 `user_id` 字段 +3. 检查 `oauth_tokens` 集合权限 + +**解决方案:** + +如果 `oauth_tokens` 没有 `user_id` 字段,需要在 Appwrite Console 中添加: + +1. 进入 Database → 选择数据库 +2. 找到 `oauth_tokens` 集合 +3. 添加字段:`user_id`(String 类型,非必填) + +**相关页面:** + +- [PlatformManagementView.vue](../../src/views/dashboard/manage/PlatformManagementView.vue) +- [PlatformUsersView.vue](../../src/views/dashboard/manage/PlatformUsersView.vue) + +--- + +### 2. 平台状态显示"审核中" + +**现象:** 新创建的平台无法使用,状态为 `pending` + +**排查步骤:** + +1. 检查是否已提交平台申请 +2. 联系管理员审核 +3. 在 [MyPlatformApplicationsView.vue](../../src/views/dashboard/manage/MyPlatformApplicationsView.vue) 查看申请状态 + +**解决方案:** + +- 等待管理员审核 +- 管理员在 [PlatformApplicationsView.vue](../../src/views/dashboard/manage/PlatformApplicationsView.vue) 中批准申请 + +--- + +### 3. 无法修改平台回调地址 + +**现象:** 在平台设置中修改回调地址失败 + +**排查步骤:** + +1. 检查是否有权限修改(所有者或管理员) +2. 检查回调地址格式是否正确 +3. 检查数据库权限配置 + +**相关页面:** [PlatformSettingsView.vue](../../src/views/dashboard/other/PlatformSettingsView.vue) + +--- + +## 网络与 CORS 问题 + +### 1. CORS 错误 + +**现象:** 浏览器控制台显示 CORS 错误 + +**错误信息:** + +``` +Access to fetch at 'https://auth.sectl.top/...' from origin 'https://auth.sectl.top' has been blocked by CORS policy +``` + +**解决方案:** + +已在 OAuth API 中添加 CORS 头: + +```javascript +res.setHeader("Access-Control-Allow-Origin", "*") +res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS") +res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization") +``` + +**排查步骤:** + +1. 确认请求头是否正确 +2. 确认是否为预检请求(OPTIONS)问题 +3. 检查服务器 CORS 配置 + +--- + +### 2. 授权码中的用户ID解码失败 + +**现象:** 换取 token 后 `user_id` 为 "anonymous" + +**排查步骤:** + +1. 检查授权码格式(应为 32 位:前16位 base64 用户ID + 后16位随机) +2. 检查 `oauth_codes` 集合是否有 `user_id` 字段 + +**代码逻辑:** + +```javascript +// 生成授权码时编码用户ID +const userIdHash = Buffer.from(userId) + .toString("base64") + .replace(/[^a-zA-Z0-9]/g, "") + .substring(0, 16) +const code = userIdHash + randomPart + +// 换取 token 时解码 +try { + const userIdHash = code.substring(0, 16) + const base64Str = userIdHash.replace(/_/g, "/").replace(/-/g, "+") + "==" + const decoded = Buffer.from(base64Str, "base64").toString("utf8") + tokenUserId = decoded +} catch (e) { + tokenUserId = "anonymous" +} +``` + +--- + +### 3. 网络超时 + +**现象:** 请求 OAuth API 超时 + +**排查步骤:** + +1. 检查网络连接 +2. 检查服务器状态 +3. 增加请求超时时间 + +**解决方案:** + +```javascript +// 增加超时时间 +const response = await fetch(url, { + ...options, + signal: AbortSignal.timeout(30000), // 30秒超时 +}) +``` + +--- + +## 调试技巧 + +### 1. 浏览器开发者工具 + +使用浏览器开发者工具排查问题: + +1. **Network 面板** - 查看请求和响应 +2. **Console 面板** - 查看错误日志 +3. **Application 面板** - 查看 Cookie 和 LocalStorage + +### 2. Appwrite Console + +在 Appwrite Console 中检查: + +1. **Database** - 检查集合数据和权限 +2. **Auth** - 检查用户和会话 +3. **Functions** - 查看函数日志 +4. **Realtime** - 检查实时连接 + +### 3. 日志记录 + +在关键位置添加日志: + +```javascript +// 授权流程日志 +console.log("OAuth params:", { client_id, redirect_uri, response_type }) +console.log("Authorization code:", code) +console.log("Token response:", tokenData) + +// 退登事件日志 +console.log("Logout event received:", event) +console.log("Current user ID:", currentUserId) +``` + +--- + +## 常见问题速查表 + +| 问题 | 可能原因 | 解决方案 | +| :------------- | :------------------- | :---------------------- | +| 授权页面 404 | 平台不存在或状态异常 | 检查平台状态和 ID | +| Invalid code | Code 过期或已使用 | 重新授权获取新 code | +| Invalid client | 密钥错误 | 检查 client_secret | +| Token 过期 | 超过 expires_in | 使用 refresh_token 刷新 | +| 用户信息 401 | Token 无效 | 检查 Token 格式和有效期 | +| 退登不生效 | Realtime 未连接 | 检查订阅代码 | +| CORS 错误 | 跨域配置问题 | 检查服务器 CORS 头 | + +--- + +## 获取帮助 + +如果以上方案无法解决问题: + +1. 查看 [API 参考](../platform-integration/API_REFERENCE.md) +2. 查看 [平台接入指南](../platform-integration/README.md) +3. 提交 Issue 到项目仓库 +4. 联系管理员 + +--- + +## 相关页面 + +- [OAuthAuthorizeView.vue](../../src/views/OAuthAuthorizeView.vue) - OAuth 授权页面 +- [AuthCallbackView.vue](../../src/views/AuthCallbackView.vue) - 认证回调 +- [LoginView.vue](../../src/views/LoginView.vue) - 登录页面 +- [PlatformManagementView.vue](../../src/views/dashboard/manage/PlatformManagementView.vue) - 平台管理 +- [PlatformSettingsView.vue](../../src/views/dashboard/other/PlatformSettingsView.vue) - 平台设置 +- [SecurityView.vue](../../src/views/dashboard/other/SecurityView.vue) - 安全设置 +- [LoginPlatformsView.vue](../../src/views/dashboard/list/LoginPlatformsView.vue) - 登录平台列表 diff --git a/package.json b/package.json index 5a1ea6f..78531b5 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,9 @@ "@ant-design/icons": "^6.1.0", "@react-awesome-query-builder/antd": "6.7.0-alpha.0", "@tauri-apps/api": "^2.5.0", + "@tauri-apps/plugin-shell": "^2.3.5", "antd": "^6.3.1", + "appwrite": "^24.0.0", "dayjs": "^1.11.20", "i18next": "^25.8.14", "json-rules-engine": "^7.3.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8b2c5bb..4c29935 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,9 +17,15 @@ importers: '@tauri-apps/api': specifier: ^2.5.0 version: 2.10.1 + '@tauri-apps/plugin-shell': + specifier: ^2.3.5 + version: 2.3.5 antd: specifier: ^6.3.1 version: 6.3.2(moment@2.30.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + appwrite: + specifier: ^24.0.0 + version: 24.0.0 dayjs: specifier: ^1.11.20 version: 1.11.20 @@ -842,79 +848,66 @@ packages: resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} cpu: [arm] os: [linux] - libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.59.0': resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} cpu: [arm] os: [linux] - libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.59.0': resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} cpu: [arm64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.59.0': resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} cpu: [arm64] os: [linux] - libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.59.0': resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} cpu: [loong64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-loong64-musl@4.59.0': resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} cpu: [loong64] os: [linux] - libc: [musl] '@rollup/rollup-linux-ppc64-gnu@4.59.0': resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} cpu: [ppc64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-ppc64-musl@4.59.0': resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} cpu: [ppc64] os: [linux] - libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.59.0': resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} cpu: [riscv64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.59.0': resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} cpu: [riscv64] os: [linux] - libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.59.0': resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} cpu: [s390x] os: [linux] - libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.59.0': resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} cpu: [x64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-x64-musl@4.59.0': resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} cpu: [x64] os: [linux] - libc: [musl] '@rollup/rollup-openbsd-x64@4.59.0': resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} @@ -978,35 +971,30 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] - libc: [glibc] '@tauri-apps/cli-linux-arm64-musl@2.10.1': resolution: {integrity: sha512-MIj78PDDGjkg3NqGptDOGgfXks7SYJwhiMh8SBoZS+vfdz7yP5jN18bNaLnDhsVIPARcAhE1TlsZe/8Yxo2zqg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - libc: [musl] '@tauri-apps/cli-linux-riscv64-gnu@2.10.1': resolution: {integrity: sha512-X0lvOVUg8PCVaoEtEAnpxmnkwlE1gcMDTqfhbefICKDnOTJ5Est3qL0SrWxizDackIOKBcvtpejrSiVpuJI1kw==} engines: {node: '>= 10'} cpu: [riscv64] os: [linux] - libc: [glibc] '@tauri-apps/cli-linux-x64-gnu@2.10.1': resolution: {integrity: sha512-2/12bEzsJS9fAKybxgicCDFxYD1WEI9kO+tlDwX5znWG2GwMBaiWcmhGlZ8fi+DMe9CXlcVarMTYc0L3REIRxw==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - libc: [glibc] '@tauri-apps/cli-linux-x64-musl@2.10.1': resolution: {integrity: sha512-Y8J0ZzswPz50UcGOFuXGEMrxbjwKSPgXftx5qnkuMs2rmwQB5ssvLb6tn54wDSYxe7S6vlLob9vt0VKuNOaCIQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - libc: [musl] '@tauri-apps/cli-win32-arm64-msvc@2.10.1': resolution: {integrity: sha512-iSt5B86jHYAPJa/IlYw++SXtFPGnWtFJriHn7X0NFBVunF6zu9+/zOn8OgqIWSl8RgzhLGXQEEtGBdR4wzpVgg==} @@ -1031,6 +1019,9 @@ packages: engines: {node: '>= 10'} hasBin: true + '@tauri-apps/plugin-shell@2.3.5': + resolution: {integrity: sha512-jewtULhiQ7lI7+owCKAjc8tYLJr92U16bPOeAa472LHJdgaibLP83NcfAF2e+wkEcA53FxKQAZ7byDzs2eeizg==} + '@ts-jison/common@0.4.1-alpha.1': resolution: {integrity: sha512-SDbHzq+UMD+V3ciKVBHwCEgVqSeyQPTCjOsd/ZNTGySUVg4x3EauR9ZcEfdVFAsYRR38XWgDI+spq5LDY46KvQ==} @@ -1172,6 +1163,9 @@ packages: react: '>=18.0.0' react-dom: '>=18.0.0' + appwrite@24.0.0: + resolution: {integrity: sha512-zo0ZMf+B5S+OgGLXMvzAFDNWU/RB3a38oO40o/Atjdk0itBj3Z6uk1cp4ckNWiwZVFoThFrjZWBw2Au+Flk7lw==} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -1223,6 +1217,9 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + bignumber.js@9.3.1: + resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + brace-expansion@1.1.12: resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} @@ -1767,6 +1764,9 @@ packages: engines: {node: '>=6'} hasBin: true + json-bigint@1.0.0: + resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} + json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} @@ -3310,6 +3310,10 @@ snapshots: '@tauri-apps/cli-win32-ia32-msvc': 2.10.1 '@tauri-apps/cli-win32-x64-msvc': 2.10.1 + '@tauri-apps/plugin-shell@2.3.5': + dependencies: + '@tauri-apps/api': 2.10.1 + '@ts-jison/common@0.4.1-alpha.1': {} '@ts-jison/lexer@0.4.1-alpha.1': @@ -3546,6 +3550,10 @@ snapshots: - luxon - moment + appwrite@24.0.0: + dependencies: + json-bigint: 1.0.0 + argparse@2.0.1: {} array-buffer-byte-length@1.0.2: @@ -3617,6 +3625,8 @@ snapshots: baseline-browser-mapping@2.10.8: {} + bignumber.js@9.3.1: {} + brace-expansion@1.1.12: dependencies: balanced-match: 1.0.2 @@ -4282,6 +4292,10 @@ snapshots: jsesc@3.1.0: {} + json-bigint@1.0.0: + dependencies: + bignumber.js: 9.3.1 + json-buffer@3.0.1: {} json-logic-js@2.0.5: {} diff --git a/resources/看板SQL生成提示词.md b/resources/看板SQL生成提示词.md index be906a4..5b28d16 100644 --- a/resources/看板SQL生成提示词.md +++ b/resources/看板SQL生成提示词.md @@ -3,6 +3,7 @@ 你是 SecScore 的“看板 SQL 生成器”。你的任务是根据“用户需求”生成一条可直接在看板执行的 SQL。 ## 1) 强约束(必须全部满足) + 1. 只允许输出**单条只读查询**,且必须以 `SELECT` 或 `WITH` 开头。 2. 禁止输出分号 `;`。 3. 禁止输出注释:`--`、`/*`、`*/`。 @@ -14,9 +15,11 @@ 6. 只返回 SQL 纯文本,不要 markdown,不要解释。 ## 2) 模板变量(仅允许以下 6 个) + 说明:本提示词里占位符写成了 `{ {xxx} }`(中间有空格),这是为了兼容部分模型平台。你在理解时请把空格忽略,按标准占位符理解;你在最终输出 SQL 时,请使用无空格的标准写法。 只允许使用: + - `{ {now} }` - `{ {today_start} }` - `{ {this_week_start} }` @@ -25,12 +28,15 @@ - `{ {since_30d} }` 并且: + 1. 模板变量必须放在**单引号**中使用,例如 `event_time >= '{ {since_7d} }'`。 2. 严禁发明任何未支持变量,例如:`{ {month_start} }`、`{ {last_month_start} }` 等。 3. 严禁输出任何带花括号但不在允许列表中的占位符。 ## 3) 系统表/元数据表禁用(防跨库报错) + 禁止查询任何数据库系统表、元数据表或 PRAGMA 信息,包括但不限于: + - `sqlite_master`, `sqlite_schema`, `pragma_*` - `pg_catalog.*`, `pg_class`, `pg_tables` - `information_schema.*` @@ -38,34 +44,45 @@ 只允许使用下面给定的业务表。 ## 4) 可用业务表与字段 + 1. `students` + - `id`, `name`, `tags`, `score`, `reward_points`, `extra_json`, `created_at`, `updated_at` 2. `reasons` + - `id`, `content`, `category`, `delta`, `is_system`, `updated_at` 3. `score_events` + - `id`, `uuid`, `student_name`, `reason_content`, `delta`, `val_prev`, `val_curr`, `event_time`, `settlement_id` 4. `settlements` + - `id`, `start_time`, `end_time`, `created_at` 5. `settings` + - `key`, `value` 6. `tags` + - `id`, `name`, `created_at`, `updated_at` 7. `student_tags` + - `id`, `student_id`, `tag_id`, `created_at` 8. `reward_settings` + - `id`, `name`, `cost_points`, `created_at`, `updated_at` 9. `reward_redemptions` + - `id`, `uuid`, `student_name`, `reward_id`, `reward_name`, `cost_points`, `redeemed_at` ## 5) 字段名使用铁律(必须遵守,防止列不存在) + 1. `SELECT`、`WHERE`、`GROUP BY`、`ORDER BY`、`JOIN ON` 中引用的字段名,必须来自上面的“可用业务表与字段”原样字段,严禁臆造字段。 2. “展示名/别名”不等于真实字段名。若需展示为 `student_name`,必须使用别名,不可把别名当字段直接查询。 3. 关键映射(高频易错): @@ -76,64 +93,80 @@ 5. 正确示例(优先生成):`SELECT name AS student_name, score FROM students` ## 6) 看板展示字段命名约定(尽量遵守) + - 学生名统一命名为:`student_name` - 常见指标命名建议:`score`, `reward_points`, `week_change`, `week_deducted`, `answered_count` ## 7) 生成策略 + 1. 排行类需求必须有 `ORDER BY`。 2. 聚合类需求必须有清晰别名。 3. 对可能为空的数据优先使用 `COALESCE`。 4. 默认不写 `LIMIT`(系统外层会限制);除非用户明确要求更小结果集。 ## 7.1) 积分符号语义(高优先级强制规则) + `score_events.delta` 的业务语义固定为: + - `delta > 0`:加分 - `delta < 0`:扣分 - `delta = 0`:不变(通常可忽略) 因此遇到“扣分”相关自然语言时,必须按以下规则改写: + 1. “扣分记录” => `delta < 0` 2. “扣分大于 N 分 / 扣了超过 N 分” => `delta < -N`(或等价写法 `delta < 0 AND ABS(delta) > N`) 3. “扣分至少 N 分” => `delta <= -N`(或等价写法 `delta < 0 AND ABS(delta) >= N`) 4. “加分大于 N 分” => `delta > N` 错误示例(禁止生成): + - “扣分 > 5” 写成 `delta > 5` 正确示例(优先生成): + - “扣分 > 5” 写成 `delta < -5` - “只看扣分” 写成 `delta < 0` ## 7.2) 积分相关查询结果字段强制规则 + 若用户意图与“积分”相关(例如:积分排行、积分变化、扣分/加分统计、学生积分看板),最终结果中必须包含“学生当前总积分”字段: + - 字段名统一输出为:`score` - 来源必须是 `students.score`(不是 `SUM(score_events.delta)`) 生成要求: + 1. 若主表是 `students`:直接选择 `students.score AS score`(或 `s.score AS score`) 2. 若主表不是 `students`(如 `score_events`):必须关联 `students` 并带出总积分 标准关联:`LEFT JOIN students s ON s.name = <学生名字段>` 3. 若查询按学生聚合,仍需在结果中包含 `score`,不要省略 错误示例(禁止生成): + - 积分相关 SQL 只返回 `student_name`、`week_change`,但没有 `score` - 用 `SUM(delta)` 命名为 `score` 冒充当前总积分 正确示例(优先生成): + - `SELECT e.student_name, COALESCE(s.score, 0) AS score, SUM(e.delta) AS week_change ... LEFT JOIN students s ON s.name = e.student_name ...` - `SELECT s.name AS student_name, s.score AS score FROM students s ...` ## 8) 自然周规则(允许生成上个自然周 SQL) + 当用户要求“上个自然周/本自然周”时,必须使用模板变量区间表达,不要自行计算数据库日期函数: + - 上个自然周:`event_time >= '{ {last_week_start} }' AND event_time < '{ {this_week_start} }'` - 本自然周:`event_time >= '{ {this_week_start} }'` 注意: + 1. 模板变量必须带单引号。 2. 不要发明其它周边界变量。 3. 避免使用 SQLite/PostgreSQL 方言日期函数(如 `strftime`、`date_trunc`)以保证跨库兼容。 ## 9) 输出前自检清单(必须全部为“是”) + - 是否只用了 `SELECT/WITH`? - 是否没有 `;` 和注释? - 是否没有禁用关键词? diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index c89fa74..6c69b4a 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -606,6 +606,26 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom 0.2.17", + "once_cell", + "tiny-keccak", +] + [[package]] name = "convert_case" version = "0.4.0" @@ -728,6 +748,12 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + [[package]] name = "crypto-common" version = "0.1.7" @@ -967,6 +993,15 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "dlv-list" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" +dependencies = [ + "const-random", +] + [[package]] name = "dom_query" version = "0.27.0" @@ -2818,6 +2853,16 @@ dependencies = [ "num-traits", ] +[[package]] +name = "ordered-multimap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" +dependencies = [ + "dlv-list", + "hashbrown 0.14.5", +] + [[package]] name = "os_pipe" version = "1.2.3" @@ -3850,6 +3895,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rust-ini" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "796e8d2b6696392a43bea58116b667fb4c29727dc5abd27d6acf338bb4f688c7" +dependencies = [ + "cfg-if", + "ordered-multimap", +] + [[package]] name = "rust_decimal" version = "1.40.0" @@ -4178,12 +4233,14 @@ dependencies = [ "sqlx", "tauri", "tauri-build", + "tauri-plugin-deep-link", "tauri-plugin-shell", "tokio", "tokio-util", "tracing", "tracing-appender", "tracing-subscriber", + "urlencoding", "uuid", ] @@ -5215,6 +5272,27 @@ dependencies = [ "walkdir", ] +[[package]] +name = "tauri-plugin-deep-link" +version = "2.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94deb2e2e4641514ac496db2cddcfc850d6fc9d51ea17b82292a0490bd20ba5b" +dependencies = [ + "dunce", + "plist", + "rust-ini", + "serde", + "serde_json", + "tauri", + "tauri-plugin", + "tauri-utils", + "thiserror 2.0.18", + "tracing", + "url", + "windows-registry", + "windows-result 0.3.4", +] + [[package]] name = "tauri-plugin-shell" version = "2.3.5" @@ -5450,6 +5528,15 @@ dependencies = [ "time-core", ] +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + [[package]] name = "tinystr" version = "0.8.2" @@ -6440,6 +6527,17 @@ dependencies = [ "windows-link 0.1.3", ] +[[package]] +name = "windows-registry" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" +dependencies = [ + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", +] + [[package]] name = "windows-result" version = "0.3.4" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 3a1fdd9..2abbe0c 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -16,6 +16,7 @@ tauri-build = { version = "2", features = [] } [dependencies] tauri = { version = "2", features = ["macos-private-api", "tray-icon", "image-png", "protocol-asset"] } tauri-plugin-shell = "2" +tauri-plugin-deep-link = "2" serde = { version = "1", features = ["derive"] } serde_json = "1" tokio = { version = "1", features = ["full"] } @@ -39,6 +40,7 @@ once_cell = "1" parking_lot = { version = "0.12", features = ["send_guard"] } dirs = "6.0.0" reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] } +urlencoding = "2.1" [profile.release] panic = "abort" diff --git a/src-tauri/data.sql b/src-tauri/data.sql new file mode 100644 index 0000000000000000000000000000000000000000..34d90ab2dce15664a56a5aa31abc6e565262ad60 GIT binary patch literal 110592 zcmeI*eQXrxod@t8kG>UF!8{=@9fSk2uyX=b%HVCP%S&$Xm1iz$EVok<7W3y$w zYi4FKZj%$XA>T#DRN5=#H{)1dX>q6LYwDX-G&BDN%@gFmsQtD7shY=q1JytEJ;HtF zeVe;l`IEDRChO=UJ>Te$3(L0)&3?i0m6S<6N8$(LL&B3oeFHs1M};TiM}?lz zkwblhq^N=T;7FTmk8GCgGZH^CA`BiP-=qEg!suY%;nBD|o2F-FYLk|x6nA!aKC6a~ zdf3I5%(qr?iHxR;)0rfRQ2xYLDo|EP_+*i^IpcKp#}D+3_Kyh7vZO0|a!P3qr86_3 zHX)SCB%~Bg3AME3En0dvd4u1KFdn0MXeU#o4U1A%C&wnug#@WMR$^p%+UEH&o(s0N zGG|XZBTQRCGCgUB*IunF6b$|j zt!o6yCd^03PT06GSjz>QnwaO!3(#)Vx-_XdmjkZAIJc}jDt2LOULd4Sq$66R(cg)X z95^%-?>jhX^b^g6>a_?%@dNRp_+W2*Sg?|{=A_(0`?&q_{y6CpdwYg^d-fOg6t42j zvv8F~vCApP?1cnJmD&WWxI%l_9q51f|=33d{ z@^oz~3)bCxm`4!5t!2`y-Ghod8T*D&Xf`v|TyWbqX0FGmzTG|8zkRMs+o?tMJ)z8+ zb#UBg-L*X>rLyL|vT)#?K5wvh+e*Urp-5Y`?il`gFUJLU>|hp#^HnuRDH_dUEmkk9 zu(hG6&W`@XQR~%42jrqqb&=jHR|8kl@|t;Wud6D^EeuqdUH6y?;TXF)M_gVvg(KIx zE$;Y8Nh0l-UNt%ySgpn@D=A%C<4!;tn>ej1r^?8d$g1iZ*^DuQb{AIM=h@lH9sRafdV@WUD|Jj3 zBppy0%vDcTcEkwivd0$$AOHafKmY;|fB*y_009U<00LiG z0s8!3!GG@I|BL*<7X%;x0SG_<0uX=z1Rwwb2tWV=_qRZG1zXS14?(aS7`BnIJ{w}Z z|Mv&J=HdT=zsO5`l=lRFAGj1a7kG*!;tK*0fB*y_009U<00Izz00bUTfye!vr=g+R z7c>7x!u%NxM|ZV{W9`vyA=0%c9NiP`YWH!TrUu3rTRO9_boqyiAHSaa=tXn+PbIR4 zs%fz#`;8xcxODj%$(VcTXJ3@c$mKJ>`}vtOX2$<3mC%!udtN&9fJ8Nan zUAdHd@!j0T3%U1yZf372kv&$yc_M}SSe5zc$2Z?OV^)bRu~Rogc50&Bm#^jCoL_qD z7dOBE!J@H~Go`A;u71*z{roc?{&)Nv{4@L~{CWOa{sjLA{+ImA4`?IDX+r=45P$## zAOHafKmY;|fB*z;S-{UWFy=Igzm9EU%sCKqKEy}2nKK^M<|3Wb;OL?`YvJ9@wlYQY z5>-Yij+uu_n&6yUV7IUlYcJ>QK}9_q@i}J$%=rQQ{r@e86gxlw0uX=z1Rwwb2tWV= z5P$##?mGec{vZGT-+dQ0R2TvffB*y_009U<00Izz00ba#O9FWRe@k4*3;_s000Izz z00bZa0SG_<0uZ<_1?cmCU2Px3{~P}={NM9$@(bjz|A+Xm^MA!x1^zwow*jGcvG$$X zzWegzP-zH200Izz00bZa0SG_<0$+x}({+{m=4v%1kyVrWtf(r9%qc~k6*XN=rYCoG zMLWWsa>qm>Dn&bEiSB4Prbv-!qFYH!M8mS&9qW?26geE}i0+=~>WW3XJ7S&Du3h19 zBGMV_*vqr~2J(fQ|M$E&Eos_JMwP?z_^$3qnC#ur)hQ*$6*(f0cStd*yDJvn9h3G1 z*u90FC3z~D&hHzM5}jSUBVFUWq6vATYxjhd2**0Q!yO%+9dbvvG{@Ig?w!j{WyX^! zMI6uQdS*&YOQ*!7u1smiwja+-Dcjq&YkF2z(z-?$6B(5zNm)J9Zm+1yjHJr#nxgAO zgJv7gkOaDrQY2YXja9lg$&pf~tg@_srQS+6_8jZ3VLJ~`Pl}05I;|x1WF}3FB|WQs zce|CO$lLemYF266uFp;@+xKkOPNqn8w?Fq>{RXyuBdwTdR7_N}DMdRr7WA{7wZ%o! zun9i4Jwzg^lKP1HaZ)caDW{T?$MtqunUJz6y{?*lv_6%Y6jRD6C6!E1WP%(U6D_Am~8Q~5#DidB`uAoNYEOq*uA`*)aaV1DUzBvE}l?k4UzC;m2CI6 zqC_zz&1SOt$r(k}XQR7#mfgY6B-3(cM*L1DGZooV!S38BOWJYMm`Y6~Cy$M7V%X3| z<192Wk<~~fkB!mK|JMc1d-(72o5)lDzw$5h34S#2Y2d&45PvD~cY&V;&h!7l|Kpc& z$)HRKKmY;|fB*y_009U<00Izr-~=9F_c8hDjiR}eI@iXcxevaP-CNkxJ+~2{+g6yl zsC}62WQrg8=`2FcLu@2sV_;O(zKaG_z90Yr2tWV=5P$##AOHafKmY;| zxJ`i$w#xHpES9@=Zt41KH{O3c8jkL2569Z0-9n^mPdK_K+EpScQc>k;h{cxv=5p@s zk4tPXkrZK!UCjU4uf+BeN%ZsoEdQy8{}cZy|Hs=rLF@(r2tWV=5P$##AOHafKmY;| zfWW;Ipnr#upLJmUYy)G?CRF&?2A?@gfY1NmyYS%15P$##AOHafKmY;|fB*y_0D-$D zK;Qp+>h9Lja2yCg00Izz00bZa0SG_<0uX=z1nz|Z-v8eVbsQ4{5P$##AOHafKmY;| zfB*y_aCZgp{{QZJ<7g0o00bZa0SG_<0uX=z1Rwx`dm(`L|Mx;2$Aka`AOHafKmY;| zfB*y_009WxT>-rRzq{Tz8U!E!0SG_<0uX=z1Rwwb2teRo2;lkuUZ~@k5P$##AOHaf zKmY;|fB*y_0D-$Jfam|a>y4v900Izz00bZa0SG_<0uX=z1nz|Z{ri7E_n9ZKt9G$Q zto^nBshY=q1JytEJ;HtFeVe;l`Ilqs?-CS~WAhkA$NJtJ|UZ*YJ7h_K>*cjFjF-GoDfg0p_j zu9~+jY~9EOBN67Ds7vE1MO9`bRTfo6R;H%)WG1aGPuXOh;YiOn`s2d#?LxC(aC{|Y zVlfgw7#|Xz9O@hB89FLF5kD&QjE)@Y8ze;y#0N*(Tzh1*WS^1vkr83=5cwYM?-xb~ z`woxB-PtrfD^vfpG^Mz+yYpE!bkxHxwq(Awic4fPU7XG&Nh`>o*h&S;3TYy;DCuVX z_QwzOjP{QR&9bB`dU8r>4y7|Qp*A6u$|R%|O$oKM^_80XOuJX*YaFs=|%PGg~g#<^H+61dOXM12~o@iRBJ=kYM4=F~R zYyAAC4P3Cko;k}I7b?v`ziV8Przz`>c)8c%U%=HBs__Q*)~}>#D$<{|bNl>UFcf0u zyA8eZ484yfGUzYI!9byH-#hDx-IVbNJ%2?m|itH8Cb2xD=R5oTH{VY8k;z+DyPcGmdL8= z8rh6-w{#oUkUz!_TayD^vM^*=2^^ zg%$UCcD8ayzwMRYU{B*p9g_t~2UG@g)sq!oI?O$4UW?{nSyN7Cm2^U}#?JOC>k3KH z#%6kVY$I7)77j8-pZvUJmT5k3*uyfd!d;5Bb={F&esgxSPO6#gbm5`Lz0nvR7>`c2 zcIenxQIL(MyH@b52Z^HR9J|n>NGqpxRVv&A-Br51Ue;a4dYck`{ttNfcmjV6d{XnD zHCHwq+0fv7*0;O*SJg4@_gupJPh=y$AOHafKmY=Hfw|g;x!^#AnQO_<123Orv!~*c z^73ts)+nJcAG|zIVShT4v3z^8l|-gG=C%a6;4rCA=W6w_=N0H!VtH{}%c+vHh!tw( z%+jK6;ez{GnK@r^z3k^kW5{Av#!hQksU~&?bDUE^vD1w~TFbZUy}?)`lXV=@7z^4@ zFxJrU;Sxu2{Q{z#mjk_ zhyNY_2LBBI34fk{mOsJ&f&V4{a(<|X1qeU@0uX=z1Rwwb2tWV=5P$##Ru%BG4UGAL z5`P`r#4MdzSi1bf#gAXlee|M_ZoBcL50@@qt2P(k{rt=sjxH`;|4HtJ54@Y%R)*wV zyz=Ue*Wb%sx^Ux#i&aJ`*Wbwf;CnZ(zL&f9QYB5uUAdHd@!j0T3%U1y&Te5N)?Vf= ziy!^?<~wI9>e+~o94hzb{L)*$xcU7L%w+ui|El4`MhHLv0uX=z1Rwwb2tWV=5P-l} zLIBVIUx_f{Bp?6*2tWV=5P$##AOHafKmY=(3gG#FRUT}F00bZa0SG_<0uX=z1Rwwb J2z(_3{vY8*M-c!3 literal 0 HcmV?d00001 diff --git a/src-tauri/gen/schemas/acl-manifests.json b/src-tauri/gen/schemas/acl-manifests.json new file mode 100644 index 0000000..93a3053 --- /dev/null +++ b/src-tauri/gen/schemas/acl-manifests.json @@ -0,0 +1 @@ +{"core":{"default_permission":{"identifier":"default","description":"Default core plugins set.","permissions":["core:path:default","core:event:default","core:window:default","core:webview:default","core:app:default","core:image:default","core:resources:default","core:menu:default","core:tray:default"]},"permissions":{},"permission_sets":{},"global_scope_schema":null},"core:app":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-version","allow-name","allow-tauri-version","allow-identifier","allow-bundle-type","allow-register-listener","allow-remove-listener"]},"permissions":{"allow-app-hide":{"identifier":"allow-app-hide","description":"Enables the app_hide command without any pre-configured scope.","commands":{"allow":["app_hide"],"deny":[]}},"allow-app-show":{"identifier":"allow-app-show","description":"Enables the app_show command without any pre-configured scope.","commands":{"allow":["app_show"],"deny":[]}},"allow-bundle-type":{"identifier":"allow-bundle-type","description":"Enables the bundle_type command without any pre-configured scope.","commands":{"allow":["bundle_type"],"deny":[]}},"allow-default-window-icon":{"identifier":"allow-default-window-icon","description":"Enables the default_window_icon command without any pre-configured scope.","commands":{"allow":["default_window_icon"],"deny":[]}},"allow-fetch-data-store-identifiers":{"identifier":"allow-fetch-data-store-identifiers","description":"Enables the fetch_data_store_identifiers command without any pre-configured scope.","commands":{"allow":["fetch_data_store_identifiers"],"deny":[]}},"allow-identifier":{"identifier":"allow-identifier","description":"Enables the identifier command without any pre-configured scope.","commands":{"allow":["identifier"],"deny":[]}},"allow-name":{"identifier":"allow-name","description":"Enables the name command without any pre-configured scope.","commands":{"allow":["name"],"deny":[]}},"allow-register-listener":{"identifier":"allow-register-listener","description":"Enables the register_listener command without any pre-configured scope.","commands":{"allow":["register_listener"],"deny":[]}},"allow-remove-data-store":{"identifier":"allow-remove-data-store","description":"Enables the remove_data_store command without any pre-configured scope.","commands":{"allow":["remove_data_store"],"deny":[]}},"allow-remove-listener":{"identifier":"allow-remove-listener","description":"Enables the remove_listener command without any pre-configured scope.","commands":{"allow":["remove_listener"],"deny":[]}},"allow-set-app-theme":{"identifier":"allow-set-app-theme","description":"Enables the set_app_theme command without any pre-configured scope.","commands":{"allow":["set_app_theme"],"deny":[]}},"allow-set-dock-visibility":{"identifier":"allow-set-dock-visibility","description":"Enables the set_dock_visibility command without any pre-configured scope.","commands":{"allow":["set_dock_visibility"],"deny":[]}},"allow-tauri-version":{"identifier":"allow-tauri-version","description":"Enables the tauri_version command without any pre-configured scope.","commands":{"allow":["tauri_version"],"deny":[]}},"allow-version":{"identifier":"allow-version","description":"Enables the version command without any pre-configured scope.","commands":{"allow":["version"],"deny":[]}},"deny-app-hide":{"identifier":"deny-app-hide","description":"Denies the app_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["app_hide"]}},"deny-app-show":{"identifier":"deny-app-show","description":"Denies the app_show command without any pre-configured scope.","commands":{"allow":[],"deny":["app_show"]}},"deny-bundle-type":{"identifier":"deny-bundle-type","description":"Denies the bundle_type command without any pre-configured scope.","commands":{"allow":[],"deny":["bundle_type"]}},"deny-default-window-icon":{"identifier":"deny-default-window-icon","description":"Denies the default_window_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["default_window_icon"]}},"deny-fetch-data-store-identifiers":{"identifier":"deny-fetch-data-store-identifiers","description":"Denies the fetch_data_store_identifiers command without any pre-configured scope.","commands":{"allow":[],"deny":["fetch_data_store_identifiers"]}},"deny-identifier":{"identifier":"deny-identifier","description":"Denies the identifier command without any pre-configured scope.","commands":{"allow":[],"deny":["identifier"]}},"deny-name":{"identifier":"deny-name","description":"Denies the name command without any pre-configured scope.","commands":{"allow":[],"deny":["name"]}},"deny-register-listener":{"identifier":"deny-register-listener","description":"Denies the register_listener command without any pre-configured scope.","commands":{"allow":[],"deny":["register_listener"]}},"deny-remove-data-store":{"identifier":"deny-remove-data-store","description":"Denies the remove_data_store command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_data_store"]}},"deny-remove-listener":{"identifier":"deny-remove-listener","description":"Denies the remove_listener command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_listener"]}},"deny-set-app-theme":{"identifier":"deny-set-app-theme","description":"Denies the set_app_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_app_theme"]}},"deny-set-dock-visibility":{"identifier":"deny-set-dock-visibility","description":"Denies the set_dock_visibility command without any pre-configured scope.","commands":{"allow":[],"deny":["set_dock_visibility"]}},"deny-tauri-version":{"identifier":"deny-tauri-version","description":"Denies the tauri_version command without any pre-configured scope.","commands":{"allow":[],"deny":["tauri_version"]}},"deny-version":{"identifier":"deny-version","description":"Denies the version command without any pre-configured scope.","commands":{"allow":[],"deny":["version"]}}},"permission_sets":{},"global_scope_schema":null},"core:event":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-listen","allow-unlisten","allow-emit","allow-emit-to"]},"permissions":{"allow-emit":{"identifier":"allow-emit","description":"Enables the emit command without any pre-configured scope.","commands":{"allow":["emit"],"deny":[]}},"allow-emit-to":{"identifier":"allow-emit-to","description":"Enables the emit_to command without any pre-configured scope.","commands":{"allow":["emit_to"],"deny":[]}},"allow-listen":{"identifier":"allow-listen","description":"Enables the listen command without any pre-configured scope.","commands":{"allow":["listen"],"deny":[]}},"allow-unlisten":{"identifier":"allow-unlisten","description":"Enables the unlisten command without any pre-configured scope.","commands":{"allow":["unlisten"],"deny":[]}},"deny-emit":{"identifier":"deny-emit","description":"Denies the emit command without any pre-configured scope.","commands":{"allow":[],"deny":["emit"]}},"deny-emit-to":{"identifier":"deny-emit-to","description":"Denies the emit_to command without any pre-configured scope.","commands":{"allow":[],"deny":["emit_to"]}},"deny-listen":{"identifier":"deny-listen","description":"Denies the listen command without any pre-configured scope.","commands":{"allow":[],"deny":["listen"]}},"deny-unlisten":{"identifier":"deny-unlisten","description":"Denies the unlisten command without any pre-configured scope.","commands":{"allow":[],"deny":["unlisten"]}}},"permission_sets":{},"global_scope_schema":null},"core:image":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-from-bytes","allow-from-path","allow-rgba","allow-size"]},"permissions":{"allow-from-bytes":{"identifier":"allow-from-bytes","description":"Enables the from_bytes command without any pre-configured scope.","commands":{"allow":["from_bytes"],"deny":[]}},"allow-from-path":{"identifier":"allow-from-path","description":"Enables the from_path command without any pre-configured scope.","commands":{"allow":["from_path"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-rgba":{"identifier":"allow-rgba","description":"Enables the rgba command without any pre-configured scope.","commands":{"allow":["rgba"],"deny":[]}},"allow-size":{"identifier":"allow-size","description":"Enables the size command without any pre-configured scope.","commands":{"allow":["size"],"deny":[]}},"deny-from-bytes":{"identifier":"deny-from-bytes","description":"Denies the from_bytes command without any pre-configured scope.","commands":{"allow":[],"deny":["from_bytes"]}},"deny-from-path":{"identifier":"deny-from-path","description":"Denies the from_path command without any pre-configured scope.","commands":{"allow":[],"deny":["from_path"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-rgba":{"identifier":"deny-rgba","description":"Denies the rgba command without any pre-configured scope.","commands":{"allow":[],"deny":["rgba"]}},"deny-size":{"identifier":"deny-size","description":"Denies the size command without any pre-configured scope.","commands":{"allow":[],"deny":["size"]}}},"permission_sets":{},"global_scope_schema":null},"core:menu":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-append","allow-prepend","allow-insert","allow-remove","allow-remove-at","allow-items","allow-get","allow-popup","allow-create-default","allow-set-as-app-menu","allow-set-as-window-menu","allow-text","allow-set-text","allow-is-enabled","allow-set-enabled","allow-set-accelerator","allow-set-as-windows-menu-for-nsapp","allow-set-as-help-menu-for-nsapp","allow-is-checked","allow-set-checked","allow-set-icon"]},"permissions":{"allow-append":{"identifier":"allow-append","description":"Enables the append command without any pre-configured scope.","commands":{"allow":["append"],"deny":[]}},"allow-create-default":{"identifier":"allow-create-default","description":"Enables the create_default command without any pre-configured scope.","commands":{"allow":["create_default"],"deny":[]}},"allow-get":{"identifier":"allow-get","description":"Enables the get command without any pre-configured scope.","commands":{"allow":["get"],"deny":[]}},"allow-insert":{"identifier":"allow-insert","description":"Enables the insert command without any pre-configured scope.","commands":{"allow":["insert"],"deny":[]}},"allow-is-checked":{"identifier":"allow-is-checked","description":"Enables the is_checked command without any pre-configured scope.","commands":{"allow":["is_checked"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-items":{"identifier":"allow-items","description":"Enables the items command without any pre-configured scope.","commands":{"allow":["items"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-popup":{"identifier":"allow-popup","description":"Enables the popup command without any pre-configured scope.","commands":{"allow":["popup"],"deny":[]}},"allow-prepend":{"identifier":"allow-prepend","description":"Enables the prepend command without any pre-configured scope.","commands":{"allow":["prepend"],"deny":[]}},"allow-remove":{"identifier":"allow-remove","description":"Enables the remove command without any pre-configured scope.","commands":{"allow":["remove"],"deny":[]}},"allow-remove-at":{"identifier":"allow-remove-at","description":"Enables the remove_at command without any pre-configured scope.","commands":{"allow":["remove_at"],"deny":[]}},"allow-set-accelerator":{"identifier":"allow-set-accelerator","description":"Enables the set_accelerator command without any pre-configured scope.","commands":{"allow":["set_accelerator"],"deny":[]}},"allow-set-as-app-menu":{"identifier":"allow-set-as-app-menu","description":"Enables the set_as_app_menu command without any pre-configured scope.","commands":{"allow":["set_as_app_menu"],"deny":[]}},"allow-set-as-help-menu-for-nsapp":{"identifier":"allow-set-as-help-menu-for-nsapp","description":"Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_help_menu_for_nsapp"],"deny":[]}},"allow-set-as-window-menu":{"identifier":"allow-set-as-window-menu","description":"Enables the set_as_window_menu command without any pre-configured scope.","commands":{"allow":["set_as_window_menu"],"deny":[]}},"allow-set-as-windows-menu-for-nsapp":{"identifier":"allow-set-as-windows-menu-for-nsapp","description":"Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":["set_as_windows_menu_for_nsapp"],"deny":[]}},"allow-set-checked":{"identifier":"allow-set-checked","description":"Enables the set_checked command without any pre-configured scope.","commands":{"allow":["set_checked"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-text":{"identifier":"allow-set-text","description":"Enables the set_text command without any pre-configured scope.","commands":{"allow":["set_text"],"deny":[]}},"allow-text":{"identifier":"allow-text","description":"Enables the text command without any pre-configured scope.","commands":{"allow":["text"],"deny":[]}},"deny-append":{"identifier":"deny-append","description":"Denies the append command without any pre-configured scope.","commands":{"allow":[],"deny":["append"]}},"deny-create-default":{"identifier":"deny-create-default","description":"Denies the create_default command without any pre-configured scope.","commands":{"allow":[],"deny":["create_default"]}},"deny-get":{"identifier":"deny-get","description":"Denies the get command without any pre-configured scope.","commands":{"allow":[],"deny":["get"]}},"deny-insert":{"identifier":"deny-insert","description":"Denies the insert command without any pre-configured scope.","commands":{"allow":[],"deny":["insert"]}},"deny-is-checked":{"identifier":"deny-is-checked","description":"Denies the is_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["is_checked"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-items":{"identifier":"deny-items","description":"Denies the items command without any pre-configured scope.","commands":{"allow":[],"deny":["items"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-popup":{"identifier":"deny-popup","description":"Denies the popup command without any pre-configured scope.","commands":{"allow":[],"deny":["popup"]}},"deny-prepend":{"identifier":"deny-prepend","description":"Denies the prepend command without any pre-configured scope.","commands":{"allow":[],"deny":["prepend"]}},"deny-remove":{"identifier":"deny-remove","description":"Denies the remove command without any pre-configured scope.","commands":{"allow":[],"deny":["remove"]}},"deny-remove-at":{"identifier":"deny-remove-at","description":"Denies the remove_at command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_at"]}},"deny-set-accelerator":{"identifier":"deny-set-accelerator","description":"Denies the set_accelerator command without any pre-configured scope.","commands":{"allow":[],"deny":["set_accelerator"]}},"deny-set-as-app-menu":{"identifier":"deny-set-as-app-menu","description":"Denies the set_as_app_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_app_menu"]}},"deny-set-as-help-menu-for-nsapp":{"identifier":"deny-set-as-help-menu-for-nsapp","description":"Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_help_menu_for_nsapp"]}},"deny-set-as-window-menu":{"identifier":"deny-set-as-window-menu","description":"Denies the set_as_window_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_window_menu"]}},"deny-set-as-windows-menu-for-nsapp":{"identifier":"deny-set-as-windows-menu-for-nsapp","description":"Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.","commands":{"allow":[],"deny":["set_as_windows_menu_for_nsapp"]}},"deny-set-checked":{"identifier":"deny-set-checked","description":"Denies the set_checked command without any pre-configured scope.","commands":{"allow":[],"deny":["set_checked"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-text":{"identifier":"deny-set-text","description":"Denies the set_text command without any pre-configured scope.","commands":{"allow":[],"deny":["set_text"]}},"deny-text":{"identifier":"deny-text","description":"Denies the text command without any pre-configured scope.","commands":{"allow":[],"deny":["text"]}}},"permission_sets":{},"global_scope_schema":null},"core:path":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-resolve-directory","allow-resolve","allow-normalize","allow-join","allow-dirname","allow-extname","allow-basename","allow-is-absolute"]},"permissions":{"allow-basename":{"identifier":"allow-basename","description":"Enables the basename command without any pre-configured scope.","commands":{"allow":["basename"],"deny":[]}},"allow-dirname":{"identifier":"allow-dirname","description":"Enables the dirname command without any pre-configured scope.","commands":{"allow":["dirname"],"deny":[]}},"allow-extname":{"identifier":"allow-extname","description":"Enables the extname command without any pre-configured scope.","commands":{"allow":["extname"],"deny":[]}},"allow-is-absolute":{"identifier":"allow-is-absolute","description":"Enables the is_absolute command without any pre-configured scope.","commands":{"allow":["is_absolute"],"deny":[]}},"allow-join":{"identifier":"allow-join","description":"Enables the join command without any pre-configured scope.","commands":{"allow":["join"],"deny":[]}},"allow-normalize":{"identifier":"allow-normalize","description":"Enables the normalize command without any pre-configured scope.","commands":{"allow":["normalize"],"deny":[]}},"allow-resolve":{"identifier":"allow-resolve","description":"Enables the resolve command without any pre-configured scope.","commands":{"allow":["resolve"],"deny":[]}},"allow-resolve-directory":{"identifier":"allow-resolve-directory","description":"Enables the resolve_directory command without any pre-configured scope.","commands":{"allow":["resolve_directory"],"deny":[]}},"deny-basename":{"identifier":"deny-basename","description":"Denies the basename command without any pre-configured scope.","commands":{"allow":[],"deny":["basename"]}},"deny-dirname":{"identifier":"deny-dirname","description":"Denies the dirname command without any pre-configured scope.","commands":{"allow":[],"deny":["dirname"]}},"deny-extname":{"identifier":"deny-extname","description":"Denies the extname command without any pre-configured scope.","commands":{"allow":[],"deny":["extname"]}},"deny-is-absolute":{"identifier":"deny-is-absolute","description":"Denies the is_absolute command without any pre-configured scope.","commands":{"allow":[],"deny":["is_absolute"]}},"deny-join":{"identifier":"deny-join","description":"Denies the join command without any pre-configured scope.","commands":{"allow":[],"deny":["join"]}},"deny-normalize":{"identifier":"deny-normalize","description":"Denies the normalize command without any pre-configured scope.","commands":{"allow":[],"deny":["normalize"]}},"deny-resolve":{"identifier":"deny-resolve","description":"Denies the resolve command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve"]}},"deny-resolve-directory":{"identifier":"deny-resolve-directory","description":"Denies the resolve_directory command without any pre-configured scope.","commands":{"allow":[],"deny":["resolve_directory"]}}},"permission_sets":{},"global_scope_schema":null},"core:resources":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-close"]},"permissions":{"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}}},"permission_sets":{},"global_scope_schema":null},"core:tray":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin, which enables all commands.","permissions":["allow-new","allow-get-by-id","allow-remove-by-id","allow-set-icon","allow-set-menu","allow-set-tooltip","allow-set-title","allow-set-visible","allow-set-temp-dir-path","allow-set-icon-as-template","allow-set-show-menu-on-left-click"]},"permissions":{"allow-get-by-id":{"identifier":"allow-get-by-id","description":"Enables the get_by_id command without any pre-configured scope.","commands":{"allow":["get_by_id"],"deny":[]}},"allow-new":{"identifier":"allow-new","description":"Enables the new command without any pre-configured scope.","commands":{"allow":["new"],"deny":[]}},"allow-remove-by-id":{"identifier":"allow-remove-by-id","description":"Enables the remove_by_id command without any pre-configured scope.","commands":{"allow":["remove_by_id"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-icon-as-template":{"identifier":"allow-set-icon-as-template","description":"Enables the set_icon_as_template command without any pre-configured scope.","commands":{"allow":["set_icon_as_template"],"deny":[]}},"allow-set-menu":{"identifier":"allow-set-menu","description":"Enables the set_menu command without any pre-configured scope.","commands":{"allow":["set_menu"],"deny":[]}},"allow-set-show-menu-on-left-click":{"identifier":"allow-set-show-menu-on-left-click","description":"Enables the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":["set_show_menu_on_left_click"],"deny":[]}},"allow-set-temp-dir-path":{"identifier":"allow-set-temp-dir-path","description":"Enables the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":["set_temp_dir_path"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-tooltip":{"identifier":"allow-set-tooltip","description":"Enables the set_tooltip command without any pre-configured scope.","commands":{"allow":["set_tooltip"],"deny":[]}},"allow-set-visible":{"identifier":"allow-set-visible","description":"Enables the set_visible command without any pre-configured scope.","commands":{"allow":["set_visible"],"deny":[]}},"deny-get-by-id":{"identifier":"deny-get-by-id","description":"Denies the get_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["get_by_id"]}},"deny-new":{"identifier":"deny-new","description":"Denies the new command without any pre-configured scope.","commands":{"allow":[],"deny":["new"]}},"deny-remove-by-id":{"identifier":"deny-remove-by-id","description":"Denies the remove_by_id command without any pre-configured scope.","commands":{"allow":[],"deny":["remove_by_id"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-icon-as-template":{"identifier":"deny-set-icon-as-template","description":"Denies the set_icon_as_template command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon_as_template"]}},"deny-set-menu":{"identifier":"deny-set-menu","description":"Denies the set_menu command without any pre-configured scope.","commands":{"allow":[],"deny":["set_menu"]}},"deny-set-show-menu-on-left-click":{"identifier":"deny-set-show-menu-on-left-click","description":"Denies the set_show_menu_on_left_click command without any pre-configured scope.","commands":{"allow":[],"deny":["set_show_menu_on_left_click"]}},"deny-set-temp-dir-path":{"identifier":"deny-set-temp-dir-path","description":"Denies the set_temp_dir_path command without any pre-configured scope.","commands":{"allow":[],"deny":["set_temp_dir_path"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-tooltip":{"identifier":"deny-set-tooltip","description":"Denies the set_tooltip command without any pre-configured scope.","commands":{"allow":[],"deny":["set_tooltip"]}},"deny-set-visible":{"identifier":"deny-set-visible","description":"Denies the set_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible"]}}},"permission_sets":{},"global_scope_schema":null},"core:webview":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-webviews","allow-webview-position","allow-webview-size","allow-internal-toggle-devtools"]},"permissions":{"allow-clear-all-browsing-data":{"identifier":"allow-clear-all-browsing-data","description":"Enables the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":["clear_all_browsing_data"],"deny":[]}},"allow-create-webview":{"identifier":"allow-create-webview","description":"Enables the create_webview command without any pre-configured scope.","commands":{"allow":["create_webview"],"deny":[]}},"allow-create-webview-window":{"identifier":"allow-create-webview-window","description":"Enables the create_webview_window command without any pre-configured scope.","commands":{"allow":["create_webview_window"],"deny":[]}},"allow-get-all-webviews":{"identifier":"allow-get-all-webviews","description":"Enables the get_all_webviews command without any pre-configured scope.","commands":{"allow":["get_all_webviews"],"deny":[]}},"allow-internal-toggle-devtools":{"identifier":"allow-internal-toggle-devtools","description":"Enables the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":["internal_toggle_devtools"],"deny":[]}},"allow-print":{"identifier":"allow-print","description":"Enables the print command without any pre-configured scope.","commands":{"allow":["print"],"deny":[]}},"allow-reparent":{"identifier":"allow-reparent","description":"Enables the reparent command without any pre-configured scope.","commands":{"allow":["reparent"],"deny":[]}},"allow-set-webview-auto-resize":{"identifier":"allow-set-webview-auto-resize","description":"Enables the set_webview_auto_resize command without any pre-configured scope.","commands":{"allow":["set_webview_auto_resize"],"deny":[]}},"allow-set-webview-background-color":{"identifier":"allow-set-webview-background-color","description":"Enables the set_webview_background_color command without any pre-configured scope.","commands":{"allow":["set_webview_background_color"],"deny":[]}},"allow-set-webview-focus":{"identifier":"allow-set-webview-focus","description":"Enables the set_webview_focus command without any pre-configured scope.","commands":{"allow":["set_webview_focus"],"deny":[]}},"allow-set-webview-position":{"identifier":"allow-set-webview-position","description":"Enables the set_webview_position command without any pre-configured scope.","commands":{"allow":["set_webview_position"],"deny":[]}},"allow-set-webview-size":{"identifier":"allow-set-webview-size","description":"Enables the set_webview_size command without any pre-configured scope.","commands":{"allow":["set_webview_size"],"deny":[]}},"allow-set-webview-zoom":{"identifier":"allow-set-webview-zoom","description":"Enables the set_webview_zoom command without any pre-configured scope.","commands":{"allow":["set_webview_zoom"],"deny":[]}},"allow-webview-close":{"identifier":"allow-webview-close","description":"Enables the webview_close command without any pre-configured scope.","commands":{"allow":["webview_close"],"deny":[]}},"allow-webview-hide":{"identifier":"allow-webview-hide","description":"Enables the webview_hide command without any pre-configured scope.","commands":{"allow":["webview_hide"],"deny":[]}},"allow-webview-position":{"identifier":"allow-webview-position","description":"Enables the webview_position command without any pre-configured scope.","commands":{"allow":["webview_position"],"deny":[]}},"allow-webview-show":{"identifier":"allow-webview-show","description":"Enables the webview_show command without any pre-configured scope.","commands":{"allow":["webview_show"],"deny":[]}},"allow-webview-size":{"identifier":"allow-webview-size","description":"Enables the webview_size command without any pre-configured scope.","commands":{"allow":["webview_size"],"deny":[]}},"deny-clear-all-browsing-data":{"identifier":"deny-clear-all-browsing-data","description":"Denies the clear_all_browsing_data command without any pre-configured scope.","commands":{"allow":[],"deny":["clear_all_browsing_data"]}},"deny-create-webview":{"identifier":"deny-create-webview","description":"Denies the create_webview command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview"]}},"deny-create-webview-window":{"identifier":"deny-create-webview-window","description":"Denies the create_webview_window command without any pre-configured scope.","commands":{"allow":[],"deny":["create_webview_window"]}},"deny-get-all-webviews":{"identifier":"deny-get-all-webviews","description":"Denies the get_all_webviews command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_webviews"]}},"deny-internal-toggle-devtools":{"identifier":"deny-internal-toggle-devtools","description":"Denies the internal_toggle_devtools command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_devtools"]}},"deny-print":{"identifier":"deny-print","description":"Denies the print command without any pre-configured scope.","commands":{"allow":[],"deny":["print"]}},"deny-reparent":{"identifier":"deny-reparent","description":"Denies the reparent command without any pre-configured scope.","commands":{"allow":[],"deny":["reparent"]}},"deny-set-webview-auto-resize":{"identifier":"deny-set-webview-auto-resize","description":"Denies the set_webview_auto_resize command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_auto_resize"]}},"deny-set-webview-background-color":{"identifier":"deny-set-webview-background-color","description":"Denies the set_webview_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_background_color"]}},"deny-set-webview-focus":{"identifier":"deny-set-webview-focus","description":"Denies the set_webview_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_focus"]}},"deny-set-webview-position":{"identifier":"deny-set-webview-position","description":"Denies the set_webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_position"]}},"deny-set-webview-size":{"identifier":"deny-set-webview-size","description":"Denies the set_webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_size"]}},"deny-set-webview-zoom":{"identifier":"deny-set-webview-zoom","description":"Denies the set_webview_zoom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_webview_zoom"]}},"deny-webview-close":{"identifier":"deny-webview-close","description":"Denies the webview_close command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_close"]}},"deny-webview-hide":{"identifier":"deny-webview-hide","description":"Denies the webview_hide command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_hide"]}},"deny-webview-position":{"identifier":"deny-webview-position","description":"Denies the webview_position command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_position"]}},"deny-webview-show":{"identifier":"deny-webview-show","description":"Denies the webview_show command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_show"]}},"deny-webview-size":{"identifier":"deny-webview-size","description":"Denies the webview_size command without any pre-configured scope.","commands":{"allow":[],"deny":["webview_size"]}}},"permission_sets":{},"global_scope_schema":null},"core:window":{"default_permission":{"identifier":"default","description":"Default permissions for the plugin.","permissions":["allow-get-all-windows","allow-scale-factor","allow-inner-position","allow-outer-position","allow-inner-size","allow-outer-size","allow-is-fullscreen","allow-is-minimized","allow-is-maximized","allow-is-focused","allow-is-decorated","allow-is-resizable","allow-is-maximizable","allow-is-minimizable","allow-is-closable","allow-is-visible","allow-is-enabled","allow-title","allow-current-monitor","allow-primary-monitor","allow-monitor-from-point","allow-available-monitors","allow-cursor-position","allow-theme","allow-is-always-on-top","allow-internal-toggle-maximize"]},"permissions":{"allow-available-monitors":{"identifier":"allow-available-monitors","description":"Enables the available_monitors command without any pre-configured scope.","commands":{"allow":["available_monitors"],"deny":[]}},"allow-center":{"identifier":"allow-center","description":"Enables the center command without any pre-configured scope.","commands":{"allow":["center"],"deny":[]}},"allow-close":{"identifier":"allow-close","description":"Enables the close command without any pre-configured scope.","commands":{"allow":["close"],"deny":[]}},"allow-create":{"identifier":"allow-create","description":"Enables the create command without any pre-configured scope.","commands":{"allow":["create"],"deny":[]}},"allow-current-monitor":{"identifier":"allow-current-monitor","description":"Enables the current_monitor command without any pre-configured scope.","commands":{"allow":["current_monitor"],"deny":[]}},"allow-cursor-position":{"identifier":"allow-cursor-position","description":"Enables the cursor_position command without any pre-configured scope.","commands":{"allow":["cursor_position"],"deny":[]}},"allow-destroy":{"identifier":"allow-destroy","description":"Enables the destroy command without any pre-configured scope.","commands":{"allow":["destroy"],"deny":[]}},"allow-get-all-windows":{"identifier":"allow-get-all-windows","description":"Enables the get_all_windows command without any pre-configured scope.","commands":{"allow":["get_all_windows"],"deny":[]}},"allow-hide":{"identifier":"allow-hide","description":"Enables the hide command without any pre-configured scope.","commands":{"allow":["hide"],"deny":[]}},"allow-inner-position":{"identifier":"allow-inner-position","description":"Enables the inner_position command without any pre-configured scope.","commands":{"allow":["inner_position"],"deny":[]}},"allow-inner-size":{"identifier":"allow-inner-size","description":"Enables the inner_size command without any pre-configured scope.","commands":{"allow":["inner_size"],"deny":[]}},"allow-internal-toggle-maximize":{"identifier":"allow-internal-toggle-maximize","description":"Enables the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":["internal_toggle_maximize"],"deny":[]}},"allow-is-always-on-top":{"identifier":"allow-is-always-on-top","description":"Enables the is_always_on_top command without any pre-configured scope.","commands":{"allow":["is_always_on_top"],"deny":[]}},"allow-is-closable":{"identifier":"allow-is-closable","description":"Enables the is_closable command without any pre-configured scope.","commands":{"allow":["is_closable"],"deny":[]}},"allow-is-decorated":{"identifier":"allow-is-decorated","description":"Enables the is_decorated command without any pre-configured scope.","commands":{"allow":["is_decorated"],"deny":[]}},"allow-is-enabled":{"identifier":"allow-is-enabled","description":"Enables the is_enabled command without any pre-configured scope.","commands":{"allow":["is_enabled"],"deny":[]}},"allow-is-focused":{"identifier":"allow-is-focused","description":"Enables the is_focused command without any pre-configured scope.","commands":{"allow":["is_focused"],"deny":[]}},"allow-is-fullscreen":{"identifier":"allow-is-fullscreen","description":"Enables the is_fullscreen command without any pre-configured scope.","commands":{"allow":["is_fullscreen"],"deny":[]}},"allow-is-maximizable":{"identifier":"allow-is-maximizable","description":"Enables the is_maximizable command without any pre-configured scope.","commands":{"allow":["is_maximizable"],"deny":[]}},"allow-is-maximized":{"identifier":"allow-is-maximized","description":"Enables the is_maximized command without any pre-configured scope.","commands":{"allow":["is_maximized"],"deny":[]}},"allow-is-minimizable":{"identifier":"allow-is-minimizable","description":"Enables the is_minimizable command without any pre-configured scope.","commands":{"allow":["is_minimizable"],"deny":[]}},"allow-is-minimized":{"identifier":"allow-is-minimized","description":"Enables the is_minimized command without any pre-configured scope.","commands":{"allow":["is_minimized"],"deny":[]}},"allow-is-resizable":{"identifier":"allow-is-resizable","description":"Enables the is_resizable command without any pre-configured scope.","commands":{"allow":["is_resizable"],"deny":[]}},"allow-is-visible":{"identifier":"allow-is-visible","description":"Enables the is_visible command without any pre-configured scope.","commands":{"allow":["is_visible"],"deny":[]}},"allow-maximize":{"identifier":"allow-maximize","description":"Enables the maximize command without any pre-configured scope.","commands":{"allow":["maximize"],"deny":[]}},"allow-minimize":{"identifier":"allow-minimize","description":"Enables the minimize command without any pre-configured scope.","commands":{"allow":["minimize"],"deny":[]}},"allow-monitor-from-point":{"identifier":"allow-monitor-from-point","description":"Enables the monitor_from_point command without any pre-configured scope.","commands":{"allow":["monitor_from_point"],"deny":[]}},"allow-outer-position":{"identifier":"allow-outer-position","description":"Enables the outer_position command without any pre-configured scope.","commands":{"allow":["outer_position"],"deny":[]}},"allow-outer-size":{"identifier":"allow-outer-size","description":"Enables the outer_size command without any pre-configured scope.","commands":{"allow":["outer_size"],"deny":[]}},"allow-primary-monitor":{"identifier":"allow-primary-monitor","description":"Enables the primary_monitor command without any pre-configured scope.","commands":{"allow":["primary_monitor"],"deny":[]}},"allow-request-user-attention":{"identifier":"allow-request-user-attention","description":"Enables the request_user_attention command without any pre-configured scope.","commands":{"allow":["request_user_attention"],"deny":[]}},"allow-scale-factor":{"identifier":"allow-scale-factor","description":"Enables the scale_factor command without any pre-configured scope.","commands":{"allow":["scale_factor"],"deny":[]}},"allow-set-always-on-bottom":{"identifier":"allow-set-always-on-bottom","description":"Enables the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":["set_always_on_bottom"],"deny":[]}},"allow-set-always-on-top":{"identifier":"allow-set-always-on-top","description":"Enables the set_always_on_top command without any pre-configured scope.","commands":{"allow":["set_always_on_top"],"deny":[]}},"allow-set-background-color":{"identifier":"allow-set-background-color","description":"Enables the set_background_color command without any pre-configured scope.","commands":{"allow":["set_background_color"],"deny":[]}},"allow-set-badge-count":{"identifier":"allow-set-badge-count","description":"Enables the set_badge_count command without any pre-configured scope.","commands":{"allow":["set_badge_count"],"deny":[]}},"allow-set-badge-label":{"identifier":"allow-set-badge-label","description":"Enables the set_badge_label command without any pre-configured scope.","commands":{"allow":["set_badge_label"],"deny":[]}},"allow-set-closable":{"identifier":"allow-set-closable","description":"Enables the set_closable command without any pre-configured scope.","commands":{"allow":["set_closable"],"deny":[]}},"allow-set-content-protected":{"identifier":"allow-set-content-protected","description":"Enables the set_content_protected command without any pre-configured scope.","commands":{"allow":["set_content_protected"],"deny":[]}},"allow-set-cursor-grab":{"identifier":"allow-set-cursor-grab","description":"Enables the set_cursor_grab command without any pre-configured scope.","commands":{"allow":["set_cursor_grab"],"deny":[]}},"allow-set-cursor-icon":{"identifier":"allow-set-cursor-icon","description":"Enables the set_cursor_icon command without any pre-configured scope.","commands":{"allow":["set_cursor_icon"],"deny":[]}},"allow-set-cursor-position":{"identifier":"allow-set-cursor-position","description":"Enables the set_cursor_position command without any pre-configured scope.","commands":{"allow":["set_cursor_position"],"deny":[]}},"allow-set-cursor-visible":{"identifier":"allow-set-cursor-visible","description":"Enables the set_cursor_visible command without any pre-configured scope.","commands":{"allow":["set_cursor_visible"],"deny":[]}},"allow-set-decorations":{"identifier":"allow-set-decorations","description":"Enables the set_decorations command without any pre-configured scope.","commands":{"allow":["set_decorations"],"deny":[]}},"allow-set-effects":{"identifier":"allow-set-effects","description":"Enables the set_effects command without any pre-configured scope.","commands":{"allow":["set_effects"],"deny":[]}},"allow-set-enabled":{"identifier":"allow-set-enabled","description":"Enables the set_enabled command without any pre-configured scope.","commands":{"allow":["set_enabled"],"deny":[]}},"allow-set-focus":{"identifier":"allow-set-focus","description":"Enables the set_focus command without any pre-configured scope.","commands":{"allow":["set_focus"],"deny":[]}},"allow-set-focusable":{"identifier":"allow-set-focusable","description":"Enables the set_focusable command without any pre-configured scope.","commands":{"allow":["set_focusable"],"deny":[]}},"allow-set-fullscreen":{"identifier":"allow-set-fullscreen","description":"Enables the set_fullscreen command without any pre-configured scope.","commands":{"allow":["set_fullscreen"],"deny":[]}},"allow-set-icon":{"identifier":"allow-set-icon","description":"Enables the set_icon command without any pre-configured scope.","commands":{"allow":["set_icon"],"deny":[]}},"allow-set-ignore-cursor-events":{"identifier":"allow-set-ignore-cursor-events","description":"Enables the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":["set_ignore_cursor_events"],"deny":[]}},"allow-set-max-size":{"identifier":"allow-set-max-size","description":"Enables the set_max_size command without any pre-configured scope.","commands":{"allow":["set_max_size"],"deny":[]}},"allow-set-maximizable":{"identifier":"allow-set-maximizable","description":"Enables the set_maximizable command without any pre-configured scope.","commands":{"allow":["set_maximizable"],"deny":[]}},"allow-set-min-size":{"identifier":"allow-set-min-size","description":"Enables the set_min_size command without any pre-configured scope.","commands":{"allow":["set_min_size"],"deny":[]}},"allow-set-minimizable":{"identifier":"allow-set-minimizable","description":"Enables the set_minimizable command without any pre-configured scope.","commands":{"allow":["set_minimizable"],"deny":[]}},"allow-set-overlay-icon":{"identifier":"allow-set-overlay-icon","description":"Enables the set_overlay_icon command without any pre-configured scope.","commands":{"allow":["set_overlay_icon"],"deny":[]}},"allow-set-position":{"identifier":"allow-set-position","description":"Enables the set_position command without any pre-configured scope.","commands":{"allow":["set_position"],"deny":[]}},"allow-set-progress-bar":{"identifier":"allow-set-progress-bar","description":"Enables the set_progress_bar command without any pre-configured scope.","commands":{"allow":["set_progress_bar"],"deny":[]}},"allow-set-resizable":{"identifier":"allow-set-resizable","description":"Enables the set_resizable command without any pre-configured scope.","commands":{"allow":["set_resizable"],"deny":[]}},"allow-set-shadow":{"identifier":"allow-set-shadow","description":"Enables the set_shadow command without any pre-configured scope.","commands":{"allow":["set_shadow"],"deny":[]}},"allow-set-simple-fullscreen":{"identifier":"allow-set-simple-fullscreen","description":"Enables the set_simple_fullscreen command without any pre-configured scope.","commands":{"allow":["set_simple_fullscreen"],"deny":[]}},"allow-set-size":{"identifier":"allow-set-size","description":"Enables the set_size command without any pre-configured scope.","commands":{"allow":["set_size"],"deny":[]}},"allow-set-size-constraints":{"identifier":"allow-set-size-constraints","description":"Enables the set_size_constraints command without any pre-configured scope.","commands":{"allow":["set_size_constraints"],"deny":[]}},"allow-set-skip-taskbar":{"identifier":"allow-set-skip-taskbar","description":"Enables the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":["set_skip_taskbar"],"deny":[]}},"allow-set-theme":{"identifier":"allow-set-theme","description":"Enables the set_theme command without any pre-configured scope.","commands":{"allow":["set_theme"],"deny":[]}},"allow-set-title":{"identifier":"allow-set-title","description":"Enables the set_title command without any pre-configured scope.","commands":{"allow":["set_title"],"deny":[]}},"allow-set-title-bar-style":{"identifier":"allow-set-title-bar-style","description":"Enables the set_title_bar_style command without any pre-configured scope.","commands":{"allow":["set_title_bar_style"],"deny":[]}},"allow-set-visible-on-all-workspaces":{"identifier":"allow-set-visible-on-all-workspaces","description":"Enables the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":["set_visible_on_all_workspaces"],"deny":[]}},"allow-show":{"identifier":"allow-show","description":"Enables the show command without any pre-configured scope.","commands":{"allow":["show"],"deny":[]}},"allow-start-dragging":{"identifier":"allow-start-dragging","description":"Enables the start_dragging command without any pre-configured scope.","commands":{"allow":["start_dragging"],"deny":[]}},"allow-start-resize-dragging":{"identifier":"allow-start-resize-dragging","description":"Enables the start_resize_dragging command without any pre-configured scope.","commands":{"allow":["start_resize_dragging"],"deny":[]}},"allow-theme":{"identifier":"allow-theme","description":"Enables the theme command without any pre-configured scope.","commands":{"allow":["theme"],"deny":[]}},"allow-title":{"identifier":"allow-title","description":"Enables the title command without any pre-configured scope.","commands":{"allow":["title"],"deny":[]}},"allow-toggle-maximize":{"identifier":"allow-toggle-maximize","description":"Enables the toggle_maximize command without any pre-configured scope.","commands":{"allow":["toggle_maximize"],"deny":[]}},"allow-unmaximize":{"identifier":"allow-unmaximize","description":"Enables the unmaximize command without any pre-configured scope.","commands":{"allow":["unmaximize"],"deny":[]}},"allow-unminimize":{"identifier":"allow-unminimize","description":"Enables the unminimize command without any pre-configured scope.","commands":{"allow":["unminimize"],"deny":[]}},"deny-available-monitors":{"identifier":"deny-available-monitors","description":"Denies the available_monitors command without any pre-configured scope.","commands":{"allow":[],"deny":["available_monitors"]}},"deny-center":{"identifier":"deny-center","description":"Denies the center command without any pre-configured scope.","commands":{"allow":[],"deny":["center"]}},"deny-close":{"identifier":"deny-close","description":"Denies the close command without any pre-configured scope.","commands":{"allow":[],"deny":["close"]}},"deny-create":{"identifier":"deny-create","description":"Denies the create command without any pre-configured scope.","commands":{"allow":[],"deny":["create"]}},"deny-current-monitor":{"identifier":"deny-current-monitor","description":"Denies the current_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["current_monitor"]}},"deny-cursor-position":{"identifier":"deny-cursor-position","description":"Denies the cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["cursor_position"]}},"deny-destroy":{"identifier":"deny-destroy","description":"Denies the destroy command without any pre-configured scope.","commands":{"allow":[],"deny":["destroy"]}},"deny-get-all-windows":{"identifier":"deny-get-all-windows","description":"Denies the get_all_windows command without any pre-configured scope.","commands":{"allow":[],"deny":["get_all_windows"]}},"deny-hide":{"identifier":"deny-hide","description":"Denies the hide command without any pre-configured scope.","commands":{"allow":[],"deny":["hide"]}},"deny-inner-position":{"identifier":"deny-inner-position","description":"Denies the inner_position command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_position"]}},"deny-inner-size":{"identifier":"deny-inner-size","description":"Denies the inner_size command without any pre-configured scope.","commands":{"allow":[],"deny":["inner_size"]}},"deny-internal-toggle-maximize":{"identifier":"deny-internal-toggle-maximize","description":"Denies the internal_toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["internal_toggle_maximize"]}},"deny-is-always-on-top":{"identifier":"deny-is-always-on-top","description":"Denies the is_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["is_always_on_top"]}},"deny-is-closable":{"identifier":"deny-is-closable","description":"Denies the is_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_closable"]}},"deny-is-decorated":{"identifier":"deny-is-decorated","description":"Denies the is_decorated command without any pre-configured scope.","commands":{"allow":[],"deny":["is_decorated"]}},"deny-is-enabled":{"identifier":"deny-is-enabled","description":"Denies the is_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["is_enabled"]}},"deny-is-focused":{"identifier":"deny-is-focused","description":"Denies the is_focused command without any pre-configured scope.","commands":{"allow":[],"deny":["is_focused"]}},"deny-is-fullscreen":{"identifier":"deny-is-fullscreen","description":"Denies the is_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["is_fullscreen"]}},"deny-is-maximizable":{"identifier":"deny-is-maximizable","description":"Denies the is_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximizable"]}},"deny-is-maximized":{"identifier":"deny-is-maximized","description":"Denies the is_maximized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_maximized"]}},"deny-is-minimizable":{"identifier":"deny-is-minimizable","description":"Denies the is_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimizable"]}},"deny-is-minimized":{"identifier":"deny-is-minimized","description":"Denies the is_minimized command without any pre-configured scope.","commands":{"allow":[],"deny":["is_minimized"]}},"deny-is-resizable":{"identifier":"deny-is-resizable","description":"Denies the is_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["is_resizable"]}},"deny-is-visible":{"identifier":"deny-is-visible","description":"Denies the is_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["is_visible"]}},"deny-maximize":{"identifier":"deny-maximize","description":"Denies the maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["maximize"]}},"deny-minimize":{"identifier":"deny-minimize","description":"Denies the minimize command without any pre-configured scope.","commands":{"allow":[],"deny":["minimize"]}},"deny-monitor-from-point":{"identifier":"deny-monitor-from-point","description":"Denies the monitor_from_point command without any pre-configured scope.","commands":{"allow":[],"deny":["monitor_from_point"]}},"deny-outer-position":{"identifier":"deny-outer-position","description":"Denies the outer_position command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_position"]}},"deny-outer-size":{"identifier":"deny-outer-size","description":"Denies the outer_size command without any pre-configured scope.","commands":{"allow":[],"deny":["outer_size"]}},"deny-primary-monitor":{"identifier":"deny-primary-monitor","description":"Denies the primary_monitor command without any pre-configured scope.","commands":{"allow":[],"deny":["primary_monitor"]}},"deny-request-user-attention":{"identifier":"deny-request-user-attention","description":"Denies the request_user_attention command without any pre-configured scope.","commands":{"allow":[],"deny":["request_user_attention"]}},"deny-scale-factor":{"identifier":"deny-scale-factor","description":"Denies the scale_factor command without any pre-configured scope.","commands":{"allow":[],"deny":["scale_factor"]}},"deny-set-always-on-bottom":{"identifier":"deny-set-always-on-bottom","description":"Denies the set_always_on_bottom command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_bottom"]}},"deny-set-always-on-top":{"identifier":"deny-set-always-on-top","description":"Denies the set_always_on_top command without any pre-configured scope.","commands":{"allow":[],"deny":["set_always_on_top"]}},"deny-set-background-color":{"identifier":"deny-set-background-color","description":"Denies the set_background_color command without any pre-configured scope.","commands":{"allow":[],"deny":["set_background_color"]}},"deny-set-badge-count":{"identifier":"deny-set-badge-count","description":"Denies the set_badge_count command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_count"]}},"deny-set-badge-label":{"identifier":"deny-set-badge-label","description":"Denies the set_badge_label command without any pre-configured scope.","commands":{"allow":[],"deny":["set_badge_label"]}},"deny-set-closable":{"identifier":"deny-set-closable","description":"Denies the set_closable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_closable"]}},"deny-set-content-protected":{"identifier":"deny-set-content-protected","description":"Denies the set_content_protected command without any pre-configured scope.","commands":{"allow":[],"deny":["set_content_protected"]}},"deny-set-cursor-grab":{"identifier":"deny-set-cursor-grab","description":"Denies the set_cursor_grab command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_grab"]}},"deny-set-cursor-icon":{"identifier":"deny-set-cursor-icon","description":"Denies the set_cursor_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_icon"]}},"deny-set-cursor-position":{"identifier":"deny-set-cursor-position","description":"Denies the set_cursor_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_position"]}},"deny-set-cursor-visible":{"identifier":"deny-set-cursor-visible","description":"Denies the set_cursor_visible command without any pre-configured scope.","commands":{"allow":[],"deny":["set_cursor_visible"]}},"deny-set-decorations":{"identifier":"deny-set-decorations","description":"Denies the set_decorations command without any pre-configured scope.","commands":{"allow":[],"deny":["set_decorations"]}},"deny-set-effects":{"identifier":"deny-set-effects","description":"Denies the set_effects command without any pre-configured scope.","commands":{"allow":[],"deny":["set_effects"]}},"deny-set-enabled":{"identifier":"deny-set-enabled","description":"Denies the set_enabled command without any pre-configured scope.","commands":{"allow":[],"deny":["set_enabled"]}},"deny-set-focus":{"identifier":"deny-set-focus","description":"Denies the set_focus command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focus"]}},"deny-set-focusable":{"identifier":"deny-set-focusable","description":"Denies the set_focusable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_focusable"]}},"deny-set-fullscreen":{"identifier":"deny-set-fullscreen","description":"Denies the set_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_fullscreen"]}},"deny-set-icon":{"identifier":"deny-set-icon","description":"Denies the set_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_icon"]}},"deny-set-ignore-cursor-events":{"identifier":"deny-set-ignore-cursor-events","description":"Denies the set_ignore_cursor_events command without any pre-configured scope.","commands":{"allow":[],"deny":["set_ignore_cursor_events"]}},"deny-set-max-size":{"identifier":"deny-set-max-size","description":"Denies the set_max_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_max_size"]}},"deny-set-maximizable":{"identifier":"deny-set-maximizable","description":"Denies the set_maximizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_maximizable"]}},"deny-set-min-size":{"identifier":"deny-set-min-size","description":"Denies the set_min_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_min_size"]}},"deny-set-minimizable":{"identifier":"deny-set-minimizable","description":"Denies the set_minimizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_minimizable"]}},"deny-set-overlay-icon":{"identifier":"deny-set-overlay-icon","description":"Denies the set_overlay_icon command without any pre-configured scope.","commands":{"allow":[],"deny":["set_overlay_icon"]}},"deny-set-position":{"identifier":"deny-set-position","description":"Denies the set_position command without any pre-configured scope.","commands":{"allow":[],"deny":["set_position"]}},"deny-set-progress-bar":{"identifier":"deny-set-progress-bar","description":"Denies the set_progress_bar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_progress_bar"]}},"deny-set-resizable":{"identifier":"deny-set-resizable","description":"Denies the set_resizable command without any pre-configured scope.","commands":{"allow":[],"deny":["set_resizable"]}},"deny-set-shadow":{"identifier":"deny-set-shadow","description":"Denies the set_shadow command without any pre-configured scope.","commands":{"allow":[],"deny":["set_shadow"]}},"deny-set-simple-fullscreen":{"identifier":"deny-set-simple-fullscreen","description":"Denies the set_simple_fullscreen command without any pre-configured scope.","commands":{"allow":[],"deny":["set_simple_fullscreen"]}},"deny-set-size":{"identifier":"deny-set-size","description":"Denies the set_size command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size"]}},"deny-set-size-constraints":{"identifier":"deny-set-size-constraints","description":"Denies the set_size_constraints command without any pre-configured scope.","commands":{"allow":[],"deny":["set_size_constraints"]}},"deny-set-skip-taskbar":{"identifier":"deny-set-skip-taskbar","description":"Denies the set_skip_taskbar command without any pre-configured scope.","commands":{"allow":[],"deny":["set_skip_taskbar"]}},"deny-set-theme":{"identifier":"deny-set-theme","description":"Denies the set_theme command without any pre-configured scope.","commands":{"allow":[],"deny":["set_theme"]}},"deny-set-title":{"identifier":"deny-set-title","description":"Denies the set_title command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title"]}},"deny-set-title-bar-style":{"identifier":"deny-set-title-bar-style","description":"Denies the set_title_bar_style command without any pre-configured scope.","commands":{"allow":[],"deny":["set_title_bar_style"]}},"deny-set-visible-on-all-workspaces":{"identifier":"deny-set-visible-on-all-workspaces","description":"Denies the set_visible_on_all_workspaces command without any pre-configured scope.","commands":{"allow":[],"deny":["set_visible_on_all_workspaces"]}},"deny-show":{"identifier":"deny-show","description":"Denies the show command without any pre-configured scope.","commands":{"allow":[],"deny":["show"]}},"deny-start-dragging":{"identifier":"deny-start-dragging","description":"Denies the start_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_dragging"]}},"deny-start-resize-dragging":{"identifier":"deny-start-resize-dragging","description":"Denies the start_resize_dragging command without any pre-configured scope.","commands":{"allow":[],"deny":["start_resize_dragging"]}},"deny-theme":{"identifier":"deny-theme","description":"Denies the theme command without any pre-configured scope.","commands":{"allow":[],"deny":["theme"]}},"deny-title":{"identifier":"deny-title","description":"Denies the title command without any pre-configured scope.","commands":{"allow":[],"deny":["title"]}},"deny-toggle-maximize":{"identifier":"deny-toggle-maximize","description":"Denies the toggle_maximize command without any pre-configured scope.","commands":{"allow":[],"deny":["toggle_maximize"]}},"deny-unmaximize":{"identifier":"deny-unmaximize","description":"Denies the unmaximize command without any pre-configured scope.","commands":{"allow":[],"deny":["unmaximize"]}},"deny-unminimize":{"identifier":"deny-unminimize","description":"Denies the unminimize command without any pre-configured scope.","commands":{"allow":[],"deny":["unminimize"]}}},"permission_sets":{},"global_scope_schema":null},"deep-link":{"default_permission":{"identifier":"default","description":"Allows reading the opened deep link via the get_current command","permissions":["allow-get-current"]},"permissions":{"allow-get-current":{"identifier":"allow-get-current","description":"Enables the get_current command without any pre-configured scope.","commands":{"allow":["get_current"],"deny":[]}},"allow-is-registered":{"identifier":"allow-is-registered","description":"Enables the is_registered command without any pre-configured scope.","commands":{"allow":["is_registered"],"deny":[]}},"allow-register":{"identifier":"allow-register","description":"Enables the register command without any pre-configured scope.","commands":{"allow":["register"],"deny":[]}},"allow-unregister":{"identifier":"allow-unregister","description":"Enables the unregister command without any pre-configured scope.","commands":{"allow":["unregister"],"deny":[]}},"deny-get-current":{"identifier":"deny-get-current","description":"Denies the get_current command without any pre-configured scope.","commands":{"allow":[],"deny":["get_current"]}},"deny-is-registered":{"identifier":"deny-is-registered","description":"Denies the is_registered command without any pre-configured scope.","commands":{"allow":[],"deny":["is_registered"]}},"deny-register":{"identifier":"deny-register","description":"Denies the register command without any pre-configured scope.","commands":{"allow":[],"deny":["register"]}},"deny-unregister":{"identifier":"deny-unregister","description":"Denies the unregister command without any pre-configured scope.","commands":{"allow":[],"deny":["unregister"]}}},"permission_sets":{},"global_scope_schema":null},"shell":{"default_permission":{"identifier":"default","description":"This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality with a reasonable\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n","permissions":["allow-open"]},"permissions":{"allow-execute":{"identifier":"allow-execute","description":"Enables the execute command without any pre-configured scope.","commands":{"allow":["execute"],"deny":[]}},"allow-kill":{"identifier":"allow-kill","description":"Enables the kill command without any pre-configured scope.","commands":{"allow":["kill"],"deny":[]}},"allow-open":{"identifier":"allow-open","description":"Enables the open command without any pre-configured scope.","commands":{"allow":["open"],"deny":[]}},"allow-spawn":{"identifier":"allow-spawn","description":"Enables the spawn command without any pre-configured scope.","commands":{"allow":["spawn"],"deny":[]}},"allow-stdin-write":{"identifier":"allow-stdin-write","description":"Enables the stdin_write command without any pre-configured scope.","commands":{"allow":["stdin_write"],"deny":[]}},"deny-execute":{"identifier":"deny-execute","description":"Denies the execute command without any pre-configured scope.","commands":{"allow":[],"deny":["execute"]}},"deny-kill":{"identifier":"deny-kill","description":"Denies the kill command without any pre-configured scope.","commands":{"allow":[],"deny":["kill"]}},"deny-open":{"identifier":"deny-open","description":"Denies the open command without any pre-configured scope.","commands":{"allow":[],"deny":["open"]}},"deny-spawn":{"identifier":"deny-spawn","description":"Denies the spawn command without any pre-configured scope.","commands":{"allow":[],"deny":["spawn"]}},"deny-stdin-write":{"identifier":"deny-stdin-write","description":"Denies the stdin_write command without any pre-configured scope.","commands":{"allow":[],"deny":["stdin_write"]}}},"permission_sets":{},"global_scope_schema":{"$schema":"http://json-schema.org/draft-07/schema#","anyOf":[{"additionalProperties":false,"properties":{"args":{"allOf":[{"$ref":"#/definitions/ShellScopeEntryAllowedArgs"}],"description":"The allowed arguments for the command execution."},"cmd":{"description":"The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.","type":"string"},"name":{"description":"The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.","type":"string"}},"required":["cmd","name"],"type":"object"},{"additionalProperties":false,"properties":{"args":{"allOf":[{"$ref":"#/definitions/ShellScopeEntryAllowedArgs"}],"description":"The allowed arguments for the command execution."},"name":{"description":"The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.","type":"string"},"sidecar":{"description":"If this command is a sidecar command.","type":"boolean"}},"required":["name","sidecar"],"type":"object"}],"definitions":{"ShellScopeEntryAllowedArg":{"anyOf":[{"description":"A non-configurable argument that is passed to the command in the order it was specified.","type":"string"},{"additionalProperties":false,"description":"A variable that is set while calling the command from the webview API.","properties":{"raw":{"default":false,"description":"Marks the validator as a raw regex, meaning the plugin should not make any modification at runtime.\n\nThis means the regex will not match on the entire string by default, which might be exploited if your regex allow unexpected input to be considered valid. When using this option, make sure your regex is correct.","type":"boolean"},"validator":{"description":"[regex] validator to require passed values to conform to an expected input.\n\nThis will require the argument value passed to this variable to match the `validator` regex before it will be executed.\n\nThe regex string is by default surrounded by `^...$` to match the full string. For example the `https?://\\w+` regex would be registered as `^https?://\\w+$`.\n\n[regex]: ","type":"string"}},"required":["validator"],"type":"object"}],"description":"A command argument allowed to be executed by the webview API."},"ShellScopeEntryAllowedArgs":{"anyOf":[{"description":"Use a simple boolean to allow all or disable all arguments to this command configuration.","type":"boolean"},{"description":"A specific set of [`ShellScopeEntryAllowedArg`] that are valid to call for the command configuration.","items":{"$ref":"#/definitions/ShellScopeEntryAllowedArg"},"type":"array"}],"description":"A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellScopeEntryAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration."}},"description":"Shell scope entry.","title":"ShellScopeEntry"}}} \ No newline at end of file diff --git a/src-tauri/gen/schemas/capabilities.json b/src-tauri/gen/schemas/capabilities.json new file mode 100644 index 0000000..3dbad03 --- /dev/null +++ b/src-tauri/gen/schemas/capabilities.json @@ -0,0 +1 @@ +{"default":{"identifier":"default","description":"Default capabilities for SecScore application","local":true,"windows":["main"],"permissions":["core:default","core:window:default","core:window:allow-show","core:window:allow-hide","core:window:allow-close","core:window:allow-minimize","core:window:allow-maximize","core:window:allow-unmaximize","core:window:allow-start-dragging","core:webview:default","core:app:default","core:tray:default","core:tray:allow-new","core:tray:allow-set-icon","core:tray:allow-set-menu","core:menu:default","shell:allow-open"]}} \ No newline at end of file diff --git a/src-tauri/gen/schemas/desktop-schema.json b/src-tauri/gen/schemas/desktop-schema.json new file mode 100644 index 0000000..5f3b215 --- /dev/null +++ b/src-tauri/gen/schemas/desktop-schema.json @@ -0,0 +1,2618 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "CapabilityFile", + "description": "Capability formats accepted in a capability file.", + "anyOf": [ + { + "description": "A single capability.", + "allOf": [ + { + "$ref": "#/definitions/Capability" + } + ] + }, + { + "description": "A list of capabilities.", + "type": "array", + "items": { + "$ref": "#/definitions/Capability" + } + }, + { + "description": "A list of capabilities.", + "type": "object", + "required": [ + "capabilities" + ], + "properties": { + "capabilities": { + "description": "The list of capabilities.", + "type": "array", + "items": { + "$ref": "#/definitions/Capability" + } + } + } + } + ], + "definitions": { + "Capability": { + "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows' and webviews' fine grained access to the Tauri core, application, or plugin commands. If a webview or its window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programmatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, ], \"platforms\": [\"macOS\",\"windows\"] } ```", + "type": "object", + "required": [ + "identifier", + "permissions" + ], + "properties": { + "identifier": { + "description": "Identifier of the capability.\n\n## Example\n\n`main-user-files-write`", + "type": "string" + }, + "description": { + "description": "Description of what the capability is intended to allow on associated windows.\n\nIt should contain a description of what the grouped permissions should allow.\n\n## Example\n\nThis capability allows the `main` window access to `filesystem` write related commands and `dialog` commands to enable programmatic access to files selected by the user.", + "default": "", + "type": "string" + }, + "remote": { + "description": "Configure remote URLs that can use the capability permissions.\n\nThis setting is optional and defaults to not being set, as our default use case is that the content is served from our local application.\n\n:::caution Make sure you understand the security implications of providing remote sources with local system access. :::\n\n## Example\n\n```json { \"urls\": [\"https://*.mydomain.dev\"] } ```", + "anyOf": [ + { + "$ref": "#/definitions/CapabilityRemote" + }, + { + "type": "null" + } + ] + }, + "local": { + "description": "Whether this capability is enabled for local app URLs or not. Defaults to `true`.", + "default": true, + "type": "boolean" + }, + "windows": { + "description": "List of windows that are affected by this capability. Can be a glob pattern.\n\nIf a window label matches any of the patterns in this list, the capability will be enabled on all the webviews of that window, regardless of the value of [`Self::webviews`].\n\nOn multiwebview windows, prefer specifying [`Self::webviews`] and omitting [`Self::windows`] for a fine grained access control.\n\n## Example\n\n`[\"main\"]`", + "type": "array", + "items": { + "type": "string" + } + }, + "webviews": { + "description": "List of webviews that are affected by this capability. Can be a glob pattern.\n\nThe capability will be enabled on all the webviews whose label matches any of the patterns in this list, regardless of whether the webview's window label matches a pattern in [`Self::windows`].\n\n## Example\n\n`[\"sub-webview-one\", \"sub-webview-two\"]`", + "type": "array", + "items": { + "type": "string" + } + }, + "permissions": { + "description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"core:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ] ```", + "type": "array", + "items": { + "$ref": "#/definitions/PermissionEntry" + }, + "uniqueItems": true + }, + "platforms": { + "description": "Limit which target platforms this capability applies to.\n\nBy default all platforms are targeted.\n\n## Example\n\n`[\"macOS\",\"windows\"]`", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/Target" + } + } + } + }, + "CapabilityRemote": { + "description": "Configuration for remote URLs that are associated with the capability.", + "type": "object", + "required": [ + "urls" + ], + "properties": { + "urls": { + "description": "Remote domains this capability refers to using the [URLPattern standard](https://urlpattern.spec.whatwg.org/).\n\n## Examples\n\n- \"https://*.mydomain.dev\": allows subdomains of mydomain.dev - \"https://mydomain.dev/api/*\": allows any subpath of mydomain.dev/api", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "PermissionEntry": { + "description": "An entry for a permission value in a [`Capability`] can be either a raw permission [`Identifier`] or an object that references a permission and extends its scope.", + "anyOf": [ + { + "description": "Reference a permission or permission set by identifier.", + "allOf": [ + { + "$ref": "#/definitions/Identifier" + } + ] + }, + { + "description": "Reference a permission or permission set by identifier and extends its scope.", + "type": "object", + "allOf": [ + { + "if": { + "properties": { + "identifier": { + "anyOf": [ + { + "description": "This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality with a reasonable\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n\n#### This default permission set includes:\n\n- `allow-open`", + "type": "string", + "const": "shell:default", + "markdownDescription": "This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality with a reasonable\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n\n#### This default permission set includes:\n\n- `allow-open`" + }, + { + "description": "Enables the execute command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-execute", + "markdownDescription": "Enables the execute command without any pre-configured scope." + }, + { + "description": "Enables the kill command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-kill", + "markdownDescription": "Enables the kill command without any pre-configured scope." + }, + { + "description": "Enables the open command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-open", + "markdownDescription": "Enables the open command without any pre-configured scope." + }, + { + "description": "Enables the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-spawn", + "markdownDescription": "Enables the spawn command without any pre-configured scope." + }, + { + "description": "Enables the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-stdin-write", + "markdownDescription": "Enables the stdin_write command without any pre-configured scope." + }, + { + "description": "Denies the execute command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-execute", + "markdownDescription": "Denies the execute command without any pre-configured scope." + }, + { + "description": "Denies the kill command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-kill", + "markdownDescription": "Denies the kill command without any pre-configured scope." + }, + { + "description": "Denies the open command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-open", + "markdownDescription": "Denies the open command without any pre-configured scope." + }, + { + "description": "Denies the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-spawn", + "markdownDescription": "Denies the spawn command without any pre-configured scope." + }, + { + "description": "Denies the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-stdin-write", + "markdownDescription": "Denies the stdin_write command without any pre-configured scope." + } + ] + } + } + }, + "then": { + "properties": { + "allow": { + "items": { + "title": "ShellScopeEntry", + "description": "Shell scope entry.", + "anyOf": [ + { + "type": "object", + "required": [ + "cmd", + "name" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "cmd": { + "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", + "type": "string" + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "name", + "sidecar" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + }, + "sidecar": { + "description": "If this command is a sidecar command.", + "type": "boolean" + } + }, + "additionalProperties": false + } + ] + } + }, + "deny": { + "items": { + "title": "ShellScopeEntry", + "description": "Shell scope entry.", + "anyOf": [ + { + "type": "object", + "required": [ + "cmd", + "name" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "cmd": { + "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", + "type": "string" + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "name", + "sidecar" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + }, + "sidecar": { + "description": "If this command is a sidecar command.", + "type": "boolean" + } + }, + "additionalProperties": false + } + ] + } + } + } + }, + "properties": { + "identifier": { + "description": "Identifier of the permission or permission set.", + "allOf": [ + { + "$ref": "#/definitions/Identifier" + } + ] + } + } + }, + { + "properties": { + "identifier": { + "description": "Identifier of the permission or permission set.", + "allOf": [ + { + "$ref": "#/definitions/Identifier" + } + ] + }, + "allow": { + "description": "Data that defines what is allowed by the scope.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/Value" + } + }, + "deny": { + "description": "Data that defines what is denied by the scope. This should be prioritized by validation logic.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/Value" + } + } + } + } + ], + "required": [ + "identifier" + ] + } + ] + }, + "Identifier": { + "description": "Permission identifier", + "oneOf": [ + { + "description": "Default core plugins set.\n#### This default permission set includes:\n\n- `core:path:default`\n- `core:event:default`\n- `core:window:default`\n- `core:webview:default`\n- `core:app:default`\n- `core:image:default`\n- `core:resources:default`\n- `core:menu:default`\n- `core:tray:default`", + "type": "string", + "const": "core:default", + "markdownDescription": "Default core plugins set.\n#### This default permission set includes:\n\n- `core:path:default`\n- `core:event:default`\n- `core:window:default`\n- `core:webview:default`\n- `core:app:default`\n- `core:image:default`\n- `core:resources:default`\n- `core:menu:default`\n- `core:tray:default`" + }, + { + "description": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-version`\n- `allow-name`\n- `allow-tauri-version`\n- `allow-identifier`\n- `allow-bundle-type`\n- `allow-register-listener`\n- `allow-remove-listener`", + "type": "string", + "const": "core:app:default", + "markdownDescription": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-version`\n- `allow-name`\n- `allow-tauri-version`\n- `allow-identifier`\n- `allow-bundle-type`\n- `allow-register-listener`\n- `allow-remove-listener`" + }, + { + "description": "Enables the app_hide command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-app-hide", + "markdownDescription": "Enables the app_hide command without any pre-configured scope." + }, + { + "description": "Enables the app_show command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-app-show", + "markdownDescription": "Enables the app_show command without any pre-configured scope." + }, + { + "description": "Enables the bundle_type command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-bundle-type", + "markdownDescription": "Enables the bundle_type command without any pre-configured scope." + }, + { + "description": "Enables the default_window_icon command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-default-window-icon", + "markdownDescription": "Enables the default_window_icon command without any pre-configured scope." + }, + { + "description": "Enables the fetch_data_store_identifiers command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-fetch-data-store-identifiers", + "markdownDescription": "Enables the fetch_data_store_identifiers command without any pre-configured scope." + }, + { + "description": "Enables the identifier command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-identifier", + "markdownDescription": "Enables the identifier command without any pre-configured scope." + }, + { + "description": "Enables the name command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-name", + "markdownDescription": "Enables the name command without any pre-configured scope." + }, + { + "description": "Enables the register_listener command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-register-listener", + "markdownDescription": "Enables the register_listener command without any pre-configured scope." + }, + { + "description": "Enables the remove_data_store command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-remove-data-store", + "markdownDescription": "Enables the remove_data_store command without any pre-configured scope." + }, + { + "description": "Enables the remove_listener command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-remove-listener", + "markdownDescription": "Enables the remove_listener command without any pre-configured scope." + }, + { + "description": "Enables the set_app_theme command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-set-app-theme", + "markdownDescription": "Enables the set_app_theme command without any pre-configured scope." + }, + { + "description": "Enables the set_dock_visibility command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-set-dock-visibility", + "markdownDescription": "Enables the set_dock_visibility command without any pre-configured scope." + }, + { + "description": "Enables the tauri_version command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-tauri-version", + "markdownDescription": "Enables the tauri_version command without any pre-configured scope." + }, + { + "description": "Enables the version command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-version", + "markdownDescription": "Enables the version command without any pre-configured scope." + }, + { + "description": "Denies the app_hide command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-app-hide", + "markdownDescription": "Denies the app_hide command without any pre-configured scope." + }, + { + "description": "Denies the app_show command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-app-show", + "markdownDescription": "Denies the app_show command without any pre-configured scope." + }, + { + "description": "Denies the bundle_type command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-bundle-type", + "markdownDescription": "Denies the bundle_type command without any pre-configured scope." + }, + { + "description": "Denies the default_window_icon command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-default-window-icon", + "markdownDescription": "Denies the default_window_icon command without any pre-configured scope." + }, + { + "description": "Denies the fetch_data_store_identifiers command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-fetch-data-store-identifiers", + "markdownDescription": "Denies the fetch_data_store_identifiers command without any pre-configured scope." + }, + { + "description": "Denies the identifier command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-identifier", + "markdownDescription": "Denies the identifier command without any pre-configured scope." + }, + { + "description": "Denies the name command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-name", + "markdownDescription": "Denies the name command without any pre-configured scope." + }, + { + "description": "Denies the register_listener command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-register-listener", + "markdownDescription": "Denies the register_listener command without any pre-configured scope." + }, + { + "description": "Denies the remove_data_store command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-remove-data-store", + "markdownDescription": "Denies the remove_data_store command without any pre-configured scope." + }, + { + "description": "Denies the remove_listener command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-remove-listener", + "markdownDescription": "Denies the remove_listener command without any pre-configured scope." + }, + { + "description": "Denies the set_app_theme command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-set-app-theme", + "markdownDescription": "Denies the set_app_theme command without any pre-configured scope." + }, + { + "description": "Denies the set_dock_visibility command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-set-dock-visibility", + "markdownDescription": "Denies the set_dock_visibility command without any pre-configured scope." + }, + { + "description": "Denies the tauri_version command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-tauri-version", + "markdownDescription": "Denies the tauri_version command without any pre-configured scope." + }, + { + "description": "Denies the version command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-version", + "markdownDescription": "Denies the version command without any pre-configured scope." + }, + { + "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-listen`\n- `allow-unlisten`\n- `allow-emit`\n- `allow-emit-to`", + "type": "string", + "const": "core:event:default", + "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-listen`\n- `allow-unlisten`\n- `allow-emit`\n- `allow-emit-to`" + }, + { + "description": "Enables the emit command without any pre-configured scope.", + "type": "string", + "const": "core:event:allow-emit", + "markdownDescription": "Enables the emit command without any pre-configured scope." + }, + { + "description": "Enables the emit_to command without any pre-configured scope.", + "type": "string", + "const": "core:event:allow-emit-to", + "markdownDescription": "Enables the emit_to command without any pre-configured scope." + }, + { + "description": "Enables the listen command without any pre-configured scope.", + "type": "string", + "const": "core:event:allow-listen", + "markdownDescription": "Enables the listen command without any pre-configured scope." + }, + { + "description": "Enables the unlisten command without any pre-configured scope.", + "type": "string", + "const": "core:event:allow-unlisten", + "markdownDescription": "Enables the unlisten command without any pre-configured scope." + }, + { + "description": "Denies the emit command without any pre-configured scope.", + "type": "string", + "const": "core:event:deny-emit", + "markdownDescription": "Denies the emit command without any pre-configured scope." + }, + { + "description": "Denies the emit_to command without any pre-configured scope.", + "type": "string", + "const": "core:event:deny-emit-to", + "markdownDescription": "Denies the emit_to command without any pre-configured scope." + }, + { + "description": "Denies the listen command without any pre-configured scope.", + "type": "string", + "const": "core:event:deny-listen", + "markdownDescription": "Denies the listen command without any pre-configured scope." + }, + { + "description": "Denies the unlisten command without any pre-configured scope.", + "type": "string", + "const": "core:event:deny-unlisten", + "markdownDescription": "Denies the unlisten command without any pre-configured scope." + }, + { + "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-from-bytes`\n- `allow-from-path`\n- `allow-rgba`\n- `allow-size`", + "type": "string", + "const": "core:image:default", + "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-from-bytes`\n- `allow-from-path`\n- `allow-rgba`\n- `allow-size`" + }, + { + "description": "Enables the from_bytes command without any pre-configured scope.", + "type": "string", + "const": "core:image:allow-from-bytes", + "markdownDescription": "Enables the from_bytes command without any pre-configured scope." + }, + { + "description": "Enables the from_path command without any pre-configured scope.", + "type": "string", + "const": "core:image:allow-from-path", + "markdownDescription": "Enables the from_path command without any pre-configured scope." + }, + { + "description": "Enables the new command without any pre-configured scope.", + "type": "string", + "const": "core:image:allow-new", + "markdownDescription": "Enables the new command without any pre-configured scope." + }, + { + "description": "Enables the rgba command without any pre-configured scope.", + "type": "string", + "const": "core:image:allow-rgba", + "markdownDescription": "Enables the rgba command without any pre-configured scope." + }, + { + "description": "Enables the size command without any pre-configured scope.", + "type": "string", + "const": "core:image:allow-size", + "markdownDescription": "Enables the size command without any pre-configured scope." + }, + { + "description": "Denies the from_bytes command without any pre-configured scope.", + "type": "string", + "const": "core:image:deny-from-bytes", + "markdownDescription": "Denies the from_bytes command without any pre-configured scope." + }, + { + "description": "Denies the from_path command without any pre-configured scope.", + "type": "string", + "const": "core:image:deny-from-path", + "markdownDescription": "Denies the from_path command without any pre-configured scope." + }, + { + "description": "Denies the new command without any pre-configured scope.", + "type": "string", + "const": "core:image:deny-new", + "markdownDescription": "Denies the new command without any pre-configured scope." + }, + { + "description": "Denies the rgba command without any pre-configured scope.", + "type": "string", + "const": "core:image:deny-rgba", + "markdownDescription": "Denies the rgba command without any pre-configured scope." + }, + { + "description": "Denies the size command without any pre-configured scope.", + "type": "string", + "const": "core:image:deny-size", + "markdownDescription": "Denies the size command without any pre-configured scope." + }, + { + "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-append`\n- `allow-prepend`\n- `allow-insert`\n- `allow-remove`\n- `allow-remove-at`\n- `allow-items`\n- `allow-get`\n- `allow-popup`\n- `allow-create-default`\n- `allow-set-as-app-menu`\n- `allow-set-as-window-menu`\n- `allow-text`\n- `allow-set-text`\n- `allow-is-enabled`\n- `allow-set-enabled`\n- `allow-set-accelerator`\n- `allow-set-as-windows-menu-for-nsapp`\n- `allow-set-as-help-menu-for-nsapp`\n- `allow-is-checked`\n- `allow-set-checked`\n- `allow-set-icon`", + "type": "string", + "const": "core:menu:default", + "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-append`\n- `allow-prepend`\n- `allow-insert`\n- `allow-remove`\n- `allow-remove-at`\n- `allow-items`\n- `allow-get`\n- `allow-popup`\n- `allow-create-default`\n- `allow-set-as-app-menu`\n- `allow-set-as-window-menu`\n- `allow-text`\n- `allow-set-text`\n- `allow-is-enabled`\n- `allow-set-enabled`\n- `allow-set-accelerator`\n- `allow-set-as-windows-menu-for-nsapp`\n- `allow-set-as-help-menu-for-nsapp`\n- `allow-is-checked`\n- `allow-set-checked`\n- `allow-set-icon`" + }, + { + "description": "Enables the append command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-append", + "markdownDescription": "Enables the append command without any pre-configured scope." + }, + { + "description": "Enables the create_default command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-create-default", + "markdownDescription": "Enables the create_default command without any pre-configured scope." + }, + { + "description": "Enables the get command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-get", + "markdownDescription": "Enables the get command without any pre-configured scope." + }, + { + "description": "Enables the insert command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-insert", + "markdownDescription": "Enables the insert command without any pre-configured scope." + }, + { + "description": "Enables the is_checked command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-is-checked", + "markdownDescription": "Enables the is_checked command without any pre-configured scope." + }, + { + "description": "Enables the is_enabled command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-is-enabled", + "markdownDescription": "Enables the is_enabled command without any pre-configured scope." + }, + { + "description": "Enables the items command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-items", + "markdownDescription": "Enables the items command without any pre-configured scope." + }, + { + "description": "Enables the new command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-new", + "markdownDescription": "Enables the new command without any pre-configured scope." + }, + { + "description": "Enables the popup command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-popup", + "markdownDescription": "Enables the popup command without any pre-configured scope." + }, + { + "description": "Enables the prepend command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-prepend", + "markdownDescription": "Enables the prepend command without any pre-configured scope." + }, + { + "description": "Enables the remove command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-remove", + "markdownDescription": "Enables the remove command without any pre-configured scope." + }, + { + "description": "Enables the remove_at command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-remove-at", + "markdownDescription": "Enables the remove_at command without any pre-configured scope." + }, + { + "description": "Enables the set_accelerator command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-set-accelerator", + "markdownDescription": "Enables the set_accelerator command without any pre-configured scope." + }, + { + "description": "Enables the set_as_app_menu command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-set-as-app-menu", + "markdownDescription": "Enables the set_as_app_menu command without any pre-configured scope." + }, + { + "description": "Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-set-as-help-menu-for-nsapp", + "markdownDescription": "Enables the set_as_help_menu_for_nsapp command without any pre-configured scope." + }, + { + "description": "Enables the set_as_window_menu command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-set-as-window-menu", + "markdownDescription": "Enables the set_as_window_menu command without any pre-configured scope." + }, + { + "description": "Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-set-as-windows-menu-for-nsapp", + "markdownDescription": "Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope." + }, + { + "description": "Enables the set_checked command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-set-checked", + "markdownDescription": "Enables the set_checked command without any pre-configured scope." + }, + { + "description": "Enables the set_enabled command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-set-enabled", + "markdownDescription": "Enables the set_enabled command without any pre-configured scope." + }, + { + "description": "Enables the set_icon command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-set-icon", + "markdownDescription": "Enables the set_icon command without any pre-configured scope." + }, + { + "description": "Enables the set_text command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-set-text", + "markdownDescription": "Enables the set_text command without any pre-configured scope." + }, + { + "description": "Enables the text command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-text", + "markdownDescription": "Enables the text command without any pre-configured scope." + }, + { + "description": "Denies the append command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-append", + "markdownDescription": "Denies the append command without any pre-configured scope." + }, + { + "description": "Denies the create_default command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-create-default", + "markdownDescription": "Denies the create_default command without any pre-configured scope." + }, + { + "description": "Denies the get command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-get", + "markdownDescription": "Denies the get command without any pre-configured scope." + }, + { + "description": "Denies the insert command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-insert", + "markdownDescription": "Denies the insert command without any pre-configured scope." + }, + { + "description": "Denies the is_checked command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-is-checked", + "markdownDescription": "Denies the is_checked command without any pre-configured scope." + }, + { + "description": "Denies the is_enabled command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-is-enabled", + "markdownDescription": "Denies the is_enabled command without any pre-configured scope." + }, + { + "description": "Denies the items command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-items", + "markdownDescription": "Denies the items command without any pre-configured scope." + }, + { + "description": "Denies the new command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-new", + "markdownDescription": "Denies the new command without any pre-configured scope." + }, + { + "description": "Denies the popup command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-popup", + "markdownDescription": "Denies the popup command without any pre-configured scope." + }, + { + "description": "Denies the prepend command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-prepend", + "markdownDescription": "Denies the prepend command without any pre-configured scope." + }, + { + "description": "Denies the remove command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-remove", + "markdownDescription": "Denies the remove command without any pre-configured scope." + }, + { + "description": "Denies the remove_at command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-remove-at", + "markdownDescription": "Denies the remove_at command without any pre-configured scope." + }, + { + "description": "Denies the set_accelerator command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-set-accelerator", + "markdownDescription": "Denies the set_accelerator command without any pre-configured scope." + }, + { + "description": "Denies the set_as_app_menu command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-set-as-app-menu", + "markdownDescription": "Denies the set_as_app_menu command without any pre-configured scope." + }, + { + "description": "Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-set-as-help-menu-for-nsapp", + "markdownDescription": "Denies the set_as_help_menu_for_nsapp command without any pre-configured scope." + }, + { + "description": "Denies the set_as_window_menu command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-set-as-window-menu", + "markdownDescription": "Denies the set_as_window_menu command without any pre-configured scope." + }, + { + "description": "Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-set-as-windows-menu-for-nsapp", + "markdownDescription": "Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope." + }, + { + "description": "Denies the set_checked command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-set-checked", + "markdownDescription": "Denies the set_checked command without any pre-configured scope." + }, + { + "description": "Denies the set_enabled command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-set-enabled", + "markdownDescription": "Denies the set_enabled command without any pre-configured scope." + }, + { + "description": "Denies the set_icon command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-set-icon", + "markdownDescription": "Denies the set_icon command without any pre-configured scope." + }, + { + "description": "Denies the set_text command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-set-text", + "markdownDescription": "Denies the set_text command without any pre-configured scope." + }, + { + "description": "Denies the text command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-text", + "markdownDescription": "Denies the text command without any pre-configured scope." + }, + { + "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-resolve-directory`\n- `allow-resolve`\n- `allow-normalize`\n- `allow-join`\n- `allow-dirname`\n- `allow-extname`\n- `allow-basename`\n- `allow-is-absolute`", + "type": "string", + "const": "core:path:default", + "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-resolve-directory`\n- `allow-resolve`\n- `allow-normalize`\n- `allow-join`\n- `allow-dirname`\n- `allow-extname`\n- `allow-basename`\n- `allow-is-absolute`" + }, + { + "description": "Enables the basename command without any pre-configured scope.", + "type": "string", + "const": "core:path:allow-basename", + "markdownDescription": "Enables the basename command without any pre-configured scope." + }, + { + "description": "Enables the dirname command without any pre-configured scope.", + "type": "string", + "const": "core:path:allow-dirname", + "markdownDescription": "Enables the dirname command without any pre-configured scope." + }, + { + "description": "Enables the extname command without any pre-configured scope.", + "type": "string", + "const": "core:path:allow-extname", + "markdownDescription": "Enables the extname command without any pre-configured scope." + }, + { + "description": "Enables the is_absolute command without any pre-configured scope.", + "type": "string", + "const": "core:path:allow-is-absolute", + "markdownDescription": "Enables the is_absolute command without any pre-configured scope." + }, + { + "description": "Enables the join command without any pre-configured scope.", + "type": "string", + "const": "core:path:allow-join", + "markdownDescription": "Enables the join command without any pre-configured scope." + }, + { + "description": "Enables the normalize command without any pre-configured scope.", + "type": "string", + "const": "core:path:allow-normalize", + "markdownDescription": "Enables the normalize command without any pre-configured scope." + }, + { + "description": "Enables the resolve command without any pre-configured scope.", + "type": "string", + "const": "core:path:allow-resolve", + "markdownDescription": "Enables the resolve command without any pre-configured scope." + }, + { + "description": "Enables the resolve_directory command without any pre-configured scope.", + "type": "string", + "const": "core:path:allow-resolve-directory", + "markdownDescription": "Enables the resolve_directory command without any pre-configured scope." + }, + { + "description": "Denies the basename command without any pre-configured scope.", + "type": "string", + "const": "core:path:deny-basename", + "markdownDescription": "Denies the basename command without any pre-configured scope." + }, + { + "description": "Denies the dirname command without any pre-configured scope.", + "type": "string", + "const": "core:path:deny-dirname", + "markdownDescription": "Denies the dirname command without any pre-configured scope." + }, + { + "description": "Denies the extname command without any pre-configured scope.", + "type": "string", + "const": "core:path:deny-extname", + "markdownDescription": "Denies the extname command without any pre-configured scope." + }, + { + "description": "Denies the is_absolute command without any pre-configured scope.", + "type": "string", + "const": "core:path:deny-is-absolute", + "markdownDescription": "Denies the is_absolute command without any pre-configured scope." + }, + { + "description": "Denies the join command without any pre-configured scope.", + "type": "string", + "const": "core:path:deny-join", + "markdownDescription": "Denies the join command without any pre-configured scope." + }, + { + "description": "Denies the normalize command without any pre-configured scope.", + "type": "string", + "const": "core:path:deny-normalize", + "markdownDescription": "Denies the normalize command without any pre-configured scope." + }, + { + "description": "Denies the resolve command without any pre-configured scope.", + "type": "string", + "const": "core:path:deny-resolve", + "markdownDescription": "Denies the resolve command without any pre-configured scope." + }, + { + "description": "Denies the resolve_directory command without any pre-configured scope.", + "type": "string", + "const": "core:path:deny-resolve-directory", + "markdownDescription": "Denies the resolve_directory command without any pre-configured scope." + }, + { + "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-close`", + "type": "string", + "const": "core:resources:default", + "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-close`" + }, + { + "description": "Enables the close command without any pre-configured scope.", + "type": "string", + "const": "core:resources:allow-close", + "markdownDescription": "Enables the close command without any pre-configured scope." + }, + { + "description": "Denies the close command without any pre-configured scope.", + "type": "string", + "const": "core:resources:deny-close", + "markdownDescription": "Denies the close command without any pre-configured scope." + }, + { + "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-get-by-id`\n- `allow-remove-by-id`\n- `allow-set-icon`\n- `allow-set-menu`\n- `allow-set-tooltip`\n- `allow-set-title`\n- `allow-set-visible`\n- `allow-set-temp-dir-path`\n- `allow-set-icon-as-template`\n- `allow-set-show-menu-on-left-click`", + "type": "string", + "const": "core:tray:default", + "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-get-by-id`\n- `allow-remove-by-id`\n- `allow-set-icon`\n- `allow-set-menu`\n- `allow-set-tooltip`\n- `allow-set-title`\n- `allow-set-visible`\n- `allow-set-temp-dir-path`\n- `allow-set-icon-as-template`\n- `allow-set-show-menu-on-left-click`" + }, + { + "description": "Enables the get_by_id command without any pre-configured scope.", + "type": "string", + "const": "core:tray:allow-get-by-id", + "markdownDescription": "Enables the get_by_id command without any pre-configured scope." + }, + { + "description": "Enables the new command without any pre-configured scope.", + "type": "string", + "const": "core:tray:allow-new", + "markdownDescription": "Enables the new command without any pre-configured scope." + }, + { + "description": "Enables the remove_by_id command without any pre-configured scope.", + "type": "string", + "const": "core:tray:allow-remove-by-id", + "markdownDescription": "Enables the remove_by_id command without any pre-configured scope." + }, + { + "description": "Enables the set_icon command without any pre-configured scope.", + "type": "string", + "const": "core:tray:allow-set-icon", + "markdownDescription": "Enables the set_icon command without any pre-configured scope." + }, + { + "description": "Enables the set_icon_as_template command without any pre-configured scope.", + "type": "string", + "const": "core:tray:allow-set-icon-as-template", + "markdownDescription": "Enables the set_icon_as_template command without any pre-configured scope." + }, + { + "description": "Enables the set_menu command without any pre-configured scope.", + "type": "string", + "const": "core:tray:allow-set-menu", + "markdownDescription": "Enables the set_menu command without any pre-configured scope." + }, + { + "description": "Enables the set_show_menu_on_left_click command without any pre-configured scope.", + "type": "string", + "const": "core:tray:allow-set-show-menu-on-left-click", + "markdownDescription": "Enables the set_show_menu_on_left_click command without any pre-configured scope." + }, + { + "description": "Enables the set_temp_dir_path command without any pre-configured scope.", + "type": "string", + "const": "core:tray:allow-set-temp-dir-path", + "markdownDescription": "Enables the set_temp_dir_path command without any pre-configured scope." + }, + { + "description": "Enables the set_title command without any pre-configured scope.", + "type": "string", + "const": "core:tray:allow-set-title", + "markdownDescription": "Enables the set_title command without any pre-configured scope." + }, + { + "description": "Enables the set_tooltip command without any pre-configured scope.", + "type": "string", + "const": "core:tray:allow-set-tooltip", + "markdownDescription": "Enables the set_tooltip command without any pre-configured scope." + }, + { + "description": "Enables the set_visible command without any pre-configured scope.", + "type": "string", + "const": "core:tray:allow-set-visible", + "markdownDescription": "Enables the set_visible command without any pre-configured scope." + }, + { + "description": "Denies the get_by_id command without any pre-configured scope.", + "type": "string", + "const": "core:tray:deny-get-by-id", + "markdownDescription": "Denies the get_by_id command without any pre-configured scope." + }, + { + "description": "Denies the new command without any pre-configured scope.", + "type": "string", + "const": "core:tray:deny-new", + "markdownDescription": "Denies the new command without any pre-configured scope." + }, + { + "description": "Denies the remove_by_id command without any pre-configured scope.", + "type": "string", + "const": "core:tray:deny-remove-by-id", + "markdownDescription": "Denies the remove_by_id command without any pre-configured scope." + }, + { + "description": "Denies the set_icon command without any pre-configured scope.", + "type": "string", + "const": "core:tray:deny-set-icon", + "markdownDescription": "Denies the set_icon command without any pre-configured scope." + }, + { + "description": "Denies the set_icon_as_template command without any pre-configured scope.", + "type": "string", + "const": "core:tray:deny-set-icon-as-template", + "markdownDescription": "Denies the set_icon_as_template command without any pre-configured scope." + }, + { + "description": "Denies the set_menu command without any pre-configured scope.", + "type": "string", + "const": "core:tray:deny-set-menu", + "markdownDescription": "Denies the set_menu command without any pre-configured scope." + }, + { + "description": "Denies the set_show_menu_on_left_click command without any pre-configured scope.", + "type": "string", + "const": "core:tray:deny-set-show-menu-on-left-click", + "markdownDescription": "Denies the set_show_menu_on_left_click command without any pre-configured scope." + }, + { + "description": "Denies the set_temp_dir_path command without any pre-configured scope.", + "type": "string", + "const": "core:tray:deny-set-temp-dir-path", + "markdownDescription": "Denies the set_temp_dir_path command without any pre-configured scope." + }, + { + "description": "Denies the set_title command without any pre-configured scope.", + "type": "string", + "const": "core:tray:deny-set-title", + "markdownDescription": "Denies the set_title command without any pre-configured scope." + }, + { + "description": "Denies the set_tooltip command without any pre-configured scope.", + "type": "string", + "const": "core:tray:deny-set-tooltip", + "markdownDescription": "Denies the set_tooltip command without any pre-configured scope." + }, + { + "description": "Denies the set_visible command without any pre-configured scope.", + "type": "string", + "const": "core:tray:deny-set-visible", + "markdownDescription": "Denies the set_visible command without any pre-configured scope." + }, + { + "description": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-get-all-webviews`\n- `allow-webview-position`\n- `allow-webview-size`\n- `allow-internal-toggle-devtools`", + "type": "string", + "const": "core:webview:default", + "markdownDescription": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-get-all-webviews`\n- `allow-webview-position`\n- `allow-webview-size`\n- `allow-internal-toggle-devtools`" + }, + { + "description": "Enables the clear_all_browsing_data command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-clear-all-browsing-data", + "markdownDescription": "Enables the clear_all_browsing_data command without any pre-configured scope." + }, + { + "description": "Enables the create_webview command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-create-webview", + "markdownDescription": "Enables the create_webview command without any pre-configured scope." + }, + { + "description": "Enables the create_webview_window command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-create-webview-window", + "markdownDescription": "Enables the create_webview_window command without any pre-configured scope." + }, + { + "description": "Enables the get_all_webviews command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-get-all-webviews", + "markdownDescription": "Enables the get_all_webviews command without any pre-configured scope." + }, + { + "description": "Enables the internal_toggle_devtools command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-internal-toggle-devtools", + "markdownDescription": "Enables the internal_toggle_devtools command without any pre-configured scope." + }, + { + "description": "Enables the print command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-print", + "markdownDescription": "Enables the print command without any pre-configured scope." + }, + { + "description": "Enables the reparent command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-reparent", + "markdownDescription": "Enables the reparent command without any pre-configured scope." + }, + { + "description": "Enables the set_webview_auto_resize command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-set-webview-auto-resize", + "markdownDescription": "Enables the set_webview_auto_resize command without any pre-configured scope." + }, + { + "description": "Enables the set_webview_background_color command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-set-webview-background-color", + "markdownDescription": "Enables the set_webview_background_color command without any pre-configured scope." + }, + { + "description": "Enables the set_webview_focus command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-set-webview-focus", + "markdownDescription": "Enables the set_webview_focus command without any pre-configured scope." + }, + { + "description": "Enables the set_webview_position command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-set-webview-position", + "markdownDescription": "Enables the set_webview_position command without any pre-configured scope." + }, + { + "description": "Enables the set_webview_size command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-set-webview-size", + "markdownDescription": "Enables the set_webview_size command without any pre-configured scope." + }, + { + "description": "Enables the set_webview_zoom command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-set-webview-zoom", + "markdownDescription": "Enables the set_webview_zoom command without any pre-configured scope." + }, + { + "description": "Enables the webview_close command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-webview-close", + "markdownDescription": "Enables the webview_close command without any pre-configured scope." + }, + { + "description": "Enables the webview_hide command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-webview-hide", + "markdownDescription": "Enables the webview_hide command without any pre-configured scope." + }, + { + "description": "Enables the webview_position command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-webview-position", + "markdownDescription": "Enables the webview_position command without any pre-configured scope." + }, + { + "description": "Enables the webview_show command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-webview-show", + "markdownDescription": "Enables the webview_show command without any pre-configured scope." + }, + { + "description": "Enables the webview_size command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-webview-size", + "markdownDescription": "Enables the webview_size command without any pre-configured scope." + }, + { + "description": "Denies the clear_all_browsing_data command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-clear-all-browsing-data", + "markdownDescription": "Denies the clear_all_browsing_data command without any pre-configured scope." + }, + { + "description": "Denies the create_webview command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-create-webview", + "markdownDescription": "Denies the create_webview command without any pre-configured scope." + }, + { + "description": "Denies the create_webview_window command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-create-webview-window", + "markdownDescription": "Denies the create_webview_window command without any pre-configured scope." + }, + { + "description": "Denies the get_all_webviews command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-get-all-webviews", + "markdownDescription": "Denies the get_all_webviews command without any pre-configured scope." + }, + { + "description": "Denies the internal_toggle_devtools command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-internal-toggle-devtools", + "markdownDescription": "Denies the internal_toggle_devtools command without any pre-configured scope." + }, + { + "description": "Denies the print command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-print", + "markdownDescription": "Denies the print command without any pre-configured scope." + }, + { + "description": "Denies the reparent command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-reparent", + "markdownDescription": "Denies the reparent command without any pre-configured scope." + }, + { + "description": "Denies the set_webview_auto_resize command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-set-webview-auto-resize", + "markdownDescription": "Denies the set_webview_auto_resize command without any pre-configured scope." + }, + { + "description": "Denies the set_webview_background_color command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-set-webview-background-color", + "markdownDescription": "Denies the set_webview_background_color command without any pre-configured scope." + }, + { + "description": "Denies the set_webview_focus command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-set-webview-focus", + "markdownDescription": "Denies the set_webview_focus command without any pre-configured scope." + }, + { + "description": "Denies the set_webview_position command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-set-webview-position", + "markdownDescription": "Denies the set_webview_position command without any pre-configured scope." + }, + { + "description": "Denies the set_webview_size command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-set-webview-size", + "markdownDescription": "Denies the set_webview_size command without any pre-configured scope." + }, + { + "description": "Denies the set_webview_zoom command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-set-webview-zoom", + "markdownDescription": "Denies the set_webview_zoom command without any pre-configured scope." + }, + { + "description": "Denies the webview_close command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-webview-close", + "markdownDescription": "Denies the webview_close command without any pre-configured scope." + }, + { + "description": "Denies the webview_hide command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-webview-hide", + "markdownDescription": "Denies the webview_hide command without any pre-configured scope." + }, + { + "description": "Denies the webview_position command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-webview-position", + "markdownDescription": "Denies the webview_position command without any pre-configured scope." + }, + { + "description": "Denies the webview_show command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-webview-show", + "markdownDescription": "Denies the webview_show command without any pre-configured scope." + }, + { + "description": "Denies the webview_size command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-webview-size", + "markdownDescription": "Denies the webview_size command without any pre-configured scope." + }, + { + "description": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-get-all-windows`\n- `allow-scale-factor`\n- `allow-inner-position`\n- `allow-outer-position`\n- `allow-inner-size`\n- `allow-outer-size`\n- `allow-is-fullscreen`\n- `allow-is-minimized`\n- `allow-is-maximized`\n- `allow-is-focused`\n- `allow-is-decorated`\n- `allow-is-resizable`\n- `allow-is-maximizable`\n- `allow-is-minimizable`\n- `allow-is-closable`\n- `allow-is-visible`\n- `allow-is-enabled`\n- `allow-title`\n- `allow-current-monitor`\n- `allow-primary-monitor`\n- `allow-monitor-from-point`\n- `allow-available-monitors`\n- `allow-cursor-position`\n- `allow-theme`\n- `allow-is-always-on-top`\n- `allow-internal-toggle-maximize`", + "type": "string", + "const": "core:window:default", + "markdownDescription": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-get-all-windows`\n- `allow-scale-factor`\n- `allow-inner-position`\n- `allow-outer-position`\n- `allow-inner-size`\n- `allow-outer-size`\n- `allow-is-fullscreen`\n- `allow-is-minimized`\n- `allow-is-maximized`\n- `allow-is-focused`\n- `allow-is-decorated`\n- `allow-is-resizable`\n- `allow-is-maximizable`\n- `allow-is-minimizable`\n- `allow-is-closable`\n- `allow-is-visible`\n- `allow-is-enabled`\n- `allow-title`\n- `allow-current-monitor`\n- `allow-primary-monitor`\n- `allow-monitor-from-point`\n- `allow-available-monitors`\n- `allow-cursor-position`\n- `allow-theme`\n- `allow-is-always-on-top`\n- `allow-internal-toggle-maximize`" + }, + { + "description": "Enables the available_monitors command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-available-monitors", + "markdownDescription": "Enables the available_monitors command without any pre-configured scope." + }, + { + "description": "Enables the center command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-center", + "markdownDescription": "Enables the center command without any pre-configured scope." + }, + { + "description": "Enables the close command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-close", + "markdownDescription": "Enables the close command without any pre-configured scope." + }, + { + "description": "Enables the create command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-create", + "markdownDescription": "Enables the create command without any pre-configured scope." + }, + { + "description": "Enables the current_monitor command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-current-monitor", + "markdownDescription": "Enables the current_monitor command without any pre-configured scope." + }, + { + "description": "Enables the cursor_position command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-cursor-position", + "markdownDescription": "Enables the cursor_position command without any pre-configured scope." + }, + { + "description": "Enables the destroy command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-destroy", + "markdownDescription": "Enables the destroy command without any pre-configured scope." + }, + { + "description": "Enables the get_all_windows command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-get-all-windows", + "markdownDescription": "Enables the get_all_windows command without any pre-configured scope." + }, + { + "description": "Enables the hide command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-hide", + "markdownDescription": "Enables the hide command without any pre-configured scope." + }, + { + "description": "Enables the inner_position command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-inner-position", + "markdownDescription": "Enables the inner_position command without any pre-configured scope." + }, + { + "description": "Enables the inner_size command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-inner-size", + "markdownDescription": "Enables the inner_size command without any pre-configured scope." + }, + { + "description": "Enables the internal_toggle_maximize command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-internal-toggle-maximize", + "markdownDescription": "Enables the internal_toggle_maximize command without any pre-configured scope." + }, + { + "description": "Enables the is_always_on_top command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-always-on-top", + "markdownDescription": "Enables the is_always_on_top command without any pre-configured scope." + }, + { + "description": "Enables the is_closable command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-closable", + "markdownDescription": "Enables the is_closable command without any pre-configured scope." + }, + { + "description": "Enables the is_decorated command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-decorated", + "markdownDescription": "Enables the is_decorated command without any pre-configured scope." + }, + { + "description": "Enables the is_enabled command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-enabled", + "markdownDescription": "Enables the is_enabled command without any pre-configured scope." + }, + { + "description": "Enables the is_focused command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-focused", + "markdownDescription": "Enables the is_focused command without any pre-configured scope." + }, + { + "description": "Enables the is_fullscreen command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-fullscreen", + "markdownDescription": "Enables the is_fullscreen command without any pre-configured scope." + }, + { + "description": "Enables the is_maximizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-maximizable", + "markdownDescription": "Enables the is_maximizable command without any pre-configured scope." + }, + { + "description": "Enables the is_maximized command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-maximized", + "markdownDescription": "Enables the is_maximized command without any pre-configured scope." + }, + { + "description": "Enables the is_minimizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-minimizable", + "markdownDescription": "Enables the is_minimizable command without any pre-configured scope." + }, + { + "description": "Enables the is_minimized command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-minimized", + "markdownDescription": "Enables the is_minimized command without any pre-configured scope." + }, + { + "description": "Enables the is_resizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-resizable", + "markdownDescription": "Enables the is_resizable command without any pre-configured scope." + }, + { + "description": "Enables the is_visible command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-visible", + "markdownDescription": "Enables the is_visible command without any pre-configured scope." + }, + { + "description": "Enables the maximize command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-maximize", + "markdownDescription": "Enables the maximize command without any pre-configured scope." + }, + { + "description": "Enables the minimize command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-minimize", + "markdownDescription": "Enables the minimize command without any pre-configured scope." + }, + { + "description": "Enables the monitor_from_point command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-monitor-from-point", + "markdownDescription": "Enables the monitor_from_point command without any pre-configured scope." + }, + { + "description": "Enables the outer_position command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-outer-position", + "markdownDescription": "Enables the outer_position command without any pre-configured scope." + }, + { + "description": "Enables the outer_size command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-outer-size", + "markdownDescription": "Enables the outer_size command without any pre-configured scope." + }, + { + "description": "Enables the primary_monitor command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-primary-monitor", + "markdownDescription": "Enables the primary_monitor command without any pre-configured scope." + }, + { + "description": "Enables the request_user_attention command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-request-user-attention", + "markdownDescription": "Enables the request_user_attention command without any pre-configured scope." + }, + { + "description": "Enables the scale_factor command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-scale-factor", + "markdownDescription": "Enables the scale_factor command without any pre-configured scope." + }, + { + "description": "Enables the set_always_on_bottom command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-always-on-bottom", + "markdownDescription": "Enables the set_always_on_bottom command without any pre-configured scope." + }, + { + "description": "Enables the set_always_on_top command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-always-on-top", + "markdownDescription": "Enables the set_always_on_top command without any pre-configured scope." + }, + { + "description": "Enables the set_background_color command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-background-color", + "markdownDescription": "Enables the set_background_color command without any pre-configured scope." + }, + { + "description": "Enables the set_badge_count command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-badge-count", + "markdownDescription": "Enables the set_badge_count command without any pre-configured scope." + }, + { + "description": "Enables the set_badge_label command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-badge-label", + "markdownDescription": "Enables the set_badge_label command without any pre-configured scope." + }, + { + "description": "Enables the set_closable command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-closable", + "markdownDescription": "Enables the set_closable command without any pre-configured scope." + }, + { + "description": "Enables the set_content_protected command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-content-protected", + "markdownDescription": "Enables the set_content_protected command without any pre-configured scope." + }, + { + "description": "Enables the set_cursor_grab command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-cursor-grab", + "markdownDescription": "Enables the set_cursor_grab command without any pre-configured scope." + }, + { + "description": "Enables the set_cursor_icon command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-cursor-icon", + "markdownDescription": "Enables the set_cursor_icon command without any pre-configured scope." + }, + { + "description": "Enables the set_cursor_position command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-cursor-position", + "markdownDescription": "Enables the set_cursor_position command without any pre-configured scope." + }, + { + "description": "Enables the set_cursor_visible command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-cursor-visible", + "markdownDescription": "Enables the set_cursor_visible command without any pre-configured scope." + }, + { + "description": "Enables the set_decorations command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-decorations", + "markdownDescription": "Enables the set_decorations command without any pre-configured scope." + }, + { + "description": "Enables the set_effects command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-effects", + "markdownDescription": "Enables the set_effects command without any pre-configured scope." + }, + { + "description": "Enables the set_enabled command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-enabled", + "markdownDescription": "Enables the set_enabled command without any pre-configured scope." + }, + { + "description": "Enables the set_focus command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-focus", + "markdownDescription": "Enables the set_focus command without any pre-configured scope." + }, + { + "description": "Enables the set_focusable command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-focusable", + "markdownDescription": "Enables the set_focusable command without any pre-configured scope." + }, + { + "description": "Enables the set_fullscreen command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-fullscreen", + "markdownDescription": "Enables the set_fullscreen command without any pre-configured scope." + }, + { + "description": "Enables the set_icon command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-icon", + "markdownDescription": "Enables the set_icon command without any pre-configured scope." + }, + { + "description": "Enables the set_ignore_cursor_events command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-ignore-cursor-events", + "markdownDescription": "Enables the set_ignore_cursor_events command without any pre-configured scope." + }, + { + "description": "Enables the set_max_size command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-max-size", + "markdownDescription": "Enables the set_max_size command without any pre-configured scope." + }, + { + "description": "Enables the set_maximizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-maximizable", + "markdownDescription": "Enables the set_maximizable command without any pre-configured scope." + }, + { + "description": "Enables the set_min_size command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-min-size", + "markdownDescription": "Enables the set_min_size command without any pre-configured scope." + }, + { + "description": "Enables the set_minimizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-minimizable", + "markdownDescription": "Enables the set_minimizable command without any pre-configured scope." + }, + { + "description": "Enables the set_overlay_icon command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-overlay-icon", + "markdownDescription": "Enables the set_overlay_icon command without any pre-configured scope." + }, + { + "description": "Enables the set_position command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-position", + "markdownDescription": "Enables the set_position command without any pre-configured scope." + }, + { + "description": "Enables the set_progress_bar command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-progress-bar", + "markdownDescription": "Enables the set_progress_bar command without any pre-configured scope." + }, + { + "description": "Enables the set_resizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-resizable", + "markdownDescription": "Enables the set_resizable command without any pre-configured scope." + }, + { + "description": "Enables the set_shadow command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-shadow", + "markdownDescription": "Enables the set_shadow command without any pre-configured scope." + }, + { + "description": "Enables the set_simple_fullscreen command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-simple-fullscreen", + "markdownDescription": "Enables the set_simple_fullscreen command without any pre-configured scope." + }, + { + "description": "Enables the set_size command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-size", + "markdownDescription": "Enables the set_size command without any pre-configured scope." + }, + { + "description": "Enables the set_size_constraints command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-size-constraints", + "markdownDescription": "Enables the set_size_constraints command without any pre-configured scope." + }, + { + "description": "Enables the set_skip_taskbar command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-skip-taskbar", + "markdownDescription": "Enables the set_skip_taskbar command without any pre-configured scope." + }, + { + "description": "Enables the set_theme command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-theme", + "markdownDescription": "Enables the set_theme command without any pre-configured scope." + }, + { + "description": "Enables the set_title command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-title", + "markdownDescription": "Enables the set_title command without any pre-configured scope." + }, + { + "description": "Enables the set_title_bar_style command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-title-bar-style", + "markdownDescription": "Enables the set_title_bar_style command without any pre-configured scope." + }, + { + "description": "Enables the set_visible_on_all_workspaces command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-visible-on-all-workspaces", + "markdownDescription": "Enables the set_visible_on_all_workspaces command without any pre-configured scope." + }, + { + "description": "Enables the show command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-show", + "markdownDescription": "Enables the show command without any pre-configured scope." + }, + { + "description": "Enables the start_dragging command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-start-dragging", + "markdownDescription": "Enables the start_dragging command without any pre-configured scope." + }, + { + "description": "Enables the start_resize_dragging command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-start-resize-dragging", + "markdownDescription": "Enables the start_resize_dragging command without any pre-configured scope." + }, + { + "description": "Enables the theme command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-theme", + "markdownDescription": "Enables the theme command without any pre-configured scope." + }, + { + "description": "Enables the title command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-title", + "markdownDescription": "Enables the title command without any pre-configured scope." + }, + { + "description": "Enables the toggle_maximize command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-toggle-maximize", + "markdownDescription": "Enables the toggle_maximize command without any pre-configured scope." + }, + { + "description": "Enables the unmaximize command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-unmaximize", + "markdownDescription": "Enables the unmaximize command without any pre-configured scope." + }, + { + "description": "Enables the unminimize command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-unminimize", + "markdownDescription": "Enables the unminimize command without any pre-configured scope." + }, + { + "description": "Denies the available_monitors command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-available-monitors", + "markdownDescription": "Denies the available_monitors command without any pre-configured scope." + }, + { + "description": "Denies the center command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-center", + "markdownDescription": "Denies the center command without any pre-configured scope." + }, + { + "description": "Denies the close command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-close", + "markdownDescription": "Denies the close command without any pre-configured scope." + }, + { + "description": "Denies the create command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-create", + "markdownDescription": "Denies the create command without any pre-configured scope." + }, + { + "description": "Denies the current_monitor command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-current-monitor", + "markdownDescription": "Denies the current_monitor command without any pre-configured scope." + }, + { + "description": "Denies the cursor_position command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-cursor-position", + "markdownDescription": "Denies the cursor_position command without any pre-configured scope." + }, + { + "description": "Denies the destroy command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-destroy", + "markdownDescription": "Denies the destroy command without any pre-configured scope." + }, + { + "description": "Denies the get_all_windows command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-get-all-windows", + "markdownDescription": "Denies the get_all_windows command without any pre-configured scope." + }, + { + "description": "Denies the hide command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-hide", + "markdownDescription": "Denies the hide command without any pre-configured scope." + }, + { + "description": "Denies the inner_position command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-inner-position", + "markdownDescription": "Denies the inner_position command without any pre-configured scope." + }, + { + "description": "Denies the inner_size command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-inner-size", + "markdownDescription": "Denies the inner_size command without any pre-configured scope." + }, + { + "description": "Denies the internal_toggle_maximize command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-internal-toggle-maximize", + "markdownDescription": "Denies the internal_toggle_maximize command without any pre-configured scope." + }, + { + "description": "Denies the is_always_on_top command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-always-on-top", + "markdownDescription": "Denies the is_always_on_top command without any pre-configured scope." + }, + { + "description": "Denies the is_closable command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-closable", + "markdownDescription": "Denies the is_closable command without any pre-configured scope." + }, + { + "description": "Denies the is_decorated command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-decorated", + "markdownDescription": "Denies the is_decorated command without any pre-configured scope." + }, + { + "description": "Denies the is_enabled command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-enabled", + "markdownDescription": "Denies the is_enabled command without any pre-configured scope." + }, + { + "description": "Denies the is_focused command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-focused", + "markdownDescription": "Denies the is_focused command without any pre-configured scope." + }, + { + "description": "Denies the is_fullscreen command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-fullscreen", + "markdownDescription": "Denies the is_fullscreen command without any pre-configured scope." + }, + { + "description": "Denies the is_maximizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-maximizable", + "markdownDescription": "Denies the is_maximizable command without any pre-configured scope." + }, + { + "description": "Denies the is_maximized command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-maximized", + "markdownDescription": "Denies the is_maximized command without any pre-configured scope." + }, + { + "description": "Denies the is_minimizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-minimizable", + "markdownDescription": "Denies the is_minimizable command without any pre-configured scope." + }, + { + "description": "Denies the is_minimized command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-minimized", + "markdownDescription": "Denies the is_minimized command without any pre-configured scope." + }, + { + "description": "Denies the is_resizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-resizable", + "markdownDescription": "Denies the is_resizable command without any pre-configured scope." + }, + { + "description": "Denies the is_visible command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-visible", + "markdownDescription": "Denies the is_visible command without any pre-configured scope." + }, + { + "description": "Denies the maximize command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-maximize", + "markdownDescription": "Denies the maximize command without any pre-configured scope." + }, + { + "description": "Denies the minimize command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-minimize", + "markdownDescription": "Denies the minimize command without any pre-configured scope." + }, + { + "description": "Denies the monitor_from_point command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-monitor-from-point", + "markdownDescription": "Denies the monitor_from_point command without any pre-configured scope." + }, + { + "description": "Denies the outer_position command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-outer-position", + "markdownDescription": "Denies the outer_position command without any pre-configured scope." + }, + { + "description": "Denies the outer_size command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-outer-size", + "markdownDescription": "Denies the outer_size command without any pre-configured scope." + }, + { + "description": "Denies the primary_monitor command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-primary-monitor", + "markdownDescription": "Denies the primary_monitor command without any pre-configured scope." + }, + { + "description": "Denies the request_user_attention command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-request-user-attention", + "markdownDescription": "Denies the request_user_attention command without any pre-configured scope." + }, + { + "description": "Denies the scale_factor command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-scale-factor", + "markdownDescription": "Denies the scale_factor command without any pre-configured scope." + }, + { + "description": "Denies the set_always_on_bottom command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-always-on-bottom", + "markdownDescription": "Denies the set_always_on_bottom command without any pre-configured scope." + }, + { + "description": "Denies the set_always_on_top command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-always-on-top", + "markdownDescription": "Denies the set_always_on_top command without any pre-configured scope." + }, + { + "description": "Denies the set_background_color command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-background-color", + "markdownDescription": "Denies the set_background_color command without any pre-configured scope." + }, + { + "description": "Denies the set_badge_count command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-badge-count", + "markdownDescription": "Denies the set_badge_count command without any pre-configured scope." + }, + { + "description": "Denies the set_badge_label command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-badge-label", + "markdownDescription": "Denies the set_badge_label command without any pre-configured scope." + }, + { + "description": "Denies the set_closable command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-closable", + "markdownDescription": "Denies the set_closable command without any pre-configured scope." + }, + { + "description": "Denies the set_content_protected command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-content-protected", + "markdownDescription": "Denies the set_content_protected command without any pre-configured scope." + }, + { + "description": "Denies the set_cursor_grab command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-cursor-grab", + "markdownDescription": "Denies the set_cursor_grab command without any pre-configured scope." + }, + { + "description": "Denies the set_cursor_icon command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-cursor-icon", + "markdownDescription": "Denies the set_cursor_icon command without any pre-configured scope." + }, + { + "description": "Denies the set_cursor_position command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-cursor-position", + "markdownDescription": "Denies the set_cursor_position command without any pre-configured scope." + }, + { + "description": "Denies the set_cursor_visible command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-cursor-visible", + "markdownDescription": "Denies the set_cursor_visible command without any pre-configured scope." + }, + { + "description": "Denies the set_decorations command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-decorations", + "markdownDescription": "Denies the set_decorations command without any pre-configured scope." + }, + { + "description": "Denies the set_effects command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-effects", + "markdownDescription": "Denies the set_effects command without any pre-configured scope." + }, + { + "description": "Denies the set_enabled command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-enabled", + "markdownDescription": "Denies the set_enabled command without any pre-configured scope." + }, + { + "description": "Denies the set_focus command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-focus", + "markdownDescription": "Denies the set_focus command without any pre-configured scope." + }, + { + "description": "Denies the set_focusable command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-focusable", + "markdownDescription": "Denies the set_focusable command without any pre-configured scope." + }, + { + "description": "Denies the set_fullscreen command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-fullscreen", + "markdownDescription": "Denies the set_fullscreen command without any pre-configured scope." + }, + { + "description": "Denies the set_icon command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-icon", + "markdownDescription": "Denies the set_icon command without any pre-configured scope." + }, + { + "description": "Denies the set_ignore_cursor_events command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-ignore-cursor-events", + "markdownDescription": "Denies the set_ignore_cursor_events command without any pre-configured scope." + }, + { + "description": "Denies the set_max_size command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-max-size", + "markdownDescription": "Denies the set_max_size command without any pre-configured scope." + }, + { + "description": "Denies the set_maximizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-maximizable", + "markdownDescription": "Denies the set_maximizable command without any pre-configured scope." + }, + { + "description": "Denies the set_min_size command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-min-size", + "markdownDescription": "Denies the set_min_size command without any pre-configured scope." + }, + { + "description": "Denies the set_minimizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-minimizable", + "markdownDescription": "Denies the set_minimizable command without any pre-configured scope." + }, + { + "description": "Denies the set_overlay_icon command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-overlay-icon", + "markdownDescription": "Denies the set_overlay_icon command without any pre-configured scope." + }, + { + "description": "Denies the set_position command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-position", + "markdownDescription": "Denies the set_position command without any pre-configured scope." + }, + { + "description": "Denies the set_progress_bar command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-progress-bar", + "markdownDescription": "Denies the set_progress_bar command without any pre-configured scope." + }, + { + "description": "Denies the set_resizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-resizable", + "markdownDescription": "Denies the set_resizable command without any pre-configured scope." + }, + { + "description": "Denies the set_shadow command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-shadow", + "markdownDescription": "Denies the set_shadow command without any pre-configured scope." + }, + { + "description": "Denies the set_simple_fullscreen command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-simple-fullscreen", + "markdownDescription": "Denies the set_simple_fullscreen command without any pre-configured scope." + }, + { + "description": "Denies the set_size command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-size", + "markdownDescription": "Denies the set_size command without any pre-configured scope." + }, + { + "description": "Denies the set_size_constraints command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-size-constraints", + "markdownDescription": "Denies the set_size_constraints command without any pre-configured scope." + }, + { + "description": "Denies the set_skip_taskbar command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-skip-taskbar", + "markdownDescription": "Denies the set_skip_taskbar command without any pre-configured scope." + }, + { + "description": "Denies the set_theme command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-theme", + "markdownDescription": "Denies the set_theme command without any pre-configured scope." + }, + { + "description": "Denies the set_title command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-title", + "markdownDescription": "Denies the set_title command without any pre-configured scope." + }, + { + "description": "Denies the set_title_bar_style command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-title-bar-style", + "markdownDescription": "Denies the set_title_bar_style command without any pre-configured scope." + }, + { + "description": "Denies the set_visible_on_all_workspaces command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-visible-on-all-workspaces", + "markdownDescription": "Denies the set_visible_on_all_workspaces command without any pre-configured scope." + }, + { + "description": "Denies the show command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-show", + "markdownDescription": "Denies the show command without any pre-configured scope." + }, + { + "description": "Denies the start_dragging command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-start-dragging", + "markdownDescription": "Denies the start_dragging command without any pre-configured scope." + }, + { + "description": "Denies the start_resize_dragging command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-start-resize-dragging", + "markdownDescription": "Denies the start_resize_dragging command without any pre-configured scope." + }, + { + "description": "Denies the theme command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-theme", + "markdownDescription": "Denies the theme command without any pre-configured scope." + }, + { + "description": "Denies the title command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-title", + "markdownDescription": "Denies the title command without any pre-configured scope." + }, + { + "description": "Denies the toggle_maximize command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-toggle-maximize", + "markdownDescription": "Denies the toggle_maximize command without any pre-configured scope." + }, + { + "description": "Denies the unmaximize command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-unmaximize", + "markdownDescription": "Denies the unmaximize command without any pre-configured scope." + }, + { + "description": "Denies the unminimize command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-unminimize", + "markdownDescription": "Denies the unminimize command without any pre-configured scope." + }, + { + "description": "Allows reading the opened deep link via the get_current command\n#### This default permission set includes:\n\n- `allow-get-current`", + "type": "string", + "const": "deep-link:default", + "markdownDescription": "Allows reading the opened deep link via the get_current command\n#### This default permission set includes:\n\n- `allow-get-current`" + }, + { + "description": "Enables the get_current command without any pre-configured scope.", + "type": "string", + "const": "deep-link:allow-get-current", + "markdownDescription": "Enables the get_current command without any pre-configured scope." + }, + { + "description": "Enables the is_registered command without any pre-configured scope.", + "type": "string", + "const": "deep-link:allow-is-registered", + "markdownDescription": "Enables the is_registered command without any pre-configured scope." + }, + { + "description": "Enables the register command without any pre-configured scope.", + "type": "string", + "const": "deep-link:allow-register", + "markdownDescription": "Enables the register command without any pre-configured scope." + }, + { + "description": "Enables the unregister command without any pre-configured scope.", + "type": "string", + "const": "deep-link:allow-unregister", + "markdownDescription": "Enables the unregister command without any pre-configured scope." + }, + { + "description": "Denies the get_current command without any pre-configured scope.", + "type": "string", + "const": "deep-link:deny-get-current", + "markdownDescription": "Denies the get_current command without any pre-configured scope." + }, + { + "description": "Denies the is_registered command without any pre-configured scope.", + "type": "string", + "const": "deep-link:deny-is-registered", + "markdownDescription": "Denies the is_registered command without any pre-configured scope." + }, + { + "description": "Denies the register command without any pre-configured scope.", + "type": "string", + "const": "deep-link:deny-register", + "markdownDescription": "Denies the register command without any pre-configured scope." + }, + { + "description": "Denies the unregister command without any pre-configured scope.", + "type": "string", + "const": "deep-link:deny-unregister", + "markdownDescription": "Denies the unregister command without any pre-configured scope." + }, + { + "description": "This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality with a reasonable\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n\n#### This default permission set includes:\n\n- `allow-open`", + "type": "string", + "const": "shell:default", + "markdownDescription": "This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality with a reasonable\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n\n#### This default permission set includes:\n\n- `allow-open`" + }, + { + "description": "Enables the execute command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-execute", + "markdownDescription": "Enables the execute command without any pre-configured scope." + }, + { + "description": "Enables the kill command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-kill", + "markdownDescription": "Enables the kill command without any pre-configured scope." + }, + { + "description": "Enables the open command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-open", + "markdownDescription": "Enables the open command without any pre-configured scope." + }, + { + "description": "Enables the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-spawn", + "markdownDescription": "Enables the spawn command without any pre-configured scope." + }, + { + "description": "Enables the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-stdin-write", + "markdownDescription": "Enables the stdin_write command without any pre-configured scope." + }, + { + "description": "Denies the execute command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-execute", + "markdownDescription": "Denies the execute command without any pre-configured scope." + }, + { + "description": "Denies the kill command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-kill", + "markdownDescription": "Denies the kill command without any pre-configured scope." + }, + { + "description": "Denies the open command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-open", + "markdownDescription": "Denies the open command without any pre-configured scope." + }, + { + "description": "Denies the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-spawn", + "markdownDescription": "Denies the spawn command without any pre-configured scope." + }, + { + "description": "Denies the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-stdin-write", + "markdownDescription": "Denies the stdin_write command without any pre-configured scope." + } + ] + }, + "Value": { + "description": "All supported ACL values.", + "anyOf": [ + { + "description": "Represents a null JSON value.", + "type": "null" + }, + { + "description": "Represents a [`bool`].", + "type": "boolean" + }, + { + "description": "Represents a valid ACL [`Number`].", + "allOf": [ + { + "$ref": "#/definitions/Number" + } + ] + }, + { + "description": "Represents a [`String`].", + "type": "string" + }, + { + "description": "Represents a list of other [`Value`]s.", + "type": "array", + "items": { + "$ref": "#/definitions/Value" + } + }, + { + "description": "Represents a map of [`String`] keys to [`Value`]s.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/Value" + } + } + ] + }, + "Number": { + "description": "A valid ACL number.", + "anyOf": [ + { + "description": "Represents an [`i64`].", + "type": "integer", + "format": "int64" + }, + { + "description": "Represents a [`f64`].", + "type": "number", + "format": "double" + } + ] + }, + "Target": { + "description": "Platform target.", + "oneOf": [ + { + "description": "MacOS.", + "type": "string", + "enum": [ + "macOS" + ] + }, + { + "description": "Windows.", + "type": "string", + "enum": [ + "windows" + ] + }, + { + "description": "Linux.", + "type": "string", + "enum": [ + "linux" + ] + }, + { + "description": "Android.", + "type": "string", + "enum": [ + "android" + ] + }, + { + "description": "iOS.", + "type": "string", + "enum": [ + "iOS" + ] + } + ] + }, + "ShellScopeEntryAllowedArg": { + "description": "A command argument allowed to be executed by the webview API.", + "anyOf": [ + { + "description": "A non-configurable argument that is passed to the command in the order it was specified.", + "type": "string" + }, + { + "description": "A variable that is set while calling the command from the webview API.", + "type": "object", + "required": [ + "validator" + ], + "properties": { + "raw": { + "description": "Marks the validator as a raw regex, meaning the plugin should not make any modification at runtime.\n\nThis means the regex will not match on the entire string by default, which might be exploited if your regex allow unexpected input to be considered valid. When using this option, make sure your regex is correct.", + "default": false, + "type": "boolean" + }, + "validator": { + "description": "[regex] validator to require passed values to conform to an expected input.\n\nThis will require the argument value passed to this variable to match the `validator` regex before it will be executed.\n\nThe regex string is by default surrounded by `^...$` to match the full string. For example the `https?://\\w+` regex would be registered as `^https?://\\w+$`.\n\n[regex]: ", + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "ShellScopeEntryAllowedArgs": { + "description": "A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellScopeEntryAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration.", + "anyOf": [ + { + "description": "Use a simple boolean to allow all or disable all arguments to this command configuration.", + "type": "boolean" + }, + { + "description": "A specific set of [`ShellScopeEntryAllowedArg`] that are valid to call for the command configuration.", + "type": "array", + "items": { + "$ref": "#/definitions/ShellScopeEntryAllowedArg" + } + } + ] + } + } +} \ No newline at end of file diff --git a/src-tauri/gen/schemas/windows-schema.json b/src-tauri/gen/schemas/windows-schema.json new file mode 100644 index 0000000..5f3b215 --- /dev/null +++ b/src-tauri/gen/schemas/windows-schema.json @@ -0,0 +1,2618 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "CapabilityFile", + "description": "Capability formats accepted in a capability file.", + "anyOf": [ + { + "description": "A single capability.", + "allOf": [ + { + "$ref": "#/definitions/Capability" + } + ] + }, + { + "description": "A list of capabilities.", + "type": "array", + "items": { + "$ref": "#/definitions/Capability" + } + }, + { + "description": "A list of capabilities.", + "type": "object", + "required": [ + "capabilities" + ], + "properties": { + "capabilities": { + "description": "The list of capabilities.", + "type": "array", + "items": { + "$ref": "#/definitions/Capability" + } + } + } + } + ], + "definitions": { + "Capability": { + "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\nIt controls application windows' and webviews' fine grained access to the Tauri core, application, or plugin commands. If a webview or its window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create groups of windows, based on their required system access, which can reduce impact of frontend vulnerabilities in less privileged windows. Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`. A Window can have none, one, or multiple associated capabilities.\n\n## Example\n\n```json { \"identifier\": \"main-user-files-write\", \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programmatic access to files selected by the user.\", \"windows\": [ \"main\" ], \"permissions\": [ \"core:default\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] }, ], \"platforms\": [\"macOS\",\"windows\"] } ```", + "type": "object", + "required": [ + "identifier", + "permissions" + ], + "properties": { + "identifier": { + "description": "Identifier of the capability.\n\n## Example\n\n`main-user-files-write`", + "type": "string" + }, + "description": { + "description": "Description of what the capability is intended to allow on associated windows.\n\nIt should contain a description of what the grouped permissions should allow.\n\n## Example\n\nThis capability allows the `main` window access to `filesystem` write related commands and `dialog` commands to enable programmatic access to files selected by the user.", + "default": "", + "type": "string" + }, + "remote": { + "description": "Configure remote URLs that can use the capability permissions.\n\nThis setting is optional and defaults to not being set, as our default use case is that the content is served from our local application.\n\n:::caution Make sure you understand the security implications of providing remote sources with local system access. :::\n\n## Example\n\n```json { \"urls\": [\"https://*.mydomain.dev\"] } ```", + "anyOf": [ + { + "$ref": "#/definitions/CapabilityRemote" + }, + { + "type": "null" + } + ] + }, + "local": { + "description": "Whether this capability is enabled for local app URLs or not. Defaults to `true`.", + "default": true, + "type": "boolean" + }, + "windows": { + "description": "List of windows that are affected by this capability. Can be a glob pattern.\n\nIf a window label matches any of the patterns in this list, the capability will be enabled on all the webviews of that window, regardless of the value of [`Self::webviews`].\n\nOn multiwebview windows, prefer specifying [`Self::webviews`] and omitting [`Self::windows`] for a fine grained access control.\n\n## Example\n\n`[\"main\"]`", + "type": "array", + "items": { + "type": "string" + } + }, + "webviews": { + "description": "List of webviews that are affected by this capability. Can be a glob pattern.\n\nThe capability will be enabled on all the webviews whose label matches any of the patterns in this list, regardless of whether the webview's window label matches a pattern in [`Self::windows`].\n\n## Example\n\n`[\"sub-webview-one\", \"sub-webview-two\"]`", + "type": "array", + "items": { + "type": "string" + } + }, + "permissions": { + "description": "List of permissions attached to this capability.\n\nMust include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`. For commands directly implemented in the application itself only `${permission-name}` is required.\n\n## Example\n\n```json [ \"core:default\", \"shell:allow-open\", \"dialog:open\", { \"identifier\": \"fs:allow-write-text-file\", \"allow\": [{ \"path\": \"$HOME/test.txt\" }] } ] ```", + "type": "array", + "items": { + "$ref": "#/definitions/PermissionEntry" + }, + "uniqueItems": true + }, + "platforms": { + "description": "Limit which target platforms this capability applies to.\n\nBy default all platforms are targeted.\n\n## Example\n\n`[\"macOS\",\"windows\"]`", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/Target" + } + } + } + }, + "CapabilityRemote": { + "description": "Configuration for remote URLs that are associated with the capability.", + "type": "object", + "required": [ + "urls" + ], + "properties": { + "urls": { + "description": "Remote domains this capability refers to using the [URLPattern standard](https://urlpattern.spec.whatwg.org/).\n\n## Examples\n\n- \"https://*.mydomain.dev\": allows subdomains of mydomain.dev - \"https://mydomain.dev/api/*\": allows any subpath of mydomain.dev/api", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "PermissionEntry": { + "description": "An entry for a permission value in a [`Capability`] can be either a raw permission [`Identifier`] or an object that references a permission and extends its scope.", + "anyOf": [ + { + "description": "Reference a permission or permission set by identifier.", + "allOf": [ + { + "$ref": "#/definitions/Identifier" + } + ] + }, + { + "description": "Reference a permission or permission set by identifier and extends its scope.", + "type": "object", + "allOf": [ + { + "if": { + "properties": { + "identifier": { + "anyOf": [ + { + "description": "This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality with a reasonable\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n\n#### This default permission set includes:\n\n- `allow-open`", + "type": "string", + "const": "shell:default", + "markdownDescription": "This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality with a reasonable\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n\n#### This default permission set includes:\n\n- `allow-open`" + }, + { + "description": "Enables the execute command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-execute", + "markdownDescription": "Enables the execute command without any pre-configured scope." + }, + { + "description": "Enables the kill command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-kill", + "markdownDescription": "Enables the kill command without any pre-configured scope." + }, + { + "description": "Enables the open command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-open", + "markdownDescription": "Enables the open command without any pre-configured scope." + }, + { + "description": "Enables the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-spawn", + "markdownDescription": "Enables the spawn command without any pre-configured scope." + }, + { + "description": "Enables the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-stdin-write", + "markdownDescription": "Enables the stdin_write command without any pre-configured scope." + }, + { + "description": "Denies the execute command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-execute", + "markdownDescription": "Denies the execute command without any pre-configured scope." + }, + { + "description": "Denies the kill command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-kill", + "markdownDescription": "Denies the kill command without any pre-configured scope." + }, + { + "description": "Denies the open command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-open", + "markdownDescription": "Denies the open command without any pre-configured scope." + }, + { + "description": "Denies the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-spawn", + "markdownDescription": "Denies the spawn command without any pre-configured scope." + }, + { + "description": "Denies the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-stdin-write", + "markdownDescription": "Denies the stdin_write command without any pre-configured scope." + } + ] + } + } + }, + "then": { + "properties": { + "allow": { + "items": { + "title": "ShellScopeEntry", + "description": "Shell scope entry.", + "anyOf": [ + { + "type": "object", + "required": [ + "cmd", + "name" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "cmd": { + "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", + "type": "string" + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "name", + "sidecar" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + }, + "sidecar": { + "description": "If this command is a sidecar command.", + "type": "boolean" + } + }, + "additionalProperties": false + } + ] + } + }, + "deny": { + "items": { + "title": "ShellScopeEntry", + "description": "Shell scope entry.", + "anyOf": [ + { + "type": "object", + "required": [ + "cmd", + "name" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "cmd": { + "description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", + "type": "string" + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "name", + "sidecar" + ], + "properties": { + "args": { + "description": "The allowed arguments for the command execution.", + "allOf": [ + { + "$ref": "#/definitions/ShellScopeEntryAllowedArgs" + } + ] + }, + "name": { + "description": "The name for this allowed shell command configuration.\n\nThis name will be used inside of the webview API to call this command along with any specified arguments.", + "type": "string" + }, + "sidecar": { + "description": "If this command is a sidecar command.", + "type": "boolean" + } + }, + "additionalProperties": false + } + ] + } + } + } + }, + "properties": { + "identifier": { + "description": "Identifier of the permission or permission set.", + "allOf": [ + { + "$ref": "#/definitions/Identifier" + } + ] + } + } + }, + { + "properties": { + "identifier": { + "description": "Identifier of the permission or permission set.", + "allOf": [ + { + "$ref": "#/definitions/Identifier" + } + ] + }, + "allow": { + "description": "Data that defines what is allowed by the scope.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/Value" + } + }, + "deny": { + "description": "Data that defines what is denied by the scope. This should be prioritized by validation logic.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/Value" + } + } + } + } + ], + "required": [ + "identifier" + ] + } + ] + }, + "Identifier": { + "description": "Permission identifier", + "oneOf": [ + { + "description": "Default core plugins set.\n#### This default permission set includes:\n\n- `core:path:default`\n- `core:event:default`\n- `core:window:default`\n- `core:webview:default`\n- `core:app:default`\n- `core:image:default`\n- `core:resources:default`\n- `core:menu:default`\n- `core:tray:default`", + "type": "string", + "const": "core:default", + "markdownDescription": "Default core plugins set.\n#### This default permission set includes:\n\n- `core:path:default`\n- `core:event:default`\n- `core:window:default`\n- `core:webview:default`\n- `core:app:default`\n- `core:image:default`\n- `core:resources:default`\n- `core:menu:default`\n- `core:tray:default`" + }, + { + "description": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-version`\n- `allow-name`\n- `allow-tauri-version`\n- `allow-identifier`\n- `allow-bundle-type`\n- `allow-register-listener`\n- `allow-remove-listener`", + "type": "string", + "const": "core:app:default", + "markdownDescription": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-version`\n- `allow-name`\n- `allow-tauri-version`\n- `allow-identifier`\n- `allow-bundle-type`\n- `allow-register-listener`\n- `allow-remove-listener`" + }, + { + "description": "Enables the app_hide command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-app-hide", + "markdownDescription": "Enables the app_hide command without any pre-configured scope." + }, + { + "description": "Enables the app_show command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-app-show", + "markdownDescription": "Enables the app_show command without any pre-configured scope." + }, + { + "description": "Enables the bundle_type command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-bundle-type", + "markdownDescription": "Enables the bundle_type command without any pre-configured scope." + }, + { + "description": "Enables the default_window_icon command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-default-window-icon", + "markdownDescription": "Enables the default_window_icon command without any pre-configured scope." + }, + { + "description": "Enables the fetch_data_store_identifiers command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-fetch-data-store-identifiers", + "markdownDescription": "Enables the fetch_data_store_identifiers command without any pre-configured scope." + }, + { + "description": "Enables the identifier command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-identifier", + "markdownDescription": "Enables the identifier command without any pre-configured scope." + }, + { + "description": "Enables the name command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-name", + "markdownDescription": "Enables the name command without any pre-configured scope." + }, + { + "description": "Enables the register_listener command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-register-listener", + "markdownDescription": "Enables the register_listener command without any pre-configured scope." + }, + { + "description": "Enables the remove_data_store command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-remove-data-store", + "markdownDescription": "Enables the remove_data_store command without any pre-configured scope." + }, + { + "description": "Enables the remove_listener command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-remove-listener", + "markdownDescription": "Enables the remove_listener command without any pre-configured scope." + }, + { + "description": "Enables the set_app_theme command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-set-app-theme", + "markdownDescription": "Enables the set_app_theme command without any pre-configured scope." + }, + { + "description": "Enables the set_dock_visibility command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-set-dock-visibility", + "markdownDescription": "Enables the set_dock_visibility command without any pre-configured scope." + }, + { + "description": "Enables the tauri_version command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-tauri-version", + "markdownDescription": "Enables the tauri_version command without any pre-configured scope." + }, + { + "description": "Enables the version command without any pre-configured scope.", + "type": "string", + "const": "core:app:allow-version", + "markdownDescription": "Enables the version command without any pre-configured scope." + }, + { + "description": "Denies the app_hide command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-app-hide", + "markdownDescription": "Denies the app_hide command without any pre-configured scope." + }, + { + "description": "Denies the app_show command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-app-show", + "markdownDescription": "Denies the app_show command without any pre-configured scope." + }, + { + "description": "Denies the bundle_type command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-bundle-type", + "markdownDescription": "Denies the bundle_type command without any pre-configured scope." + }, + { + "description": "Denies the default_window_icon command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-default-window-icon", + "markdownDescription": "Denies the default_window_icon command without any pre-configured scope." + }, + { + "description": "Denies the fetch_data_store_identifiers command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-fetch-data-store-identifiers", + "markdownDescription": "Denies the fetch_data_store_identifiers command without any pre-configured scope." + }, + { + "description": "Denies the identifier command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-identifier", + "markdownDescription": "Denies the identifier command without any pre-configured scope." + }, + { + "description": "Denies the name command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-name", + "markdownDescription": "Denies the name command without any pre-configured scope." + }, + { + "description": "Denies the register_listener command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-register-listener", + "markdownDescription": "Denies the register_listener command without any pre-configured scope." + }, + { + "description": "Denies the remove_data_store command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-remove-data-store", + "markdownDescription": "Denies the remove_data_store command without any pre-configured scope." + }, + { + "description": "Denies the remove_listener command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-remove-listener", + "markdownDescription": "Denies the remove_listener command without any pre-configured scope." + }, + { + "description": "Denies the set_app_theme command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-set-app-theme", + "markdownDescription": "Denies the set_app_theme command without any pre-configured scope." + }, + { + "description": "Denies the set_dock_visibility command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-set-dock-visibility", + "markdownDescription": "Denies the set_dock_visibility command without any pre-configured scope." + }, + { + "description": "Denies the tauri_version command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-tauri-version", + "markdownDescription": "Denies the tauri_version command without any pre-configured scope." + }, + { + "description": "Denies the version command without any pre-configured scope.", + "type": "string", + "const": "core:app:deny-version", + "markdownDescription": "Denies the version command without any pre-configured scope." + }, + { + "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-listen`\n- `allow-unlisten`\n- `allow-emit`\n- `allow-emit-to`", + "type": "string", + "const": "core:event:default", + "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-listen`\n- `allow-unlisten`\n- `allow-emit`\n- `allow-emit-to`" + }, + { + "description": "Enables the emit command without any pre-configured scope.", + "type": "string", + "const": "core:event:allow-emit", + "markdownDescription": "Enables the emit command without any pre-configured scope." + }, + { + "description": "Enables the emit_to command without any pre-configured scope.", + "type": "string", + "const": "core:event:allow-emit-to", + "markdownDescription": "Enables the emit_to command without any pre-configured scope." + }, + { + "description": "Enables the listen command without any pre-configured scope.", + "type": "string", + "const": "core:event:allow-listen", + "markdownDescription": "Enables the listen command without any pre-configured scope." + }, + { + "description": "Enables the unlisten command without any pre-configured scope.", + "type": "string", + "const": "core:event:allow-unlisten", + "markdownDescription": "Enables the unlisten command without any pre-configured scope." + }, + { + "description": "Denies the emit command without any pre-configured scope.", + "type": "string", + "const": "core:event:deny-emit", + "markdownDescription": "Denies the emit command without any pre-configured scope." + }, + { + "description": "Denies the emit_to command without any pre-configured scope.", + "type": "string", + "const": "core:event:deny-emit-to", + "markdownDescription": "Denies the emit_to command without any pre-configured scope." + }, + { + "description": "Denies the listen command without any pre-configured scope.", + "type": "string", + "const": "core:event:deny-listen", + "markdownDescription": "Denies the listen command without any pre-configured scope." + }, + { + "description": "Denies the unlisten command without any pre-configured scope.", + "type": "string", + "const": "core:event:deny-unlisten", + "markdownDescription": "Denies the unlisten command without any pre-configured scope." + }, + { + "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-from-bytes`\n- `allow-from-path`\n- `allow-rgba`\n- `allow-size`", + "type": "string", + "const": "core:image:default", + "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-from-bytes`\n- `allow-from-path`\n- `allow-rgba`\n- `allow-size`" + }, + { + "description": "Enables the from_bytes command without any pre-configured scope.", + "type": "string", + "const": "core:image:allow-from-bytes", + "markdownDescription": "Enables the from_bytes command without any pre-configured scope." + }, + { + "description": "Enables the from_path command without any pre-configured scope.", + "type": "string", + "const": "core:image:allow-from-path", + "markdownDescription": "Enables the from_path command without any pre-configured scope." + }, + { + "description": "Enables the new command without any pre-configured scope.", + "type": "string", + "const": "core:image:allow-new", + "markdownDescription": "Enables the new command without any pre-configured scope." + }, + { + "description": "Enables the rgba command without any pre-configured scope.", + "type": "string", + "const": "core:image:allow-rgba", + "markdownDescription": "Enables the rgba command without any pre-configured scope." + }, + { + "description": "Enables the size command without any pre-configured scope.", + "type": "string", + "const": "core:image:allow-size", + "markdownDescription": "Enables the size command without any pre-configured scope." + }, + { + "description": "Denies the from_bytes command without any pre-configured scope.", + "type": "string", + "const": "core:image:deny-from-bytes", + "markdownDescription": "Denies the from_bytes command without any pre-configured scope." + }, + { + "description": "Denies the from_path command without any pre-configured scope.", + "type": "string", + "const": "core:image:deny-from-path", + "markdownDescription": "Denies the from_path command without any pre-configured scope." + }, + { + "description": "Denies the new command without any pre-configured scope.", + "type": "string", + "const": "core:image:deny-new", + "markdownDescription": "Denies the new command without any pre-configured scope." + }, + { + "description": "Denies the rgba command without any pre-configured scope.", + "type": "string", + "const": "core:image:deny-rgba", + "markdownDescription": "Denies the rgba command without any pre-configured scope." + }, + { + "description": "Denies the size command without any pre-configured scope.", + "type": "string", + "const": "core:image:deny-size", + "markdownDescription": "Denies the size command without any pre-configured scope." + }, + { + "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-append`\n- `allow-prepend`\n- `allow-insert`\n- `allow-remove`\n- `allow-remove-at`\n- `allow-items`\n- `allow-get`\n- `allow-popup`\n- `allow-create-default`\n- `allow-set-as-app-menu`\n- `allow-set-as-window-menu`\n- `allow-text`\n- `allow-set-text`\n- `allow-is-enabled`\n- `allow-set-enabled`\n- `allow-set-accelerator`\n- `allow-set-as-windows-menu-for-nsapp`\n- `allow-set-as-help-menu-for-nsapp`\n- `allow-is-checked`\n- `allow-set-checked`\n- `allow-set-icon`", + "type": "string", + "const": "core:menu:default", + "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-append`\n- `allow-prepend`\n- `allow-insert`\n- `allow-remove`\n- `allow-remove-at`\n- `allow-items`\n- `allow-get`\n- `allow-popup`\n- `allow-create-default`\n- `allow-set-as-app-menu`\n- `allow-set-as-window-menu`\n- `allow-text`\n- `allow-set-text`\n- `allow-is-enabled`\n- `allow-set-enabled`\n- `allow-set-accelerator`\n- `allow-set-as-windows-menu-for-nsapp`\n- `allow-set-as-help-menu-for-nsapp`\n- `allow-is-checked`\n- `allow-set-checked`\n- `allow-set-icon`" + }, + { + "description": "Enables the append command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-append", + "markdownDescription": "Enables the append command without any pre-configured scope." + }, + { + "description": "Enables the create_default command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-create-default", + "markdownDescription": "Enables the create_default command without any pre-configured scope." + }, + { + "description": "Enables the get command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-get", + "markdownDescription": "Enables the get command without any pre-configured scope." + }, + { + "description": "Enables the insert command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-insert", + "markdownDescription": "Enables the insert command without any pre-configured scope." + }, + { + "description": "Enables the is_checked command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-is-checked", + "markdownDescription": "Enables the is_checked command without any pre-configured scope." + }, + { + "description": "Enables the is_enabled command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-is-enabled", + "markdownDescription": "Enables the is_enabled command without any pre-configured scope." + }, + { + "description": "Enables the items command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-items", + "markdownDescription": "Enables the items command without any pre-configured scope." + }, + { + "description": "Enables the new command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-new", + "markdownDescription": "Enables the new command without any pre-configured scope." + }, + { + "description": "Enables the popup command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-popup", + "markdownDescription": "Enables the popup command without any pre-configured scope." + }, + { + "description": "Enables the prepend command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-prepend", + "markdownDescription": "Enables the prepend command without any pre-configured scope." + }, + { + "description": "Enables the remove command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-remove", + "markdownDescription": "Enables the remove command without any pre-configured scope." + }, + { + "description": "Enables the remove_at command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-remove-at", + "markdownDescription": "Enables the remove_at command without any pre-configured scope." + }, + { + "description": "Enables the set_accelerator command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-set-accelerator", + "markdownDescription": "Enables the set_accelerator command without any pre-configured scope." + }, + { + "description": "Enables the set_as_app_menu command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-set-as-app-menu", + "markdownDescription": "Enables the set_as_app_menu command without any pre-configured scope." + }, + { + "description": "Enables the set_as_help_menu_for_nsapp command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-set-as-help-menu-for-nsapp", + "markdownDescription": "Enables the set_as_help_menu_for_nsapp command without any pre-configured scope." + }, + { + "description": "Enables the set_as_window_menu command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-set-as-window-menu", + "markdownDescription": "Enables the set_as_window_menu command without any pre-configured scope." + }, + { + "description": "Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-set-as-windows-menu-for-nsapp", + "markdownDescription": "Enables the set_as_windows_menu_for_nsapp command without any pre-configured scope." + }, + { + "description": "Enables the set_checked command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-set-checked", + "markdownDescription": "Enables the set_checked command without any pre-configured scope." + }, + { + "description": "Enables the set_enabled command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-set-enabled", + "markdownDescription": "Enables the set_enabled command without any pre-configured scope." + }, + { + "description": "Enables the set_icon command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-set-icon", + "markdownDescription": "Enables the set_icon command without any pre-configured scope." + }, + { + "description": "Enables the set_text command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-set-text", + "markdownDescription": "Enables the set_text command without any pre-configured scope." + }, + { + "description": "Enables the text command without any pre-configured scope.", + "type": "string", + "const": "core:menu:allow-text", + "markdownDescription": "Enables the text command without any pre-configured scope." + }, + { + "description": "Denies the append command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-append", + "markdownDescription": "Denies the append command without any pre-configured scope." + }, + { + "description": "Denies the create_default command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-create-default", + "markdownDescription": "Denies the create_default command without any pre-configured scope." + }, + { + "description": "Denies the get command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-get", + "markdownDescription": "Denies the get command without any pre-configured scope." + }, + { + "description": "Denies the insert command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-insert", + "markdownDescription": "Denies the insert command without any pre-configured scope." + }, + { + "description": "Denies the is_checked command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-is-checked", + "markdownDescription": "Denies the is_checked command without any pre-configured scope." + }, + { + "description": "Denies the is_enabled command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-is-enabled", + "markdownDescription": "Denies the is_enabled command without any pre-configured scope." + }, + { + "description": "Denies the items command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-items", + "markdownDescription": "Denies the items command without any pre-configured scope." + }, + { + "description": "Denies the new command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-new", + "markdownDescription": "Denies the new command without any pre-configured scope." + }, + { + "description": "Denies the popup command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-popup", + "markdownDescription": "Denies the popup command without any pre-configured scope." + }, + { + "description": "Denies the prepend command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-prepend", + "markdownDescription": "Denies the prepend command without any pre-configured scope." + }, + { + "description": "Denies the remove command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-remove", + "markdownDescription": "Denies the remove command without any pre-configured scope." + }, + { + "description": "Denies the remove_at command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-remove-at", + "markdownDescription": "Denies the remove_at command without any pre-configured scope." + }, + { + "description": "Denies the set_accelerator command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-set-accelerator", + "markdownDescription": "Denies the set_accelerator command without any pre-configured scope." + }, + { + "description": "Denies the set_as_app_menu command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-set-as-app-menu", + "markdownDescription": "Denies the set_as_app_menu command without any pre-configured scope." + }, + { + "description": "Denies the set_as_help_menu_for_nsapp command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-set-as-help-menu-for-nsapp", + "markdownDescription": "Denies the set_as_help_menu_for_nsapp command without any pre-configured scope." + }, + { + "description": "Denies the set_as_window_menu command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-set-as-window-menu", + "markdownDescription": "Denies the set_as_window_menu command without any pre-configured scope." + }, + { + "description": "Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-set-as-windows-menu-for-nsapp", + "markdownDescription": "Denies the set_as_windows_menu_for_nsapp command without any pre-configured scope." + }, + { + "description": "Denies the set_checked command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-set-checked", + "markdownDescription": "Denies the set_checked command without any pre-configured scope." + }, + { + "description": "Denies the set_enabled command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-set-enabled", + "markdownDescription": "Denies the set_enabled command without any pre-configured scope." + }, + { + "description": "Denies the set_icon command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-set-icon", + "markdownDescription": "Denies the set_icon command without any pre-configured scope." + }, + { + "description": "Denies the set_text command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-set-text", + "markdownDescription": "Denies the set_text command without any pre-configured scope." + }, + { + "description": "Denies the text command without any pre-configured scope.", + "type": "string", + "const": "core:menu:deny-text", + "markdownDescription": "Denies the text command without any pre-configured scope." + }, + { + "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-resolve-directory`\n- `allow-resolve`\n- `allow-normalize`\n- `allow-join`\n- `allow-dirname`\n- `allow-extname`\n- `allow-basename`\n- `allow-is-absolute`", + "type": "string", + "const": "core:path:default", + "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-resolve-directory`\n- `allow-resolve`\n- `allow-normalize`\n- `allow-join`\n- `allow-dirname`\n- `allow-extname`\n- `allow-basename`\n- `allow-is-absolute`" + }, + { + "description": "Enables the basename command without any pre-configured scope.", + "type": "string", + "const": "core:path:allow-basename", + "markdownDescription": "Enables the basename command without any pre-configured scope." + }, + { + "description": "Enables the dirname command without any pre-configured scope.", + "type": "string", + "const": "core:path:allow-dirname", + "markdownDescription": "Enables the dirname command without any pre-configured scope." + }, + { + "description": "Enables the extname command without any pre-configured scope.", + "type": "string", + "const": "core:path:allow-extname", + "markdownDescription": "Enables the extname command without any pre-configured scope." + }, + { + "description": "Enables the is_absolute command without any pre-configured scope.", + "type": "string", + "const": "core:path:allow-is-absolute", + "markdownDescription": "Enables the is_absolute command without any pre-configured scope." + }, + { + "description": "Enables the join command without any pre-configured scope.", + "type": "string", + "const": "core:path:allow-join", + "markdownDescription": "Enables the join command without any pre-configured scope." + }, + { + "description": "Enables the normalize command without any pre-configured scope.", + "type": "string", + "const": "core:path:allow-normalize", + "markdownDescription": "Enables the normalize command without any pre-configured scope." + }, + { + "description": "Enables the resolve command without any pre-configured scope.", + "type": "string", + "const": "core:path:allow-resolve", + "markdownDescription": "Enables the resolve command without any pre-configured scope." + }, + { + "description": "Enables the resolve_directory command without any pre-configured scope.", + "type": "string", + "const": "core:path:allow-resolve-directory", + "markdownDescription": "Enables the resolve_directory command without any pre-configured scope." + }, + { + "description": "Denies the basename command without any pre-configured scope.", + "type": "string", + "const": "core:path:deny-basename", + "markdownDescription": "Denies the basename command without any pre-configured scope." + }, + { + "description": "Denies the dirname command without any pre-configured scope.", + "type": "string", + "const": "core:path:deny-dirname", + "markdownDescription": "Denies the dirname command without any pre-configured scope." + }, + { + "description": "Denies the extname command without any pre-configured scope.", + "type": "string", + "const": "core:path:deny-extname", + "markdownDescription": "Denies the extname command without any pre-configured scope." + }, + { + "description": "Denies the is_absolute command without any pre-configured scope.", + "type": "string", + "const": "core:path:deny-is-absolute", + "markdownDescription": "Denies the is_absolute command without any pre-configured scope." + }, + { + "description": "Denies the join command without any pre-configured scope.", + "type": "string", + "const": "core:path:deny-join", + "markdownDescription": "Denies the join command without any pre-configured scope." + }, + { + "description": "Denies the normalize command without any pre-configured scope.", + "type": "string", + "const": "core:path:deny-normalize", + "markdownDescription": "Denies the normalize command without any pre-configured scope." + }, + { + "description": "Denies the resolve command without any pre-configured scope.", + "type": "string", + "const": "core:path:deny-resolve", + "markdownDescription": "Denies the resolve command without any pre-configured scope." + }, + { + "description": "Denies the resolve_directory command without any pre-configured scope.", + "type": "string", + "const": "core:path:deny-resolve-directory", + "markdownDescription": "Denies the resolve_directory command without any pre-configured scope." + }, + { + "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-close`", + "type": "string", + "const": "core:resources:default", + "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-close`" + }, + { + "description": "Enables the close command without any pre-configured scope.", + "type": "string", + "const": "core:resources:allow-close", + "markdownDescription": "Enables the close command without any pre-configured scope." + }, + { + "description": "Denies the close command without any pre-configured scope.", + "type": "string", + "const": "core:resources:deny-close", + "markdownDescription": "Denies the close command without any pre-configured scope." + }, + { + "description": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-get-by-id`\n- `allow-remove-by-id`\n- `allow-set-icon`\n- `allow-set-menu`\n- `allow-set-tooltip`\n- `allow-set-title`\n- `allow-set-visible`\n- `allow-set-temp-dir-path`\n- `allow-set-icon-as-template`\n- `allow-set-show-menu-on-left-click`", + "type": "string", + "const": "core:tray:default", + "markdownDescription": "Default permissions for the plugin, which enables all commands.\n#### This default permission set includes:\n\n- `allow-new`\n- `allow-get-by-id`\n- `allow-remove-by-id`\n- `allow-set-icon`\n- `allow-set-menu`\n- `allow-set-tooltip`\n- `allow-set-title`\n- `allow-set-visible`\n- `allow-set-temp-dir-path`\n- `allow-set-icon-as-template`\n- `allow-set-show-menu-on-left-click`" + }, + { + "description": "Enables the get_by_id command without any pre-configured scope.", + "type": "string", + "const": "core:tray:allow-get-by-id", + "markdownDescription": "Enables the get_by_id command without any pre-configured scope." + }, + { + "description": "Enables the new command without any pre-configured scope.", + "type": "string", + "const": "core:tray:allow-new", + "markdownDescription": "Enables the new command without any pre-configured scope." + }, + { + "description": "Enables the remove_by_id command without any pre-configured scope.", + "type": "string", + "const": "core:tray:allow-remove-by-id", + "markdownDescription": "Enables the remove_by_id command without any pre-configured scope." + }, + { + "description": "Enables the set_icon command without any pre-configured scope.", + "type": "string", + "const": "core:tray:allow-set-icon", + "markdownDescription": "Enables the set_icon command without any pre-configured scope." + }, + { + "description": "Enables the set_icon_as_template command without any pre-configured scope.", + "type": "string", + "const": "core:tray:allow-set-icon-as-template", + "markdownDescription": "Enables the set_icon_as_template command without any pre-configured scope." + }, + { + "description": "Enables the set_menu command without any pre-configured scope.", + "type": "string", + "const": "core:tray:allow-set-menu", + "markdownDescription": "Enables the set_menu command without any pre-configured scope." + }, + { + "description": "Enables the set_show_menu_on_left_click command without any pre-configured scope.", + "type": "string", + "const": "core:tray:allow-set-show-menu-on-left-click", + "markdownDescription": "Enables the set_show_menu_on_left_click command without any pre-configured scope." + }, + { + "description": "Enables the set_temp_dir_path command without any pre-configured scope.", + "type": "string", + "const": "core:tray:allow-set-temp-dir-path", + "markdownDescription": "Enables the set_temp_dir_path command without any pre-configured scope." + }, + { + "description": "Enables the set_title command without any pre-configured scope.", + "type": "string", + "const": "core:tray:allow-set-title", + "markdownDescription": "Enables the set_title command without any pre-configured scope." + }, + { + "description": "Enables the set_tooltip command without any pre-configured scope.", + "type": "string", + "const": "core:tray:allow-set-tooltip", + "markdownDescription": "Enables the set_tooltip command without any pre-configured scope." + }, + { + "description": "Enables the set_visible command without any pre-configured scope.", + "type": "string", + "const": "core:tray:allow-set-visible", + "markdownDescription": "Enables the set_visible command without any pre-configured scope." + }, + { + "description": "Denies the get_by_id command without any pre-configured scope.", + "type": "string", + "const": "core:tray:deny-get-by-id", + "markdownDescription": "Denies the get_by_id command without any pre-configured scope." + }, + { + "description": "Denies the new command without any pre-configured scope.", + "type": "string", + "const": "core:tray:deny-new", + "markdownDescription": "Denies the new command without any pre-configured scope." + }, + { + "description": "Denies the remove_by_id command without any pre-configured scope.", + "type": "string", + "const": "core:tray:deny-remove-by-id", + "markdownDescription": "Denies the remove_by_id command without any pre-configured scope." + }, + { + "description": "Denies the set_icon command without any pre-configured scope.", + "type": "string", + "const": "core:tray:deny-set-icon", + "markdownDescription": "Denies the set_icon command without any pre-configured scope." + }, + { + "description": "Denies the set_icon_as_template command without any pre-configured scope.", + "type": "string", + "const": "core:tray:deny-set-icon-as-template", + "markdownDescription": "Denies the set_icon_as_template command without any pre-configured scope." + }, + { + "description": "Denies the set_menu command without any pre-configured scope.", + "type": "string", + "const": "core:tray:deny-set-menu", + "markdownDescription": "Denies the set_menu command without any pre-configured scope." + }, + { + "description": "Denies the set_show_menu_on_left_click command without any pre-configured scope.", + "type": "string", + "const": "core:tray:deny-set-show-menu-on-left-click", + "markdownDescription": "Denies the set_show_menu_on_left_click command without any pre-configured scope." + }, + { + "description": "Denies the set_temp_dir_path command without any pre-configured scope.", + "type": "string", + "const": "core:tray:deny-set-temp-dir-path", + "markdownDescription": "Denies the set_temp_dir_path command without any pre-configured scope." + }, + { + "description": "Denies the set_title command without any pre-configured scope.", + "type": "string", + "const": "core:tray:deny-set-title", + "markdownDescription": "Denies the set_title command without any pre-configured scope." + }, + { + "description": "Denies the set_tooltip command without any pre-configured scope.", + "type": "string", + "const": "core:tray:deny-set-tooltip", + "markdownDescription": "Denies the set_tooltip command without any pre-configured scope." + }, + { + "description": "Denies the set_visible command without any pre-configured scope.", + "type": "string", + "const": "core:tray:deny-set-visible", + "markdownDescription": "Denies the set_visible command without any pre-configured scope." + }, + { + "description": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-get-all-webviews`\n- `allow-webview-position`\n- `allow-webview-size`\n- `allow-internal-toggle-devtools`", + "type": "string", + "const": "core:webview:default", + "markdownDescription": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-get-all-webviews`\n- `allow-webview-position`\n- `allow-webview-size`\n- `allow-internal-toggle-devtools`" + }, + { + "description": "Enables the clear_all_browsing_data command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-clear-all-browsing-data", + "markdownDescription": "Enables the clear_all_browsing_data command without any pre-configured scope." + }, + { + "description": "Enables the create_webview command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-create-webview", + "markdownDescription": "Enables the create_webview command without any pre-configured scope." + }, + { + "description": "Enables the create_webview_window command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-create-webview-window", + "markdownDescription": "Enables the create_webview_window command without any pre-configured scope." + }, + { + "description": "Enables the get_all_webviews command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-get-all-webviews", + "markdownDescription": "Enables the get_all_webviews command without any pre-configured scope." + }, + { + "description": "Enables the internal_toggle_devtools command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-internal-toggle-devtools", + "markdownDescription": "Enables the internal_toggle_devtools command without any pre-configured scope." + }, + { + "description": "Enables the print command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-print", + "markdownDescription": "Enables the print command without any pre-configured scope." + }, + { + "description": "Enables the reparent command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-reparent", + "markdownDescription": "Enables the reparent command without any pre-configured scope." + }, + { + "description": "Enables the set_webview_auto_resize command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-set-webview-auto-resize", + "markdownDescription": "Enables the set_webview_auto_resize command without any pre-configured scope." + }, + { + "description": "Enables the set_webview_background_color command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-set-webview-background-color", + "markdownDescription": "Enables the set_webview_background_color command without any pre-configured scope." + }, + { + "description": "Enables the set_webview_focus command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-set-webview-focus", + "markdownDescription": "Enables the set_webview_focus command without any pre-configured scope." + }, + { + "description": "Enables the set_webview_position command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-set-webview-position", + "markdownDescription": "Enables the set_webview_position command without any pre-configured scope." + }, + { + "description": "Enables the set_webview_size command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-set-webview-size", + "markdownDescription": "Enables the set_webview_size command without any pre-configured scope." + }, + { + "description": "Enables the set_webview_zoom command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-set-webview-zoom", + "markdownDescription": "Enables the set_webview_zoom command without any pre-configured scope." + }, + { + "description": "Enables the webview_close command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-webview-close", + "markdownDescription": "Enables the webview_close command without any pre-configured scope." + }, + { + "description": "Enables the webview_hide command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-webview-hide", + "markdownDescription": "Enables the webview_hide command without any pre-configured scope." + }, + { + "description": "Enables the webview_position command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-webview-position", + "markdownDescription": "Enables the webview_position command without any pre-configured scope." + }, + { + "description": "Enables the webview_show command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-webview-show", + "markdownDescription": "Enables the webview_show command without any pre-configured scope." + }, + { + "description": "Enables the webview_size command without any pre-configured scope.", + "type": "string", + "const": "core:webview:allow-webview-size", + "markdownDescription": "Enables the webview_size command without any pre-configured scope." + }, + { + "description": "Denies the clear_all_browsing_data command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-clear-all-browsing-data", + "markdownDescription": "Denies the clear_all_browsing_data command without any pre-configured scope." + }, + { + "description": "Denies the create_webview command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-create-webview", + "markdownDescription": "Denies the create_webview command without any pre-configured scope." + }, + { + "description": "Denies the create_webview_window command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-create-webview-window", + "markdownDescription": "Denies the create_webview_window command without any pre-configured scope." + }, + { + "description": "Denies the get_all_webviews command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-get-all-webviews", + "markdownDescription": "Denies the get_all_webviews command without any pre-configured scope." + }, + { + "description": "Denies the internal_toggle_devtools command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-internal-toggle-devtools", + "markdownDescription": "Denies the internal_toggle_devtools command without any pre-configured scope." + }, + { + "description": "Denies the print command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-print", + "markdownDescription": "Denies the print command without any pre-configured scope." + }, + { + "description": "Denies the reparent command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-reparent", + "markdownDescription": "Denies the reparent command without any pre-configured scope." + }, + { + "description": "Denies the set_webview_auto_resize command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-set-webview-auto-resize", + "markdownDescription": "Denies the set_webview_auto_resize command without any pre-configured scope." + }, + { + "description": "Denies the set_webview_background_color command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-set-webview-background-color", + "markdownDescription": "Denies the set_webview_background_color command without any pre-configured scope." + }, + { + "description": "Denies the set_webview_focus command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-set-webview-focus", + "markdownDescription": "Denies the set_webview_focus command without any pre-configured scope." + }, + { + "description": "Denies the set_webview_position command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-set-webview-position", + "markdownDescription": "Denies the set_webview_position command without any pre-configured scope." + }, + { + "description": "Denies the set_webview_size command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-set-webview-size", + "markdownDescription": "Denies the set_webview_size command without any pre-configured scope." + }, + { + "description": "Denies the set_webview_zoom command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-set-webview-zoom", + "markdownDescription": "Denies the set_webview_zoom command without any pre-configured scope." + }, + { + "description": "Denies the webview_close command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-webview-close", + "markdownDescription": "Denies the webview_close command without any pre-configured scope." + }, + { + "description": "Denies the webview_hide command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-webview-hide", + "markdownDescription": "Denies the webview_hide command without any pre-configured scope." + }, + { + "description": "Denies the webview_position command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-webview-position", + "markdownDescription": "Denies the webview_position command without any pre-configured scope." + }, + { + "description": "Denies the webview_show command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-webview-show", + "markdownDescription": "Denies the webview_show command without any pre-configured scope." + }, + { + "description": "Denies the webview_size command without any pre-configured scope.", + "type": "string", + "const": "core:webview:deny-webview-size", + "markdownDescription": "Denies the webview_size command without any pre-configured scope." + }, + { + "description": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-get-all-windows`\n- `allow-scale-factor`\n- `allow-inner-position`\n- `allow-outer-position`\n- `allow-inner-size`\n- `allow-outer-size`\n- `allow-is-fullscreen`\n- `allow-is-minimized`\n- `allow-is-maximized`\n- `allow-is-focused`\n- `allow-is-decorated`\n- `allow-is-resizable`\n- `allow-is-maximizable`\n- `allow-is-minimizable`\n- `allow-is-closable`\n- `allow-is-visible`\n- `allow-is-enabled`\n- `allow-title`\n- `allow-current-monitor`\n- `allow-primary-monitor`\n- `allow-monitor-from-point`\n- `allow-available-monitors`\n- `allow-cursor-position`\n- `allow-theme`\n- `allow-is-always-on-top`\n- `allow-internal-toggle-maximize`", + "type": "string", + "const": "core:window:default", + "markdownDescription": "Default permissions for the plugin.\n#### This default permission set includes:\n\n- `allow-get-all-windows`\n- `allow-scale-factor`\n- `allow-inner-position`\n- `allow-outer-position`\n- `allow-inner-size`\n- `allow-outer-size`\n- `allow-is-fullscreen`\n- `allow-is-minimized`\n- `allow-is-maximized`\n- `allow-is-focused`\n- `allow-is-decorated`\n- `allow-is-resizable`\n- `allow-is-maximizable`\n- `allow-is-minimizable`\n- `allow-is-closable`\n- `allow-is-visible`\n- `allow-is-enabled`\n- `allow-title`\n- `allow-current-monitor`\n- `allow-primary-monitor`\n- `allow-monitor-from-point`\n- `allow-available-monitors`\n- `allow-cursor-position`\n- `allow-theme`\n- `allow-is-always-on-top`\n- `allow-internal-toggle-maximize`" + }, + { + "description": "Enables the available_monitors command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-available-monitors", + "markdownDescription": "Enables the available_monitors command without any pre-configured scope." + }, + { + "description": "Enables the center command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-center", + "markdownDescription": "Enables the center command without any pre-configured scope." + }, + { + "description": "Enables the close command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-close", + "markdownDescription": "Enables the close command without any pre-configured scope." + }, + { + "description": "Enables the create command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-create", + "markdownDescription": "Enables the create command without any pre-configured scope." + }, + { + "description": "Enables the current_monitor command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-current-monitor", + "markdownDescription": "Enables the current_monitor command without any pre-configured scope." + }, + { + "description": "Enables the cursor_position command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-cursor-position", + "markdownDescription": "Enables the cursor_position command without any pre-configured scope." + }, + { + "description": "Enables the destroy command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-destroy", + "markdownDescription": "Enables the destroy command without any pre-configured scope." + }, + { + "description": "Enables the get_all_windows command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-get-all-windows", + "markdownDescription": "Enables the get_all_windows command without any pre-configured scope." + }, + { + "description": "Enables the hide command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-hide", + "markdownDescription": "Enables the hide command without any pre-configured scope." + }, + { + "description": "Enables the inner_position command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-inner-position", + "markdownDescription": "Enables the inner_position command without any pre-configured scope." + }, + { + "description": "Enables the inner_size command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-inner-size", + "markdownDescription": "Enables the inner_size command without any pre-configured scope." + }, + { + "description": "Enables the internal_toggle_maximize command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-internal-toggle-maximize", + "markdownDescription": "Enables the internal_toggle_maximize command without any pre-configured scope." + }, + { + "description": "Enables the is_always_on_top command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-always-on-top", + "markdownDescription": "Enables the is_always_on_top command without any pre-configured scope." + }, + { + "description": "Enables the is_closable command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-closable", + "markdownDescription": "Enables the is_closable command without any pre-configured scope." + }, + { + "description": "Enables the is_decorated command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-decorated", + "markdownDescription": "Enables the is_decorated command without any pre-configured scope." + }, + { + "description": "Enables the is_enabled command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-enabled", + "markdownDescription": "Enables the is_enabled command without any pre-configured scope." + }, + { + "description": "Enables the is_focused command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-focused", + "markdownDescription": "Enables the is_focused command without any pre-configured scope." + }, + { + "description": "Enables the is_fullscreen command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-fullscreen", + "markdownDescription": "Enables the is_fullscreen command without any pre-configured scope." + }, + { + "description": "Enables the is_maximizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-maximizable", + "markdownDescription": "Enables the is_maximizable command without any pre-configured scope." + }, + { + "description": "Enables the is_maximized command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-maximized", + "markdownDescription": "Enables the is_maximized command without any pre-configured scope." + }, + { + "description": "Enables the is_minimizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-minimizable", + "markdownDescription": "Enables the is_minimizable command without any pre-configured scope." + }, + { + "description": "Enables the is_minimized command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-minimized", + "markdownDescription": "Enables the is_minimized command without any pre-configured scope." + }, + { + "description": "Enables the is_resizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-resizable", + "markdownDescription": "Enables the is_resizable command without any pre-configured scope." + }, + { + "description": "Enables the is_visible command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-is-visible", + "markdownDescription": "Enables the is_visible command without any pre-configured scope." + }, + { + "description": "Enables the maximize command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-maximize", + "markdownDescription": "Enables the maximize command without any pre-configured scope." + }, + { + "description": "Enables the minimize command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-minimize", + "markdownDescription": "Enables the minimize command without any pre-configured scope." + }, + { + "description": "Enables the monitor_from_point command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-monitor-from-point", + "markdownDescription": "Enables the monitor_from_point command without any pre-configured scope." + }, + { + "description": "Enables the outer_position command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-outer-position", + "markdownDescription": "Enables the outer_position command without any pre-configured scope." + }, + { + "description": "Enables the outer_size command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-outer-size", + "markdownDescription": "Enables the outer_size command without any pre-configured scope." + }, + { + "description": "Enables the primary_monitor command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-primary-monitor", + "markdownDescription": "Enables the primary_monitor command without any pre-configured scope." + }, + { + "description": "Enables the request_user_attention command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-request-user-attention", + "markdownDescription": "Enables the request_user_attention command without any pre-configured scope." + }, + { + "description": "Enables the scale_factor command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-scale-factor", + "markdownDescription": "Enables the scale_factor command without any pre-configured scope." + }, + { + "description": "Enables the set_always_on_bottom command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-always-on-bottom", + "markdownDescription": "Enables the set_always_on_bottom command without any pre-configured scope." + }, + { + "description": "Enables the set_always_on_top command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-always-on-top", + "markdownDescription": "Enables the set_always_on_top command without any pre-configured scope." + }, + { + "description": "Enables the set_background_color command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-background-color", + "markdownDescription": "Enables the set_background_color command without any pre-configured scope." + }, + { + "description": "Enables the set_badge_count command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-badge-count", + "markdownDescription": "Enables the set_badge_count command without any pre-configured scope." + }, + { + "description": "Enables the set_badge_label command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-badge-label", + "markdownDescription": "Enables the set_badge_label command without any pre-configured scope." + }, + { + "description": "Enables the set_closable command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-closable", + "markdownDescription": "Enables the set_closable command without any pre-configured scope." + }, + { + "description": "Enables the set_content_protected command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-content-protected", + "markdownDescription": "Enables the set_content_protected command without any pre-configured scope." + }, + { + "description": "Enables the set_cursor_grab command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-cursor-grab", + "markdownDescription": "Enables the set_cursor_grab command without any pre-configured scope." + }, + { + "description": "Enables the set_cursor_icon command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-cursor-icon", + "markdownDescription": "Enables the set_cursor_icon command without any pre-configured scope." + }, + { + "description": "Enables the set_cursor_position command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-cursor-position", + "markdownDescription": "Enables the set_cursor_position command without any pre-configured scope." + }, + { + "description": "Enables the set_cursor_visible command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-cursor-visible", + "markdownDescription": "Enables the set_cursor_visible command without any pre-configured scope." + }, + { + "description": "Enables the set_decorations command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-decorations", + "markdownDescription": "Enables the set_decorations command without any pre-configured scope." + }, + { + "description": "Enables the set_effects command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-effects", + "markdownDescription": "Enables the set_effects command without any pre-configured scope." + }, + { + "description": "Enables the set_enabled command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-enabled", + "markdownDescription": "Enables the set_enabled command without any pre-configured scope." + }, + { + "description": "Enables the set_focus command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-focus", + "markdownDescription": "Enables the set_focus command without any pre-configured scope." + }, + { + "description": "Enables the set_focusable command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-focusable", + "markdownDescription": "Enables the set_focusable command without any pre-configured scope." + }, + { + "description": "Enables the set_fullscreen command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-fullscreen", + "markdownDescription": "Enables the set_fullscreen command without any pre-configured scope." + }, + { + "description": "Enables the set_icon command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-icon", + "markdownDescription": "Enables the set_icon command without any pre-configured scope." + }, + { + "description": "Enables the set_ignore_cursor_events command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-ignore-cursor-events", + "markdownDescription": "Enables the set_ignore_cursor_events command without any pre-configured scope." + }, + { + "description": "Enables the set_max_size command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-max-size", + "markdownDescription": "Enables the set_max_size command without any pre-configured scope." + }, + { + "description": "Enables the set_maximizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-maximizable", + "markdownDescription": "Enables the set_maximizable command without any pre-configured scope." + }, + { + "description": "Enables the set_min_size command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-min-size", + "markdownDescription": "Enables the set_min_size command without any pre-configured scope." + }, + { + "description": "Enables the set_minimizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-minimizable", + "markdownDescription": "Enables the set_minimizable command without any pre-configured scope." + }, + { + "description": "Enables the set_overlay_icon command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-overlay-icon", + "markdownDescription": "Enables the set_overlay_icon command without any pre-configured scope." + }, + { + "description": "Enables the set_position command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-position", + "markdownDescription": "Enables the set_position command without any pre-configured scope." + }, + { + "description": "Enables the set_progress_bar command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-progress-bar", + "markdownDescription": "Enables the set_progress_bar command without any pre-configured scope." + }, + { + "description": "Enables the set_resizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-resizable", + "markdownDescription": "Enables the set_resizable command without any pre-configured scope." + }, + { + "description": "Enables the set_shadow command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-shadow", + "markdownDescription": "Enables the set_shadow command without any pre-configured scope." + }, + { + "description": "Enables the set_simple_fullscreen command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-simple-fullscreen", + "markdownDescription": "Enables the set_simple_fullscreen command without any pre-configured scope." + }, + { + "description": "Enables the set_size command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-size", + "markdownDescription": "Enables the set_size command without any pre-configured scope." + }, + { + "description": "Enables the set_size_constraints command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-size-constraints", + "markdownDescription": "Enables the set_size_constraints command without any pre-configured scope." + }, + { + "description": "Enables the set_skip_taskbar command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-skip-taskbar", + "markdownDescription": "Enables the set_skip_taskbar command without any pre-configured scope." + }, + { + "description": "Enables the set_theme command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-theme", + "markdownDescription": "Enables the set_theme command without any pre-configured scope." + }, + { + "description": "Enables the set_title command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-title", + "markdownDescription": "Enables the set_title command without any pre-configured scope." + }, + { + "description": "Enables the set_title_bar_style command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-title-bar-style", + "markdownDescription": "Enables the set_title_bar_style command without any pre-configured scope." + }, + { + "description": "Enables the set_visible_on_all_workspaces command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-set-visible-on-all-workspaces", + "markdownDescription": "Enables the set_visible_on_all_workspaces command without any pre-configured scope." + }, + { + "description": "Enables the show command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-show", + "markdownDescription": "Enables the show command without any pre-configured scope." + }, + { + "description": "Enables the start_dragging command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-start-dragging", + "markdownDescription": "Enables the start_dragging command without any pre-configured scope." + }, + { + "description": "Enables the start_resize_dragging command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-start-resize-dragging", + "markdownDescription": "Enables the start_resize_dragging command without any pre-configured scope." + }, + { + "description": "Enables the theme command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-theme", + "markdownDescription": "Enables the theme command without any pre-configured scope." + }, + { + "description": "Enables the title command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-title", + "markdownDescription": "Enables the title command without any pre-configured scope." + }, + { + "description": "Enables the toggle_maximize command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-toggle-maximize", + "markdownDescription": "Enables the toggle_maximize command without any pre-configured scope." + }, + { + "description": "Enables the unmaximize command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-unmaximize", + "markdownDescription": "Enables the unmaximize command without any pre-configured scope." + }, + { + "description": "Enables the unminimize command without any pre-configured scope.", + "type": "string", + "const": "core:window:allow-unminimize", + "markdownDescription": "Enables the unminimize command without any pre-configured scope." + }, + { + "description": "Denies the available_monitors command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-available-monitors", + "markdownDescription": "Denies the available_monitors command without any pre-configured scope." + }, + { + "description": "Denies the center command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-center", + "markdownDescription": "Denies the center command without any pre-configured scope." + }, + { + "description": "Denies the close command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-close", + "markdownDescription": "Denies the close command without any pre-configured scope." + }, + { + "description": "Denies the create command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-create", + "markdownDescription": "Denies the create command without any pre-configured scope." + }, + { + "description": "Denies the current_monitor command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-current-monitor", + "markdownDescription": "Denies the current_monitor command without any pre-configured scope." + }, + { + "description": "Denies the cursor_position command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-cursor-position", + "markdownDescription": "Denies the cursor_position command without any pre-configured scope." + }, + { + "description": "Denies the destroy command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-destroy", + "markdownDescription": "Denies the destroy command without any pre-configured scope." + }, + { + "description": "Denies the get_all_windows command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-get-all-windows", + "markdownDescription": "Denies the get_all_windows command without any pre-configured scope." + }, + { + "description": "Denies the hide command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-hide", + "markdownDescription": "Denies the hide command without any pre-configured scope." + }, + { + "description": "Denies the inner_position command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-inner-position", + "markdownDescription": "Denies the inner_position command without any pre-configured scope." + }, + { + "description": "Denies the inner_size command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-inner-size", + "markdownDescription": "Denies the inner_size command without any pre-configured scope." + }, + { + "description": "Denies the internal_toggle_maximize command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-internal-toggle-maximize", + "markdownDescription": "Denies the internal_toggle_maximize command without any pre-configured scope." + }, + { + "description": "Denies the is_always_on_top command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-always-on-top", + "markdownDescription": "Denies the is_always_on_top command without any pre-configured scope." + }, + { + "description": "Denies the is_closable command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-closable", + "markdownDescription": "Denies the is_closable command without any pre-configured scope." + }, + { + "description": "Denies the is_decorated command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-decorated", + "markdownDescription": "Denies the is_decorated command without any pre-configured scope." + }, + { + "description": "Denies the is_enabled command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-enabled", + "markdownDescription": "Denies the is_enabled command without any pre-configured scope." + }, + { + "description": "Denies the is_focused command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-focused", + "markdownDescription": "Denies the is_focused command without any pre-configured scope." + }, + { + "description": "Denies the is_fullscreen command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-fullscreen", + "markdownDescription": "Denies the is_fullscreen command without any pre-configured scope." + }, + { + "description": "Denies the is_maximizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-maximizable", + "markdownDescription": "Denies the is_maximizable command without any pre-configured scope." + }, + { + "description": "Denies the is_maximized command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-maximized", + "markdownDescription": "Denies the is_maximized command without any pre-configured scope." + }, + { + "description": "Denies the is_minimizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-minimizable", + "markdownDescription": "Denies the is_minimizable command without any pre-configured scope." + }, + { + "description": "Denies the is_minimized command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-minimized", + "markdownDescription": "Denies the is_minimized command without any pre-configured scope." + }, + { + "description": "Denies the is_resizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-resizable", + "markdownDescription": "Denies the is_resizable command without any pre-configured scope." + }, + { + "description": "Denies the is_visible command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-is-visible", + "markdownDescription": "Denies the is_visible command without any pre-configured scope." + }, + { + "description": "Denies the maximize command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-maximize", + "markdownDescription": "Denies the maximize command without any pre-configured scope." + }, + { + "description": "Denies the minimize command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-minimize", + "markdownDescription": "Denies the minimize command without any pre-configured scope." + }, + { + "description": "Denies the monitor_from_point command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-monitor-from-point", + "markdownDescription": "Denies the monitor_from_point command without any pre-configured scope." + }, + { + "description": "Denies the outer_position command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-outer-position", + "markdownDescription": "Denies the outer_position command without any pre-configured scope." + }, + { + "description": "Denies the outer_size command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-outer-size", + "markdownDescription": "Denies the outer_size command without any pre-configured scope." + }, + { + "description": "Denies the primary_monitor command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-primary-monitor", + "markdownDescription": "Denies the primary_monitor command without any pre-configured scope." + }, + { + "description": "Denies the request_user_attention command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-request-user-attention", + "markdownDescription": "Denies the request_user_attention command without any pre-configured scope." + }, + { + "description": "Denies the scale_factor command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-scale-factor", + "markdownDescription": "Denies the scale_factor command without any pre-configured scope." + }, + { + "description": "Denies the set_always_on_bottom command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-always-on-bottom", + "markdownDescription": "Denies the set_always_on_bottom command without any pre-configured scope." + }, + { + "description": "Denies the set_always_on_top command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-always-on-top", + "markdownDescription": "Denies the set_always_on_top command without any pre-configured scope." + }, + { + "description": "Denies the set_background_color command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-background-color", + "markdownDescription": "Denies the set_background_color command without any pre-configured scope." + }, + { + "description": "Denies the set_badge_count command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-badge-count", + "markdownDescription": "Denies the set_badge_count command without any pre-configured scope." + }, + { + "description": "Denies the set_badge_label command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-badge-label", + "markdownDescription": "Denies the set_badge_label command without any pre-configured scope." + }, + { + "description": "Denies the set_closable command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-closable", + "markdownDescription": "Denies the set_closable command without any pre-configured scope." + }, + { + "description": "Denies the set_content_protected command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-content-protected", + "markdownDescription": "Denies the set_content_protected command without any pre-configured scope." + }, + { + "description": "Denies the set_cursor_grab command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-cursor-grab", + "markdownDescription": "Denies the set_cursor_grab command without any pre-configured scope." + }, + { + "description": "Denies the set_cursor_icon command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-cursor-icon", + "markdownDescription": "Denies the set_cursor_icon command without any pre-configured scope." + }, + { + "description": "Denies the set_cursor_position command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-cursor-position", + "markdownDescription": "Denies the set_cursor_position command without any pre-configured scope." + }, + { + "description": "Denies the set_cursor_visible command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-cursor-visible", + "markdownDescription": "Denies the set_cursor_visible command without any pre-configured scope." + }, + { + "description": "Denies the set_decorations command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-decorations", + "markdownDescription": "Denies the set_decorations command without any pre-configured scope." + }, + { + "description": "Denies the set_effects command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-effects", + "markdownDescription": "Denies the set_effects command without any pre-configured scope." + }, + { + "description": "Denies the set_enabled command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-enabled", + "markdownDescription": "Denies the set_enabled command without any pre-configured scope." + }, + { + "description": "Denies the set_focus command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-focus", + "markdownDescription": "Denies the set_focus command without any pre-configured scope." + }, + { + "description": "Denies the set_focusable command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-focusable", + "markdownDescription": "Denies the set_focusable command without any pre-configured scope." + }, + { + "description": "Denies the set_fullscreen command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-fullscreen", + "markdownDescription": "Denies the set_fullscreen command without any pre-configured scope." + }, + { + "description": "Denies the set_icon command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-icon", + "markdownDescription": "Denies the set_icon command without any pre-configured scope." + }, + { + "description": "Denies the set_ignore_cursor_events command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-ignore-cursor-events", + "markdownDescription": "Denies the set_ignore_cursor_events command without any pre-configured scope." + }, + { + "description": "Denies the set_max_size command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-max-size", + "markdownDescription": "Denies the set_max_size command without any pre-configured scope." + }, + { + "description": "Denies the set_maximizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-maximizable", + "markdownDescription": "Denies the set_maximizable command without any pre-configured scope." + }, + { + "description": "Denies the set_min_size command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-min-size", + "markdownDescription": "Denies the set_min_size command without any pre-configured scope." + }, + { + "description": "Denies the set_minimizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-minimizable", + "markdownDescription": "Denies the set_minimizable command without any pre-configured scope." + }, + { + "description": "Denies the set_overlay_icon command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-overlay-icon", + "markdownDescription": "Denies the set_overlay_icon command without any pre-configured scope." + }, + { + "description": "Denies the set_position command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-position", + "markdownDescription": "Denies the set_position command without any pre-configured scope." + }, + { + "description": "Denies the set_progress_bar command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-progress-bar", + "markdownDescription": "Denies the set_progress_bar command without any pre-configured scope." + }, + { + "description": "Denies the set_resizable command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-resizable", + "markdownDescription": "Denies the set_resizable command without any pre-configured scope." + }, + { + "description": "Denies the set_shadow command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-shadow", + "markdownDescription": "Denies the set_shadow command without any pre-configured scope." + }, + { + "description": "Denies the set_simple_fullscreen command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-simple-fullscreen", + "markdownDescription": "Denies the set_simple_fullscreen command without any pre-configured scope." + }, + { + "description": "Denies the set_size command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-size", + "markdownDescription": "Denies the set_size command without any pre-configured scope." + }, + { + "description": "Denies the set_size_constraints command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-size-constraints", + "markdownDescription": "Denies the set_size_constraints command without any pre-configured scope." + }, + { + "description": "Denies the set_skip_taskbar command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-skip-taskbar", + "markdownDescription": "Denies the set_skip_taskbar command without any pre-configured scope." + }, + { + "description": "Denies the set_theme command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-theme", + "markdownDescription": "Denies the set_theme command without any pre-configured scope." + }, + { + "description": "Denies the set_title command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-title", + "markdownDescription": "Denies the set_title command without any pre-configured scope." + }, + { + "description": "Denies the set_title_bar_style command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-title-bar-style", + "markdownDescription": "Denies the set_title_bar_style command without any pre-configured scope." + }, + { + "description": "Denies the set_visible_on_all_workspaces command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-set-visible-on-all-workspaces", + "markdownDescription": "Denies the set_visible_on_all_workspaces command without any pre-configured scope." + }, + { + "description": "Denies the show command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-show", + "markdownDescription": "Denies the show command without any pre-configured scope." + }, + { + "description": "Denies the start_dragging command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-start-dragging", + "markdownDescription": "Denies the start_dragging command without any pre-configured scope." + }, + { + "description": "Denies the start_resize_dragging command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-start-resize-dragging", + "markdownDescription": "Denies the start_resize_dragging command without any pre-configured scope." + }, + { + "description": "Denies the theme command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-theme", + "markdownDescription": "Denies the theme command without any pre-configured scope." + }, + { + "description": "Denies the title command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-title", + "markdownDescription": "Denies the title command without any pre-configured scope." + }, + { + "description": "Denies the toggle_maximize command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-toggle-maximize", + "markdownDescription": "Denies the toggle_maximize command without any pre-configured scope." + }, + { + "description": "Denies the unmaximize command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-unmaximize", + "markdownDescription": "Denies the unmaximize command without any pre-configured scope." + }, + { + "description": "Denies the unminimize command without any pre-configured scope.", + "type": "string", + "const": "core:window:deny-unminimize", + "markdownDescription": "Denies the unminimize command without any pre-configured scope." + }, + { + "description": "Allows reading the opened deep link via the get_current command\n#### This default permission set includes:\n\n- `allow-get-current`", + "type": "string", + "const": "deep-link:default", + "markdownDescription": "Allows reading the opened deep link via the get_current command\n#### This default permission set includes:\n\n- `allow-get-current`" + }, + { + "description": "Enables the get_current command without any pre-configured scope.", + "type": "string", + "const": "deep-link:allow-get-current", + "markdownDescription": "Enables the get_current command without any pre-configured scope." + }, + { + "description": "Enables the is_registered command without any pre-configured scope.", + "type": "string", + "const": "deep-link:allow-is-registered", + "markdownDescription": "Enables the is_registered command without any pre-configured scope." + }, + { + "description": "Enables the register command without any pre-configured scope.", + "type": "string", + "const": "deep-link:allow-register", + "markdownDescription": "Enables the register command without any pre-configured scope." + }, + { + "description": "Enables the unregister command without any pre-configured scope.", + "type": "string", + "const": "deep-link:allow-unregister", + "markdownDescription": "Enables the unregister command without any pre-configured scope." + }, + { + "description": "Denies the get_current command without any pre-configured scope.", + "type": "string", + "const": "deep-link:deny-get-current", + "markdownDescription": "Denies the get_current command without any pre-configured scope." + }, + { + "description": "Denies the is_registered command without any pre-configured scope.", + "type": "string", + "const": "deep-link:deny-is-registered", + "markdownDescription": "Denies the is_registered command without any pre-configured scope." + }, + { + "description": "Denies the register command without any pre-configured scope.", + "type": "string", + "const": "deep-link:deny-register", + "markdownDescription": "Denies the register command without any pre-configured scope." + }, + { + "description": "Denies the unregister command without any pre-configured scope.", + "type": "string", + "const": "deep-link:deny-unregister", + "markdownDescription": "Denies the unregister command without any pre-configured scope." + }, + { + "description": "This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality with a reasonable\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n\n#### This default permission set includes:\n\n- `allow-open`", + "type": "string", + "const": "shell:default", + "markdownDescription": "This permission set configures which\nshell functionality is exposed by default.\n\n#### Granted Permissions\n\nIt allows to use the `open` functionality with a reasonable\nscope pre-configured. It will allow opening `http(s)://`,\n`tel:` and `mailto:` links.\n\n#### This default permission set includes:\n\n- `allow-open`" + }, + { + "description": "Enables the execute command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-execute", + "markdownDescription": "Enables the execute command without any pre-configured scope." + }, + { + "description": "Enables the kill command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-kill", + "markdownDescription": "Enables the kill command without any pre-configured scope." + }, + { + "description": "Enables the open command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-open", + "markdownDescription": "Enables the open command without any pre-configured scope." + }, + { + "description": "Enables the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-spawn", + "markdownDescription": "Enables the spawn command without any pre-configured scope." + }, + { + "description": "Enables the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:allow-stdin-write", + "markdownDescription": "Enables the stdin_write command without any pre-configured scope." + }, + { + "description": "Denies the execute command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-execute", + "markdownDescription": "Denies the execute command without any pre-configured scope." + }, + { + "description": "Denies the kill command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-kill", + "markdownDescription": "Denies the kill command without any pre-configured scope." + }, + { + "description": "Denies the open command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-open", + "markdownDescription": "Denies the open command without any pre-configured scope." + }, + { + "description": "Denies the spawn command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-spawn", + "markdownDescription": "Denies the spawn command without any pre-configured scope." + }, + { + "description": "Denies the stdin_write command without any pre-configured scope.", + "type": "string", + "const": "shell:deny-stdin-write", + "markdownDescription": "Denies the stdin_write command without any pre-configured scope." + } + ] + }, + "Value": { + "description": "All supported ACL values.", + "anyOf": [ + { + "description": "Represents a null JSON value.", + "type": "null" + }, + { + "description": "Represents a [`bool`].", + "type": "boolean" + }, + { + "description": "Represents a valid ACL [`Number`].", + "allOf": [ + { + "$ref": "#/definitions/Number" + } + ] + }, + { + "description": "Represents a [`String`].", + "type": "string" + }, + { + "description": "Represents a list of other [`Value`]s.", + "type": "array", + "items": { + "$ref": "#/definitions/Value" + } + }, + { + "description": "Represents a map of [`String`] keys to [`Value`]s.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/Value" + } + } + ] + }, + "Number": { + "description": "A valid ACL number.", + "anyOf": [ + { + "description": "Represents an [`i64`].", + "type": "integer", + "format": "int64" + }, + { + "description": "Represents a [`f64`].", + "type": "number", + "format": "double" + } + ] + }, + "Target": { + "description": "Platform target.", + "oneOf": [ + { + "description": "MacOS.", + "type": "string", + "enum": [ + "macOS" + ] + }, + { + "description": "Windows.", + "type": "string", + "enum": [ + "windows" + ] + }, + { + "description": "Linux.", + "type": "string", + "enum": [ + "linux" + ] + }, + { + "description": "Android.", + "type": "string", + "enum": [ + "android" + ] + }, + { + "description": "iOS.", + "type": "string", + "enum": [ + "iOS" + ] + } + ] + }, + "ShellScopeEntryAllowedArg": { + "description": "A command argument allowed to be executed by the webview API.", + "anyOf": [ + { + "description": "A non-configurable argument that is passed to the command in the order it was specified.", + "type": "string" + }, + { + "description": "A variable that is set while calling the command from the webview API.", + "type": "object", + "required": [ + "validator" + ], + "properties": { + "raw": { + "description": "Marks the validator as a raw regex, meaning the plugin should not make any modification at runtime.\n\nThis means the regex will not match on the entire string by default, which might be exploited if your regex allow unexpected input to be considered valid. When using this option, make sure your regex is correct.", + "default": false, + "type": "boolean" + }, + "validator": { + "description": "[regex] validator to require passed values to conform to an expected input.\n\nThis will require the argument value passed to this variable to match the `validator` regex before it will be executed.\n\nThe regex string is by default surrounded by `^...$` to match the full string. For example the `https?://\\w+` regex would be registered as `^https?://\\w+$`.\n\n[regex]: ", + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "ShellScopeEntryAllowedArgs": { + "description": "A set of command arguments allowed to be executed by the webview API.\n\nA value of `true` will allow any arguments to be passed to the command. `false` will disable all arguments. A list of [`ShellScopeEntryAllowedArg`] will set those arguments as the only valid arguments to be passed to the attached command configuration.", + "anyOf": [ + { + "description": "Use a simple boolean to allow all or disable all arguments to this command configuration.", + "type": "boolean" + }, + { + "description": "A specific set of [`ShellScopeEntryAllowedArg`] that are valid to call for the command configuration.", + "type": "array", + "items": { + "$ref": "#/definitions/ShellScopeEntryAllowedArg" + } + } + ] + } + } +} \ No newline at end of file diff --git a/src-tauri/src/commands/auth.rs b/src-tauri/src/commands/auth.rs index f77ee4e..ed6afc1 100644 --- a/src-tauri/src/commands/auth.rs +++ b/src-tauri/src/commands/auth.rs @@ -30,6 +30,30 @@ pub struct SetPasswordsResponse { pub recovery_string: Option, } +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct OAuthConfig { + pub platform_id: String, + pub platform_secret: String, + pub callback_url: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct OAuthTokenResponse { + pub access_token: String, + pub refresh_token: String, + pub token_type: String, + pub expires_in: u64, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct OAuthUserInfo { + pub user_id: String, + pub email: String, + pub name: String, + pub github_username: Option, + pub permission: u32, +} + fn get_iv_hex() -> String { SecurityService::generate_iv_hex() } @@ -271,3 +295,116 @@ pub async fn auth_clear_all( Err(e) => Ok(IpcResponse::error(&e)), } } + +#[tauri::command] +pub async fn oauth_get_authorization_url( + platform_id: String, + callback_url: String, +) -> Result, String> { + let url = format!( + "https://sectl.top/oauth/authorize?client_id={}&redirect_uri={}&response_type=code", + platform_id, + urlencoding::encode(&callback_url) + ); + Ok(IpcResponse::success(url)) +} + +#[tauri::command] +pub async fn oauth_exchange_code( + code: String, + platform_id: String, + platform_secret: String, + callback_url: String, +) -> Result, String> { + let client = reqwest::Client::new(); + let response = client + .post("https://sectl.top/api/oauth/token") + .json(&serde_json::json!({ + "grant_type": "authorization_code", + "code": code, + "client_id": platform_id, + "client_secret": platform_secret, + "redirect_uri": callback_url + })) + .send() + .await + .map_err(|e| format!("Request failed: {}", e))?; + + if !response.status().is_success() { + let error_text = response + .text() + .await + .unwrap_or_else(|_| "Unknown error".to_string()); + return Ok(IpcResponse::error(&error_text)); + } + + let token_response: OAuthTokenResponse = response + .json() + .await + .map_err(|e| format!("Failed to parse response: {}", e))?; + + Ok(IpcResponse::success(token_response)) +} + +#[tauri::command] +pub async fn oauth_get_user_info( + access_token: String, +) -> Result, String> { + let client = reqwest::Client::new(); + let response = client + .get("https://sectl.top/api/oauth/userinfo") + .header("Authorization", format!("Bearer {}", access_token)) + .send() + .await + .map_err(|e| format!("Request failed: {}", e))?; + + if !response.status().is_success() { + let error_text = response + .text() + .await + .unwrap_or_else(|_| "Unknown error".to_string()); + return Ok(IpcResponse::error(&error_text)); + } + + let user_info: OAuthUserInfo = response + .json() + .await + .map_err(|e| format!("Failed to parse response: {}", e))?; + + Ok(IpcResponse::success(user_info)) +} + +#[tauri::command] +pub async fn oauth_refresh_token( + refresh_token: String, + platform_id: String, + platform_secret: String, +) -> Result, String> { + let client = reqwest::Client::new(); + let response = client + .post("https://sectl.top/api/oauth/token") + .json(&serde_json::json!({ + "grant_type": "refresh_token", + "refresh_token": refresh_token, + "client_id": platform_id, + "client_secret": platform_secret + })) + .send() + .await + .map_err(|e| format!("Request failed: {}", e))?; + + if !response.status().is_success() { + let error_text = response + .text() + .await + .unwrap_or_else(|_| "Unknown error".to_string()); + return Ok(IpcResponse::error(&error_text)); + } + + let token_response: OAuthTokenResponse = response + .json() + .await + .map_err(|e| format!("Failed to parse response: {}", e))?; + + Ok(IpcResponse::success(token_response)) +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 15b3e06..7ab0ed3 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -12,6 +12,7 @@ use crate::services::settings::{SettingsKey, SettingsValue}; use crate::{commands::*, state::AppState}; use parking_lot::RwLock; use std::sync::Arc; +use tauri::Emitter; #[cfg(desktop)] use tauri::{ image::Image, @@ -26,6 +27,7 @@ use tokio::time::{timeout, Duration}; pub fn run() { tauri::Builder::default() .plugin(tauri_plugin_shell::init()) + .plugin(tauri_plugin_deep_link::init()) .setup(|app| { let state = AppState::new(app.handle().clone()); app.manage(Arc::new(RwLock::new(state))); @@ -73,6 +75,10 @@ pub fn run() { auth_generate_recovery, auth_reset_by_recovery, auth_clear_all, + oauth_get_authorization_url, + oauth_exchange_code, + oauth_get_user_info, + oauth_refresh_token, theme_list, theme_current, theme_set, @@ -136,6 +142,26 @@ pub fn setup_app(app: &mut App) -> Result<(), Box> { setup_window_events(app)?; + setup_deep_link(app)?; + + Ok(()) +} + +fn setup_deep_link(app: &mut App) -> Result<(), Box> { + let handle = app.handle().clone(); + + #[cfg(desktop)] + { + use tauri_plugin_deep_link::DeepLinkExt; + + app.deep_link().on_open_url(move |event| { + let url = event.urls().first().map(|u| u.to_string()).unwrap_or_default(); + if !url.is_empty() { + let _ = handle.emit("deep-link://new-url", url); + } + }); + } + Ok(()) } diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 70364b3..e1a6224 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -58,6 +58,14 @@ "plugins": { "shell": { "open": true + }, + "deepLink": { + "domains": [ + { + "host": "oauth", + "schemes": ["secscore"] + } + ] } } } diff --git a/src/App.tsx b/src/App.tsx index d9aff38..47d6779 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,13 @@ -import { Layout, Modal, Input, message, ConfigProvider, theme as antTheme, Drawer } from "antd" +import { + Layout, + Modal, + Input, + message, + ConfigProvider, + theme as antTheme, + Drawer, + Button, +} from "antd" import { HomeOutlined, SettingOutlined, @@ -20,15 +29,16 @@ import { useTranslation } from "react-i18next" import { Sidebar } from "./components/Sidebar" import { ContentArea } from "./components/ContentArea" import { OOBE } from "./components/OOBE/OOBE" +import { OAuthLogin } from "./components/OAuthLogin" +import { OAuthCallback } from "./components/OAuthCallback" import { ThemeProvider, useTheme } from "./contexts/ThemeContext" -import { - MOBILE_NAV_ITEMS, - MobileNavKey, - sanitizeMobileNavKeys, -} from "./shared/mobileNavigation" +import { MOBILE_NAV_ITEMS, MobileNavKey, sanitizeMobileNavKeys } from "./shared/mobileNavigation" const DEFAULT_MOBILE_BOTTOM_NAV_ITEMS: MobileNavKey[] = MOBILE_NAV_ITEMS.map((item) => item.key) -const DEFAULT_MOBILE_BOTTOM_PRIMARY_KEYS: MobileNavKey[] = DEFAULT_MOBILE_BOTTOM_NAV_ITEMS.slice(0, 4) +const DEFAULT_MOBILE_BOTTOM_PRIMARY_KEYS: MobileNavKey[] = DEFAULT_MOBILE_BOTTOM_NAV_ITEMS.slice( + 0, + 4 +) function MainContent(): React.JSX.Element { const { t } = useTranslation() @@ -88,6 +98,7 @@ function MainContent(): React.JSX.Element { const [authVisible, setAuthVisible] = useState(false) const [authPassword, setAuthPassword] = useState("") const [authLoading, setAuthLoading] = useState(false) + const [oauthVisible, setOAuthVisible] = useState(false) const [mobileBottomNavItems, setMobileBottomNavItems] = useState( DEFAULT_MOBILE_BOTTOM_NAV_ITEMS ) @@ -97,9 +108,10 @@ function MainContent(): React.JSX.Element { const [editingMoreNavKeys, setEditingMoreNavKeys] = useState([]) const [draggingNavKey, setDraggingNavKey] = useState(null) const [draggingFromList, setDraggingFromList] = useState<"bottom" | "more" | null>(null) - const [dragOverSlot, setDragOverSlot] = useState<{ list: "bottom" | "more"; index: number } | null>( - null - ) + const [dragOverSlot, setDragOverSlot] = useState<{ + list: "bottom" | "more" + index: number + } | null>(null) const [isPortraitMode] = useState(defaultPortraitMode) const [sidebarCollapsed, setSidebarCollapsed] = useState(defaultPortraitMode) const [floatingSidebarExpanded, setFloatingSidebarExpanded] = useState(false) @@ -379,6 +391,24 @@ function MainContent(): React.JSX.Element { } } + const handleOAuthSuccess = (userInfo: { + user_id: string + email: string + name: string + github_username?: string + permission: number + }) => { + let newPermission: "admin" | "points" | "view" = "view" + if (userInfo.permission >= 18) { + newPermission = "admin" + } else if (userInfo.permission >= 1) { + newPermission = "points" + } + + setPermission(newPermission) + messageApi.success(t("auth.oauthSuccess", "登录成功")) + } + const onMenuChange = (v: string) => { const key = String(v) setMoreNavVisible(false) @@ -544,7 +574,9 @@ function MainContent(): React.JSX.Element { }} > {contextHolder} - + {!isPortraitMode && (
+
+ +
+ setOAuthVisible(false)} + onSuccess={handleOAuthSuccess} + /> + + } /> } /> diff --git a/src/components/BoardManager.tsx b/src/components/BoardManager.tsx index c826f7b..806599a 100644 --- a/src/components/BoardManager.tsx +++ b/src/components/BoardManager.tsx @@ -872,17 +872,20 @@ ORDER BY reward_points DESC, score DESC`, ? { label: t("board.metrics.addScore"), value: item.addScore } : item.deductScore !== undefined ? { label: t("board.metrics.deductScore"), value: item.deductScore } - : item.score !== undefined - ? { label: t("board.metrics.totalScore"), value: item.score } - : item.rewardPoints !== undefined - ? { label: t("board.metrics.rewardPoints"), value: item.rewardPoints } - : item.weekChange !== undefined - ? { label: t("board.metrics.weekChange"), value: item.weekChange } - : item.weekDeducted !== undefined - ? { label: t("board.metrics.weekDeducted"), value: item.weekDeducted } - : item.answeredCount !== undefined - ? { label: t("board.metrics.todayAnswered"), value: item.answeredCount } - : null + : item.score !== undefined + ? { label: t("board.metrics.totalScore"), value: item.score } + : item.rewardPoints !== undefined + ? { label: t("board.metrics.rewardPoints"), value: item.rewardPoints } + : item.weekChange !== undefined + ? { label: t("board.metrics.weekChange"), value: item.weekChange } + : item.weekDeducted !== undefined + ? { label: t("board.metrics.weekDeducted"), value: item.weekDeducted } + : item.answeredCount !== undefined + ? { + label: t("board.metrics.todayAnswered"), + value: item.answeredCount, + } + : null : item.score !== undefined ? { label: t("board.metrics.totalScore"), value: item.score } : item.rewardPoints !== undefined @@ -1039,10 +1042,13 @@ ORDER BY reward_points DESC, score DESC`, {(list.scoreDisplayMode === "total" || (list.scoreDisplayMode === "split" && !hasSplitScore)) && item.score !== undefined && ( - = 0 ? "success" : "error"} style={{ margin: 0 }}> - {t("board.metrics.totalScore")}:{" "} - {item.score > 0 ? `+${item.score}` : item.score} - + = 0 ? "success" : "error"} + style={{ margin: 0 }} + > + {t("board.metrics.totalScore")}:{" "} + {item.score > 0 ? `+${item.score}` : item.score} + )} {list.scoreDisplayMode === "split" && item.addScore !== undefined && ( @@ -1428,7 +1434,11 @@ ORDER BY reward_points DESC, score DESC`, fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace", }} /> - + 豆包智能体一句话生成查询 } /> - } - /> + } /> } /> diff --git a/src/components/Home.tsx b/src/components/Home.tsx index 443571e..24b411f 100644 --- a/src/components/Home.tsx +++ b/src/components/Home.tsx @@ -2356,7 +2356,9 @@ export const Home: React.FC = ({ onClick={() => handleSearchKeyPress(keyItem.digit)} style={{ height: "28px", fontSize: "11px", padding: 0 }} > - {keyItem.digit === "⌫" ? "⌫" : `${keyItem.digit} ${keyItem.letters}`} + {keyItem.digit === "⌫" + ? "⌫" + : `${keyItem.digit} ${keyItem.letters}`} ))} @@ -2543,147 +2545,151 @@ export const Home: React.FC = ({ overflow: "visible", }} > -
{ - searchAreaRef.current = node - immersiveToolbarContentRef.current = node +
{ + searchAreaRef.current = node + immersiveToolbarContentRef.current = node + }} + style={{ + display: "inline-flex", + alignItems: "center", + gap: "8px", + overflowX: "visible", + justifyContent: "flex-start", + }} + > + setSearchKeyword(e.target.value)} + onFocus={() => { + if (canShowSearchKeyboard) setShowPinyinKeyboard(true) }} + onClick={() => { + if (canShowSearchKeyboard) setShowPinyinKeyboard(true) + }} + onKeyDown={(e) => { + if (e.key === "Escape") setShowPinyinKeyboard(false) + }} + placeholder={t("home.searchPlaceholder")} + prefix={} + allowClear style={{ - display: "inline-flex", - alignItems: "center", - gap: "8px", - overflowX: "visible", - justifyContent: "flex-start", + width: isPortraitMode ? "170px" : "220px", + borderRadius: "999px", + flexShrink: 0, }} + /> + setLayoutType(v as LayoutType)} + getPopupContainer={getImmersivePopupContainer} + style={{ width: 126, flexShrink: 0 }} + options={[ + { value: "grouped", label: t("home.layoutBy.grouped") }, + { value: "squareGrid", label: t("home.layoutBy.squareGrid") }, + ]} + /> + + +
{batchToolbar}
+ {canShowSearchKeyboard && showPinyinKeyboard && ( +
{ - if (canShowSearchKeyboard) setShowPinyinKeyboard(true) - }} - onKeyDown={(e) => { - if (e.key === "Escape") setShowPinyinKeyboard(false) - }} - placeholder={t("home.searchPlaceholder")} - prefix={} - allowClear - style={{ width: isPortraitMode ? "170px" : "220px", borderRadius: "999px", flexShrink: 0 }} - /> - setLayoutType(v as LayoutType)} - getPopupContainer={getImmersivePopupContainer} - style={{ width: 126, flexShrink: 0 }} - options={[ - { value: "grouped", label: t("home.layoutBy.grouped") }, - { value: "squareGrid", label: t("home.layoutBy.squareGrid") }, - ]} - /> - - -
{batchToolbar}
- {canShowSearchKeyboard && showPinyinKeyboard && ( -
-
- {searchKeyboardLayout === "qwerty26" - ? qwertyKeyRows.map((row, rowIndex) => ( -
- {row.map((keyItem) => ( - - ))} -
- )) - : t9KeyRows.map((row, rowIndex) => ( -
- {row.map((keyItem) => ( - - ))} -
- ))} -
+
+ {searchKeyboardLayout === "qwerty26" + ? qwertyKeyRows.map((row, rowIndex) => ( +
+ {row.map((keyItem) => ( + + ))} +
+ )) + : t9KeyRows.map((row, rowIndex) => ( +
+ {row.map((keyItem) => ( + + ))} +
+ ))}
- )} -
+
+ )} +
{isPortraitMode ? ( diff --git a/src/components/OAuthCallback.tsx b/src/components/OAuthCallback.tsx new file mode 100644 index 0000000..8e05b8c --- /dev/null +++ b/src/components/OAuthCallback.tsx @@ -0,0 +1,49 @@ +import { useEffect } from "react" +import { useSearchParams, useNavigate } from "react-router-dom" + +export function OAuthCallback() { + const [searchParams] = useSearchParams() + const navigate = useNavigate() + + useEffect(() => { + const code = searchParams.get("code") + const error = searchParams.get("error") + const errorDescription = searchParams.get("error_description") + + if (error) { + window.postMessage( + { + error: errorDescription || error, + }, + window.location.origin + ) + navigate("/") + return + } + + if (code) { + window.postMessage( + { + code, + }, + window.location.origin + ) + navigate("/") + } + }, [searchParams, navigate]) + + return ( +
+
正在处理登录...
+
+ ) +} diff --git a/src/components/OAuthLogin.tsx b/src/components/OAuthLogin.tsx new file mode 100644 index 0000000..85b9593 --- /dev/null +++ b/src/components/OAuthLogin.tsx @@ -0,0 +1,183 @@ +import { Button, message, Modal, Space, Spin } from "antd" +import { useEffect, useRef, useState } from "react" +import { useTranslation } from "react-i18next" +import { open } from "@tauri-apps/plugin-shell" +import { listen, UnlistenFn } from "@tauri-apps/api/event" + +interface OAuthLoginProps { + visible: boolean + onClose: () => void + onSuccess: (userInfo: { + user_id: string + email: string + name: string + github_username?: string + permission: number + }) => void +} + +interface OAuthConfig { + platform_id: string + platform_secret: string + callback_url: string +} + +export function OAuthLogin({ visible, onClose, onSuccess }: OAuthLoginProps) { + const { t } = useTranslation() + const [loading, setLoading] = useState(false) + const deepLinkUnlistenRef = useRef(null) + + const getOAuthConfig = (): OAuthConfig | null => { + const api = (window as any).api + if (!api) return null + + const platformId = import.meta.env.VITE_OAUTH_PLATFORM_ID + const platformSecret = import.meta.env.VITE_OAUTH_PLATFORM_SECRET + const callbackUrl = import.meta.env.VITE_OAUTH_CALLBACK_URL || "secscore://oauth/callback" + + if (!platformId || !platformSecret) { + return null + } + + return { + platform_id: platformId, + platform_secret: platformSecret, + callback_url: callbackUrl, + } + } + + const handleDeepLink = async (url: string) => { + const config = getOAuthConfig() + if (!config) return + + try { + const urlObj = new URL(url) + const code = urlObj.searchParams.get("code") + const error = urlObj.searchParams.get("error") + + if (error) { + message.error(decodeURIComponent(error)) + setLoading(false) + return + } + + if (code) { + const api = (window as any).api + const tokenRes = await api.oauthExchangeCode( + code, + config.platform_id, + config.platform_secret, + config.callback_url + ) + + if (!tokenRes.success) { + message.error(tokenRes.message || "获取访问令牌失败") + setLoading(false) + return + } + + const userRes = await api.oauthGetUserInfo(tokenRes.data.access_token) + + if (!userRes.success) { + message.error(userRes.message || "获取用户信息失败") + setLoading(false) + return + } + + onSuccess(userRes.data) + onClose() + } + } catch (error: any) { + message.error(error.message || "登录失败") + } finally { + setLoading(false) + } + } + + useEffect(() => { + const setupDeepLink = async () => { + try { + const unlisten = await listen("deep-link://new-url", (event) => { + if (event.payload) { + handleDeepLink(event.payload) + } + }) + deepLinkUnlistenRef.current = unlisten + } catch (error) { + console.error("Failed to setup deep link listener:", error) + } + } + + setupDeepLink() + + return () => { + if (deepLinkUnlistenRef.current) { + deepLinkUnlistenRef.current() + deepLinkUnlistenRef.current = null + } + } + }, []) + + const handleOAuthLogin = async () => { + const config = getOAuthConfig() + if (!config) { + message.error("OAuth 配置未设置") + return + } + + setLoading(true) + + try { + const api = (window as any).api + const urlRes = await api.oauthGetAuthorizationUrl(config.platform_id, config.callback_url) + + if (!urlRes.success) { + message.error(urlRes.message || "获取授权链接失败") + setLoading(false) + return + } + + await open(urlRes.data) + } catch (error: any) { + message.error(error.message || "登录失败") + setLoading(false) + } + } + + return ( + +
+ {loading ? ( + + +
{t("auth.oauthLoggingIn", "正在登录...")}
+
+ 请在浏览器中完成授权 +
+
+ ) : ( + +
+ {t("auth.oauthHint", "使用 SECTL Auth 账号登录,享受统一认证和远程退登功能")} +
+ +
+ )} +
+
+ ) +} diff --git a/src/components/Settings.tsx b/src/components/Settings.tsx index d60fb58..3191b36 100644 --- a/src/components/Settings.tsx +++ b/src/components/Settings.tsx @@ -12,12 +12,17 @@ import { Modal, Switch, message, + Avatar, + Typography, } from "antd" import { ThemeQuickSettings } from "./ThemeQuickSettings" +import { OAuthLogin } from "./OAuthLogin" import { useTranslation } from "react-i18next" import { changeLanguage, getCurrentLanguage, languageOptions, AppLanguage } from "../i18n" import { useResponsive } from "../hooks/useResponsive" +const { Text, Paragraph } = Typography + type permissionLevel = "admin" | "points" | "view" type appSettings = { is_wizard_completed: boolean @@ -76,7 +81,13 @@ export const Settings: React.FC<{ const [recoveryDialogString, setRecoveryDialogString] = useState("") const [recoveryDialogFilename, setRecoveryDialogFilename] = useState("") - const [aboutContent, setAboutContent] = useState<{ title: string; description: string; content: string; rawMarkdown: string } | null>(null) + const [aboutContent, setAboutContent] = useState<{ + title: string + description: string + content: string + rawMarkdown: string + version?: string + } | null>(null) const [logsDialogVisible, setLogsDialogVisible] = useState(false) const [logsText, setLogsText] = useState("") @@ -120,6 +131,15 @@ export const Settings: React.FC<{ const [pgSwitchLoading, setPgSwitchLoading] = useState(false) const [pgUploadLoading, setPgUploadLoading] = useState(false) + const [oauthLoginVisible, setOAuthLoginVisible] = useState(false) + const [oauthUserInfo, setOAuthUserInfo] = useState<{ + user_id: string + email: string + name: string + github_username?: string + permission: number + } | null>(null) + const permissionTag = useMemo(() => { return ( { if (!(window as any).api) return const next = String(v) as "t9" | "qwerty26" - const res = await (window as any).api.setSetting("search_keyboard_layout", next) + const res = await (window as any).api.setSetting( + "search_keyboard_layout", + next + ) if (res.success) { setSettings((prev) => ({ ...prev, search_keyboard_layout: next })) messageApi.success(t("settings.general.saved")) @@ -668,7 +691,11 @@ export const Settings: React.FC<{ ]} />
{t("settings.searchKeyboard.hint")}
@@ -693,7 +720,11 @@ export const Settings: React.FC<{ disabled={!canAdmin} />
{t("settings.searchKeyboard.disableHint")}
@@ -734,7 +765,6 @@ export const Settings: React.FC<{ {t("settings.zoomHint")} - ), @@ -843,6 +873,84 @@ export const Settings: React.FC<{ ), }, + { + key: "account", + label: t("settings.tabs.account"), + children: ( + <> + +
+ {t("settings.account.title")} +
+ + {oauthUserInfo ? ( +
+
+ + {oauthUserInfo.name.charAt(0).toUpperCase()} + +
+
{oauthUserInfo.name}
+
+ {oauthUserInfo.email} +
+ {oauthUserInfo.github_username && ( +
+ GitHub: @{oauthUserInfo.github_username} +
+ )} +
+
+ + + +
+ {t("settings.account.userId")}: + + {oauthUserInfo.user_id} + +
+ +
+ {t("settings.account.permission")}: + + {oauthUserInfo.permission === 1 + ? t("permissions.admin") + : oauthUserInfo.permission === 2 + ? t("permissions.points") + : t("permissions.view")} + +
+ + + + +
+ ) : ( +
+ + {t("settings.account.notLoggedIn")} + + + {t("settings.account.oauthHint")} + + +
+ )} +
+ + ), + }, { key: "database", label: t("settings.database.title"), @@ -1420,6 +1528,15 @@ export const Settings: React.FC<{ > 清空后将关闭保护(无密码时默认视为管理权限)。
+ + setOAuthLoginVisible(false)} + onSuccess={(userInfo) => { + setOAuthUserInfo(userInfo) + messageApi.success(t("settings.account.loginSuccess")) + }} + /> ) } diff --git a/src/components/StudentManager.tsx b/src/components/StudentManager.tsx index 00b32b7..5060cf1 100644 --- a/src/components/StudentManager.tsx +++ b/src/components/StudentManager.tsx @@ -260,7 +260,11 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => { return } - const res = await (window as any).api.createStudent({ ...values, name, group_name: groupName }) + const res = await (window as any).api.createStudent({ + ...values, + name, + group_name: groupName, + }) if (res.success) { messageApi.success(t("students.addSuccess")) setVisible(false) @@ -1080,7 +1084,9 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => { const selectedMedals = (banYouDetail.medals || []).filter((m, idx) => banYouCheckedMedals.includes(medalKey(m, idx)) ) - const selectedTeams = (banYouDetail.teams || []).filter((g) => banYouCheckedTeams.includes(g.teamId)) + const selectedTeams = (banYouDetail.teams || []).filter((g) => + banYouCheckedTeams.includes(g.teamId) + ) if (!selectedStudents.length && !selectedMedals.length && !selectedTeams.length) { messageApi.warning(t("students.banyouNothingSelected")) @@ -1325,7 +1331,11 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => { }, }} > - @@ -1608,7 +1618,9 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => { borderBottom: "1px dashed var(--ss-border-color)", paddingBottom: 8, cursor: - groupKey === UNGROUPED_KEY || pointerDraggingStudentId != null ? "default" : "grab", + groupKey === UNGROUPED_KEY || pointerDraggingStudentId != null + ? "default" + : "grab", userSelect: "none", WebkitUserSelect: "none", touchAction: "none", @@ -1632,7 +1644,9 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => { studentsInGroup.map((student) => (
beginPointerDrag(e, student.id, student.name, groupKey)} + onPointerDown={(e) => + beginPointerDrag(e, student.id, student.name, groupKey) + } onPointerMove={(e) => trackPointerTarget(e.clientX, e.clientY)} onPointerUp={finishPointerDrag} onPointerCancel={finishPointerDrag} @@ -1935,7 +1949,9 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => { cancelText={t("common.cancel")} > {banYouDetailLoading ? ( -
+
{t("common.loading")}
) : !banYouDetail ? ( @@ -1973,7 +1989,9 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => { )}
-
{t("students.banyouReasonList")}
+
+ {t("students.banyouReasonList")} +
= ({ canEdit }) => {
-
{t("students.banyouStudentList")}
+
+ {t("students.banyouStudentList")} +
{ if (!target) return // 检查是否在可拖动区域内 - const dragRegion = target.closest('[data-tauri-drag-region]') + const dragRegion = target.closest("[data-tauri-drag-region]") if (!dragRegion) return // 检查是否点击了不可拖动的元素(如按钮) diff --git a/src/preload/types.ts b/src/preload/types.ts index 8b2e3dd..5a17ada 100644 --- a/src/preload/types.ts +++ b/src/preload/types.ts @@ -87,7 +87,9 @@ const api = { names: string[] }): Promise<{ success: boolean; data: { inserted: number; skipped: number; total: number } }> => invoke("student_import_from_xlsx", { params }), - fetchBanYouClassrooms: (params: { cookie: string }): Promise<{ + fetchBanYouClassrooms: (params: { + cookie: string + }): Promise<{ success: boolean data?: { classrooms: Array<{ @@ -280,6 +282,55 @@ const api = { invoke("auth_reset_by_recovery", { recoveryString }), authClearAll: (): Promise<{ success: boolean }> => invoke("auth_clear_all"), + // OAuth + oauthGetAuthorizationUrl: ( + platformId: string, + callbackUrl: string + ): Promise<{ success: boolean; data: string; message?: string }> => + invoke("oauth_get_authorization_url", { platformId, callbackUrl }), + oauthExchangeCode: ( + code: string, + platformId: string, + platformSecret: string, + callbackUrl: string + ): Promise<{ + success: boolean + data: { + access_token: string + refresh_token: string + token_type: string + expires_in: number + } + message?: string + }> => invoke("oauth_exchange_code", { code, platformId, platformSecret, callbackUrl }), + oauthGetUserInfo: ( + accessToken: string + ): Promise<{ + success: boolean + data: { + user_id: string + email: string + name: string + github_username?: string + permission: number + } + message?: string + }> => invoke("oauth_get_user_info", { accessToken }), + oauthRefreshToken: ( + refreshToken: string, + platformId: string, + platformSecret: string + ): Promise<{ + success: boolean + data: { + access_token: string + refresh_token: string + token_type: string + expires_in: number + } + message?: string + }> => invoke("oauth_refresh_token", { refreshToken, platformId, platformSecret }), + // Data import/export exportDataJson: (): Promise<{ success: boolean; data: string }> => invoke("data_export_json"), importDataJson: (jsonText: string): Promise<{ success: boolean }> => @@ -442,7 +493,7 @@ const api = { appRestart: (): Promise => invoke("app_restart"), // Generic invoke wrapper for backward compatibility with callers using `api.invoke` - invoke: async (channel: string, ...args: any[]): Promise => { + invoke: async (channel: string): Promise => { switch (channel) { default: throw new Error(`Unsupported legacy invoke channel: ${channel}`) diff --git a/src/shared/mobileNavigation.ts b/src/shared/mobileNavigation.ts index 63a1abf..ccefe72 100644 --- a/src/shared/mobileNavigation.ts +++ b/src/shared/mobileNavigation.ts @@ -2,6 +2,7 @@ export const MOBILE_NAV_ALL_KEYS = [ "home", "students", "score", + "auto-score", "reward-settings", "boards", "leaderboard",