mirror of https://github.com/halo-dev/halo-admin
feat: support permission judgment of interface elements and routes
parent
74274ef78b
commit
e8fd09205d
|
@ -33,15 +33,16 @@
|
||||||
"@formkit/vue": "1.0.0-beta.9",
|
"@formkit/vue": "1.0.0-beta.9",
|
||||||
"@halo-dev/admin-api": "^1.1.0",
|
"@halo-dev/admin-api": "^1.1.0",
|
||||||
"@halo-dev/admin-shared": "workspace:*",
|
"@halo-dev/admin-shared": "workspace:*",
|
||||||
"@halo-dev/api-client": "^0.0.0",
|
"@halo-dev/api-client": "^0.0.2",
|
||||||
"@halo-dev/components": "workspace:*",
|
"@halo-dev/components": "workspace:*",
|
||||||
"@vueuse/components": "^8.9.2",
|
"@vueuse/components": "^8.9.3",
|
||||||
"@vueuse/core": "^8.9.2",
|
"@vueuse/core": "^8.9.3",
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
"filepond": "^4.30.4",
|
"filepond": "^4.30.4",
|
||||||
"filepond-plugin-image-preview": "^4.6.11",
|
"filepond-plugin-image-preview": "^4.6.11",
|
||||||
"floating-vue": "2.0.0-beta.16",
|
"floating-vue": "2.0.0-beta.16",
|
||||||
"lodash.clonedeep": "^4.5.0",
|
"lodash.clonedeep": "^4.5.0",
|
||||||
|
"lodash.isequal": "^4.5.0",
|
||||||
"pinia": "^2.0.16",
|
"pinia": "^2.0.16",
|
||||||
"qs": "^6.11.0",
|
"qs": "^6.11.0",
|
||||||
"uuid": "^8.3.2",
|
"uuid": "^8.3.2",
|
||||||
|
@ -51,7 +52,7 @@
|
||||||
"vue-router": "^4.1.2"
|
"vue-router": "^4.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@changesets/cli": "^2.23.1",
|
"@changesets/cli": "^2.23.2",
|
||||||
"@rushstack/eslint-patch": "^1.1.4",
|
"@rushstack/eslint-patch": "^1.1.4",
|
||||||
"@tailwindcss/aspect-ratio": "^0.4.0",
|
"@tailwindcss/aspect-ratio": "^0.4.0",
|
||||||
"@types/jsdom": "^16.2.14",
|
"@types/jsdom": "^16.2.14",
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
"@rollup/plugin-typescript": "^8.3.3",
|
"@rollup/plugin-typescript": "^8.3.3",
|
||||||
"histoire": "^0.7.9",
|
"histoire": "^0.7.9",
|
||||||
"unplugin-icons": "^0.14.7",
|
"unplugin-icons": "^0.14.7",
|
||||||
"vite-plugin-dts": "^1.2.1"
|
"vite-plugin-dts": "^1.3.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"vue": "^3.2.37",
|
"vue": "^3.2.37",
|
||||||
|
|
|
@ -36,12 +36,12 @@
|
||||||
"homepage": "https://github.com/halo-dev/halo-admin/tree/next/shared/components#readme",
|
"homepage": "https://github.com/halo-dev/halo-admin/tree/next/shared/components#readme",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@halo-dev/api-client": "^0.0.0",
|
"@halo-dev/api-client": "^0.0.2",
|
||||||
"@halo-dev/components": "workspace:*",
|
"@halo-dev/components": "workspace:*",
|
||||||
"axios": "^0.27.2"
|
"axios": "^0.27.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"vite-plugin-dts": "^1.2.1"
|
"vite-plugin-dts": "^1.3.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"vue": "^3.2.37",
|
"vue": "^3.2.37",
|
||||||
|
|
|
@ -6,4 +6,5 @@ export interface FunctionalPagesState {
|
||||||
name: string;
|
name: string;
|
||||||
path: string;
|
path: string;
|
||||||
url?: string;
|
url?: string;
|
||||||
|
permissions?: Array<string>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ importers:
|
||||||
|
|
||||||
.:
|
.:
|
||||||
specifiers:
|
specifiers:
|
||||||
'@changesets/cli': ^2.23.1
|
'@changesets/cli': ^2.23.2
|
||||||
'@formkit/addons': 1.0.0-beta.9
|
'@formkit/addons': 1.0.0-beta.9
|
||||||
'@formkit/core': 1.0.0-beta.9
|
'@formkit/core': 1.0.0-beta.9
|
||||||
'@formkit/i18n': 1.0.0-beta.9
|
'@formkit/i18n': 1.0.0-beta.9
|
||||||
|
@ -13,7 +13,7 @@ importers:
|
||||||
'@formkit/vue': 1.0.0-beta.9
|
'@formkit/vue': 1.0.0-beta.9
|
||||||
'@halo-dev/admin-api': ^1.1.0
|
'@halo-dev/admin-api': ^1.1.0
|
||||||
'@halo-dev/admin-shared': workspace:*
|
'@halo-dev/admin-shared': workspace:*
|
||||||
'@halo-dev/api-client': ^0.0.0
|
'@halo-dev/api-client': ^0.0.2
|
||||||
'@halo-dev/components': workspace:*
|
'@halo-dev/components': workspace:*
|
||||||
'@rushstack/eslint-patch': ^1.1.4
|
'@rushstack/eslint-patch': ^1.1.4
|
||||||
'@tailwindcss/aspect-ratio': ^0.4.0
|
'@tailwindcss/aspect-ratio': ^0.4.0
|
||||||
|
@ -30,8 +30,8 @@ importers:
|
||||||
'@vue/eslint-config-typescript': ^11.0.0
|
'@vue/eslint-config-typescript': ^11.0.0
|
||||||
'@vue/test-utils': ^2.0.2
|
'@vue/test-utils': ^2.0.2
|
||||||
'@vue/tsconfig': ^0.1.3
|
'@vue/tsconfig': ^0.1.3
|
||||||
'@vueuse/components': ^8.9.2
|
'@vueuse/components': ^8.9.3
|
||||||
'@vueuse/core': ^8.9.2
|
'@vueuse/core': ^8.9.3
|
||||||
autoprefixer: ^10.4.7
|
autoprefixer: ^10.4.7
|
||||||
axios: ^0.27.2
|
axios: ^0.27.2
|
||||||
c8: ^7.11.3
|
c8: ^7.11.3
|
||||||
|
@ -45,6 +45,7 @@ importers:
|
||||||
husky: ^8.0.1
|
husky: ^8.0.1
|
||||||
jsdom: ^19.0.0
|
jsdom: ^19.0.0
|
||||||
lodash.clonedeep: ^4.5.0
|
lodash.clonedeep: ^4.5.0
|
||||||
|
lodash.isequal: ^4.5.0
|
||||||
pinia: ^2.0.16
|
pinia: ^2.0.16
|
||||||
postcss: ^8.4.14
|
postcss: ^8.4.14
|
||||||
prettier: ^2.7.1
|
prettier: ^2.7.1
|
||||||
|
@ -78,15 +79,16 @@ importers:
|
||||||
'@formkit/vue': 1.0.0-beta.9_jly5jqkcc2zgnt3crhnp3znzv4
|
'@formkit/vue': 1.0.0-beta.9_jly5jqkcc2zgnt3crhnp3znzv4
|
||||||
'@halo-dev/admin-api': 1.1.0
|
'@halo-dev/admin-api': 1.1.0
|
||||||
'@halo-dev/admin-shared': link:packages/shared
|
'@halo-dev/admin-shared': link:packages/shared
|
||||||
'@halo-dev/api-client': 0.0.0
|
'@halo-dev/api-client': 0.0.2
|
||||||
'@halo-dev/components': link:packages/components
|
'@halo-dev/components': link:packages/components
|
||||||
'@vueuse/components': 8.9.2_vue@3.2.37
|
'@vueuse/components': 8.9.3_vue@3.2.37
|
||||||
'@vueuse/core': 8.9.2_vue@3.2.37
|
'@vueuse/core': 8.9.3_vue@3.2.37
|
||||||
axios: 0.27.2
|
axios: 0.27.2
|
||||||
filepond: 4.30.4
|
filepond: 4.30.4
|
||||||
filepond-plugin-image-preview: 4.6.11_filepond@4.30.4
|
filepond-plugin-image-preview: 4.6.11_filepond@4.30.4
|
||||||
floating-vue: 2.0.0-beta.16_vue@3.2.37
|
floating-vue: 2.0.0-beta.16_vue@3.2.37
|
||||||
lodash.clonedeep: 4.5.0
|
lodash.clonedeep: 4.5.0
|
||||||
|
lodash.isequal: 4.5.0
|
||||||
pinia: 2.0.16_j6bzmzd4ujpabbp5objtwxyjp4
|
pinia: 2.0.16_j6bzmzd4ujpabbp5objtwxyjp4
|
||||||
qs: 6.11.0
|
qs: 6.11.0
|
||||||
uuid: 8.3.2
|
uuid: 8.3.2
|
||||||
|
@ -95,7 +97,7 @@ importers:
|
||||||
vue-grid-layout: 3.0.0-beta1
|
vue-grid-layout: 3.0.0-beta1
|
||||||
vue-router: 4.1.2_vue@3.2.37
|
vue-router: 4.1.2_vue@3.2.37
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@changesets/cli': 2.23.1
|
'@changesets/cli': 2.23.2
|
||||||
'@rushstack/eslint-patch': 1.1.4
|
'@rushstack/eslint-patch': 1.1.4
|
||||||
'@tailwindcss/aspect-ratio': 0.4.0_tailwindcss@3.1.6
|
'@tailwindcss/aspect-ratio': 0.4.0_tailwindcss@3.1.6
|
||||||
'@types/jsdom': 16.2.14
|
'@types/jsdom': 16.2.14
|
||||||
|
@ -143,26 +145,26 @@ importers:
|
||||||
'@rollup/plugin-typescript': ^8.3.3
|
'@rollup/plugin-typescript': ^8.3.3
|
||||||
histoire: ^0.7.9
|
histoire: ^0.7.9
|
||||||
unplugin-icons: ^0.14.7
|
unplugin-icons: ^0.14.7
|
||||||
vite-plugin-dts: ^1.2.1
|
vite-plugin-dts: ^1.3.0
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@iconify-json/ri': 1.1.3
|
'@iconify-json/ri': 1.1.3
|
||||||
'@rollup/plugin-typescript': 8.3.3
|
'@rollup/plugin-typescript': 8.3.3
|
||||||
histoire: 0.7.9
|
histoire: 0.7.9
|
||||||
unplugin-icons: 0.14.7
|
unplugin-icons: 0.14.7
|
||||||
vite-plugin-dts: 1.2.1
|
vite-plugin-dts: 1.3.0
|
||||||
|
|
||||||
packages/shared:
|
packages/shared:
|
||||||
specifiers:
|
specifiers:
|
||||||
'@halo-dev/api-client': ^0.0.0
|
'@halo-dev/api-client': ^0.0.2
|
||||||
'@halo-dev/components': workspace:*
|
'@halo-dev/components': workspace:*
|
||||||
axios: ^0.27.2
|
axios: ^0.27.2
|
||||||
vite-plugin-dts: ^1.2.1
|
vite-plugin-dts: ^1.3.0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@halo-dev/api-client': 0.0.0
|
'@halo-dev/api-client': 0.0.2
|
||||||
'@halo-dev/components': link:../components
|
'@halo-dev/components': link:../components
|
||||||
axios: 0.27.2
|
axios: 0.27.2
|
||||||
devDependencies:
|
devDependencies:
|
||||||
vite-plugin-dts: 1.2.1
|
vite-plugin-dts: 1.3.0
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
|
@ -1454,8 +1456,8 @@ packages:
|
||||||
'@changesets/types': 5.0.0
|
'@changesets/types': 5.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@changesets/cli/2.23.1:
|
/@changesets/cli/2.23.2:
|
||||||
resolution: {integrity: sha512-yXQ29Iw/26yq1oJpOCa7BJDeUvuurZmREmCX9p9m5RxlKNDnROJBylQDCVfqQdZbeV2jfvd3XRKvci80SvGssg==}
|
resolution: {integrity: sha512-o7CWC+mcwOmA3yK5axqHOSYPYEjX/x+nq/s9aX78AyzH1SQZa6L5HX4P9uUXibyjcKynklkmusxv8vN8+hJggA==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.17.9
|
'@babel/runtime': 7.17.9
|
||||||
|
@ -1787,8 +1789,8 @@ packages:
|
||||||
- debug
|
- debug
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@halo-dev/api-client/0.0.0:
|
/@halo-dev/api-client/0.0.2:
|
||||||
resolution: {integrity: sha512-DC+0MsnX3e5IkqFFya3gz8JK893hGH+9ohKzLp1b7QqYj1Hvxxc1Nbr77IxvVbktZ14LUZTeHOdWHdqFAFQdvw==}
|
resolution: {integrity: sha512-7amtdteNPCZ9ObM969HfknIqd+eXK8gjJ0cKWc7F7TET6puerlPxmmPC0SSdUEpnTf8zK1XUJg+Y06joxZboHA==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@halo-dev/logger/1.1.0:
|
/@halo-dev/logger/1.1.0:
|
||||||
|
@ -2876,11 +2878,11 @@ packages:
|
||||||
'@types/node': 17.0.45
|
'@types/node': 17.0.45
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@vueuse/components/8.9.2_vue@3.2.37:
|
/@vueuse/components/8.9.3_vue@3.2.37:
|
||||||
resolution: {integrity: sha512-7K39dgpSdMJgotCGCaa3W7q/9AEZ2jitG+mBWH0TK+HSqLeYd5syHQKKK61raWP/qImu/mrwcsqeKtbFunU1FA==}
|
resolution: {integrity: sha512-7A97cUdJxwAESo1dJvIzxGW7Z8n5LGrLPOrQ9qgNGUKZlwVgBHJNiQ5KMddDDoqSwTVrLGspc1p8q8/+tYpHKA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vueuse/core': 8.9.2_vue@3.2.37
|
'@vueuse/core': 8.9.3_vue@3.2.37
|
||||||
'@vueuse/shared': 8.9.2_vue@3.2.37
|
'@vueuse/shared': 8.9.3_vue@3.2.37
|
||||||
vue-demi: 0.12.1_vue@3.2.37
|
vue-demi: 0.12.1_vue@3.2.37
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@vue/composition-api'
|
- '@vue/composition-api'
|
||||||
|
@ -2903,9 +2905,33 @@ packages:
|
||||||
'@vueuse/shared': 8.9.2_vue@3.2.37
|
'@vueuse/shared': 8.9.2_vue@3.2.37
|
||||||
vue: 3.2.37
|
vue: 3.2.37
|
||||||
vue-demi: 0.12.1_vue@3.2.37
|
vue-demi: 0.12.1_vue@3.2.37
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@vueuse/core/8.9.3_vue@3.2.37:
|
||||||
|
resolution: {integrity: sha512-q2pr3N7FPG7IBBhEXTYOJU+38VwKMLP5IfD33byzBV4Th7f1JHT4qPKvJrvr17knAefPRzNqgt9et+xFqaRlPQ==}
|
||||||
|
peerDependencies:
|
||||||
|
'@vue/composition-api': ^1.1.0
|
||||||
|
vue: ^2.6.0 || ^3.2.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@vue/composition-api':
|
||||||
|
optional: true
|
||||||
|
vue:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@types/web-bluetooth': 0.0.14
|
||||||
|
'@vueuse/metadata': 8.9.3
|
||||||
|
'@vueuse/shared': 8.9.3_vue@3.2.37
|
||||||
|
vue: 3.2.37
|
||||||
|
vue-demi: 0.12.1_vue@3.2.37
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@vueuse/metadata/8.9.2:
|
/@vueuse/metadata/8.9.2:
|
||||||
resolution: {integrity: sha512-g2s2BeyeEtJElmMFfFPnM+BTvnt0omniyvz8U18/zXDpQIMGozlNQgHoFeratyMfgVBhH/u2VKzmchChtDsgPQ==}
|
resolution: {integrity: sha512-g2s2BeyeEtJElmMFfFPnM+BTvnt0omniyvz8U18/zXDpQIMGozlNQgHoFeratyMfgVBhH/u2VKzmchChtDsgPQ==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@vueuse/metadata/8.9.3:
|
||||||
|
resolution: {integrity: sha512-57gZZKtWAmcJaUBmciCohvmumVLz4+FnoVnWj7U5BWs5PC2/7gU9Z0/i1i9leDNeboAauFzAq7z1GjS8eYnT+w==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@vueuse/shared/8.9.2_vue@3.2.37:
|
/@vueuse/shared/8.9.2_vue@3.2.37:
|
||||||
resolution: {integrity: sha512-s4Nk82oheL5z1GywyGnqjob0MzbAt88olMZa0vgt/p3gcMsT8Ff7+SqmNgEFC6AAs6xiuhOAZpnew9Zs3d90yQ==}
|
resolution: {integrity: sha512-s4Nk82oheL5z1GywyGnqjob0MzbAt88olMZa0vgt/p3gcMsT8Ff7+SqmNgEFC6AAs6xiuhOAZpnew9Zs3d90yQ==}
|
||||||
|
@ -2920,6 +2946,22 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
vue: 3.2.37
|
vue: 3.2.37
|
||||||
vue-demi: 0.12.1_vue@3.2.37
|
vue-demi: 0.12.1_vue@3.2.37
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@vueuse/shared/8.9.3_vue@3.2.37:
|
||||||
|
resolution: {integrity: sha512-foorYQAU3CGknAO1w9No/rpGBJmb7L74MPltnZAYxeBRfhsajjJYYgja+D5IT2vT+/a0NciISaVp3fDwMN1ocA==}
|
||||||
|
peerDependencies:
|
||||||
|
'@vue/composition-api': ^1.1.0
|
||||||
|
vue: ^2.6.0 || ^3.2.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@vue/composition-api':
|
||||||
|
optional: true
|
||||||
|
vue:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
vue: 3.2.37
|
||||||
|
vue-demi: 0.12.1_vue@3.2.37
|
||||||
|
dev: false
|
||||||
|
|
||||||
/abab/2.0.5:
|
/abab/2.0.5:
|
||||||
resolution: {integrity: sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==}
|
resolution: {integrity: sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==}
|
||||||
|
@ -3731,7 +3773,7 @@ packages:
|
||||||
cli-table3: 0.6.1
|
cli-table3: 0.6.1
|
||||||
commander: 5.1.0
|
commander: 5.1.0
|
||||||
common-tags: 1.8.2
|
common-tags: 1.8.2
|
||||||
dayjs: 1.10.8
|
dayjs: 1.11.3
|
||||||
debug: 4.3.4_supports-color@8.1.1
|
debug: 4.3.4_supports-color@8.1.1
|
||||||
enquirer: 2.3.6
|
enquirer: 2.3.6
|
||||||
eventemitter2: 6.4.5
|
eventemitter2: 6.4.5
|
||||||
|
@ -3775,8 +3817,8 @@ packages:
|
||||||
whatwg-url: 10.0.0
|
whatwg-url: 10.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/dayjs/1.10.8:
|
/dayjs/1.11.3:
|
||||||
resolution: {integrity: sha512-wbNwDfBHHur9UOzNUjeKUOJ0fCb0a52Wx0xInmQ7Y8FstyajiV1NmK1e00cxsr9YrE9r7yAChE0VvpuY5Rnlow==}
|
resolution: {integrity: sha512-xxwlswWOlGhzgQ4TKzASQkUhqERI3egRNqgV4ScR8wlANA/A9tZ7miXa44vTTKEq5l7vWoL5G57bG3zA+Kow0A==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/debug/2.6.9:
|
/debug/2.6.9:
|
||||||
|
@ -5777,7 +5819,6 @@ packages:
|
||||||
|
|
||||||
/lodash.isequal/4.5.0:
|
/lodash.isequal/4.5.0:
|
||||||
resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==}
|
resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/lodash.merge/4.6.2:
|
/lodash.merge/4.6.2:
|
||||||
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
||||||
|
@ -6067,7 +6108,7 @@ packages:
|
||||||
resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==}
|
resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
hosted-git-info: 2.8.9
|
hosted-git-info: 2.8.9
|
||||||
resolve: 1.22.0
|
resolve: 1.22.1
|
||||||
semver: 5.7.1
|
semver: 5.7.1
|
||||||
validate-npm-package-license: 3.0.4
|
validate-npm-package-license: 3.0.4
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -7755,8 +7796,8 @@ packages:
|
||||||
- stylus
|
- stylus
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vite-plugin-dts/1.2.1:
|
/vite-plugin-dts/1.3.0:
|
||||||
resolution: {integrity: sha512-V59rsKQnPI6FTGybh/ED4+dyK3UeSkvC1CJzpuDNoXb7mKNUcWmg66EM0N5Ijoc8xDAfZIXYxQjg675YHIDvFw==}
|
resolution: {integrity: sha512-YxDNqOE2wp713SyZ6AMmSu/sNfmiiy7GtlFXCMvlpD4nMaIbpqltidbve7fNlc3+gxlV+e156As/TwBtBp3g4Q==}
|
||||||
engines: {node: '>=12.0.0'}
|
engines: {node: '>=12.0.0'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
vite: '>=2.4.4'
|
vite: '>=2.4.4'
|
||||||
|
|
26
src/main.ts
26
src/main.ts
|
@ -1,3 +1,4 @@
|
||||||
|
import type { DirectiveBinding } from "vue";
|
||||||
import { createApp } from "vue";
|
import { createApp } from "vue";
|
||||||
import { createPinia } from "pinia";
|
import { createPinia } from "pinia";
|
||||||
import App from "./App.vue";
|
import App from "./App.vue";
|
||||||
|
@ -18,6 +19,8 @@ import { coreModules } from "./modules";
|
||||||
import { useScriptTag } from "@vueuse/core";
|
import { useScriptTag } from "@vueuse/core";
|
||||||
import { usePluginStore } from "@/stores/plugin";
|
import { usePluginStore } from "@/stores/plugin";
|
||||||
import type { User } from "@halo-dev/api-client";
|
import type { User } from "@halo-dev/api-client";
|
||||||
|
import { hasPermission } from "@/utils/permission";
|
||||||
|
import { useRoleStore } from "@/stores/role";
|
||||||
|
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
|
|
||||||
|
@ -141,10 +144,29 @@ async function loadCurrentUser() {
|
||||||
const { data: user } = await apiClient.user.getCurrentUserDetail();
|
const { data: user } = await apiClient.user.getCurrentUserDetail();
|
||||||
app.provide<User>("currentUser", user);
|
app.provide<User>("currentUser", user);
|
||||||
|
|
||||||
const { data: permissions } = await apiClient.user.getPermissions(
|
const { data: currentPermissions } = await apiClient.user.getPermissions(
|
||||||
user.metadata.name
|
user.metadata.name
|
||||||
);
|
);
|
||||||
app.provide("permissions", permissions);
|
const roleStore = useRoleStore();
|
||||||
|
roleStore.$patch({
|
||||||
|
permissions: currentPermissions,
|
||||||
|
});
|
||||||
|
app.directive(
|
||||||
|
"permission",
|
||||||
|
(el: HTMLElement, binding: DirectiveBinding<string[]>) => {
|
||||||
|
const uiPermissions = Array.from<string>(
|
||||||
|
currentPermissions.uiPermissions
|
||||||
|
);
|
||||||
|
const { value } = binding;
|
||||||
|
const { any, enable } = binding.modifiers;
|
||||||
|
|
||||||
|
if (hasPermission(uiPermissions, value, any)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
enable ? (el.style.backgroundColor = "red") : el.remove();
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
(async function () {
|
(async function () {
|
||||||
|
|
|
@ -99,6 +99,7 @@ onMounted(() => {
|
||||||
<li
|
<li
|
||||||
v-for="(page, index) in pagesPublicState.functionalPages"
|
v-for="(page, index) in pagesPublicState.functionalPages"
|
||||||
:key="index"
|
:key="index"
|
||||||
|
v-permission="page.permissions"
|
||||||
@click="$router.push({ path: page.path })"
|
@click="$router.push({ path: page.path })"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { useRoleStore } from "@/stores/role";
|
||||||
|
import { hasPermission } from "@/utils/permission";
|
||||||
|
import type { Router } from "vue-router";
|
||||||
|
|
||||||
|
export function setupPermissionGuard(router: Router) {
|
||||||
|
router.beforeEach((to, from, next) => {
|
||||||
|
const roleStore = useRoleStore();
|
||||||
|
const { uiPermissions } = roleStore.permissions;
|
||||||
|
const { meta } = to;
|
||||||
|
if (meta && meta.permissions) {
|
||||||
|
const flag = hasPermission(
|
||||||
|
Array.from(uiPermissions),
|
||||||
|
meta.permissions as string[],
|
||||||
|
false
|
||||||
|
);
|
||||||
|
if (!flag) {
|
||||||
|
next({ name: "Forbidden" });
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
import { createRouter, createWebHashHistory } from "vue-router";
|
import { createRouter, createWebHashHistory } from "vue-router";
|
||||||
import routesConfig from "@/router/routes.config";
|
import routesConfig from "@/router/routes.config";
|
||||||
|
import { setupPermissionGuard } from "./guards/permission";
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHashHistory(import.meta.env.BASE_URL),
|
history: createWebHashHistory(import.meta.env.BASE_URL),
|
||||||
|
@ -7,4 +8,6 @@ const router = createRouter({
|
||||||
scrollBehavior: () => ({ left: 0, top: 0 }),
|
scrollBehavior: () => ({ left: 0, top: 0 }),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
setupPermissionGuard(router);
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import type { RouteRecordRaw } from "vue-router";
|
import type { RouteRecordRaw } from "vue-router";
|
||||||
import NotFound from "@/views/exceptions/NotFound.vue";
|
import NotFound from "@/views/exceptions/NotFound.vue";
|
||||||
|
import Forbidden from "@/views/exceptions/Forbidden.vue";
|
||||||
import { BasicLayout } from "@halo-dev/admin-shared";
|
import { BasicLayout } from "@halo-dev/admin-shared";
|
||||||
|
|
||||||
export const routes: Array<RouteRecordRaw> = [
|
export const routes: Array<RouteRecordRaw> = [
|
||||||
|
@ -8,6 +9,17 @@ export const routes: Array<RouteRecordRaw> = [
|
||||||
component: BasicLayout,
|
component: BasicLayout,
|
||||||
children: [{ path: "", name: "NotFound", component: NotFound }],
|
children: [{ path: "", name: "NotFound", component: NotFound }],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/403",
|
||||||
|
component: BasicLayout,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: "",
|
||||||
|
name: "Forbidden",
|
||||||
|
component: Forbidden,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export default routes;
|
export default routes;
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { defineStore } from "pinia";
|
||||||
|
import type { Role, UserPermission } from "@halo-dev/api-client";
|
||||||
|
|
||||||
|
interface RoleStoreState {
|
||||||
|
roles: Role[]; // all roles
|
||||||
|
permissions: UserPermission; // current user's permissions
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useRoleStore = defineStore({
|
||||||
|
id: "role",
|
||||||
|
state: (): RoleStoreState => ({
|
||||||
|
roles: [],
|
||||||
|
permissions: {
|
||||||
|
roles: new Set<Role>([]),
|
||||||
|
uiPermissions: new Set<string>([]),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { hasPermission } from "../permission";
|
||||||
|
|
||||||
|
describe("hasPermission", () => {
|
||||||
|
it("should return true if user has permission", () => {
|
||||||
|
const uiPermissions = ["system:post:manage", "system:post:view"];
|
||||||
|
expect(hasPermission(uiPermissions, ["*"], false)).toBe(true);
|
||||||
|
expect(hasPermission(uiPermissions, ["*"], true)).toBe(true);
|
||||||
|
expect(hasPermission(uiPermissions, ["system:post:manage"], false)).toBe(
|
||||||
|
false
|
||||||
|
);
|
||||||
|
expect(hasPermission(uiPermissions, ["system:post:view"], false)).toBe(
|
||||||
|
false
|
||||||
|
);
|
||||||
|
expect(hasPermission(uiPermissions, ["system:post:view"], true)).toBe(true);
|
||||||
|
expect(
|
||||||
|
hasPermission(
|
||||||
|
uiPermissions,
|
||||||
|
["system:post:manage", "system:post:view"],
|
||||||
|
true
|
||||||
|
)
|
||||||
|
).toBe(true);
|
||||||
|
expect(
|
||||||
|
hasPermission(
|
||||||
|
uiPermissions,
|
||||||
|
["system:post:manage", "system:post:view"],
|
||||||
|
false
|
||||||
|
)
|
||||||
|
).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,26 @@
|
||||||
|
import isEqual from "lodash.isEqual";
|
||||||
|
|
||||||
|
export function hasPermission(
|
||||||
|
uiPermissions: Array<string>,
|
||||||
|
targetPermissions: Array<string>,
|
||||||
|
any: boolean
|
||||||
|
): boolean {
|
||||||
|
if (!targetPermissions || !targetPermissions.length) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// super admin has all permissions
|
||||||
|
if (targetPermissions.includes("*")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const intersection = uiPermissions.filter((p) =>
|
||||||
|
targetPermissions.includes(p)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (any && intersection.length) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !!(!any && isEqual(uiPermissions, targetPermissions));
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
<template>403</template>
|
Loading…
Reference in New Issue