docs(deploy): 添加部署文档并更新SDK API设计规范
- 新增完整的XuqmGroup部署文档,包含服务器配置、Docker Compose部署策略 - 更新SDK API重设计规范至V2.0,统一各端SDK初始化和登录接口 - 添加安全设计规范文档,涵盖密码安全、AppSecret验证等内容 - 新增离线推送架构设计文档,定义厂商推送集成方案 - 重构SDK登录流程,统一使用userId + userSig鉴权模式 - 移除dbName等外部配置参数,实现零感知平台地址配置 - 完善部署架构图和配置示例文件
这个提交包含在:
父节点
92002ab19f
当前提交
3c7ae4d766
@ -30,8 +30,8 @@ yarn add @xuqm/rn-common @xuqm/rn-im @xuqm/rn-push @xuqm/rn-update
|
|||||||
|
|
||||||
## 入口
|
## 入口
|
||||||
|
|
||||||
- `XuqmSDK.initialize({ appKey, debug })`
|
- `XuqmSDK.initialize({ appKey, logLevel })`
|
||||||
- `XuqmSDK.login({ userId, userSig, profile, expiresAt, refreshUserSig })`
|
- `XuqmSDK.login({ userId, userSig })`
|
||||||
- `XuqmSDK.logout()`
|
- `XuqmSDK.logout()`
|
||||||
- `ImSDK`
|
- `ImSDK`
|
||||||
- `PushSDK`
|
- `PushSDK`
|
||||||
|
|||||||
@ -283,33 +283,18 @@ function resolveMimeTypeFromUri(uri: string, fallback: string): string {
|
|||||||
|
|
||||||
export const ImSDK = {
|
export const ImSDK = {
|
||||||
/**
|
/**
|
||||||
* Login to IM service. Fetches a token internally and opens the WebSocket connection.
|
* Login to IM service with a pre-obtained userSig and open the WebSocket connection.
|
||||||
* Pass dbName to enable local SQLite message caching (requires @nozbe/watermelondb).
|
|
||||||
*/
|
*/
|
||||||
async login(userId: string, dbName?: string): Promise<void> {
|
async login(userId: string, userSig: string): Promise<void> {
|
||||||
const config = getConfig()
|
const config = getConfig()
|
||||||
const device = await getDeviceInfo()
|
|
||||||
client?.disconnect()
|
client?.disconnect()
|
||||||
const res = await apiRequest<{ token: string }>('/api/im/auth/login', {
|
await _saveToken(userSig)
|
||||||
method: 'POST',
|
|
||||||
skipAuth: true,
|
|
||||||
params: {
|
|
||||||
appId: config.appId,
|
|
||||||
userId,
|
|
||||||
deviceId: device.deviceId,
|
|
||||||
platform: device.platform,
|
|
||||||
brand: device.brand,
|
|
||||||
model: device.model,
|
|
||||||
osVersion: device.osVersion,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
await _saveToken(res.token)
|
|
||||||
_currentUserId = userId
|
_currentUserId = userId
|
||||||
setCommonUserId(userId)
|
setCommonUserId(userId)
|
||||||
|
|
||||||
ImDatabase.init(dbName ?? buildDbName(config.appKey, userId))
|
ImDatabase.init(buildDbName(config.appKey, userId))
|
||||||
|
|
||||||
client = new ImClient(config.imWsUrl, res.token, config.appId)
|
client = new ImClient(config.imWsUrl, userSig, config.appId)
|
||||||
client.addListener({
|
client.addListener({
|
||||||
onConnected: () => {
|
onConnected: () => {
|
||||||
_syncHistoryForAllConversations().catch(() => {})
|
_syncHistoryForAllConversations().catch(() => {})
|
||||||
@ -318,32 +303,6 @@ export const ImSDK = {
|
|||||||
void client.connect()
|
void client.connect()
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Login with a pre-obtained IM token (e.g. from demo-service).
|
|
||||||
* Sets up the IM connection without calling the auth endpoint.
|
|
||||||
*/
|
|
||||||
async loginWithToken(userId: string, token: string, dbName?: string): Promise<void> {
|
|
||||||
const config = getConfig()
|
|
||||||
client?.disconnect()
|
|
||||||
await _saveToken(token)
|
|
||||||
_currentUserId = userId
|
|
||||||
setCommonUserId(userId)
|
|
||||||
|
|
||||||
ImDatabase.init(dbName ?? buildDbName(config.appKey, userId))
|
|
||||||
|
|
||||||
client = new ImClient(config.imWsUrl, token, config.appId)
|
|
||||||
client.addListener({
|
|
||||||
onConnected: () => {
|
|
||||||
_syncHistoryForAllConversations().catch(() => {})
|
|
||||||
},
|
|
||||||
})
|
|
||||||
void client.connect()
|
|
||||||
},
|
|
||||||
|
|
||||||
async loginWithUserSig(userId: string, userSig: string, dbName?: string): Promise<void> {
|
|
||||||
return ImSDK.loginWithToken(userId, userSig, dbName)
|
|
||||||
},
|
|
||||||
|
|
||||||
async reconnect(): Promise<void> {
|
async reconnect(): Promise<void> {
|
||||||
const config = getConfig()
|
const config = getConfig()
|
||||||
const token = await _getToken()
|
const token = await _getToken()
|
||||||
|
|||||||
@ -24,7 +24,7 @@ export async function uploadFile(
|
|||||||
const config = getConfig()
|
const config = getConfig()
|
||||||
const token = await _getToken()
|
const token = await _getToken()
|
||||||
if (!token) {
|
if (!token) {
|
||||||
throw new Error('[uploadFile] No active session — call ImSDK.loginWithToken() first.')
|
throw new Error('[uploadFile] No active session — call XuqmSDK.login() first.')
|
||||||
}
|
}
|
||||||
|
|
||||||
const form = new FormData()
|
const form = new FormData()
|
||||||
|
|||||||
@ -12,7 +12,7 @@ let currentSession: UnifiedLoginOptions | null = null
|
|||||||
async function applyLoginSession(session: UnifiedLoginOptions): Promise<void> {
|
async function applyLoginSession(session: UnifiedLoginOptions): Promise<void> {
|
||||||
setCommonUserId(session.userId)
|
setCommonUserId(session.userId)
|
||||||
try {
|
try {
|
||||||
await ImSDK.loginWithUserSig(session.userId, session.userSig)
|
await ImSDK.login(session.userId, session.userSig)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setCommonUserId(null)
|
setCommonUserId(null)
|
||||||
currentSession = null
|
currentSession = null
|
||||||
|
|||||||
正在加载...
在新工单中引用
屏蔽一个用户