mirror of
https://github.com/sinanyuntu/trade-message-center.git
synced 2026-09-17 13:22:11 +08:00
fix(harness): add workspace authorization input
This commit is contained in:
@@ -13,6 +13,7 @@ import { hasExactKeys, isJsonRequest, isNonEmptyString, readBody } from "../requ
|
||||
import { writeAuthorization, writePlainResponse, writeRejection } from "../response.ts";
|
||||
|
||||
export const MIND_SESSION_AUTHORIZATION_PATH = "/internal/bright/onetalk/authorize-session";
|
||||
const MIND_WORKSPACE_HEADER = "sinan-pilot-workspace-id";
|
||||
|
||||
const readSessionRequest = (body: unknown): { channelAccountId: string } | null => {
|
||||
if (
|
||||
@@ -45,6 +46,7 @@ export const handleSessionAuthorization = async (
|
||||
authorization: MindMockAuthorization,
|
||||
channelAccountIds: readonly string[],
|
||||
cookie: string,
|
||||
workspaceAuthorization: string,
|
||||
result: MindMockSessionResult,
|
||||
): Promise<void> => {
|
||||
if (!isJsonRequest(request)) {
|
||||
@@ -68,6 +70,10 @@ export const handleSessionAuthorization = async (
|
||||
writeRejection(response, 401, "auth_required");
|
||||
return;
|
||||
}
|
||||
if (request.headers[MIND_WORKSPACE_HEADER] !== workspaceAuthorization) {
|
||||
writeRejection(response, 403, "scope_mismatch");
|
||||
return;
|
||||
}
|
||||
if (!channelAccountIds.includes(input.channelAccountId)) {
|
||||
writeRejection(response, 403, "scope_mismatch");
|
||||
return;
|
||||
|
||||
@@ -28,6 +28,7 @@ export type MindMockConfig = {
|
||||
host: string;
|
||||
port: number;
|
||||
cookie: string;
|
||||
workspaceAuthorization: string;
|
||||
authorization: MindMockAuthorization;
|
||||
channelAccountIds: readonly string[];
|
||||
bindingResult?: MindMockBindingResult;
|
||||
@@ -167,6 +168,11 @@ export const parseMindMockConfig = (
|
||||
"MIND_MOCK_PORT",
|
||||
),
|
||||
cookie: parseFixtureString(environment, "MIND_MOCK_COOKIE", DEFAULT_COOKIE),
|
||||
workspaceAuthorization: parseFixtureString(
|
||||
environment,
|
||||
"MIND_MOCK_WORKSPACE_AUTHORIZATION",
|
||||
authorization.mindScope.workspaceId,
|
||||
),
|
||||
authorization,
|
||||
channelAccountIds,
|
||||
bindingResult: parseResult(environment, "MIND_MOCK_BINDING_RESULT", BINDING_MOCK_RESULTS),
|
||||
|
||||
@@ -17,6 +17,7 @@ export const harnessEventsScript = String.raw` const writeCookie = ()
|
||||
fields.uploadFileButton.addEventListener('click', uploadFile);
|
||||
fields.copyUploadUrl.addEventListener('click', copyUploadUrl);
|
||||
fields.account.addEventListener('input', resetForAccountOrQueryChange);
|
||||
fields.workspaceAuthorization.addEventListener('input', resetForAccountOrQueryChange);
|
||||
fields.conversationQuery.addEventListener('input', resetForAccountOrQueryChange);
|
||||
fields.wsFrameFilter.addEventListener('input', () => {
|
||||
state.wsFrameFilterKeyword = fields.wsFrameFilter.value.trim().toLowerCase();
|
||||
|
||||
@@ -26,6 +26,7 @@ export const harnessPageMarkup = String.raw` <main>
|
||||
<h2 id="connection-heading">账号与连接</h2>
|
||||
<div class="field-grid">
|
||||
<label>OneTalk 账号 ID<input id="account-id" autocomplete="off" placeholder="onetalk-account-1" required></label>
|
||||
<label>Workspace Authorization<input id="workspace-authorization" autocomplete="off" placeholder="workspace-1" required></label>
|
||||
<label>会话查询<input id="conversation-query" autocomplete="off" placeholder="名称或会话 ID"></label>
|
||||
<label class="span-2">会话<select id="conversation-id" disabled><option value="">先加载会话</option></select></label>
|
||||
<label class="span-2">开发 Cookie<input id="mind-cookie" autocomplete="off" placeholder="mind_session=opaque"></label>
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
// 页面脚本分片:scope、URL 构造与会话/消息读取(由 harness/index.ts 组装进主 IIFE)
|
||||
|
||||
export const harnessReadingScript = String.raw` const requestedChannelAccountId = () => fields.account.value.trim();
|
||||
const requestedWorkspaceAuthorization = () => fields.workspaceAuthorization.value.trim();
|
||||
const requestedQuery = () => fields.conversationQuery.value.trim();
|
||||
const currentScope = () => state.scope && state.scope.channelAccountId === requestedChannelAccountId() ? state.scope : null;
|
||||
const currentScope = () => state.scope
|
||||
&& state.scope.channelAccountId === requestedChannelAccountId()
|
||||
&& state.scope.workspaceId === requestedWorkspaceAuthorization()
|
||||
? state.scope
|
||||
: null;
|
||||
const matchesCurrentScope = (scope) => {
|
||||
const activeScope = currentScope();
|
||||
return activeScope
|
||||
@@ -48,7 +53,13 @@ export const harnessReadingScript = String.raw` const requestedChanne
|
||||
};
|
||||
|
||||
const readResponse = async (url, requestHeaders = {}) => {
|
||||
return fetchWithDeadline(url, { headers: requestHeaders, credentials: 'include' }, async (response) => {
|
||||
return fetchWithDeadline(url, {
|
||||
headers: {
|
||||
...requestHeaders,
|
||||
'Sinan-Pilot-Workspace-Id': requestedWorkspaceAuthorization()
|
||||
},
|
||||
credentials: 'include'
|
||||
}, async (response) => {
|
||||
let body = null;
|
||||
try { body = await response.json(); } catch (_) { body = null; }
|
||||
if (!response.ok) {
|
||||
@@ -141,11 +152,16 @@ export const harnessReadingScript = String.raw` const requestedChanne
|
||||
|
||||
const loadConversations = async (append = false) => {
|
||||
const channelAccountId = requestedChannelAccountId();
|
||||
const workspaceAuthorization = requestedWorkspaceAuthorization();
|
||||
const queryValue = requestedQuery();
|
||||
if (!channelAccountId) {
|
||||
setStatus(fields.historyStatus, '请输入 OneTalk 账号 ID', 'error');
|
||||
return;
|
||||
}
|
||||
if (!workspaceAuthorization) {
|
||||
setStatus(fields.historyStatus, '请输入 Workspace Authorization', 'error');
|
||||
return;
|
||||
}
|
||||
if (append) {
|
||||
if (!state.scope || state.scope.channelAccountId !== channelAccountId || state.listQuery !== queryValue || !state.listCursor) {
|
||||
return;
|
||||
|
||||
@@ -33,6 +33,7 @@ export const harnessRuntimeScript = String.raw` const heartbeatInterv
|
||||
const element = (id) => document.getElementById(id);
|
||||
const fields = {
|
||||
account: element('account-id'),
|
||||
workspaceAuthorization: element('workspace-authorization'),
|
||||
conversationQuery: element('conversation-query'),
|
||||
conversation: element('conversation-id'),
|
||||
cookie: element('mind-cookie'),
|
||||
|
||||
@@ -150,6 +150,7 @@ export const harnessWebsocketScript = String.raw` const frameMatchesF
|
||||
const wsUrl = () => {
|
||||
const url = new URL('/ws/mind', brightBaseUrl);
|
||||
url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
url.searchParams.set('workspaceId', requestedWorkspaceAuthorization());
|
||||
return url.toString();
|
||||
};
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ const handleRequest = async (
|
||||
config.authorization,
|
||||
config.channelAccountIds,
|
||||
config.cookie,
|
||||
config.workspaceAuthorization,
|
||||
config.sessionResult ?? "allow",
|
||||
);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user