Skip to content

Commit cb97264

Browse files
committed
Cookie
1 parent 50d4664 commit cb97264

File tree

11 files changed

+199
-235
lines changed

11 files changed

+199
-235
lines changed

.github/dependabot.yml.disable

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# To get started with Dependabot version updates, you'll need to specify which
2+
# package ecosystems to update and where the package manifests are located.
3+
# Please see the documentation for all configuration options:
4+
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
5+
6+
version: 2
7+
updates:
8+
# Enable version updates for npm
9+
- package-ecosystem: "npm"
10+
# Look for `package.json` and `lock` files in the `root` directory
11+
directory: "/"
12+
# Check the npm registry for updates every day (weekdays)
13+
schedule:
14+
interval: "daily"
15+
16+
# Enable version updates for Docker
17+
- package-ecosystem: "docker"
18+
# Look for a `Dockerfile` in the `root` directory
19+
directory: "/"
20+
# Check for updates once a week
21+
schedule:
22+
interval: "weekly"

README.md

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,53 @@
11
[![language.badge]][language.url] [![release.badge]][release.url] [![docker.badge]][docker.url]
22

3-
# Web GUI for App Mesh
3+
# App Mesh Web GUI
44

5-
Web GUI for [App Mesh](https://github.com/laoshanxi/app-mesh)
5+
This is the Web GUI implementation for [App Mesh](https://github.com/laoshanxi/app-mesh).
66

77
<div align=center>
8-
<img src="https://raw.githubusercontent.com/laoshanxi/app-mesh-ui/main/doc/diagram.png" width=434 height=334 alt="Architecture"/>
8+
<img src="https://raw.githubusercontent.com/laoshanxi/app-mesh-ui/main/doc/diagram.png" width=434 height=334 alt="System Architecture"/>
99
</div>
1010

11-
## Development
11+
## Features
1212

13-
## Build Docker image
13+
- Modern web interface built with Vue.js
14+
- Visual management for all App Mesh core functionalities
15+
- Intuitive application monitoring and management interface
16+
- Quick deployment via Docker container
1417

15-
```bash
16-
docker build -t appmesh-ui .
17-
```
18+
## Development Guide
1819

19-
## Develop environment
20+
### Environment Setup
2021

2122
```bash
22-
# preview the release environment effect
23+
# Install dependencies
24+
npm install
25+
26+
# Start development server
27+
npm run dev
28+
29+
# Preview production build
2330
npm run preview
2431

25-
# preview the release environment effect + static resource analysis
32+
# Preview with bundle analyzer report
2633
npm run preview -- --report
2734

28-
# code format check
35+
# Lint code
2936
npm run lint
3037

31-
# code format check and auto fix
38+
# Lint and auto-fix
3239
npm run lint -- --fix
40+
```
3341

34-
# run development
35-
npm run dev
42+
### Build Docker Image
43+
44+
```bash
45+
docker build -t appmesh-ui .
3646
```
3747

38-
## Deploy
48+
## Deployment Guide
3949

40-
- Use docker to start a container connected to local App Mesh
50+
### Method 1: Connect to Local App Mesh
4151

4252
```shell
4353
docker run \
@@ -52,14 +62,30 @@ docker run \
5262
laoshanxi/appmesh-ui
5363
```
5464

55-
The following environment variables can be used to customize the deployment:
65+
### Method 2: Host Network Mode
66+
67+
When App Mesh runs on the host OS, use this recommended command:
68+
69+
```shell
70+
docker run \
71+
--name=appmesh-ui \
72+
-d \
73+
--restart=always \
74+
--net=host \
75+
-e VUE_APP_TITLE=`hostname` \
76+
-v /opt/appmesh/ssl/server.pem:/etc/nginx/conf.d/server.crt:ro \
77+
-v /opt/appmesh/ssl/server-key.pem:/etc/nginx/conf.d/server.key:ro \
78+
laoshanxi/appmesh-ui
79+
```
80+
81+
### Environment Variables
5682

57-
| Variable | Description | Default Value |
58-
| ------------------ | ---------------------------- | ------------------------ |
59-
| `APP_MESH_API_URL` | The App Mesh API service URL | `https://127.0.0.1:6060` |
60-
| `VUE_APP_TITLE` | The Web Site Title | `App Mesh` |
83+
| Variable Name | Description | Default Value |
84+
| ------------------ | ------------------------ | ------------------------ |
85+
| `APP_MESH_API_URL` | App Mesh API service URL | `https://127.0.0.1:6060` |
86+
| `VUE_APP_TITLE` | Web site title | `App Mesh` |
6187

62-
## Demo
88+
## Interface Preview
6389

6490
<img src="https://github.com/laoshanxi/picture/blob/master/appmesh/1.png?raw=true" />
6591
<img src="https://github.com/laoshanxi/picture/blob/master/appmesh/2.png?raw=true" />
@@ -78,7 +104,7 @@ The following environment variables can be used to customize the deployment:
78104

79105
## License
80106

81-
[MIT](https://github.com/laoshanxi/app-mesh-ui/LICENSE) license.
107+
This project is licensed under the [MIT](https://github.com/laoshanxi/app-mesh-ui/LICENSE) License.
82108

83109
[language.url]: https://nodejs.org/
84110
[language.badge]: https://img.shields.io/badge/language-nodes.vue-blue.svg

nginx/server.crt

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,14 @@
11
-----BEGIN CERTIFICATE-----
2-
MIIDpjCCAo6gAwIBAgIJALuFAyY7SRH+MA0GCSqGSIb3DQEBCwUAMH8xCzAJBgNV
3-
BAYTAkNOMQswCQYDVQQIDAJTWDENMAsGA1UEBwwEWGlBbjELMAkGA1UECgwCSVQx
4-
FjAUBgNVBAsMDUlUIERlcGFydG1lbnQxGzAZBgkqhkiG9w0BCQEWDGx2am1AMTYz
5-
LmNvbTESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTE5MDEzMTExMTgyOVoXDTIwMDEz
6-
MTExMTgyOVowfzELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAlNYMQ0wCwYDVQQHDARY
7-
aUFuMQswCQYDVQQKDAJJVDEWMBQGA1UECwwNSVQgRGVwYXJ0bWVudDEbMBkGCSqG
8-
SIb3DQEJARYMbHZqbUAxNjMuY29tMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0G
9-
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCezITTyxxJIV/uTpC7wX2c+SDZnZrK
10-
j5iA3NYtOMiUjX2GNL5yJC6YkYO1fkSZ9anzU43lbXEJV7Zhbz61B/rdHSfScgzf
11-
c2bJ4JocABKu0MJ7UorrDnpS/tYzq3vrIpR9c/pHHi4J4rQSmxqQFekglNocJWQo
12-
szwqVu80uVOamDlDeNnO6hJyOstTw6lud7LRqMBODP+LjKAK9R86vvaG1u+iWmg5
13-
T15tmJcGcthnVk8qRY5qXCBOUJNqL1L285QyAPFrfTsZfEWjw5YDRbDnQbdSvg4v
14-
lelPOkfns+ImQUV+Tz9hefkt5Xsgomw3fwhZUFuT+gXUe7oEeVC1CMfDAgMBAAGj
15-
JTAjMCEGA1UdEQQaMBiCCyoubG9jYWxob3N0gglsb2NhbGhvc3QwDQYJKoZIhvcN
16-
AQELBQADggEBAEpvkBgYSsoWi5eJJxxfFn++p543dfzL9L/CofJp3QhDQgovE2bY
17-
ZnuSGbW+wjCjnYZu938qEizYOK4cx9gIMJ6biFA+fb/NIVS+UeJ08TP179sYl14R
18-
NlSnAhQJafCzT6RzW6ULmofPeX9hWkfm20EAJyiHczRuoaTruPNcvD6z0vq84nQU
19-
k6F3Pw+p97hvupuxOfunjEbte1+GETAIQWDdNqDsb/MppJpoRDuCWnDDolNvaeqg
20-
amOovSOoZbeefkXgdkUz/VZpaoeiIhq249mCFwlmbeO3gKYFIniX1AoD21TaCeFN
21-
cbT+VcUgDLYM7XJwO/ROz2WwqrE7WYCMcn4=
2+
MIICMzCCAdmgAwIBAgIUdBHCDdAtPpPjBDuythrDZII/56cwCgYIKoZIzj0EAwIw
3+
ZzELMAkGA1UEBhMCQ04xEDAOBgNVBAgTB0JlaWppbmcxEDAOBgNVBAcTB1NoYWFu
4+
eGkxETAPBgNVBAoTCERldkdyb3VwMQ8wDQYDVQQLEwZTeXN0ZW0xEDAOBgNVBAMT
5+
B0FwcE1lc2gwIBcNMjUwNDE1MDgzODAwWhgPMjA3NTA0MDMwODM4MDBaMBQxEjAQ
6+
BgNVBAMTCWxhb3NoYW54aTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABAMrVeuE
7+
/bCWLgu7bOryRxMx4U7ARv/OJAr2OuWBIekphMvBl/kcIlegsqkm6G+JmFxl+4pH
8+
PUf+mWu+lE27TdajgbMwgbAwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsG
9+
AQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQlPjaGodGo
10+
LhqLaLYP3+BUSXN1nDAfBgNVHSMEGDAWgBTx9N9xNhgRWS4u+AoFfs6p3mgFVDAx
11+
BgNVHREEKjAogglsb2NhbGhvc3SCCWxhb3NoYW54aYcEwKgyPIcErBEAAYcEfwAA
12+
ATAKBggqhkjOPQQDAgNIADBFAiEAhz1xBoQOIXCHyhlEkjticoHckHIdSEcw636Y
13+
me2ZbtcCIH6GwbVqoqAAKEuNMXRAhney1rm8G1EftePQ6hoI7ERd
2214
-----END CERTIFICATE-----

nginx/server.key

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,5 @@
1-
-----BEGIN PRIVATE KEY-----
2-
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCezITTyxxJIV/u
3-
TpC7wX2c+SDZnZrKj5iA3NYtOMiUjX2GNL5yJC6YkYO1fkSZ9anzU43lbXEJV7Zh
4-
bz61B/rdHSfScgzfc2bJ4JocABKu0MJ7UorrDnpS/tYzq3vrIpR9c/pHHi4J4rQS
5-
mxqQFekglNocJWQoszwqVu80uVOamDlDeNnO6hJyOstTw6lud7LRqMBODP+LjKAK
6-
9R86vvaG1u+iWmg5T15tmJcGcthnVk8qRY5qXCBOUJNqL1L285QyAPFrfTsZfEWj
7-
w5YDRbDnQbdSvg4vlelPOkfns+ImQUV+Tz9hefkt5Xsgomw3fwhZUFuT+gXUe7oE
8-
eVC1CMfDAgMBAAECggEARighPtjrRDvkgAph0zGm52UBaGNC8d8DB1uJnC0MIOVp
9-
4ZMH2LG3jFwtjk+cy1BHp2Lwu73gRLplryJQ1/YQlQO+hjExEr+PV/1M2LYHiwhc
10-
A9Px3+tji6tewzEt7DI43DwTBLyGpoNr/xRbZfDoMCbTPcAfQgP9vs7tm6ONFi0c
11-
ZvkRHjeD5wCDaLsUtUEN5ZdSwlsNHzLOvzxc6g5Yty/iXYyD5cM5VdZv4c5xDyRD
12-
EeRT4OtoqB/HYN1oaWXlbexOZFKtwFWQpiLc0+wQB1vpIH1L2WxtwVHfFSNczkkg
13-
B5vGr48E1Eo9qgCBZ6XSEhG6BELNsLzfIVlF6lF5kQKBgQDKcnB4KE7iHmSqmrQG
14-
Vj4eQpjnjfljAJDFOcoqn8OtMF0UgjSJSLzRYbwUR6FOAwm8qfgvwGbExGE3U5H1
15-
864LIiDiIfiDZhf/C0T6OI53st3fwNiWopI4KhQnYZSVkVfKiEk3Vf4+mSM9zIbA
16-
FeO4pTk9Irgj2d48VoHzXku8LQKBgQDIzkLb6z8zGWPETKQTNArwgYF52OfQlRln
17-
ZfZYuV4ukcxDg7/ulkEcKjm4sdqWNTb2JQ/nqZfnzmaMjWdUbeYS9RZlwKiUGHCO
18-
kaxUL4CQpz45vl2srrvet403d8Jx7of9a93Dnd4dZqq0H03zdssqJTGpIcykte24
19-
i4iRa2XZrwKBgQC4Ct96LNLBt/W2Lxv4ItEn+008PJJ6UVpLIiVLKKDgQnZsHY6b
20-
O5gEFYDBQvk+jX59mFt7NcN3oDvs6zlnShdwIZ+ZVF6zPc4U227ityW1ZdNVBeEg
21-
2DxreL2Hq6tDabVQ9yLwfmm7CMbD+LqLx5qVEwd9L6INXZQucEqFL7VUJQKBgQCs
22-
pPnCzr1ll5y5NxOSFxqYsR+6vQyBvs86oOVuXuFktKGkInAwFysfpgY+j1tZ7aK1
23-
eiP0j1E1UbXFfgWrB1naTrHVBhFqUqDjUseREc49kCzlxJARWaHY2IMnf2XEQsrU
24-
zZq7Bs3jBVQazRdeDXKbZ6MMwSyLKIecNQtTy7yjrQKBgHl6igmhr89qCoMRGaNF
25-
09poE5tUqGZQeMYj8ZugL6+W2E6n2M9PtqR4ECnhK3h02Wzqw/+xmjCaN99xinv/
26-
wkou5OzQF1kKEz5rcCAdbcp9UEyJef2wt9m7/XKUR4ucAJVNupw8rgpCVI57MPrn
27-
Ft5gGkwe3gn2XQk9gxMnY24D
28-
-----END PRIVATE KEY-----
1+
-----BEGIN EC PRIVATE KEY-----
2+
MHcCAQEEIIiG2zZYtUxqPkUEC4wlH7QRA3PodIkOYKygTM/NFAP9oAoGCCqGSM49
3+
AwEHoUQDQgAEAytV64T9sJYuC7ts6vJHEzHhTsBG/84kCvY65YEh6SmEy8GX+Rwi
4+
V6CyqSbob4mYXGX7ikc9R/6Za76UTbtN1g==
5+
-----END EC PRIVATE KEY-----

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"@antv/data-set": "^0.11.8",
1919
"@antv/g2": "^4.2.10",
2020
"af-table-column": "^1.0.3",
21-
"appmesh": "^1.0.1",
21+
"appmesh": "^1.0.2",
2222
"axios": "^1.6.2",
2323
"element-ui": "^2.15.14",
2424
"js-base64": "^3.7.5",

src/layout/components/Navbar.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ export default {
129129
this.fullscreenLoading = true;
130130
131131
getClient().forwardingHost = this.forward;
132-
await getClient().authenticate(getClient().jwtToken);
132+
await getClient().authenticate();
133133
await this.$store.dispatch("settings/changeSetting", {
134134
key: "forwarding",
135135
value: this.forward

src/permission.js

Lines changed: 75 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,92 @@
1-
import router from './router'
2-
import store from './store'
3-
import { Message } from 'element-ui'
4-
import NProgress from 'nprogress' // progress bar
5-
import 'nprogress/nprogress.css' // progress bar style
6-
import { getToken } from '@/utils/auth' // get token from cookie
7-
import getPageTitle from '@/utils/get-page-title'
1+
import router from "./router";
2+
import store from "./store";
3+
import { Message } from "element-ui";
4+
import NProgress from "nprogress";
5+
import "nprogress/nprogress.css";
6+
import getPageTitle from "@/utils/get-page-title";
87

9-
NProgress.configure({ showSpinner: false }) // NProgress Configuration
8+
NProgress.configure({ showSpinner: false });
109

11-
const whiteList = ['/login'] // no redirect whitelist
10+
const whiteList = ["/login"];
11+
12+
// Helper function to check permissions
13+
const hasRequiredPermission = (userPermissions, requiredRoles) => {
14+
if (
15+
!requiredRoles ||
16+
!Array.isArray(requiredRoles) ||
17+
requiredRoles.length === 0
18+
)
19+
return true;
20+
if (!userPermissions || !Array.isArray(userPermissions)) return false;
21+
return requiredRoles.some((role) => userPermissions.includes(role));
22+
};
23+
24+
// Helper function to handle loading state
25+
const finishLoading = () => {
26+
NProgress.done();
27+
setTimeout(() => {
28+
store.dispatch("app/setLoading", false);
29+
}, 1000);
30+
};
1231

1332
router.beforeEach(async (to, from, next) => {
14-
// start progress bar
15-
NProgress.start()
33+
NProgress.start();
1634
store.dispatch("app/setLoading", true);
1735

18-
// set page title
19-
document.title = getPageTitle(to.meta.title)
36+
// Set page title
37+
document.title = getPageTitle(to.meta?.title);
2038

21-
// determine whether the user has logged in
22-
const hasToken = getToken()
39+
// Check whitelist paths
40+
if (whiteList.includes(to.path)) {
41+
next();
42+
finishLoading();
43+
return;
44+
}
2345

24-
if (hasToken) {
25-
if (to.path === '/login') {
26-
// if is logged in, redirect to the home page
27-
next({ path: '/' })
28-
NProgress.done()
29-
} else {
30-
// TODO: When the browser is closed and reopened, the user permission info will be lost.
31-
// If the user navigates directly to another page without going through the login page,
32-
// the permissions need to be re-validated.
33-
const hasGetUserInfo = store.getters.user
34-
if (hasGetUserInfo) {
35-
if (to.meta && to.meta.roles && to.meta.roles.length > 0) {
36-
let curPermissions = to.meta.roles;
37-
let permissions = hasGetUserInfo.permissions;
38-
let hasPermission = false;
39-
if (permissions) {
40-
for (let i = 0; i < curPermissions.length; i++) {
41-
if (permissions.indexOf(curPermissions[i]) >= 0) {
42-
hasPermission = true;
43-
break;
44-
}
45-
}
46-
}
46+
try {
47+
const userInfo = store.getters.user;
4748

48-
if (hasPermission) {
49-
next();
50-
} else {
51-
next('/401');
52-
NProgress.done();
53-
setTimeout(() => {
54-
store.dispatch("app/setLoading", false);
55-
}, 1000);
56-
}
57-
} else {
58-
next();
59-
}
60-
} else {
61-
try {
62-
// get user info
63-
await store.dispatch('user/getInfo')
49+
// Redirect to home if logged in user tries to access login page
50+
if (to.path === "/login" && userInfo && userInfo.name) {
51+
next({ path: "/" });
52+
finishLoading();
53+
return;
54+
}
6455

65-
next()
66-
} catch (error) {
67-
// remove token and go to login page to re-login
68-
await store.dispatch('user/resetToken')
69-
Message.error(error || 'Has Error')
70-
next(`/login?redirect=${to.path}`)
71-
NProgress.done()
72-
}
56+
// Handle not logged in or session expired
57+
if (!userInfo || !userInfo.name) {
58+
try {
59+
await store.dispatch("user/getInfo");
60+
// Continue to requested page after successful login
61+
next({ ...to, replace: true });
62+
} catch (error) {
63+
// If getInfo fails, redirect to login
64+
next(`/login?redirect=${encodeURIComponent(to.fullPath)}`);
7365
}
66+
finishLoading();
67+
return;
7468
}
75-
} else {
76-
/* has no token*/
7769

78-
if (whiteList.indexOf(to.path) !== -1) {
79-
// in the free login whitelist, go directly
80-
next()
81-
} else {
82-
// other pages that do not have permission to access are redirected to the login page.
83-
next(`/login?redirect=${to.path}`)
84-
NProgress.done()
70+
// Check page permissions
71+
if (
72+
to.meta?.roles &&
73+
!hasRequiredPermission(userInfo.permissions, to.meta.roles)
74+
) {
75+
Message.error("You don't have permission to access this page");
76+
next("/401");
77+
finishLoading();
78+
return;
8579
}
80+
81+
next();
82+
} catch (error) {
83+
console.error("Route permission check failed:", error);
84+
Message.error(error?.message || "Please login first");
85+
next(`/login?redirect=${encodeURIComponent(to.fullPath)}`);
86+
finishLoading();
8687
}
87-
})
88+
});
8889

8990
router.afterEach(() => {
90-
// finish progress bar
91-
NProgress.done();
92-
setTimeout(() => {
93-
store.dispatch("app/setLoading", false);
94-
}, 1000);
95-
})
91+
finishLoading();
92+
});

0 commit comments

Comments
 (0)