This commit is contained in:
Eric85710 2026-06-30 15:54:13 +08:00
parent 8230a5cf63
commit 7e936e4e05
2 changed files with 25 additions and 28 deletions

View file

@ -34,8 +34,6 @@ data class UserInfo(
) )
//register data //register data
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
data class RegisterRequest( data class RegisterRequest(

View file

@ -5,6 +5,7 @@ import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.longPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.core.stringSetPreferencesKey import androidx.datastore.preferences.core.stringSetPreferencesKey
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@ -14,63 +15,61 @@ import javax.inject.Inject
class TokenManager @Inject constructor( class TokenManager @Inject constructor(
private val dataStore: DataStore<Preferences> private val dataStore: DataStore<Preferences>
) { ) {
// 獲取所有已登入的使用者 ID 清單
val allUserIds: Flow<Set<String>> = dataStore.data.map { preferences -> val allUserIds: Flow<Set<String>> = dataStore.data.map { preferences ->
preferences[USER_ID_LIST] ?: emptySet() preferences[USER_ID_LIST] ?: emptySet()
} }
// TokenManager 內部建議改動
companion object { companion object {
private val USER_ID_LIST = stringSetPreferencesKey("user_id_list") // 移到這裡 private val USER_ID_LIST = stringSetPreferencesKey("user_id_list")
private val CURRENT_USER_ID = stringPreferencesKey("current_user_id") private val CURRENT_USER_ID = stringPreferencesKey("current_user_id")
// 動態生成每個 User 專屬的 Key
private fun accessTokenKey(userId: String) = stringPreferencesKey("access_token_$userId") private fun accessTokenKey(userId: String) = stringPreferencesKey("access_token_$userId")
private fun refreshTokenKey(userId: String) = stringPreferencesKey("refresh_token_$userId")
private fun expiresAtKey(userId: String) = longPreferencesKey("expires_at_$userId")
} }
// 儲存特定使用者的 Token // 儲存特定使用者的完整 Auth 資料(新增了 refreshToken 與 expiresIn)
suspend fun saveAuthData(userId: String, token: String) { suspend fun saveAuthData(userId: String, accessToken: String, refreshToken: String, expiresInSec: Int) {
dataStore.edit { preferences -> dataStore.edit { preferences ->
preferences[accessTokenKey(userId)] = token preferences[accessTokenKey(userId)] = accessToken
preferences[refreshTokenKey(userId)] = refreshToken
// 計算絕對過期時間戳記:當前時間(毫秒)+ 有效秒數 * 1000
val expiresAt = System.currentTimeMillis() + (expiresInSec * 1000L)
preferences[expiresAtKey(userId)] = expiresAt
preferences[CURRENT_USER_ID] = userId preferences[CURRENT_USER_ID] = userId
// 更新 ID 清單:把新的 userId 加進去
val currentList = preferences[USER_ID_LIST] ?: emptySet() val currentList = preferences[USER_ID_LIST] ?: emptySet()
preferences[USER_ID_LIST] = currentList + userId preferences[USER_ID_LIST] = currentList + userId
} }
} }
// 獲取「當前活躍使用者」的 ID
val currentUserId: Flow<String?> = dataStore.data.map { it[CURRENT_USER_ID] } val currentUserId: Flow<String?> = dataStore.data.map { it[CURRENT_USER_ID] }
// 自動讀取「當前帳號」的 Token // 獲取當前帳號的 Access Token
val currentAccessToken: Flow<String?> = dataStore.data.map { preferences -> val currentAccessToken: Flow<String?> = dataStore.data.map { preferences ->
val userId = preferences[CURRENT_USER_ID] val userId = preferences[CURRENT_USER_ID] ?: return@map null
if (userId != null) { preferences[accessTokenKey(userId)]
preferences[accessTokenKey(userId)]
} else {
null
}
} }
// 切換帳號:只需更改 CURRENT_USER_ID // 💡 新增:獲取當前帳號的 Refresh Token(供 Authenticator 使用)
suspend fun switchAccount(userId: String) { val currentRefreshToken: Flow<String?> = dataStore.data.map { preferences ->
dataStore.edit { preferences -> val userId = preferences[CURRENT_USER_ID] ?: return@map null
// 先檢查該 userId 的 token 是否存在 preferences[refreshTokenKey(userId)]
if (preferences.contains(accessTokenKey(userId))) {
preferences[CURRENT_USER_ID] = userId
}
}
} }
// 登出特定帳號 // 切換帳號、登出等邏輯保持不變,但登出時記得一併移除 refresh_token 與 expires_at
suspend fun logout(userId: String) { suspend fun logout(userId: String) {
dataStore.edit { preferences -> dataStore.edit { preferences ->
preferences.remove(accessTokenKey(userId)) preferences.remove(accessTokenKey(userId))
preferences.remove(refreshTokenKey(userId))
preferences.remove(expiresAtKey(userId))
// 從 ID 清單中移除
val currentList = preferences[USER_ID_LIST] ?: emptySet() val currentList = preferences[USER_ID_LIST] ?: emptySet()
preferences[USER_ID_LIST] = currentList - userId preferences[USER_ID_LIST] = currentList - userId
// 如果登出的是當前帳號,自動選另一個帳號或清空
if (preferences[CURRENT_USER_ID] == userId) { if (preferences[CURRENT_USER_ID] == userId) {
val remainingUser = (currentList - userId).firstOrNull() val remainingUser = (currentList - userId).firstOrNull()
if (remainingUser != null) { if (remainingUser != null) {