Skip to content

Commit

Permalink
refactor: Make refresh button force to refresh the user cred
Browse files Browse the repository at this point in the history
  • Loading branch information
ci010 committed Apr 2, 2024
1 parent 450bc38 commit 4beae74
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 16 deletions.
22 changes: 15 additions & 7 deletions xmcl-keystone-ui/src/components/UserCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
:refreshing="refreshing"
@remove="onShowDeleteDialog()"
@abort-refresh="abortRefresh()"
@refresh="onRefresh()"
@refresh="onRefresh(true)"
/>
</v-list>

Expand Down Expand Up @@ -93,6 +93,7 @@
</transition>
<DeleteDialog
dialog="user-delete"
:width="400"
:title="t('userAccount.removeTitle')"
@confirm="onRemoveUser"
>
Expand Down Expand Up @@ -126,24 +127,31 @@ const onSelectUser = (user: string) => {
select(user)
}
const login = ref(users.value.length === 0)
const { refresh: onRefresh, refreshing, error } = useRefreshable(async () => {
if (users.value.length === 0) {
login.value = true
} else {
const refreshing = ref(false)
async function onRefresh(force = false) {
refreshing.value = true
try {
if (users.value.length === 0) {
login.value = true
return
}
if (!selected.value.id) {
select(users.value[0].id)
}
if (selected.value?.id || selected.value.invalidated || expired.value) {
// Try to refresh
const authority = selected.value?.authority
await refreshUser(selected.value.id).catch((e) => {
await refreshUser(selected.value.id, false, true).catch((e) => {
console.error(e)
reset({ username: selected.value?.username, authority, error: t('login.userRelogin') })
login.value = true
})
}
} finally {
refreshing.value = false
}
})
}
watch(() => props.show, (s) => {
if (!s) return
Expand Down
2 changes: 1 addition & 1 deletion xmcl-runtime-api/src/services/UserService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ export interface UserService extends GenericEventEmitter<UserServiceEventMap> {
*
* @throw 'userAccessTokenExpired'
*/
refreshUser(userId: string): Promise<void>
refreshUser(userId: string, silent?: boolean, force?: boolean): Promise<void>
/**
* Upload the skin to server. If the userId and profileId is not assigned,
* it will use the selected user and selected profile.
Expand Down
4 changes: 2 additions & 2 deletions xmcl-runtime/user/UserService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ export class UserService extends StatefulService<UserState> implements IUserServ
* Refresh the current user login status
*/
@Lock('refreshUser')
async refreshUser(userId: string, slientOnly = false) {
async refreshUser(userId: string, slientOnly = false, force = false) {
const user = this.state.users[userId]

if (!user) {
Expand All @@ -168,7 +168,7 @@ export class UserService extends StatefulService<UserState> implements IUserServ
const system = this.accountSystems[user.authority] || this.yggdrasilAccountSystem.yggdrasilAccountSystem
this.refreshController = new AbortController()

const newUser = await system.refresh(user, this.refreshController.signal, slientOnly).finally(() => {
const newUser = await system.refresh(user, this.refreshController.signal, slientOnly, force).finally(() => {
this.refreshController = undefined
})

Expand Down
2 changes: 1 addition & 1 deletion xmcl-runtime/user/accountSystems/AccountSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface UserAccountSystem {
/**
* Refresh the user profile
*/
refresh(userProfile: UserProfile, signal: AbortSignal, slientOnly?: boolean): Promise<UserProfile>
refresh(userProfile: UserProfile, signal: AbortSignal, slientOnly?: boolean, force?: boolean): Promise<UserProfile>
/**
* Set skin to the game profile. This should also update the game profile skin data and return the new user profile.
*/
Expand Down
6 changes: 3 additions & 3 deletions xmcl-runtime/user/accountSystems/MicrosoftAccountSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ export class MicrosoftAccountSystem implements UserAccountSystem {
return profile
}

async refresh(user: UserProfile, signal: AbortSignal, slientOnly = false): Promise<UserProfile> {
async refresh(user: UserProfile, signal: AbortSignal, slientOnly = false, force = false): Promise<UserProfile> {
const diff = Date.now() - user.expiredAt
if (!user.expiredAt || diff > 0 || (diff / 1000 / 3600 / 24) > 14 || user.invalidated) {
if (force || !user.expiredAt || diff > 0 || (diff / 1000 / 3600 / 24) > 14 || user.invalidated) {
// expired
this.logger.log('Microsoft accessToken expired. Refresh a new one.')
try {
Expand All @@ -51,7 +51,7 @@ export class MicrosoftAccountSystem implements UserAccountSystem {
user.invalidated = false
await this.userTokenStorage.put(user, accessToken)
} catch (e) {
this.logger.error(new Error(`Fail to refresh ${user.username}`, { cause: e }))
this.logger.error(e as any)
user.invalidated = true
await this.userTokenStorage.put(user, '')
}
Expand Down
4 changes: 2 additions & 2 deletions xmcl-runtime/user/accountSystems/YggdrasilAccountSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export class YggdrasilAccountSystem implements UserAccountSystem {
}
}

async refresh(userProfile: UserProfile, signal?: AbortSignal): Promise<UserProfile> {
async refresh(userProfile: UserProfile, signal?: AbortSignal, _ = false, force = false): Promise<UserProfile> {
const client = this.getClient(userProfile.authority)

const token = await this.storage.get(userProfile)
Expand All @@ -126,7 +126,7 @@ export class YggdrasilAccountSystem implements UserAccountSystem {

this.logger.log(`Validate ${userProfile.authority} user access token: ${valid ? 'valid' : 'invalid'}`)

if (!valid) {
if (!valid || force) {
try {
const result = await client.refresh({
accessToken: token,
Expand Down

0 comments on commit 4beae74

Please sign in to comment.