diff --git a/src/modules/html/studio-app-list/index.ts b/src/modules/html/studio-app-list/index.ts
new file mode 100644
index 0000000..364ea31
--- /dev/null
+++ b/src/modules/html/studio-app-list/index.ts
@@ -0,0 +1,344 @@
+type StudioOpts = { user: string, userAppKey?: string; appIds: string[] }
+export const createStudioAppListHtml = (opts: StudioOpts) => {
+ const user = opts.user!;
+ const userAppKey = opts?.userAppKey;
+ let showUserAppKey = userAppKey;
+ if (showUserAppKey && showUserAppKey.startsWith(user + '-')) {
+ showUserAppKey = showUserAppKey.replace(user + '-', '');
+ }
+ const pathApps = opts?.appIds?.map(appId => {
+ const shortAppId = appId.replace(opts!.user + '-', '')
+ return {
+ appId,
+ shortAppId,
+ pathname: `/${user}/v1/${shortAppId}`
+ };
+ }) || []
+
+ // 应用列表内容
+ const appListContent = `
+
+
+
+
+ ${pathApps.length === 0 ? `
+
+ ` : ''}
+ `
+
+ return `
+
+
+
+
+
+ Studio - ${user} 的应用
+
+
+
+
+ ${showUserAppKey ? `
+
+
+
应用不存在
+
抱歉,您访问的应用 ${showUserAppKey || ''} 不存在。
+
请检查应用 Key 是否正确,或联系管理员。
+
← 返回应用列表
+
+ ` : ''}
+ ${appListContent}
+
+
+
+
+
+ `;
+};
diff --git a/src/modules/ws-proxy/manager.ts b/src/modules/ws-proxy/manager.ts
index 04514d8..2abec23 100644
--- a/src/modules/ws-proxy/manager.ts
+++ b/src/modules/ws-proxy/manager.ts
@@ -71,7 +71,10 @@ export class WsProxyManager {
}
this.wssMap.delete(id);
}
- getIds() {
+ getIds(beginWith?: string) {
+ if (beginWith) {
+ return Array.from(this.wssMap.keys()).filter(key => key.startsWith(beginWith));
+ }
return Array.from(this.wssMap.keys());
}
get(id: string) {
diff --git a/src/modules/ws-proxy/proxy.ts b/src/modules/ws-proxy/proxy.ts
index 1deda4d..6486118 100644
--- a/src/modules/ws-proxy/proxy.ts
+++ b/src/modules/ws-proxy/proxy.ts
@@ -4,6 +4,7 @@ import { wsProxyManager } from './index.ts';
import { App } from '@kevisual/router';
import { logger } from '../logger.ts';
import { getLoginUser } from '@/modules/auth.ts';
+import { createStudioAppListHtml } from '../html/studio-app-list/index.ts';
type ProxyOptions = {
createNotFoundPage: (msg?: string) => any;
@@ -13,13 +14,10 @@ export const UserV1Proxy = async (req: IncomingMessage, res: ServerResponse, opt
const _url = new URL(url || '', `http://localhost`);
const { pathname, searchParams } = _url;
let [user, app, userAppKey] = pathname.split('/').slice(1);
- if (!user || !app || !userAppKey) {
+ if (!user || !app) {
opts?.createNotFoundPage?.('应用未找到');
return false;
}
- if (!userAppKey.includes('-')) {
- userAppKey = user + '-' + userAppKey;
- }
const data = await App.handleRequest(req, res);
const loginUser = await getLoginUser(req);
@@ -27,7 +25,26 @@ export const UserV1Proxy = async (req: IncomingMessage, res: ServerResponse, opt
opts?.createNotFoundPage?.('没有登录');
return false;
}
+
const isAdmin = loginUser.tokenUser?.username === user
+
+ if (!userAppKey) {
+ if (isAdmin) {
+ // 获取所有的管理员的应用列表
+ const ids = wsProxyManager.getIds(user + '-');
+ const html = createStudioAppListHtml({ user, appIds: ids, userAppKey });
+ res.writeHead(200, { 'Content-Type': 'text/html' });
+ res.end(html);
+ return;
+ } else {
+ opts?.createNotFoundPage?.('没有访问应用权限');
+ return false;
+ }
+ }
+ if (!userAppKey.includes('-')) {
+ userAppKey = user + '-' + userAppKey;
+ }
+
// TODO: 如果不是管理员,是否需要添加其他人可以访问的逻辑?
if (!isAdmin) {
opts?.createNotFoundPage?.('没有访问应用权限');
@@ -38,10 +55,12 @@ export const UserV1Proxy = async (req: IncomingMessage, res: ServerResponse, opt
}
logger.debug('data', data);
const client = wsProxyManager.get(userAppKey);
- const ids = wsProxyManager.getIds();
+ const ids = wsProxyManager.getIds(user + '-');
if (!client) {
if (isAdmin) {
- opts?.createNotFoundPage?.(`未找到应用 [${userAppKey}], 当前应用列表: ${ids.join(',')}`);
+ const html = createStudioAppListHtml({ user, appIds: ids, userAppKey });
+ res.writeHead(200, { 'Content-Type': 'text/html' });
+ res.end(html);
} else {
opts?.createNotFoundPage?.('应用访问失败');
}