From 5c3d48abab2cf0754b58d1f9f0392b80456cf29b Mon Sep 17 00:00:00 2001 From: xion Date: Sat, 22 Mar 2025 12:48:49 +0800 Subject: [PATCH] feat: change permission for mino -resources --- .gitignore | 4 +- .gitmodules | 3 + .npmrc | 1 + package.json | 8 +- pnpm-lock.yaml | 370 ++++++++++++++++++ src/routes-simple/middleware/auth.ts | 23 ++ src/routes-simple/minio/get-minio-resource.ts | 82 +--- src/routes/config/models/model.ts | 5 +- src/routes/config/services/share.ts | 30 +- src/routes/config/share-config.ts | 15 +- submodules/permission | 1 + turbo.json | 17 + 12 files changed, 478 insertions(+), 81 deletions(-) create mode 160000 submodules/permission create mode 100644 turbo.json diff --git a/.gitignore b/.gitignore index 9c7f722..0f7caac 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,6 @@ cache-file logs release/* -!release/.gitkeep \ No newline at end of file +!release/.gitkeep + +.turbo diff --git a/.gitmodules b/.gitmodules index d2fe36d..0685a16 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "submodules/code-center-module"] path = submodules/code-center-module url = git@git.xiongxiao.me:kevisual/code-center-module.git +[submodule "submodules/permission"] + path = submodules/permission + url = git@git.xiongxiao.me:kevisual/kevsiual-permission.git diff --git a/.npmrc b/.npmrc index d9b4b32..3ca2007 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1,2 @@ @abearxiong:registry=https://npm.pkg.github.com +ignore-workspace-root-check=true \ No newline at end of file diff --git a/package.json b/package.json index 31193b6..092dfd7 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,8 @@ "release": "node ./config/release/index.mjs", "pub": "envision pack -p -u", "ssh": "ssh -L 6379:localhost:6379 light ", - "ssh:sky": "ssh -L 6379:172.21.32.13:6379 sky" + "ssh:sky": "ssh -L 6379:172.21.32.13:6379 sky", + "dev:lib": "turbo run dev:lib" }, "keywords": [], "types": "types/index.d.ts", @@ -34,6 +35,7 @@ "license": "UNLICENSED", "dependencies": { "@kevisual/local-app-manager": "0.1.9", + "@kevisual/permission": "workspace:*", "@kevisual/router": "0.0.9", "@kevisual/use-config": "^1.0.9", "@types/semver": "^7.5.8", @@ -86,6 +88,7 @@ "rollup-plugin-dts": "^6.2.0", "tape": "^5.9.0", "tsx": "^4.19.3", + "turbo": "^2.4.4", "typescript": "^5.8.2" }, "resolutions": { @@ -93,5 +96,6 @@ "rimraf": "latest", "picomatch": "^4.0.2" }, - "pnpm": {} + "pnpm": {}, + "packageManager": "pnpm@9.15.0" } \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b76cb4b..922d9f6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,6 +16,9 @@ importers: '@kevisual/local-app-manager': specifier: 0.1.9 version: 0.1.9(@kevisual/router@0.0.9)(@kevisual/types@0.0.6)(@kevisual/use-config@1.0.9)(pm2@6.0.5) + '@kevisual/permission': + specifier: workspace:* + version: link:submodules/permission '@kevisual/router': specifier: 0.0.9 version: 0.0.9 @@ -167,6 +170,9 @@ importers: tsx: specifier: ^4.19.3 version: 4.19.3 + turbo: + specifier: ^2.4.4 + version: 2.4.4 typescript: specifier: ^5.8.2 version: 5.8.2 @@ -280,6 +286,12 @@ importers: specifier: ^5.8.2 version: 5.8.2 + submodules/permission: + devDependencies: + tsup: + specifier: ^8.4.0 + version: 8.4.0(tsx@4.19.3)(typescript@5.8.2) + packages: '@babel/code-frame@7.26.2': @@ -451,9 +463,24 @@ packages: resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} engines: {node: '>=18.0.0'} + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@kevisual/auth@1.0.5': resolution: {integrity: sha512-GwsLj7unKXi7lmMiIIgdig4LwwLiDJnOy15HHZR5gMbyK6s5/uJiMY5RXPB2+onGzTNDqFo/hXjsD2wkerHPVg==} @@ -888,6 +915,9 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} @@ -997,6 +1027,16 @@ packages: buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + bundle-require@5.1.0: + resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + call-bind@1.0.7: resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} engines: {node: '>= 0.4'} @@ -1016,6 +1056,10 @@ packages: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + chownr@3.0.0: resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} engines: {node: '>=18'} @@ -1045,6 +1089,10 @@ packages: commander@2.15.1: resolution: {integrity: sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==} + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + commondir@1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} @@ -1060,6 +1108,10 @@ packages: engines: {node: '>=18'} hasBin: true + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + cookie@0.4.2: resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} engines: {node: '>= 0.6'} @@ -1334,6 +1386,14 @@ packages: picomatch: optional: true + fdir@6.4.3: + resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} + peerDependencies: + picomatch: ^4.0.2 + peerDependenciesMeta: + picomatch: + optional: true + fetch-blob@3.2.0: resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} engines: {node: ^12.20 || >= 14.13} @@ -1682,6 +1742,10 @@ packages: resolution: {integrity: sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==} engines: {node: 20 || >=22} + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + js-git@0.7.8: resolution: {integrity: sha512-+E5ZH/HeRnoc/LW0AmAyhU+mNcWBzAKE+30+IDMLSLbbK+Tdt02AdkOKq9u15rlJsDEGFqtgckc8ZM59LhhiUA==} @@ -1723,6 +1787,17 @@ packages: resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} engines: {node: '>= 0.6.3'} + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + lodash-es@4.17.21: resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} @@ -1753,6 +1828,9 @@ packages: lodash.once@4.1.1: resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} @@ -1852,6 +1930,9 @@ packages: mute-stream@0.0.8: resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + nanoid@5.1.3: resolution: {integrity: sha512-zAbEOEr7u2CbxwoMRlz/pNSpRP0FdAU4pRaYunCdEezWohXFs+a0Xw7RfkKaezMsmSM1vttcLthJtwRnVtOfHQ==} engines: {node: ^18 || >=20} @@ -2008,6 +2089,9 @@ packages: picocolors@1.1.0: resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + picomatch@4.0.2: resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} engines: {node: '>=12'} @@ -2020,6 +2104,10 @@ packages: resolution: {integrity: sha512-g0VU+y08pKw5M8EZ2rIGiEBaB8wrQMjYGFfW2QVIfyT8V+fq8YFLkvlz4bz5ljvFDJYNFCWT3PWqcRr2FKO81w==} engines: {node: '>=10'} + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + pm2-axon-rpc@0.7.1: resolution: {integrity: sha512-FbLvW60w+vEyvMjP/xom2UPhUN/2bVpdtLfKJeYM3gwzYhoTEEChCOICfFzxkxuoEleOlnpjie+n1nue91bDQw==} engines: {node: '>=5'} @@ -2047,6 +2135,24 @@ packages: resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} engines: {node: '>= 0.4'} + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + postgres-array@2.0.0: resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} engines: {node: '>=4'} @@ -2083,6 +2189,10 @@ packages: pstree.remy@1.1.8: resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + query-string@7.1.3: resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==} engines: {node: '>=6'} @@ -2115,6 +2225,10 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + redis-errors@1.2.0: resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} engines: {node: '>=4'} @@ -2135,6 +2249,10 @@ packages: resolution: {integrity: sha512-efCx3b+0Z69/LGJmm9Yvi4cqEdxnoGnxYxGxBghkkTTFeXRtTCmmhO0AnAfHz59k957uTSuy8WaHqOs8wbYUWg==} engines: {node: '>=6'} + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} @@ -2344,6 +2462,10 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + source-map@0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + split-on-first@1.1.0: resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} engines: {node: '>=6'} @@ -2414,6 +2536,11 @@ packages: strnum@1.0.5: resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -2450,9 +2577,23 @@ packages: text-decoder@1.2.0: resolution: {integrity: sha512-n1yg1mOj9DNpk3NeZOx7T6jchTbyJS3i3cucbNN6FcdPriMZx7NsgrGpWWdWZZGxD7ES1XB+3uoqHMgOKaN+fg==} + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + through2@4.0.2: resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinyglobby@0.2.12: + resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} + engines: {node: '>=12.0.0'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -2464,21 +2605,80 @@ packages: resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==} hasBin: true + tr46@1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + tslib@1.9.3: resolution: {integrity: sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==} tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsup@8.4.0: + resolution: {integrity: sha512-b+eZbPCjz10fRryaAA7C8xlIHnf8VnsaRqydheLIqwG/Mcpfk8Z5zp3HayX7GaTygkigHl5cBUs+IhcySiIexQ==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.5.0' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + tsx@4.19.3: resolution: {integrity: sha512-4H8vUNGNjQ4V2EOoGw005+c+dGuPSnhpPBPHBtsZdGZBk/iJb4kguGlPWaZTZ3q5nMtFOEsY0nRDlh9PJyd6SQ==} engines: {node: '>=18.0.0'} hasBin: true + turbo-darwin-64@2.4.4: + resolution: {integrity: sha512-5kPvRkLAfmWI0MH96D+/THnDMGXlFNmjeqNRj5grLKiry+M9pKj3pRuScddAXPdlxjO5Ptz06UNaOQrrYGTx1g==} + cpu: [x64] + os: [darwin] + + turbo-darwin-arm64@2.4.4: + resolution: {integrity: sha512-/gtHPqbGQXDFhrmy+Q/MFW2HUTUlThJ97WLLSe4bxkDrKHecDYhAjbZ4rN3MM93RV9STQb3Tqy4pZBtsd4DfCw==} + cpu: [arm64] + os: [darwin] + + turbo-linux-64@2.4.4: + resolution: {integrity: sha512-SR0gri4k0bda56hw5u9VgDXLKb1Q+jrw4lM7WAhnNdXvVoep4d6LmnzgMHQQR12Wxl3KyWPbkz9d1whL6NTm2Q==} + cpu: [x64] + os: [linux] + + turbo-linux-arm64@2.4.4: + resolution: {integrity: sha512-COXXwzRd3vslQIfJhXUklgEqlwq35uFUZ7hnN+AUyXx7hUOLIiD5NblL+ETrHnhY4TzWszrbwUMfe2BYWtaPQg==} + cpu: [arm64] + os: [linux] + + turbo-windows-64@2.4.4: + resolution: {integrity: sha512-PV9rYNouGz4Ff3fd6sIfQy5L7HT9a4fcZoEv8PKRavU9O75G7PoDtm8scpHU10QnK0QQNLbE9qNxOAeRvF0fJg==} + cpu: [x64] + os: [win32] + + turbo-windows-arm64@2.4.4: + resolution: {integrity: sha512-403sqp9t5sx6YGEC32IfZTVWkRAixOQomGYB8kEc6ZD+//LirSxzeCHCnM8EmSXw7l57U1G+Fb0kxgTcKPU/Lg==} + cpu: [arm64] + os: [win32] + + turbo@2.4.4: + resolution: {integrity: sha512-N9FDOVaY3yz0YCOhYIgOGYad7+m2ptvinXygw27WPLQvcZDl3+0Sa77KGVlLSiuPDChOUEnTKE9VJwLSi9BPGQ==} + hasBin: true + tv4@1.3.0: resolution: {integrity: sha512-afizzfpJgvPr+eDkREK4MxJ/+r8nEEHcmitwgnPUqpaP+FpwQyadnxNoSACbgc/b1LsZYtODGoPiFxQrgJgjvw==} engines: {node: '>= 0.8.0'} @@ -2561,6 +2761,12 @@ packages: resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} engines: {node: '>= 8'} + webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + + whatwg-url@7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} @@ -2767,8 +2973,23 @@ snapshots: dependencies: minipass: 7.1.2 + '@jridgewell/gen-mapping@0.3.8': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + '@kevisual/auth@1.0.5': {} '@kevisual/load@0.0.4': @@ -3211,6 +3432,8 @@ snapshots: ansi-styles@6.2.1: {} + any-promise@1.3.0: {} + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 @@ -3329,6 +3552,13 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 + bundle-require@5.1.0(esbuild@0.25.0): + dependencies: + esbuild: 0.25.0 + load-tsconfig: 0.2.5 + + cac@6.7.14: {} + call-bind@1.0.7: dependencies: es-define-property: 1.0.0 @@ -3361,6 +3591,10 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + chownr@3.0.0: {} cli-tableau@2.0.1: @@ -3385,6 +3619,8 @@ snapshots: commander@2.15.1: {} + commander@4.1.1: {} + commondir@1.0.1: {} compress-commons@6.0.2: @@ -3407,6 +3643,8 @@ snapshots: tree-kill: 1.2.2 yargs: 17.7.2 + consola@3.4.2: {} + cookie@0.4.2: {} core-util-is@1.0.3: {} @@ -3751,6 +3989,10 @@ snapshots: optionalDependencies: picomatch: 4.0.2 + fdir@6.4.3(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + fetch-blob@3.2.0: dependencies: node-domexception: 1.0.0 @@ -4113,6 +4355,8 @@ snapshots: dependencies: '@isaacs/cliui': 8.0.2 + joycon@3.1.1: {} + js-git@0.7.8: dependencies: bodec: 0.1.0 @@ -4172,6 +4416,12 @@ snapshots: dependencies: readable-stream: 2.3.8 + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + + load-tsconfig@0.2.5: {} + lodash-es@4.17.21: {} lodash.defaults@4.2.0: {} @@ -4192,6 +4442,8 @@ snapshots: lodash.once@4.1.1: {} + lodash.sortby@4.7.0: {} + lodash@4.17.21: {} lru-cache@10.4.3: {} @@ -4293,6 +4545,12 @@ snapshots: mute-stream@0.0.8: {} + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + nanoid@5.1.3: {} nanoid@5.1.5: {} @@ -4445,6 +4703,8 @@ snapshots: picocolors@1.1.0: optional: true + picocolors@1.1.1: {} + picomatch@4.0.2: {} pidusage@2.0.21: @@ -4456,6 +4716,8 @@ snapshots: dependencies: safe-buffer: 5.2.1 + pirates@4.0.6: {} + pm2-axon-rpc@0.7.1: dependencies: debug: 4.4.0 @@ -4531,6 +4793,12 @@ snapshots: possible-typed-array-names@1.0.0: {} + postcss-load-config@6.0.1(tsx@4.19.3): + dependencies: + lilconfig: 3.1.3 + optionalDependencies: + tsx: 4.19.3 + postgres-array@2.0.0: {} postgres-bytea@1.0.0: {} @@ -4566,6 +4834,8 @@ snapshots: pstree.remy@1.1.8: {} + punycode@2.3.1: {} + query-string@7.1.3: dependencies: decode-uri-component: 0.2.2 @@ -4613,6 +4883,8 @@ snapshots: dependencies: picomatch: 4.0.2 + readdirp@4.1.2: {} + redis-errors@1.2.0: {} redis-parser@3.0.0: @@ -4636,6 +4908,8 @@ snapshots: transitivePeerDependencies: - supports-color + resolve-from@5.0.0: {} + resolve-pkg-maps@1.0.0: {} resolve@1.22.8: @@ -4917,6 +5191,10 @@ snapshots: source-map@0.6.1: {} + source-map@0.8.0-beta.0: + dependencies: + whatwg-url: 7.1.0 + split-on-first@1.1.0: {} split2@4.2.0: {} @@ -4996,6 +5274,16 @@ snapshots: strnum@1.0.5: {} + sucrase@3.35.0: + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + commander: 4.1.1 + glob: 10.4.5 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + supports-color@5.5.0: dependencies: has-flag: 3.0.0 @@ -5057,10 +5345,25 @@ snapshots: dependencies: b4a: 1.6.7 + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + through2@4.0.2: dependencies: readable-stream: 3.6.2 + tinyexec@0.3.2: {} + + tinyglobby@0.2.12: + dependencies: + fdir: 6.4.3(picomatch@4.0.2) + picomatch: 4.0.2 + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -5069,12 +5372,44 @@ snapshots: touch@3.1.1: {} + tr46@1.0.1: + dependencies: + punycode: 2.3.1 + tree-kill@1.2.2: {} + ts-interface-checker@0.1.13: {} + tslib@1.9.3: {} tslib@2.8.1: {} + tsup@8.4.0(tsx@4.19.3)(typescript@5.8.2): + dependencies: + bundle-require: 5.1.0(esbuild@0.25.0) + cac: 6.7.14 + chokidar: 4.0.3 + consola: 3.4.2 + debug: 4.4.0 + esbuild: 0.25.0 + joycon: 3.1.1 + picocolors: 1.1.1 + postcss-load-config: 6.0.1(tsx@4.19.3) + resolve-from: 5.0.0 + rollup: 4.36.0 + source-map: 0.8.0-beta.0 + sucrase: 3.35.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.12 + tree-kill: 1.2.2 + optionalDependencies: + typescript: 5.8.2 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + tsx@4.19.3: dependencies: esbuild: 0.25.0 @@ -5082,6 +5417,33 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + turbo-darwin-64@2.4.4: + optional: true + + turbo-darwin-arm64@2.4.4: + optional: true + + turbo-linux-64@2.4.4: + optional: true + + turbo-linux-arm64@2.4.4: + optional: true + + turbo-windows-64@2.4.4: + optional: true + + turbo-windows-arm64@2.4.4: + optional: true + + turbo@2.4.4: + optionalDependencies: + turbo-darwin-64: 2.4.4 + turbo-darwin-arm64: 2.4.4 + turbo-linux-64: 2.4.4 + turbo-linux-arm64: 2.4.4 + turbo-windows-64: 2.4.4 + turbo-windows-arm64: 2.4.4 + tv4@1.3.0: {} tx2@1.0.5: @@ -5176,6 +5538,14 @@ snapshots: web-streams-polyfill@3.3.3: {} + webidl-conversions@4.0.2: {} + + whatwg-url@7.1.0: + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + which-boxed-primitive@1.0.2: dependencies: is-bigint: 1.0.4 diff --git a/src/routes-simple/middleware/auth.ts b/src/routes-simple/middleware/auth.ts index b6839ad..06e8ca6 100644 --- a/src/routes-simple/middleware/auth.ts +++ b/src/routes-simple/middleware/auth.ts @@ -36,3 +36,26 @@ export const checkAuth = async (req: http.IncomingMessage, res: http.ServerRespo } return { tokenUser, token }; }; + +export const getLoginUser = async (req: http.IncomingMessage) => { + let token = (req.headers?.['authorization'] as string) || (req.headers?.['Authorization'] as string) || ''; + const url = new URL(req.url || '', 'http://localhost'); + if (!token) { + token = url.searchParams.get('token') || ''; + } + if (!token) { + const parsedCookies = cookie.parse(req.headers.cookie || ''); + token = parsedCookies.token || ''; + } + + if (token) { + token = token.replace('Bearer ', ''); + } + let tokenUser; + try { + tokenUser = await User.verifyToken(token); + return { tokenUser, token }; + } catch (e) { + return null; + } +}; diff --git a/src/routes-simple/minio/get-minio-resource.ts b/src/routes-simple/minio/get-minio-resource.ts index 893cf80..cfce8be 100644 --- a/src/routes-simple/minio/get-minio-resource.ts +++ b/src/routes-simple/minio/get-minio-resource.ts @@ -1,11 +1,13 @@ /** * 更新时间:2025-03-17 + * 第二次更新:2025-03-22 */ import { minioClient } from '@/app.ts'; import { IncomingMessage, ServerResponse } from 'http'; import { bucketName } from '@/modules/minio.ts'; -import { checkAuth } from '../middleware/auth.ts'; +import { getLoginUser } from '../middleware/auth.ts'; import { BucketItemStat } from 'minio'; +import { UserPermission, Permission } from '@kevisual/permission'; /** * 过滤 metaData 中的 key, 去除 password, accesskey, secretkey, @@ -23,54 +25,7 @@ const filterKeys = (metaData: Record, clearKeys: string[] = []) return acc; }, {} as Record); }; -export const checkMetaAuth = async ( - metaData: Record, - { tokenUser, token, share, userKey, password }: { tokenUser: any; share: ShareType; token: string; userKey: string; password: string }, -) => { - const tokenUsername = tokenUser?.username; - if (share === 'public') { - return { - code: 20000, - msg: '资源是公开的', - }; - } - if (tokenUsername === userKey) { - return { - code: 20001, - msg: '用户是资源所有者', - }; - } - // 1. 检查资源是否过期(有,则检查) - if (metaData['expiration-time']) { - const expirationTime = new Date(metaData['expiration-time']); - const currentTime = new Date(); - if (expirationTime < currentTime) { - return { - code: 20100, - msg: '资源已过期', - }; - } - } - // 2. 检查密码是否正确(可选,password存在的情况) - if (password && metaData.password && password === metaData.password) { - return { - code: 20002, - msg: '用户通过密码正确访问', - }; - } - const usernames = metaData['usernames'] || ''; - if (usernames && usernames.includes(tokenUsername)) { - // TODO: 可以检查用户的orgs 是否在 metaData['orgs'] 中 - return { - code: 20003, - msg: '用户在usernames列表中', - }; - } - return { - code: 20101, - msg: '用户没有权限访问', - }; -}; + export const NotFoundFile = (res: ServerResponse, msg?: string, code = 404) => { res.writeHead(code, { 'Content-Type': 'text/plain' }); res.end(msg || 'Not Found File'); @@ -95,22 +50,21 @@ export const authMinio = async (req: IncomingMessage, res: ServerResponse, objec if (stat.size === 0) { return NotFoundFile(res); } - const share = (metaData.share as ShareType) || 'private'; // 默认是 private - let tokenUser: any = null; - let token: string | null = null; - if (password && metaData.password && password === metaData.password) { - // 密码正确,直接返回 - } else if (share !== 'public') { - ({ tokenUser, token } = await checkAuth(req, res)); - if (!tokenUser) { - return; - } - const checkMetaAuthResult = await checkMetaAuth(metaData, { tokenUser, token, share, userKey, password }); - const { code } = checkMetaAuthResult; - if (code >= 20100) { - return NotFoundFile(res); - } + const { tokenUser } = await getLoginUser(req); + const username = tokenUser?.username; + const owner = userKey; + const permission = new UserPermission({ + permission: metaData as Permission, + owner, + }); + const checkPermissionResult = permission.checkPermissionSuccess({ + username, + password, + }); + if (!checkPermissionResult.success) { + return NotFoundFile(res, checkPermissionResult.message, checkPermissionResult.code); } + const contentLength = stat.size; const etag = stat.etag; const lastModified = stat.lastModified.toISOString(); diff --git a/src/routes/config/models/model.ts b/src/routes/config/models/model.ts index b0b2bcc..5b822e9 100644 --- a/src/routes/config/models/model.ts +++ b/src/routes/config/models/model.ts @@ -1,13 +1,12 @@ import { useContextKey } from '@kevisual/use-config/context'; import { sequelize } from '../../../modules/sequelize.ts'; import { DataTypes, Model } from 'sequelize'; +import { Permission } from '@kevisual/permission'; export interface ConfigData { key?: string; version?: string; - permission?: { - share?: 'public' | 'private'; - }; + permission?: Permission; } export type Config = Partial>; diff --git a/src/routes/config/services/share.ts b/src/routes/config/services/share.ts index b1c1c44..bf9e7e7 100644 --- a/src/routes/config/services/share.ts +++ b/src/routes/config/services/share.ts @@ -1,7 +1,9 @@ -import { ConfigModel } from '../models/model.ts'; +import { ConfigModel, Config } from '../models/model.ts'; import { CustomError } from '@kevisual/router'; import { redis } from '@/app.ts'; import { User } from '@/models/user.ts'; +import { UserPermission, UserPermissionOptions } from '@kevisual/permission'; + export class ShareConfigService extends ConfigModel { /** * 获取分享的配置 @@ -9,10 +11,23 @@ export class ShareConfigService extends ConfigModel { * @param username 分享者的username * @returns 配置 */ - static async getShareConfig(key: string, username: string) { - const shareCacheConfig = await redis.get(`config:share:${username}:${key}`); + static async getShareConfig(key: string, username: string, options: UserPermissionOptions) { + const shareCacheConfigString = await redis.get(`config:share:${username}:${key}`); + let shareCacheConfig: Config; + try { + shareCacheConfig = JSON.parse(shareCacheConfigString); + } catch (e) { + await redis.set(`config:share:${username}:${key}`, '', 'EX', 0); // 删除缓存 + throw new CustomError(400, 'config parse error'); + } + const owner = username; if (shareCacheConfig) { - return JSON.parse(shareCacheConfig); + const permission = new UserPermission({ permission: shareCacheConfig?.data?.permission, owner }); + const result = permission.checkPermissionSuccess(options); + if (!result.success) { + throw new CustomError(403, 'no permission'); + } + return shareCacheConfig; } const user = await User.findOne({ where: { username }, @@ -26,8 +41,9 @@ export class ShareConfigService extends ConfigModel { if (!config) { throw new CustomError(404, 'config not found'); } - const configData = config?.data?.permission; - if (configData?.share !== 'public') { + const permission = new UserPermission({ permission: config?.data?.permission, owner }); + const result = permission.checkPermissionSuccess(options); + if (!result.success) { throw new CustomError(403, 'no permission'); } await redis.set(`config:share:${username}:${key}`, JSON.stringify(config), 'EX', 60 * 60 * 24 * 7); // 7天 @@ -35,7 +51,7 @@ export class ShareConfigService extends ConfigModel { } static async expireShareConfig(key: string, username: string) { if (key && username) { - await redis.del(`config:share:${username}:${key}`); + await redis.set(`config:share:${username}:${key}`, '', 'EX', 0); } } } diff --git a/src/routes/config/share-config.ts b/src/routes/config/share-config.ts index f8ab0f7..9af16a0 100644 --- a/src/routes/config/share-config.ts +++ b/src/routes/config/share-config.ts @@ -7,15 +7,22 @@ app middleware: ['auth'], }) .define(async (ctx) => { - const { key, username } = ctx.query?.data || {}; - if (!key) { - ctx.throw(400, 'key is required'); + const tokenUser = ctx.state.tokenUser; + const { p, username, configKey } = ctx.query || {}; + const queryUsername = tokenUser?.username; + const password = p; + if (!configKey) { + ctx.throw(400, 'configKey is required'); } if (!username) { ctx.throw(400, 'username is required'); } + try { - const config = await ShareConfigService.getShareConfig(key, username); + const config = await ShareConfigService.getShareConfig(configKey, username, { + username: queryUsername, + password, + }); ctx.body = config; } catch (error) { if (error?.code === 500) { diff --git a/submodules/permission b/submodules/permission new file mode 160000 index 0000000..bc6df19 --- /dev/null +++ b/submodules/permission @@ -0,0 +1 @@ +Subproject commit bc6df19c9c5365b7950929ebe1be9fbb7224c670 diff --git a/turbo.json b/turbo.json new file mode 100644 index 0000000..a7a1e28 --- /dev/null +++ b/turbo.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://turbo.build/schema.json", + "tasks": { + "build": { + "dependsOn": [ + "^build" + ], + "outputs": [ + "dist/**" + ] + }, + "dev:lib": { + "persistent": true, + "cache": false + } + } +} \ No newline at end of file