docs(deploy): 添加部署文档并更新SDK API设计规范

- 新增完整的XuqmGroup部署文档,包含服务器配置、Docker Compose部署策略
- 更新SDK API重设计规范至V2.0,统一各端SDK初始化和登录接口
- 添加安全设计规范文档,涵盖密码安全、AppSecret验证等内容
- 新增离线推送架构设计文档,定义厂商推送集成方案
- 重构SDK登录流程,统一使用userId + userSig鉴权模式
- 移除dbName等外部配置参数,实现零感知平台地址配置
- 完善部署架构图和配置示例文件
这个提交包含在:
徐勤民 2026-05-02 11:29:49 +08:00
父节点 0ca5d43fdb
当前提交 7909e4cf66
共有 3 个文件被更改,包括 6 次插入30 次删除

查看文件

@ -43,9 +43,7 @@ export interface UserProfile {
export interface AuthResult { export interface AuthResult {
demoToken: string demoToken: string
demoTokenExpiresAt?: number | null
imToken: string imToken: string
imTokenExpiresAt?: number | null
profile: UserProfile profile: UserProfile
} }
@ -66,14 +64,6 @@ export const demoApi = {
}) })
}, },
refreshImToken(appId: string = APP_ID): Promise<{ imToken: string; imTokenExpiresAt?: number | null }> {
return request('/auth/refresh-im', {
method: 'POST',
skipAuth: false,
params: { appId },
})
},
getProfile(): Promise<UserProfile> { getProfile(): Promise<UserProfile> {
return request('/user/profile') return request('/user/profile')
}, },

查看文件

@ -26,21 +26,10 @@ const AuthContext = createContext<AuthContextValue | null>(null)
export function AuthProvider({ children }: { children: React.ReactNode }) { export function AuthProvider({ children }: { children: React.ReactNode }) {
const [state, setState] = useState<AuthState>({ ready: false, userId: null, profile: null }) const [state, setState] = useState<AuthState>({ ready: false, userId: null, profile: null })
const initSDK = useCallback(async (profile: UserProfile, imToken: string, imTokenExpiresAt?: number | null) => { const initSDK = useCallback(async (profile: UserProfile, imToken: string) => {
const appKey = profile.appId || APP_ID const appKey = profile.appId || APP_ID
await XuqmSDK.initialize({ appKey }) await XuqmSDK.initialize({ appKey })
await XuqmSDK.login({ await XuqmSDK.login({ userId: profile.userId, userSig: imToken })
userId: profile.userId,
userSig: imToken,
expiresAt: imTokenExpiresAt ?? undefined,
profile,
refreshUserSig: async () => {
const refreshed = await demoApi.refreshImToken(appKey)
await save(K.IM_TOKEN, refreshed.imToken)
await save(K.IM_TOKEN_EXPIRES_AT, refreshed.imTokenExpiresAt ?? null)
return { userSig: refreshed.imToken, expiresAt: refreshed.imTokenExpiresAt ?? undefined }
},
})
setState({ ready: true, userId: profile.userId, profile }) setState({ ready: true, userId: profile.userId, profile })
UpdateSDK.checkAppUpdate() UpdateSDK.checkAppUpdate()
@ -66,10 +55,9 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
try { try {
const demoToken = await load<string>(K.DEMO_TOKEN) const demoToken = await load<string>(K.DEMO_TOKEN)
const imToken = await load<string>(K.IM_TOKEN) const imToken = await load<string>(K.IM_TOKEN)
const imTokenExpiresAt = await load<number | null>(K.IM_TOKEN_EXPIRES_AT)
const profile = await load<UserProfile>(K.PROFILE) const profile = await load<UserProfile>(K.PROFILE)
if (demoToken && imToken && profile) { if (demoToken && imToken && profile) {
await initSDK(profile, imToken, imTokenExpiresAt ?? undefined) await initSDK(profile, imToken)
return return
} }
} catch { } catch {
@ -80,12 +68,11 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
restore() restore()
}, [initSDK]) }, [initSDK])
const handleAuthResult = useCallback(async (result: { demoToken: string; demoTokenExpiresAt?: number | null; imToken: string; imTokenExpiresAt?: number | null; profile: UserProfile }) => { const handleAuthResult = useCallback(async (result: { demoToken: string; imToken: string; profile: UserProfile }) => {
await save(K.DEMO_TOKEN, result.demoToken) await save(K.DEMO_TOKEN, result.demoToken)
await save(K.IM_TOKEN, result.imToken) await save(K.IM_TOKEN, result.imToken)
await save(K.IM_TOKEN_EXPIRES_AT, result.imTokenExpiresAt ?? null)
await save(K.PROFILE, result.profile) await save(K.PROFILE, result.profile)
await initSDK(result.profile, result.imToken, result.imTokenExpiresAt ?? undefined) await initSDK(result.profile, result.imToken)
}, [initSDK]) }, [initSDK])
const login = useCallback(async (userId: string, password: string) => { const login = useCallback(async (userId: string, password: string) => {

查看文件

@ -3,7 +3,6 @@ import AsyncStorage from '@react-native-async-storage/async-storage'
export const K = { export const K = {
DEMO_TOKEN: '@xuqm:demoToken', DEMO_TOKEN: '@xuqm:demoToken',
IM_TOKEN: '@xuqm:imToken', IM_TOKEN: '@xuqm:imToken',
IM_TOKEN_EXPIRES_AT: '@xuqm:imTokenExpiresAt',
PROFILE: '@xuqm:profile', PROFILE: '@xuqm:profile',
CONTACTS: '@xuqm:contacts', CONTACTS: '@xuqm:contacts',
} as const } as const
@ -23,5 +22,5 @@ export async function remove(key: string): Promise<void> {
} }
export async function clearSession(): Promise<void> { export async function clearSession(): Promise<void> {
await Promise.all([K.DEMO_TOKEN, K.IM_TOKEN, K.IM_TOKEN_EXPIRES_AT, K.PROFILE].map(k => AsyncStorage.removeItem(k))) await Promise.all([K.DEMO_TOKEN, K.IM_TOKEN, K.PROFILE].map(k => AsyncStorage.removeItem(k)))
} }