@qmuse/cloud-client 1.0.4 → 1.0.5

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/auth.js CHANGED
@@ -13,7 +13,7 @@ export function toCloudAuthUser(value) {
13
13
  const id = value?.$id?.trim();
14
14
  const internalUsername = /^([a-z0-9_]{3,32})@qmuse[.]cn$/.exec(value?.email?.trim().toLowerCase() ?? '')?.[1];
15
15
  const displayName = value?.name?.trim();
16
- const username = internalUsername ?? displayName ?? (id ? `user_${id.slice(-8)}` : undefined);
16
+ const username = internalUsername || displayName || (id ? `user_${id.slice(-8)}` : undefined);
17
17
  if (!id || !username) {
18
18
  throw new QmuseCloudError('AppBase returned an invalid current user', 'AUTH_USER_INVALID');
19
19
  }
package/docs/auth.md CHANGED
@@ -23,9 +23,31 @@ export async function submitAuth(mode: 'login' | 'register', username: string, p
23
23
  if (mode === 'register') await authService.register(input);
24
24
  return authService.login(input);
25
25
  }
26
+
27
+ // 仅当认证接口必须原生 HTTP 调用时使用;普通业务继续使用现有 facade。
28
+ import { createWebSessionBridge } from '@qmuse/cloud-client/web';
29
+ const sessionBridge = createWebSessionBridge();
30
+ export async function authHttpRequest(url: string, init: RequestInit): Promise<Response> {
31
+ const headers = new Headers(init.headers);
32
+ for (const [key, value] of Object.entries(sessionBridge.getSessionHeaders())) headers.set(key, value);
33
+ const response = await fetch(url, { ...init, headers, credentials: 'include' });
34
+ sessionBridge.observeResponseHeaders(response.headers);
35
+ return response;
36
+ }
37
+
38
+ // 外部 HTTP 验码已建立 Session,响应凭证保存后强制重新读取账号。
39
+ // 首次读取失败时,重试按钮也只调用此函数,不再次提交验证码。
40
+ export const restoreAfterExternalAuth = (): Promise<CloudAuthUser | null> => authService.restoreSession();
26
41
  ```
27
42
 
28
43
  - 页面启动先等待 `restoreUser()`;返回用户后才加载私有数据,返回 `null` 时展示登录表单。异常应展示服务错误,不等同于未登录。
29
44
  - `register()` 只创建账号,不建立或替换 Session。只有 `submitAuth()` 登录成功后才更新已登录状态、加载私有数据;注册成功而登录失败时,提示账号已创建并引导登录,不自动重新注册。
30
45
  - 退出成功后清空页面用户和私有数据缓存;恢复会话为空时同样清空旧状态。
31
46
  - 请求失败通过异常返回,私有 API 的 401 按未登录处理;网络错误和 5xx 保留服务异常语义。不记录密码或 Session,不从页面传入角色或用户 ID 代替服务端鉴权。
47
+
48
+ - 原生 HTTP 认证请求复用 `createWebSessionBridge()`:请求携带 `getSessionHeaders()`,响应到达后立即调用 `observeResponseHeaders(response.headers)`,完成后才恢复 SDK 会话、读取账号。保留 `credentials: 'include'`;无新兜底响应头时保留旧凭证,不读取 HttpOnly Cookie,不记录凭证。手机号验码已建立 Session,不再次创建 Session;验码成功但账号读取失败时只重试读取。
49
+ - 外部验码成功并保存响应凭证后,立即等待 `restoreAfterExternalAuth()`;返回账号才进入已登录状态,返回 `null` 展示登录表单,异常保留真实原因并提供只读取账号的重试。`user_session_already_exists` 同样先恢复已有账号,不自动删除会话。
50
+ - `restoreSession()` 重新读取账号和当前会话;`getCurrentUser()` 初始化后可能返回缓存,包括启动时的 `null`,不能作为外部验码后的首次读取。`refreshSession()` 用于刷新已有会话,不是外部验码后的恢复步骤;不得先刷新会话、忽略刷新异常再读取缓存。
51
+ - `username` 按“内部邮箱用户名 → trim 后的非空姓名 → user_ 加用户 ID 后八位”生成;空姓名允许登录,缺少有效用户 ID 仍拒绝。已有会话冲突时先恢复并读取已有账号,失败展示具体原因,不自动删除会话或宣称已切换账号。
52
+ - 页面实际使用 `user.avatarUrl` 渲染图片(如 `<img src={user.avatarUrl} alt="用户头像" />`);只有 URL 缺失或图片加载失败时才显示 `username` 首字母兜底。不能始终只渲染首字母,也不依赖平台用户头像。
53
+ - 浏览器兜底凭证依赖当前 origin 的 localStorage。临时预览域名改变后不能读取旧域名的凭证,可能需要重新登录;Session 尚未过期不保证跨域名免登录。存储不可用时明确展示会话恢复失败,不以延长 Session 或自动登出规避。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qmuse/cloud-client",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "Narrow HTTP-style client for the single QMuse Cloud API Function",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",