guanwei 1.2.6 → 1.3.0

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.
@@ -3,6 +3,16 @@ import type { InterpretationResult } from '@core/engine/tarotEngine';
3
3
 
4
4
  // 开发环境直连后端(规避 proxy/IPv6 组合的 SSE 不确定性);生产同域 /api
5
5
  const API_BASE = (import.meta.env.VITE_API_BASE as string | undefined) || '/api';
6
+
7
+ // 云同步 token(登录后 localStorage 会话中保存):所有需要归属校验的请求带上,
8
+ // 后端有 token 即以 token 解析用户,堵「自报 username」越权(H-NEW1 修复)
9
+ function authHeaders(): Record<string, string> {
10
+ try {
11
+ const sess = JSON.parse(localStorage.getItem('guanwei_session') || 'null');
12
+ if (sess?.token) return { 'X-Guanwei-Token': sess.token };
13
+ } catch { /* ignore */ }
14
+ return {};
15
+ }
6
16
  // 诊断:全局暴露当前 API 基址
7
17
  if (typeof window !== 'undefined') { (window as any).__API_BASE__ = API_BASE; }
8
18
  console.log('[观微] API_BASE =', API_BASE);
@@ -11,6 +21,7 @@ async function request<T>(endpoint: string, options: RequestInit = {}): Promise<
11
21
  const res = await fetch(`${API_BASE}${endpoint}`, {
12
22
  headers: {
13
23
  'Content-Type': 'application/json',
24
+ ...authHeaders(),
14
25
  ...options.headers,
15
26
  },
16
27
  ...options,
@@ -169,7 +180,7 @@ export async function aiInterpretStream(
169
180
  try {
170
181
  const res = await fetch(API_BASE + '/ai/interpret/stream', {
171
182
  method: 'POST',
172
- headers: { 'Content-Type': 'application/json' },
183
+ headers: { 'Content-Type': 'application/json', ...authHeaders() },
173
184
  body: JSON.stringify(params),
174
185
  signal: controller.signal,
175
186
  });
@@ -238,12 +249,14 @@ export interface DivineResult {
238
249
  divineId: string;
239
250
  resultRaw: unknown;
240
251
  display?: unknown;
252
+ /** 起占建档返回的 claimToken(本地占位账号注册升级用,L-NEW1) */
253
+ claimToken?: string;
241
254
  }
242
255
 
243
256
  export async function apiDivine(username: string, artId: string, inputs: unknown, profile?: unknown, question?: string, _profileId?: string): Promise<DivineResult> {
244
257
  const res = await fetch(API_BASE + '/divine', {
245
258
  method: 'POST',
246
- headers: { 'Content-Type': 'application/json' },
259
+ headers: { 'Content-Type': 'application/json', ...authHeaders() },
247
260
  body: JSON.stringify({ username, artId, inputs, profile, question }),
248
261
  });
249
262
  if (!res.ok) {
@@ -264,19 +277,19 @@ export interface DivineHistoryItem {
264
277
  }
265
278
 
266
279
  export async function apiDivineHistory(username: string, page = 1, pageSize = 20, profileId?: string): Promise<{ list: DivineHistoryItem[]; total: number }> {
267
- const res = await fetch(API_BASE + '/divine?username=' + encodeURIComponent(username) + '&page=' + page + '&pageSize=' + pageSize + (profileId ? '&profileId=' + encodeURIComponent(profileId) : ''));
280
+ const res = await fetch(API_BASE + '/divine?username=' + encodeURIComponent(username) + '&page=' + page + '&pageSize=' + pageSize + (profileId ? '&profileId=' + encodeURIComponent(profileId) : ''), { headers: authHeaders() });
268
281
  if (!res.ok) return { list: [], total: 0 };
269
282
  return res.json();
270
283
  }
271
284
 
272
285
  export async function apiDivineDetail(id: string, username: string): Promise<Record<string, unknown> | null> {
273
- const res = await fetch(API_BASE + '/divine/' + id + '?username=' + encodeURIComponent(username));
286
+ const res = await fetch(API_BASE + '/divine/' + id + '?username=' + encodeURIComponent(username), { headers: authHeaders() });
274
287
  if (!res.ok) return null;
275
288
  return res.json();
276
289
  }
277
290
 
278
291
  export async function apiDivineDelete(id: string, username: string): Promise<boolean> {
279
- const res = await fetch(API_BASE + '/divine/' + id + '?username=' + encodeURIComponent(username), { method: 'DELETE' });
292
+ const res = await fetch(API_BASE + '/divine/' + id + '?username=' + encodeURIComponent(username), { method: 'DELETE', headers: authHeaders() });
280
293
  return res.ok;
281
294
  }
282
295
 
@@ -330,7 +343,7 @@ export async function apiHourInfer(params: {
330
343
  }): Promise<HourInferResult> {
331
344
  const res = await fetch(API_BASE + '/hour-infer', {
332
345
  method: 'POST',
333
- headers: { 'Content-Type': 'application/json' },
346
+ headers: { 'Content-Type': 'application/json', ...authHeaders() },
334
347
  body: JSON.stringify(params),
335
348
  });
336
349
  if (!res.ok) {