docs(deploy): 添加部署文档并更新SDK API设计规范
- 新增完整的XuqmGroup部署文档,包含服务器配置、Docker Compose部署策略 - 更新SDK API重设计规范至V2.0,统一各端SDK初始化和登录接口 - 添加安全设计规范文档,涵盖密码安全、AppSecret验证等内容 - 新增离线推送架构设计文档,定义厂商推送集成方案 - 重构SDK登录流程,统一使用userId + userSig鉴权模式 - 移除dbName等外部配置参数,实现零感知平台地址配置 - 完善部署架构图和配置示例文件
这个提交包含在:
父节点
0ca5d43fdb
当前提交
7909e4cf66
@ -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)))
|
||||||
}
|
}
|
||||||
|
|||||||
正在加载...
在新工单中引用
屏蔽一个用户