Skip to content

Commit 8dd2ee6

Browse files
committed
add necessary authorization before open devtools
1 parent 09102f1 commit 8dd2ee6

File tree

14 files changed

+178
-55
lines changed

14 files changed

+178
-55
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
"@huolala-tech/page-spy-browser": "^1.8.3",
4848
"@huolala-tech/page-spy-plugin-data-harbor": "^1.2.3",
4949
"@huolala-tech/page-spy-plugin-rrweb": "^1.1.3",
50-
"@huolala-tech/page-spy-types": "^1.7.5",
50+
"@huolala-tech/page-spy-types": "^1.8.3",
5151
"@huolala-tech/react-json-view": "^1.2.4",
5252
"@huolala-tech/request": "^1.1.2",
5353
"acorn": "^8.11.3",

src/apis/index.ts

+9
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,12 @@ export const deleteSpyLog = (params: { fileId: string }) => {
2929
params,
3030
});
3131
};
32+
33+
export const checkRoomSecret = (params: {
34+
address: string;
35+
secret: string;
36+
}) => {
37+
return request.get<I.Response<any>>('/room/check', {
38+
params,
39+
});
40+
};

src/assets/image/lock.svg

+4
Loading

src/assets/locales/en.json

+6-2
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@
163163
},
164164
"socket": {
165165
"client-name": "Client",
166-
"client-not-in-connection": "No client in the current connection",
166+
"client-not-in-connection": "No client in the current connection. Please check the WebSocket of the client.",
167167
"client-not-found": "Client not found",
168168
"client-offline": "Client is offline",
169169
"client-fail": "Client has lost the connection, please contact the relevant tester.",
@@ -173,7 +173,11 @@
173173
"reconnect-fail-desc": "Reconnect failed, you have lost the connection. Please refresh the page or select another.",
174174
"room-not-found": "Room is not found",
175175
"network-timeout": "Network timeout",
176-
"server-down": "Server error"
176+
"server-down": "Server error",
177+
"room-secret": "Room Secret",
178+
"secret": "Secret",
179+
"secret-placeholder": "Please enter a 6-digit room password",
180+
"invalid-secret": "Invalid Password"
177181
},
178182
"connections": {
179183
"select-os": "Select OS",

src/assets/locales/ja.json

+6-2
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@
163163
},
164164
"socket": {
165165
"client-name": "クライアント",
166-
"client-not-in-connection": "現在の接続にクライアントが存在しません",
166+
"client-not-in-connection": "現在の接続でデバッグするクライアントが見つかりませんでした。クライアントのWebSocketを確認してください。",
167167
"client-not-found": "クライアントが見つかりません",
168168
"client-offline": "クライアントがオフラインです",
169169
"client-fail": "クライアントの接続が切断されました。関連するテスターにお問い合わせください。",
@@ -173,7 +173,11 @@
173173
"reconnect-fail-desc": "再接続に失敗しました。ページをリフレッシュするか、再選択してください。",
174174
"room-not-found": "ルームが存在しません",
175175
"network-timeout": "ネットワークエラー、接続がタイムアウトしました",
176-
"server-down": "サーバーエラー"
176+
"server-down": "サーバーエラー",
177+
"room-secret": "ルームパスワード",
178+
"secret": "パスワード",
179+
"secret-placeholder": "6桁の部屋のパスワードを入力してください",
180+
"invalid-secret": "パスワードが無効です"
177181
},
178182
"connections": {
179183
"select-os": "オペレーティング システムを選択",

src/assets/locales/ko.json

+6-2
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@
163163
},
164164
"socket": {
165165
"client-name": "클라이언트",
166-
"client-not-in-connection": "현재 연결에 클라이언트가 없습니다",
166+
"client-not-in-connection": "현재 연결에서 디버그 대상 클라이언트를 찾을 수 없습니다. 클라이언트의 WebSocket을 확인하세요.",
167167
"client-not-found": "클라이언트를 찾을 수 없습니다",
168168
"client-offline": "클라이언트가 오프라인 상태입니다",
169169
"client-fail": "클라이언트의 연결이 끊어졌습니다. 관련 테스터에 문의하십시오.",
@@ -173,7 +173,11 @@
173173
"reconnect-fail-desc": "재연결에 실패했습니다. 페이지를 새로 고치거나 다시 선택하십시오.",
174174
"room-not-found": "방이 존재하지 않습니다",
175175
"network-timeout": "네트워크 오류, 연결 시간 초과",
176-
"server-down": "서버 오류"
176+
"server-down": "서버 오류",
177+
"room-secret": "방 비밀번호",
178+
"secret": "비밀번호",
179+
"secret-placeholder": "6 자리 숫자의 방 비밀번호를 입력하십시오",
180+
"invalid-secret": "잘못된 비밀번호"
177181
},
178182
"connections": {
179183
"select-os": "운영 체제 선택",

src/assets/locales/zh.json

+6-2
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@
163163
},
164164
"socket": {
165165
"client-name": "客户端",
166-
"client-not-in-connection": "当前连接不存在客户端",
166+
"client-not-in-connection": "当前连接未找到待调试的客户端,请检查客户端的 WebSocket 连接",
167167
"client-not-found": "未找到客户端",
168168
"client-offline": "客户端已离线",
169169
"client-fail": "客户端的连接已断开,请联系相关测试人员。",
@@ -173,7 +173,11 @@
173173
"reconnect-fail-desc": "重连失败,您的连接已断开。请刷新页面或者重新选择。",
174174
"room-not-found": "房间不存在",
175175
"network-timeout": "网络故障,连接超时",
176-
"server-down": "服务出错"
176+
"server-down": "服务出错",
177+
"room-secret": "房间密码",
178+
"secret": "密码",
179+
"secret-placeholder": "请输入 6 位数字的房间密码",
180+
"invalid-secret": "密码错误"
177181
},
178182
"connections": {
179183
"select-os": "选择系统",

src/pages/Devtools/index.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ const ClientInfo = memo(() => {
303303

304304
export default function Devtools() {
305305
const { hash = '#Console' } = useLocation();
306-
const { address = '' } = useSearch();
306+
const { address = '', secret = '' } = useSearch();
307307
const [socket, initSocket] = useSocketMessageStore((state) => [
308308
state.socket,
309309
state.initSocket,
@@ -313,8 +313,8 @@ export default function Devtools() {
313313

314314
useEffect(() => {
315315
if (socket) return;
316-
initSocket(address);
317-
}, [address, initSocket, socket]);
316+
initSocket({ address, secret });
317+
}, [address, initSocket, secret, socket]);
318318

319319
const hashKey = useMemo<MenuType>(() => {
320320
const value = hash.slice(1);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { checkRoomSecret } from '@/apis';
2+
import { withPopup } from '@/utils/withPopup';
3+
import { useRequest } from 'ahooks';
4+
import { Button, Form, Input, Modal, message } from 'antd';
5+
import { useTranslation } from 'react-i18next';
6+
7+
export interface IArgs {
8+
address: string;
9+
}
10+
11+
export const SecretModal = withPopup<IArgs, string>(
12+
({ resolve, reject, params, visible }) => {
13+
const { t } = useTranslation();
14+
const [form] = Form.useForm();
15+
const { loading, run: requestCheckSecret } = useRequest(
16+
async () => {
17+
const secret = form.getFieldValue('secret');
18+
const { success } = await checkRoomSecret({
19+
address: params!.address,
20+
secret,
21+
});
22+
if (success) {
23+
resolve(secret);
24+
}
25+
},
26+
{
27+
manual: true,
28+
onError() {
29+
message.error(t('socket.invalid-secret'));
30+
},
31+
},
32+
);
33+
34+
return (
35+
<Modal
36+
open={visible}
37+
title={t('socket.room-secret')}
38+
footer={null}
39+
maskClosable
40+
onCancel={() => {
41+
form.resetFields();
42+
reject(null);
43+
}}
44+
width="400px"
45+
>
46+
<Form
47+
form={form}
48+
labelCol={{ span: 4 }}
49+
style={{ marginTop: 24 }}
50+
onFinish={requestCheckSecret}
51+
>
52+
<Form.Item
53+
label={t('socket.secret')}
54+
name="secret"
55+
rules={[{ required: true }]}
56+
>
57+
<Input placeholder={t('socket.secret-placeholder')!} />
58+
</Form.Item>
59+
<Form.Item wrapperCol={{ offset: 4 }}>
60+
<Button type="primary" loading={loading} htmlType="submit">
61+
{t('common.confirm')}
62+
</Button>
63+
</Form.Item>
64+
</Form>
65+
</Modal>
66+
);
67+
},
68+
);
+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { usePopupRef } from '@/utils/withPopup';
2+
import { Tooltip, Button, Space } from 'antd';
3+
import { useCallback } from 'react';
4+
import { useTranslation } from 'react-i18next';
5+
import { Link, useHref, useLocation } from 'react-router-dom';
6+
import { IArgs, SecretModal } from './SecretModal';
7+
import Icon from '@ant-design/icons';
8+
import { ReactComponent as LockSvg } from '@/assets/image/lock.svg';
9+
10+
interface Props {
11+
room: I.SpyRoom;
12+
}
13+
14+
export const DebugButton = ({ room }: Props) => {
15+
const { t } = useTranslation();
16+
const { connections, address, useSecret } = room;
17+
const client = connections.find(({ userId }) => userId === 'Client');
18+
const modalRef = usePopupRef<IArgs, string>();
19+
const devtoolPath = useHref('/devtools');
20+
21+
const startDebug = useCallback(async () => {
22+
try {
23+
if (useSecret) {
24+
const secret = await modalRef.current?.popup({
25+
address,
26+
});
27+
window.open(`${devtoolPath}?address=${address}&secret=${secret}`);
28+
} else {
29+
window.open(`${devtoolPath}?address=${address}`);
30+
}
31+
} catch (e) {}
32+
}, [address, devtoolPath, modalRef, useSecret]);
33+
34+
return (
35+
<Tooltip title={!client && t('socket.client-not-in-connection')}>
36+
<div>
37+
<Button
38+
type="primary"
39+
disabled={!client}
40+
style={{
41+
width: '100%',
42+
pointerEvents: !client ? 'none' : 'auto',
43+
}}
44+
shape="round"
45+
onClick={startDebug}
46+
>
47+
<Space style={{ display: 'flex', justifyContent: 'center' }}>
48+
{room.useSecret && <Icon component={LockSvg} />}
49+
{t('common.debug')}
50+
</Space>
51+
</Button>
52+
<SecretModal ref={modalRef} />
53+
</div>
54+
</Tooltip>
55+
);
56+
};

src/pages/RoomList/index.tsx

+5-31
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ import clsx from 'clsx';
2626
import { PropsWithChildren, useCallback, useMemo, useState } from 'react';
2727
import { useTranslation } from 'react-i18next';
2828
import './index.less';
29-
import { Link } from 'react-router-dom';
3029
import { ClearOutlined, SearchOutlined } from '@ant-design/icons';
30+
import { DebugButton } from './DebugButton';
3131

3232
const { Title } = Typography;
3333
const { Option } = Select;
@@ -173,10 +173,10 @@ export const RoomList = () => {
173173

174174
return (
175175
<Row gutter={24}>
176-
{list.map(({ address, name, connections, group, tags }) => {
176+
{list.map((item) => {
177+
const { address, name, group, tags } = item;
177178
const simpleAddress = address.slice(0, 4);
178179
const { os, browser } = parseUserAgent(name);
179-
const client = connections.find(({ userId }) => userId === 'Client');
180180

181181
return (
182182
<Col key={address} span={8} xl={6} xxl={4}>
@@ -217,40 +217,14 @@ export const RoomList = () => {
217217
</ConnDetailItem>
218218
</Col>
219219
</Row>
220-
<Tooltip
221-
title={!client && t('socket.client-not-in-connection')}
222-
>
223-
<div>
224-
<Button
225-
type="primary"
226-
disabled={!client}
227-
style={{
228-
width: '100%',
229-
pointerEvents: !client ? 'none' : 'auto',
230-
}}
231-
shape="round"
232-
>
233-
{!client ? (
234-
t('common.debug')
235-
) : (
236-
<Link
237-
to={`/devtools?address=${address}`}
238-
target="_blank"
239-
style={{ display: 'block' }}
240-
>
241-
{t('common.debug')}
242-
</Link>
243-
)}
244-
</Button>
245-
</div>
246-
</Tooltip>
220+
<DebugButton room={item} />
247221
</div>
248222
</Col>
249223
);
250224
})}
251225
</Row>
252226
);
253-
}, [conditions, connectionList, error, t]);
227+
}, [conditions, connectionList, error]);
254228

255229
return (
256230
<Layout style={{ height: '100%' }} className="room-list">

src/store/socket-message/index.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ interface SocketMessage {
2222
socket: SocketStore | null;
2323
consoleMsg: SpyConsole.DataItem[];
2424
consoleMsgTypeFilter: string[];
25-
consoleMsgKeywordFilter:string,
25+
consoleMsgKeywordFilter: string;
2626
networkMsg: SpyNetwork.RequestInfo[];
2727
systemMsg: SpySystem.DataItem[];
2828
connectMsg: string[];
@@ -36,7 +36,7 @@ interface SocketMessage {
3636
basicInfo: SpyDatabase.DBInfo[] | null;
3737
data: SpyDatabase.GetTypeDataItem | null;
3838
};
39-
initSocket: (url: string) => void;
39+
initSocket: (args: Record<string, string>) => void;
4040
setConsoleMsgTypeFilter: (typeList: string[]) => void;
4141
setConsoleMsgKeywordFilter: (keyword: string) => void;
4242
clearRecord: (key: string) => void;
@@ -47,7 +47,7 @@ export const useSocketMessageStore = create<SocketMessage>((set, get) => ({
4747
socket: null,
4848
consoleMsg: [],
4949
consoleMsgTypeFilter: [],
50-
consoleMsgKeywordFilter:'',
50+
consoleMsgKeywordFilter: '',
5151
networkMsg: [],
5252
systemMsg: [],
5353
connectMsg: [],
@@ -66,16 +66,16 @@ export const useSocketMessageStore = create<SocketMessage>((set, get) => ({
6666
basicInfo: null,
6767
data: null,
6868
},
69-
initSocket: (room: string) => {
70-
if (!room) return;
71-
const address = decodeURIComponent(room).split('#')[0] ?? '';
69+
initSocket: ({ address, secret }: Record<string, string>) => {
7270
if (!address) return;
71+
const roomID = decodeURIComponent(address).split('#')[0] ?? '';
72+
if (!roomID) return;
7373

7474
const _socket = get().socket;
7575
if (_socket) return;
7676

7777
const [, protocol] = resolveProtocol();
78-
const url = `${protocol}${API_BASE_URL}/api/v1/ws/room/join?address=${address}&userId=${USER_ID}`;
78+
const url = `${protocol}${API_BASE_URL}/api/v1/ws/room/join?address=${roomID}&userId=${USER_ID}&secret=${secret}`;
7979

8080
const socket = new SocketStore(url);
8181
set({ socket });

src/types/api.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ declare namespace I {
1313
name: string; // TODO this `name` is used for browser and os info, should be reconsidered.
1414
password: string;
1515
tags: Record<string, any>;
16+
useSecret: boolean;
1617
}
1718

1819
export interface SpyLog {

yarn.lock

-5
Original file line numberDiff line numberDiff line change
@@ -779,11 +779,6 @@
779779
"@huolala-tech/page-spy-types" "^1.8.3"
780780
rrweb "^2.0.0-alpha.4"
781781

782-
"@huolala-tech/page-spy-types@^1.7.5":
783-
version "1.7.5"
784-
resolved "https://registry.npmjs.org/@huolala-tech/page-spy-types/-/page-spy-types-1.7.5.tgz#21cb1fb75635c1b254da7d13abd720eb280e1267"
785-
integrity sha512-CvbY4gy/oviQDqTTxc0my5L951Hn+se/3jK4hB+QYD2E8sEkNDgG788TnIhGnauqZxh2f6GVj57HTTklkkZe5Q==
786-
787782
"@huolala-tech/page-spy-types@^1.8.3":
788783
version "1.8.3"
789784
resolved "https://registry.yarnpkg.com/@huolala-tech/page-spy-types/-/page-spy-types-1.8.3.tgz#2979957bbc2f48e8e3dfc8617511be7fa98e248d"

0 commit comments

Comments
 (0)