agentlink-sdk 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +44 -18
- package/dist/index.d.ts +44 -18
- package/dist/index.js +80 -17
- package/dist/index.mjs +80 -17
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
interface URLData {
|
|
2
|
-
data: any;
|
|
3
|
-
type: string;
|
|
4
|
-
}
|
|
5
|
-
/**
|
|
6
|
-
* 将数据编码为 URL hash
|
|
7
|
-
*/
|
|
8
|
-
declare function encodeDataToUrl(data: any, type: string, baseUrl: string): Promise<string>;
|
|
9
|
-
/**
|
|
10
|
-
* 从 URL 中解码数据
|
|
11
|
-
*/
|
|
12
|
-
declare function decodeDataFromUrl(urlStr: string): Promise<URLData | null>;
|
|
13
|
-
|
|
14
1
|
interface AgentLinkClientOptions {
|
|
15
2
|
/**
|
|
16
3
|
* 服务端验证地址
|
|
@@ -26,13 +13,33 @@ interface WhitelistResponse {
|
|
|
26
13
|
whitelist: WhitelistInfo | WhitelistInfo[] | null;
|
|
27
14
|
origin: string | null;
|
|
28
15
|
}
|
|
16
|
+
interface SenderInfo {
|
|
17
|
+
domain: string;
|
|
18
|
+
description: string | null;
|
|
19
|
+
}
|
|
29
20
|
/**
|
|
30
|
-
* AgentLink 客户端 SDK (URL Hash 方案)
|
|
21
|
+
* AgentLink 客户端 SDK (URL Hash + Token 方案)
|
|
31
22
|
*/
|
|
32
23
|
declare class AgentLinkClient {
|
|
33
24
|
private serverUrl;
|
|
34
25
|
private static DEFAULT_WINDOW_NAME;
|
|
26
|
+
private token;
|
|
27
|
+
private tokenPromise;
|
|
28
|
+
private static tokenCache;
|
|
29
|
+
private static CACHE_TTL;
|
|
35
30
|
constructor(options: AgentLinkClientOptions);
|
|
31
|
+
/**
|
|
32
|
+
* 确保有 Token(自动获取)
|
|
33
|
+
*/
|
|
34
|
+
private ensureToken;
|
|
35
|
+
/**
|
|
36
|
+
* 从服务器获取 Token
|
|
37
|
+
*/
|
|
38
|
+
private fetchToken;
|
|
39
|
+
/**
|
|
40
|
+
* 验证发送端的 Token 和 Origin
|
|
41
|
+
*/
|
|
42
|
+
private verifySender;
|
|
36
43
|
/**
|
|
37
44
|
* 发送数据到目标应用
|
|
38
45
|
* @param targetUrl 目标应用的地址
|
|
@@ -45,11 +52,15 @@ declare class AgentLinkClient {
|
|
|
45
52
|
* 监听来自 URL 的数据
|
|
46
53
|
* @param callback 接收到数据时的回调函数
|
|
47
54
|
*/
|
|
48
|
-
receiveData(callback: (data: any, type: string) => void): () => void;
|
|
55
|
+
receiveData(callback: (data: any, type: string, senderInfo?: SenderInfo) => void): () => void;
|
|
49
56
|
/**
|
|
50
|
-
* 从当前 URL
|
|
57
|
+
* 从当前 URL 获取数据并验证发送方
|
|
51
58
|
*/
|
|
52
|
-
getDataFromUrl(url?: string): Promise<
|
|
59
|
+
getDataFromUrl(url?: string): Promise<{
|
|
60
|
+
data: any;
|
|
61
|
+
type: string;
|
|
62
|
+
senderInfo?: SenderInfo;
|
|
63
|
+
} | null>;
|
|
53
64
|
/**
|
|
54
65
|
* 获取白名单信息
|
|
55
66
|
*/
|
|
@@ -73,6 +84,21 @@ declare function uint8ArrayToBase64(arr: Uint8Array): string;
|
|
|
73
84
|
*/
|
|
74
85
|
declare function base64ToUint8Array(base64: string): Uint8Array;
|
|
75
86
|
|
|
87
|
+
interface URLData {
|
|
88
|
+
data: any;
|
|
89
|
+
type: string;
|
|
90
|
+
token: string;
|
|
91
|
+
origin: string;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* 将数据编码为 URL hash
|
|
95
|
+
*/
|
|
96
|
+
declare function encodeDataToUrl(data: any, type: string, token: string, origin: string, baseUrl: string): Promise<string>;
|
|
97
|
+
/**
|
|
98
|
+
* 从 URL 中解码数据
|
|
99
|
+
*/
|
|
100
|
+
declare function decodeDataFromUrl(urlStr: string): Promise<URLData | null>;
|
|
101
|
+
|
|
76
102
|
/**
|
|
77
103
|
* 验证域名是否在白名单中
|
|
78
104
|
*/
|
|
@@ -82,4 +108,4 @@ declare function verifyWhitelist(serverUrl: string, origin?: string): Promise<bo
|
|
|
82
108
|
*/
|
|
83
109
|
declare function fetchWhitelistInfo(serverUrl: string, includeAll?: boolean): Promise<any>;
|
|
84
110
|
|
|
85
|
-
export { AgentLinkClient, type AgentLinkClientOptions, type URLData, type WhitelistInfo, type WhitelistResponse, base64ToUint8Array, compress, decodeDataFromUrl, decompress, encodeDataToUrl, fetchWhitelistInfo, uint8ArrayToBase64, verifyWhitelist };
|
|
111
|
+
export { AgentLinkClient, type AgentLinkClientOptions, type SenderInfo, type URLData, type WhitelistInfo, type WhitelistResponse, base64ToUint8Array, compress, decodeDataFromUrl, decompress, encodeDataToUrl, fetchWhitelistInfo, uint8ArrayToBase64, verifyWhitelist };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
interface URLData {
|
|
2
|
-
data: any;
|
|
3
|
-
type: string;
|
|
4
|
-
}
|
|
5
|
-
/**
|
|
6
|
-
* 将数据编码为 URL hash
|
|
7
|
-
*/
|
|
8
|
-
declare function encodeDataToUrl(data: any, type: string, baseUrl: string): Promise<string>;
|
|
9
|
-
/**
|
|
10
|
-
* 从 URL 中解码数据
|
|
11
|
-
*/
|
|
12
|
-
declare function decodeDataFromUrl(urlStr: string): Promise<URLData | null>;
|
|
13
|
-
|
|
14
1
|
interface AgentLinkClientOptions {
|
|
15
2
|
/**
|
|
16
3
|
* 服务端验证地址
|
|
@@ -26,13 +13,33 @@ interface WhitelistResponse {
|
|
|
26
13
|
whitelist: WhitelistInfo | WhitelistInfo[] | null;
|
|
27
14
|
origin: string | null;
|
|
28
15
|
}
|
|
16
|
+
interface SenderInfo {
|
|
17
|
+
domain: string;
|
|
18
|
+
description: string | null;
|
|
19
|
+
}
|
|
29
20
|
/**
|
|
30
|
-
* AgentLink 客户端 SDK (URL Hash 方案)
|
|
21
|
+
* AgentLink 客户端 SDK (URL Hash + Token 方案)
|
|
31
22
|
*/
|
|
32
23
|
declare class AgentLinkClient {
|
|
33
24
|
private serverUrl;
|
|
34
25
|
private static DEFAULT_WINDOW_NAME;
|
|
26
|
+
private token;
|
|
27
|
+
private tokenPromise;
|
|
28
|
+
private static tokenCache;
|
|
29
|
+
private static CACHE_TTL;
|
|
35
30
|
constructor(options: AgentLinkClientOptions);
|
|
31
|
+
/**
|
|
32
|
+
* 确保有 Token(自动获取)
|
|
33
|
+
*/
|
|
34
|
+
private ensureToken;
|
|
35
|
+
/**
|
|
36
|
+
* 从服务器获取 Token
|
|
37
|
+
*/
|
|
38
|
+
private fetchToken;
|
|
39
|
+
/**
|
|
40
|
+
* 验证发送端的 Token 和 Origin
|
|
41
|
+
*/
|
|
42
|
+
private verifySender;
|
|
36
43
|
/**
|
|
37
44
|
* 发送数据到目标应用
|
|
38
45
|
* @param targetUrl 目标应用的地址
|
|
@@ -45,11 +52,15 @@ declare class AgentLinkClient {
|
|
|
45
52
|
* 监听来自 URL 的数据
|
|
46
53
|
* @param callback 接收到数据时的回调函数
|
|
47
54
|
*/
|
|
48
|
-
receiveData(callback: (data: any, type: string) => void): () => void;
|
|
55
|
+
receiveData(callback: (data: any, type: string, senderInfo?: SenderInfo) => void): () => void;
|
|
49
56
|
/**
|
|
50
|
-
* 从当前 URL
|
|
57
|
+
* 从当前 URL 获取数据并验证发送方
|
|
51
58
|
*/
|
|
52
|
-
getDataFromUrl(url?: string): Promise<
|
|
59
|
+
getDataFromUrl(url?: string): Promise<{
|
|
60
|
+
data: any;
|
|
61
|
+
type: string;
|
|
62
|
+
senderInfo?: SenderInfo;
|
|
63
|
+
} | null>;
|
|
53
64
|
/**
|
|
54
65
|
* 获取白名单信息
|
|
55
66
|
*/
|
|
@@ -73,6 +84,21 @@ declare function uint8ArrayToBase64(arr: Uint8Array): string;
|
|
|
73
84
|
*/
|
|
74
85
|
declare function base64ToUint8Array(base64: string): Uint8Array;
|
|
75
86
|
|
|
87
|
+
interface URLData {
|
|
88
|
+
data: any;
|
|
89
|
+
type: string;
|
|
90
|
+
token: string;
|
|
91
|
+
origin: string;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* 将数据编码为 URL hash
|
|
95
|
+
*/
|
|
96
|
+
declare function encodeDataToUrl(data: any, type: string, token: string, origin: string, baseUrl: string): Promise<string>;
|
|
97
|
+
/**
|
|
98
|
+
* 从 URL 中解码数据
|
|
99
|
+
*/
|
|
100
|
+
declare function decodeDataFromUrl(urlStr: string): Promise<URLData | null>;
|
|
101
|
+
|
|
76
102
|
/**
|
|
77
103
|
* 验证域名是否在白名单中
|
|
78
104
|
*/
|
|
@@ -82,4 +108,4 @@ declare function verifyWhitelist(serverUrl: string, origin?: string): Promise<bo
|
|
|
82
108
|
*/
|
|
83
109
|
declare function fetchWhitelistInfo(serverUrl: string, includeAll?: boolean): Promise<any>;
|
|
84
110
|
|
|
85
|
-
export { AgentLinkClient, type AgentLinkClientOptions, type URLData, type WhitelistInfo, type WhitelistResponse, base64ToUint8Array, compress, decodeDataFromUrl, decompress, encodeDataToUrl, fetchWhitelistInfo, uint8ArrayToBase64, verifyWhitelist };
|
|
111
|
+
export { AgentLinkClient, type AgentLinkClientOptions, type SenderInfo, type URLData, type WhitelistInfo, type WhitelistResponse, base64ToUint8Array, compress, decodeDataFromUrl, decompress, encodeDataToUrl, fetchWhitelistInfo, uint8ArrayToBase64, verifyWhitelist };
|
package/dist/index.js
CHANGED
|
@@ -66,8 +66,8 @@ function base64ToUint8Array(base64) {
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
// src/utils/url.ts
|
|
69
|
-
async function encodeDataToUrl(data, type, baseUrl) {
|
|
70
|
-
const payload = { data, type };
|
|
69
|
+
async function encodeDataToUrl(data, type, token, origin, baseUrl) {
|
|
70
|
+
const payload = { data, type, token, origin };
|
|
71
71
|
const jsonString = JSON.stringify(payload);
|
|
72
72
|
const compressed = await compress(jsonString);
|
|
73
73
|
const base64 = uint8ArrayToBase64(compressed);
|
|
@@ -137,8 +137,64 @@ async function fetchWhitelistInfo(serverUrl, includeAll = false) {
|
|
|
137
137
|
// src/client.ts
|
|
138
138
|
var _AgentLinkClient = class _AgentLinkClient {
|
|
139
139
|
constructor(options) {
|
|
140
|
+
// 发送端 Token 缓存(实例级别)
|
|
141
|
+
this.token = null;
|
|
142
|
+
this.tokenPromise = null;
|
|
140
143
|
this.serverUrl = options.serverUrl.replace(/\/$/, "");
|
|
141
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* 确保有 Token(自动获取)
|
|
147
|
+
*/
|
|
148
|
+
async ensureToken() {
|
|
149
|
+
if (this.token) return this.token;
|
|
150
|
+
if (!this.tokenPromise) {
|
|
151
|
+
this.tokenPromise = this.fetchToken();
|
|
152
|
+
}
|
|
153
|
+
return this.tokenPromise;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* 从服务器获取 Token
|
|
157
|
+
*/
|
|
158
|
+
async fetchToken() {
|
|
159
|
+
const origin = window.location.origin;
|
|
160
|
+
const response = await fetch(`${this.serverUrl}/api/tokens/get?origin=${encodeURIComponent(origin)}`);
|
|
161
|
+
if (!response.ok) {
|
|
162
|
+
const data2 = await response.json();
|
|
163
|
+
throw new Error(`[AgentLink] Failed to get token: ${data2.error || response.statusText}`);
|
|
164
|
+
}
|
|
165
|
+
const data = await response.json();
|
|
166
|
+
if (!data.token) {
|
|
167
|
+
throw new Error("[AgentLink] No token returned from server");
|
|
168
|
+
}
|
|
169
|
+
const token = data.token;
|
|
170
|
+
this.token = token;
|
|
171
|
+
return token;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* 验证发送端的 Token 和 Origin
|
|
175
|
+
*/
|
|
176
|
+
async verifySender(token, origin) {
|
|
177
|
+
const cached = _AgentLinkClient.tokenCache.get(token);
|
|
178
|
+
if (cached && Date.now() - cached.timestamp < _AgentLinkClient.CACHE_TTL) {
|
|
179
|
+
return { domain: cached.domain, description: cached.description };
|
|
180
|
+
}
|
|
181
|
+
const response = await fetch(
|
|
182
|
+
`${this.serverUrl}/api/tokens/verify?token=${encodeURIComponent(token)}&origin=${encodeURIComponent(origin)}`
|
|
183
|
+
);
|
|
184
|
+
if (!response.ok) {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
const data = await response.json();
|
|
188
|
+
if (!data.valid) {
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
_AgentLinkClient.tokenCache.set(token, {
|
|
192
|
+
domain: data.domain,
|
|
193
|
+
description: data.description,
|
|
194
|
+
timestamp: Date.now()
|
|
195
|
+
});
|
|
196
|
+
return { domain: data.domain, description: data.description };
|
|
197
|
+
}
|
|
142
198
|
/**
|
|
143
199
|
* 发送数据到目标应用
|
|
144
200
|
* @param targetUrl 目标应用的地址
|
|
@@ -147,11 +203,9 @@ var _AgentLinkClient = class _AgentLinkClient {
|
|
|
147
203
|
* @param windowName 窗口名称,用于复用(默认: 'agentlink-window')
|
|
148
204
|
*/
|
|
149
205
|
async sendData(targetUrl, data, type, windowName = _AgentLinkClient.DEFAULT_WINDOW_NAME) {
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
154
|
-
const encodedUrl = await encodeDataToUrl(data, type, targetUrl);
|
|
206
|
+
const token = await this.ensureToken();
|
|
207
|
+
const origin = window.location.origin;
|
|
208
|
+
const encodedUrl = await encodeDataToUrl(data, type, token, origin, targetUrl);
|
|
155
209
|
const targetWindow = window.open(encodedUrl, windowName);
|
|
156
210
|
if (!targetWindow) {
|
|
157
211
|
throw new Error("[AgentLink] Failed to open target window. It might be blocked by a popup blocker.");
|
|
@@ -166,7 +220,7 @@ var _AgentLinkClient = class _AgentLinkClient {
|
|
|
166
220
|
const handleHashChange = async () => {
|
|
167
221
|
const result = await this.getDataFromUrl();
|
|
168
222
|
if (result) {
|
|
169
|
-
callback(result.data, result.type);
|
|
223
|
+
callback(result.data, result.type, result.senderInfo);
|
|
170
224
|
}
|
|
171
225
|
};
|
|
172
226
|
window.addEventListener("hashchange", handleHashChange);
|
|
@@ -176,19 +230,24 @@ var _AgentLinkClient = class _AgentLinkClient {
|
|
|
176
230
|
};
|
|
177
231
|
}
|
|
178
232
|
/**
|
|
179
|
-
* 从当前 URL
|
|
233
|
+
* 从当前 URL 获取数据并验证发送方
|
|
180
234
|
*/
|
|
181
235
|
async getDataFromUrl(url) {
|
|
182
236
|
const targetUrl = url || window.location.href;
|
|
183
|
-
const
|
|
184
|
-
if (
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
237
|
+
const urlData = await decodeDataFromUrl(targetUrl);
|
|
238
|
+
if (!urlData) {
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
const senderInfo = await this.verifySender(urlData.token, urlData.origin);
|
|
242
|
+
if (!senderInfo) {
|
|
243
|
+
console.warn(`[AgentLink] Data received but sender verification failed`);
|
|
244
|
+
return null;
|
|
190
245
|
}
|
|
191
|
-
return
|
|
246
|
+
return {
|
|
247
|
+
data: urlData.data,
|
|
248
|
+
type: urlData.type,
|
|
249
|
+
senderInfo
|
|
250
|
+
};
|
|
192
251
|
}
|
|
193
252
|
/**
|
|
194
253
|
* 获取白名单信息
|
|
@@ -198,5 +257,9 @@ var _AgentLinkClient = class _AgentLinkClient {
|
|
|
198
257
|
}
|
|
199
258
|
};
|
|
200
259
|
_AgentLinkClient.DEFAULT_WINDOW_NAME = "agentlink-window";
|
|
260
|
+
// 接收端验证结果缓存(静态,跨实例共享)
|
|
261
|
+
_AgentLinkClient.tokenCache = /* @__PURE__ */ new Map();
|
|
262
|
+
// 缓存过期时间:1 小时
|
|
263
|
+
_AgentLinkClient.CACHE_TTL = 60 * 60 * 1e3;
|
|
201
264
|
var AgentLinkClient = _AgentLinkClient;
|
|
202
265
|
//# sourceMappingURL=index.js.map
|
package/dist/index.mjs
CHANGED
|
@@ -32,8 +32,8 @@ function base64ToUint8Array(base64) {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
// src/utils/url.ts
|
|
35
|
-
async function encodeDataToUrl(data, type, baseUrl) {
|
|
36
|
-
const payload = { data, type };
|
|
35
|
+
async function encodeDataToUrl(data, type, token, origin, baseUrl) {
|
|
36
|
+
const payload = { data, type, token, origin };
|
|
37
37
|
const jsonString = JSON.stringify(payload);
|
|
38
38
|
const compressed = await compress(jsonString);
|
|
39
39
|
const base64 = uint8ArrayToBase64(compressed);
|
|
@@ -103,8 +103,64 @@ async function fetchWhitelistInfo(serverUrl, includeAll = false) {
|
|
|
103
103
|
// src/client.ts
|
|
104
104
|
var _AgentLinkClient = class _AgentLinkClient {
|
|
105
105
|
constructor(options) {
|
|
106
|
+
// 发送端 Token 缓存(实例级别)
|
|
107
|
+
this.token = null;
|
|
108
|
+
this.tokenPromise = null;
|
|
106
109
|
this.serverUrl = options.serverUrl.replace(/\/$/, "");
|
|
107
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* 确保有 Token(自动获取)
|
|
113
|
+
*/
|
|
114
|
+
async ensureToken() {
|
|
115
|
+
if (this.token) return this.token;
|
|
116
|
+
if (!this.tokenPromise) {
|
|
117
|
+
this.tokenPromise = this.fetchToken();
|
|
118
|
+
}
|
|
119
|
+
return this.tokenPromise;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* 从服务器获取 Token
|
|
123
|
+
*/
|
|
124
|
+
async fetchToken() {
|
|
125
|
+
const origin = window.location.origin;
|
|
126
|
+
const response = await fetch(`${this.serverUrl}/api/tokens/get?origin=${encodeURIComponent(origin)}`);
|
|
127
|
+
if (!response.ok) {
|
|
128
|
+
const data2 = await response.json();
|
|
129
|
+
throw new Error(`[AgentLink] Failed to get token: ${data2.error || response.statusText}`);
|
|
130
|
+
}
|
|
131
|
+
const data = await response.json();
|
|
132
|
+
if (!data.token) {
|
|
133
|
+
throw new Error("[AgentLink] No token returned from server");
|
|
134
|
+
}
|
|
135
|
+
const token = data.token;
|
|
136
|
+
this.token = token;
|
|
137
|
+
return token;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* 验证发送端的 Token 和 Origin
|
|
141
|
+
*/
|
|
142
|
+
async verifySender(token, origin) {
|
|
143
|
+
const cached = _AgentLinkClient.tokenCache.get(token);
|
|
144
|
+
if (cached && Date.now() - cached.timestamp < _AgentLinkClient.CACHE_TTL) {
|
|
145
|
+
return { domain: cached.domain, description: cached.description };
|
|
146
|
+
}
|
|
147
|
+
const response = await fetch(
|
|
148
|
+
`${this.serverUrl}/api/tokens/verify?token=${encodeURIComponent(token)}&origin=${encodeURIComponent(origin)}`
|
|
149
|
+
);
|
|
150
|
+
if (!response.ok) {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
const data = await response.json();
|
|
154
|
+
if (!data.valid) {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
_AgentLinkClient.tokenCache.set(token, {
|
|
158
|
+
domain: data.domain,
|
|
159
|
+
description: data.description,
|
|
160
|
+
timestamp: Date.now()
|
|
161
|
+
});
|
|
162
|
+
return { domain: data.domain, description: data.description };
|
|
163
|
+
}
|
|
108
164
|
/**
|
|
109
165
|
* 发送数据到目标应用
|
|
110
166
|
* @param targetUrl 目标应用的地址
|
|
@@ -113,11 +169,9 @@ var _AgentLinkClient = class _AgentLinkClient {
|
|
|
113
169
|
* @param windowName 窗口名称,用于复用(默认: 'agentlink-window')
|
|
114
170
|
*/
|
|
115
171
|
async sendData(targetUrl, data, type, windowName = _AgentLinkClient.DEFAULT_WINDOW_NAME) {
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
const encodedUrl = await encodeDataToUrl(data, type, targetUrl);
|
|
172
|
+
const token = await this.ensureToken();
|
|
173
|
+
const origin = window.location.origin;
|
|
174
|
+
const encodedUrl = await encodeDataToUrl(data, type, token, origin, targetUrl);
|
|
121
175
|
const targetWindow = window.open(encodedUrl, windowName);
|
|
122
176
|
if (!targetWindow) {
|
|
123
177
|
throw new Error("[AgentLink] Failed to open target window. It might be blocked by a popup blocker.");
|
|
@@ -132,7 +186,7 @@ var _AgentLinkClient = class _AgentLinkClient {
|
|
|
132
186
|
const handleHashChange = async () => {
|
|
133
187
|
const result = await this.getDataFromUrl();
|
|
134
188
|
if (result) {
|
|
135
|
-
callback(result.data, result.type);
|
|
189
|
+
callback(result.data, result.type, result.senderInfo);
|
|
136
190
|
}
|
|
137
191
|
};
|
|
138
192
|
window.addEventListener("hashchange", handleHashChange);
|
|
@@ -142,19 +196,24 @@ var _AgentLinkClient = class _AgentLinkClient {
|
|
|
142
196
|
};
|
|
143
197
|
}
|
|
144
198
|
/**
|
|
145
|
-
* 从当前 URL
|
|
199
|
+
* 从当前 URL 获取数据并验证发送方
|
|
146
200
|
*/
|
|
147
201
|
async getDataFromUrl(url) {
|
|
148
202
|
const targetUrl = url || window.location.href;
|
|
149
|
-
const
|
|
150
|
-
if (
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
203
|
+
const urlData = await decodeDataFromUrl(targetUrl);
|
|
204
|
+
if (!urlData) {
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
const senderInfo = await this.verifySender(urlData.token, urlData.origin);
|
|
208
|
+
if (!senderInfo) {
|
|
209
|
+
console.warn(`[AgentLink] Data received but sender verification failed`);
|
|
210
|
+
return null;
|
|
156
211
|
}
|
|
157
|
-
return
|
|
212
|
+
return {
|
|
213
|
+
data: urlData.data,
|
|
214
|
+
type: urlData.type,
|
|
215
|
+
senderInfo
|
|
216
|
+
};
|
|
158
217
|
}
|
|
159
218
|
/**
|
|
160
219
|
* 获取白名单信息
|
|
@@ -164,6 +223,10 @@ var _AgentLinkClient = class _AgentLinkClient {
|
|
|
164
223
|
}
|
|
165
224
|
};
|
|
166
225
|
_AgentLinkClient.DEFAULT_WINDOW_NAME = "agentlink-window";
|
|
226
|
+
// 接收端验证结果缓存(静态,跨实例共享)
|
|
227
|
+
_AgentLinkClient.tokenCache = /* @__PURE__ */ new Map();
|
|
228
|
+
// 缓存过期时间:1 小时
|
|
229
|
+
_AgentLinkClient.CACHE_TTL = 60 * 60 * 1e3;
|
|
167
230
|
var AgentLinkClient = _AgentLinkClient;
|
|
168
231
|
export {
|
|
169
232
|
AgentLinkClient,
|