fix(runtime): enforce session and environment contracts
This commit is contained in:
@@ -284,15 +284,21 @@ export class AuthRepository implements IAuthRepository {
|
||||
});
|
||||
|
||||
if (data.isGuest || !data.hasCompleteFacebookIdentity) {
|
||||
await this.storage.setGuestToken(data.token);
|
||||
await this.storage.setLoginProvider(LoginStatus.Guest);
|
||||
const tokenResult = await this.storage.setGuestToken(data.token);
|
||||
if (Result.isErr(tokenResult)) throw tokenResult.error;
|
||||
if (input.deviceId) {
|
||||
await this.storage.setDeviceId(input.deviceId);
|
||||
const deviceResult = await this.storage.setDeviceId(input.deviceId);
|
||||
if (Result.isErr(deviceResult)) throw deviceResult.error;
|
||||
}
|
||||
const userId = data.userId || data.user?.id || "";
|
||||
if (userId) {
|
||||
await this.userStorage.setUserId(userId);
|
||||
const userIdResult = await this.userStorage.setUserId(userId);
|
||||
if (Result.isErr(userIdResult)) throw userIdResult.error;
|
||||
}
|
||||
const providerResult = await this.storage.setLoginProvider(
|
||||
LoginStatus.Guest,
|
||||
);
|
||||
if (Result.isErr(providerResult)) throw providerResult.error;
|
||||
return LoginStatus.Guest;
|
||||
}
|
||||
|
||||
@@ -345,13 +351,7 @@ export class AuthRepository implements IAuthRepository {
|
||||
async getCurrentUser(): Promise<Result<User>> {
|
||||
return Result.wrap(async () => {
|
||||
const user = await this.api.getCurrentUser();
|
||||
const writeResult = await this.userStorage.setUser(user.toJson());
|
||||
if (!writeResult.success) {
|
||||
log.warn(
|
||||
"[AuthRepository] failed to cache current user",
|
||||
writeResult.error,
|
||||
);
|
||||
}
|
||||
await this._cacheUser(user);
|
||||
return user;
|
||||
});
|
||||
}
|
||||
@@ -360,7 +360,7 @@ export class AuthRepository implements IAuthRepository {
|
||||
|
||||
/**
|
||||
* 社交登录的公共包装:调 API → 调 `_saveLoginData` 持久化。
|
||||
* `_saveLoginData` 内部全部 best-effort,存储写失败不抛错。
|
||||
* 会话关键数据写入失败时,登录 Result 必须失败。
|
||||
*/
|
||||
private async _socialLogin(
|
||||
provider: LoginStatusT,
|
||||
@@ -374,35 +374,42 @@ export class AuthRepository implements IAuthRepository {
|
||||
}
|
||||
|
||||
/**
|
||||
* 持久化登录态:login token → refresh token → User 对象 → userId。
|
||||
* 全部 best-effort,错误用 `Logger.warn` 记录但不让登录「失败」——
|
||||
* 调用方已经从 API 拿到了 LoginResponse,缓存只是离线加速。
|
||||
* 持久化登录态:login token → refresh token → userId → provider。
|
||||
* 这些字段共同决定会话是否可恢复,任一写入失败都会让登录 Result 失败;
|
||||
* provider 最后写入,作为会话完成标记。完整 User 对象仅用于离线展示,
|
||||
* 缓存失败只记录告警,不影响已经建立的会话。
|
||||
*/
|
||||
private async _saveLoginData(
|
||||
data: LoginResponse,
|
||||
provider: LoginStatusT,
|
||||
): Promise<void> {
|
||||
const r1 = await this.storage.setLoginToken(data.token);
|
||||
if (!r1.success) {
|
||||
log.warn("[AuthRepository] setLoginToken failed", r1.error);
|
||||
}
|
||||
const providerResult = await this.storage.setLoginProvider(provider);
|
||||
if (!providerResult.success) {
|
||||
log.warn("[AuthRepository] setLoginProvider failed", providerResult.error);
|
||||
}
|
||||
const tokenResult = await this.storage.setLoginToken(data.token);
|
||||
if (Result.isErr(tokenResult)) throw tokenResult.error;
|
||||
|
||||
if (data.refreshToken) {
|
||||
const r2 = await this.storage.setRefreshToken(data.refreshToken);
|
||||
if (!r2.success) {
|
||||
log.warn("[AuthRepository] setRefreshToken failed", r2.error);
|
||||
const refreshTokenResult = await this.storage.setRefreshToken(
|
||||
data.refreshToken,
|
||||
);
|
||||
if (Result.isErr(refreshTokenResult)) throw refreshTokenResult.error;
|
||||
}
|
||||
|
||||
const userIdResult = await this.userStorage.setUserId(data.user.id);
|
||||
if (Result.isErr(userIdResult)) throw userIdResult.error;
|
||||
|
||||
const providerResult = await this.storage.setLoginProvider(provider);
|
||||
if (Result.isErr(providerResult)) throw providerResult.error;
|
||||
|
||||
await this._cacheUser(data.user);
|
||||
}
|
||||
|
||||
private async _cacheUser(user: User): Promise<void> {
|
||||
try {
|
||||
const userResult = await this.userStorage.setUser(user.toJson());
|
||||
if (Result.isErr(userResult)) {
|
||||
log.warn("[AuthRepository] setUser failed", userResult.error);
|
||||
}
|
||||
}
|
||||
const r3 = await this.userStorage.setUser(data.user.toJson());
|
||||
if (!r3.success) {
|
||||
log.warn("[AuthRepository] setUser failed", r3.error);
|
||||
}
|
||||
const r4 = await this.userStorage.setUserId(data.user.id);
|
||||
if (!r4.success) {
|
||||
log.warn("[AuthRepository] setUserId failed", r4.error);
|
||||
} catch (error) {
|
||||
log.warn("[AuthRepository] setUser threw", error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user