fix(auth): handle logout and refresh results
Propagate storage Result failures through logout, guest restoration, token refresh, and user state actors. Clear invalid sessions after failed automatic refreshes and cover both business and guest flows.
This commit is contained in:
@@ -112,30 +112,37 @@ export class AuthRepository implements IAuthRepository {
|
||||
}
|
||||
|
||||
try {
|
||||
await this.storage.clearBusinessAuthData();
|
||||
await this.userStorage.clearUserData();
|
||||
const authClearResult = await this.storage.clearBusinessAuthData();
|
||||
const userClearResult = await this.userStorage.clearUserData();
|
||||
if (Result.isErr(authClearResult)) return authClearResult;
|
||||
if (Result.isErr(userClearResult)) return userClearResult;
|
||||
} catch (e) {
|
||||
return Result.err(e);
|
||||
}
|
||||
|
||||
const deviceId = await deviceIdentifier.getDeviceId();
|
||||
const guestResult = await this.guestLogin(deviceId);
|
||||
if (Result.isOk(guestResult)) return Result.ok(undefined);
|
||||
try {
|
||||
const deviceId = await deviceIdentifier.getDeviceId();
|
||||
const guestResult = await this.guestLogin(deviceId);
|
||||
if (Result.isOk(guestResult)) return Result.ok(undefined);
|
||||
|
||||
const hasGuestToken = await this.storage.hasGuestToken();
|
||||
if (hasGuestToken.success && hasGuestToken.data) {
|
||||
const providerResult = await this.storage.setLoginProvider(
|
||||
LoginStatus.Guest,
|
||||
);
|
||||
if (Result.isErr(providerResult)) return providerResult;
|
||||
log.warn(
|
||||
"[AuthRepository] guest login failed after logout, falling back to local guest token",
|
||||
guestResult.error,
|
||||
);
|
||||
return Result.ok(undefined);
|
||||
const hasGuestToken = await this.storage.hasGuestToken();
|
||||
if (Result.isErr(hasGuestToken)) return hasGuestToken;
|
||||
if (hasGuestToken.data) {
|
||||
const providerResult = await this.storage.setLoginProvider(
|
||||
LoginStatus.Guest,
|
||||
);
|
||||
if (Result.isErr(providerResult)) return providerResult;
|
||||
log.warn(
|
||||
"[AuthRepository] guest login failed after logout, falling back to local guest token",
|
||||
guestResult.error,
|
||||
);
|
||||
return Result.ok(undefined);
|
||||
}
|
||||
|
||||
return Result.err(guestResult.error);
|
||||
} catch (e) {
|
||||
return Result.err(e);
|
||||
}
|
||||
|
||||
return Result.err(guestResult.error);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,11 +163,17 @@ export class AuthRepository implements IAuthRepository {
|
||||
hasUser: !!response.user,
|
||||
userLastMessageAt: response.user?.lastMessageAt,
|
||||
});
|
||||
await this.storage.setGuestToken(response.token);
|
||||
await this.storage.setLoginProvider(LoginStatus.Guest);
|
||||
await this.storage.setDeviceId(deviceId);
|
||||
const tokenResult = await this.storage.setGuestToken(response.token);
|
||||
if (Result.isErr(tokenResult)) throw tokenResult.error;
|
||||
const providerResult = await this.storage.setLoginProvider(
|
||||
LoginStatus.Guest,
|
||||
);
|
||||
if (Result.isErr(providerResult)) throw providerResult.error;
|
||||
const deviceResult = await this.storage.setDeviceId(deviceId);
|
||||
if (Result.isErr(deviceResult)) throw deviceResult.error;
|
||||
if (response.userId) {
|
||||
await this.userStorage.setUserId(response.userId);
|
||||
const userIdResult = await this.userStorage.setUserId(response.userId);
|
||||
if (Result.isErr(userIdResult)) throw userIdResult.error;
|
||||
}
|
||||
return response;
|
||||
}).catch((e) => {
|
||||
@@ -304,24 +317,26 @@ export class AuthRepository implements IAuthRepository {
|
||||
* 调用 API 成功后写回新的 login token + refresh token。
|
||||
*/
|
||||
async refreshToken(): Promise<Result<RefreshTokenResponse>> {
|
||||
const existing = await this.storage.getRefreshToken();
|
||||
if (!existing.success || !existing.data) {
|
||||
return Result.err(
|
||||
new ApiError(
|
||||
return Result.wrap(async () => {
|
||||
const existing = await this.storage.getRefreshToken();
|
||||
if (Result.isErr(existing)) throw existing.error;
|
||||
if (!existing.data) {
|
||||
throw new ApiError(
|
||||
"HTTP_UNAUTHORIZED",
|
||||
"No refresh token available",
|
||||
ErrorCode.httpUnauthorized,
|
||||
),
|
||||
);
|
||||
}
|
||||
const refreshToken = existing.data;
|
||||
return Result.wrap(async () => {
|
||||
);
|
||||
}
|
||||
const response = await this.api.refreshToken(
|
||||
RefreshTokenRequest.from({ refreshToken }),
|
||||
RefreshTokenRequest.from({ refreshToken: existing.data }),
|
||||
);
|
||||
await this.storage.setLoginToken(response.token);
|
||||
const tokenResult = await this.storage.setLoginToken(response.token);
|
||||
if (Result.isErr(tokenResult)) throw tokenResult.error;
|
||||
if (response.refreshToken) {
|
||||
await this.storage.setRefreshToken(response.refreshToken);
|
||||
const refreshTokenResult = await this.storage.setRefreshToken(
|
||||
response.refreshToken,
|
||||
);
|
||||
if (Result.isErr(refreshTokenResult)) throw refreshTokenResult.error;
|
||||
}
|
||||
return response;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user