feat(auth): mark test accounts in login requests
This commit is contained in:
@@ -8,7 +8,7 @@ import type { FetchHook } from "ofetch";
|
||||
import { ApiPath } from "../../../data/services/api/api_path";
|
||||
import { ApiError, ErrorCode } from "../../../data/services/api/api_result";
|
||||
import { AuthStorage } from "@/data/storage/auth/auth_storage";
|
||||
import { deviceIdentifier, Result } from "@/utils";
|
||||
import { AppEnvUtil, deviceIdentifier, Result } from "@/utils";
|
||||
|
||||
/**
|
||||
* 不需要 auth token 刷新的路径
|
||||
@@ -105,7 +105,7 @@ async function refreshGuestToken(baseUrl: string): Promise<void> {
|
||||
const response = await fetch(`${baseUrl}${ApiPath.guestLogin}`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ deviceId }),
|
||||
body: JSON.stringify(withTestAccountFlag({ deviceId })),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -125,6 +125,12 @@ async function refreshGuestToken(baseUrl: string): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
function withTestAccountFlag<T extends Record<string, unknown>>(
|
||||
payload: T,
|
||||
): T & { isTestAccount: boolean } {
|
||||
return { ...payload, isTestAccount: !AppEnvUtil.isProduction() };
|
||||
}
|
||||
|
||||
/**
|
||||
* 401 → 刷新 token 并重试
|
||||
*/
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
export class AppleLoginRequest {
|
||||
declare readonly identityToken: string;
|
||||
declare readonly platform: string;
|
||||
declare readonly isTestAccount: boolean;
|
||||
|
||||
private constructor(input: AppleLoginRequestInput) {
|
||||
const data = AppleLoginRequestSchema.parse(input);
|
||||
|
||||
@@ -11,6 +11,7 @@ export class FacebookLoginRequest {
|
||||
declare readonly accessToken: string;
|
||||
declare readonly platform: string;
|
||||
declare readonly guestId: string;
|
||||
declare readonly isTestAccount: boolean;
|
||||
|
||||
private constructor(input: FacebookLoginRequestInput) {
|
||||
const data = FacebookLoginRequestSchema.parse(input);
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
export class FbIdLoginRequest {
|
||||
declare readonly fbId: string;
|
||||
declare readonly avatarUrl: string;
|
||||
declare readonly isTestAccount: boolean;
|
||||
|
||||
private constructor(input: FbIdLoginRequestInput) {
|
||||
const data = FbIdLoginRequestSchema.parse(input);
|
||||
|
||||
@@ -11,6 +11,7 @@ export class GoogleLoginRequest {
|
||||
declare readonly idToken: string;
|
||||
declare readonly platform: string;
|
||||
declare readonly guestId: string;
|
||||
declare readonly isTestAccount: boolean;
|
||||
|
||||
private constructor(input: GoogleLoginRequestInput) {
|
||||
const data = GoogleLoginRequestSchema.parse(input);
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
|
||||
export class GuestLoginRequest {
|
||||
declare readonly deviceId: string;
|
||||
declare readonly isTestAccount: boolean;
|
||||
|
||||
private constructor(input: GuestLoginRequestInput) {
|
||||
const data = GuestLoginRequestSchema.parse(input);
|
||||
|
||||
@@ -13,6 +13,7 @@ export class LoginRequest {
|
||||
declare readonly password: string;
|
||||
declare readonly platform: string;
|
||||
declare readonly guestId: string;
|
||||
declare readonly isTestAccount: boolean;
|
||||
|
||||
private constructor(input: LoginRequestInput) {
|
||||
const data = LoginRequestSchema.parse(input);
|
||||
|
||||
@@ -13,6 +13,7 @@ export class RegisterRequest {
|
||||
declare readonly password: string;
|
||||
declare readonly platform: string;
|
||||
declare readonly guestId: string;
|
||||
declare readonly isTestAccount: boolean;
|
||||
|
||||
private constructor(input: RegisterRequestInput) {
|
||||
const data = RegisterRequestSchema.parse(input);
|
||||
|
||||
@@ -28,7 +28,7 @@ import {
|
||||
SendCodeRequest,
|
||||
} from "@/data/dto/auth";
|
||||
import { User } from "@/data/dto/user";
|
||||
import { Result, Logger } from "@/utils";
|
||||
import { AppEnvUtil, Result, Logger } from "@/utils";
|
||||
import type { IAuthRepository } from "@/data/repositories/interfaces";
|
||||
import { AuthStorage, type IAuthStorage } from "@/data/storage/auth";
|
||||
import { UserStorage, type IUserStorage } from "@/data/storage/user";
|
||||
@@ -37,6 +37,7 @@ const log = new Logger("DataRepositoriesAuthRepository");
|
||||
|
||||
/** 硬编码平台名,对齐 Dart `PlatformUtil.platformName.toLowerCase()`(Web 平台)。 */
|
||||
const WEB_PLATFORM = "web";
|
||||
const TEST_ACCOUNT_FLAG = "isTestAccount";
|
||||
|
||||
export class AuthRepository implements IAuthRepository {
|
||||
constructor(
|
||||
@@ -59,13 +60,15 @@ export class AuthRepository implements IAuthRepository {
|
||||
}): Promise<Result<void>> {
|
||||
return Result.wrap(async () => {
|
||||
await this.api.register(
|
||||
RegisterRequest.from({
|
||||
RegisterRequest.from(
|
||||
withTestAccountFlag({
|
||||
username: input.username,
|
||||
email: input.email,
|
||||
password: input.password,
|
||||
platform: WEB_PLATFORM,
|
||||
guestId: input.guestId ?? "",
|
||||
}),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -79,13 +82,15 @@ export class AuthRepository implements IAuthRepository {
|
||||
}): Promise<Result<LoginResponse>> {
|
||||
return Result.wrap(async () => {
|
||||
const response = await this.api.emailLogin(
|
||||
LoginRequest.from({
|
||||
LoginRequest.from(
|
||||
withTestAccountFlag({
|
||||
email: input.email ?? "",
|
||||
username: input.username ?? "",
|
||||
password: input.password,
|
||||
platform: WEB_PLATFORM,
|
||||
guestId: input.guestId ?? "",
|
||||
}),
|
||||
),
|
||||
);
|
||||
await this._saveLoginData(response);
|
||||
return response;
|
||||
@@ -131,7 +136,7 @@ export class AuthRepository implements IAuthRepository {
|
||||
});
|
||||
return Result.wrap(async () => {
|
||||
const response = await this.api.guestLogin(
|
||||
GuestLoginRequest.from({ deviceId }),
|
||||
GuestLoginRequest.from(withTestAccountFlag({ deviceId })),
|
||||
);
|
||||
log.debug("[AuthRepository.guestLogin] API call SUCCESS (Zod parsed)", {
|
||||
hasToken: !!response.token,
|
||||
@@ -160,12 +165,14 @@ export class AuthRepository implements IAuthRepository {
|
||||
}): Promise<Result<LoginResponse>> {
|
||||
return this._socialLogin(() =>
|
||||
this.api.googleLogin(
|
||||
GoogleLoginRequest.from({
|
||||
GoogleLoginRequest.from(
|
||||
withTestAccountFlag({
|
||||
idToken: input.idToken,
|
||||
platform: WEB_PLATFORM,
|
||||
guestId: input.guestId ?? "",
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -176,12 +183,14 @@ export class AuthRepository implements IAuthRepository {
|
||||
}): Promise<Result<LoginResponse>> {
|
||||
return this._socialLogin(() =>
|
||||
this.api.facebookLogin(
|
||||
FacebookLoginRequest.from({
|
||||
FacebookLoginRequest.from(
|
||||
withTestAccountFlag({
|
||||
accessToken: input.accessToken,
|
||||
platform: WEB_PLATFORM,
|
||||
guestId: input.guestId ?? "",
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -192,11 +201,13 @@ export class AuthRepository implements IAuthRepository {
|
||||
}): Promise<Result<LoginResponse>> {
|
||||
return this._socialLogin(() =>
|
||||
this.api.facebookIdLogin(
|
||||
FbIdLoginRequest.from({
|
||||
FbIdLoginRequest.from(
|
||||
withTestAccountFlag({
|
||||
fbId: input.fbId,
|
||||
avatarUrl: input.avatarUrl ?? "",
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -208,11 +219,13 @@ export class AuthRepository implements IAuthRepository {
|
||||
async appleLogin(identityToken: string): Promise<Result<LoginResponse>> {
|
||||
return this._socialLogin(() =>
|
||||
this.api.appleLogin(
|
||||
AppleLoginRequest.from({
|
||||
AppleLoginRequest.from(
|
||||
withTestAccountFlag({
|
||||
identityToken,
|
||||
platform: WEB_PLATFORM,
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -305,3 +318,12 @@ export const authRepository = new AuthRepository(
|
||||
AuthStorage.getInstance(),
|
||||
UserStorage.getInstance(),
|
||||
);
|
||||
|
||||
function withTestAccountFlag<T extends Record<string, unknown>>(
|
||||
payload: T,
|
||||
): T & { isTestAccount: boolean } {
|
||||
return {
|
||||
...payload,
|
||||
[TEST_ACCOUNT_FLAG]: !AppEnvUtil.isProduction(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { z } from "zod";
|
||||
export const AppleLoginRequestSchema = z.object({
|
||||
identityToken: z.string(),
|
||||
platform: z.string(),
|
||||
isTestAccount: z.boolean().default(false),
|
||||
});
|
||||
|
||||
export type AppleLoginRequestInput = z.input<typeof AppleLoginRequestSchema>;
|
||||
|
||||
@@ -8,6 +8,7 @@ export const FacebookLoginRequestSchema = z.object({
|
||||
accessToken: z.string(),
|
||||
platform: z.string(),
|
||||
guestId: z.string().default(""),
|
||||
isTestAccount: z.boolean().default(false),
|
||||
});
|
||||
|
||||
export type FacebookLoginRequestInput = z.input<typeof FacebookLoginRequestSchema>;
|
||||
|
||||
@@ -7,6 +7,7 @@ import { z } from "zod";
|
||||
export const FbIdLoginRequestSchema = z.object({
|
||||
fbId: z.string(),
|
||||
avatarUrl: z.string().default(""),
|
||||
isTestAccount: z.boolean().default(false),
|
||||
});
|
||||
|
||||
export type FbIdLoginRequestInput = z.input<typeof FbIdLoginRequestSchema>;
|
||||
|
||||
@@ -8,6 +8,7 @@ export const GoogleLoginRequestSchema = z.object({
|
||||
idToken: z.string(),
|
||||
platform: z.string(),
|
||||
guestId: z.string().default(""),
|
||||
isTestAccount: z.boolean().default(false),
|
||||
});
|
||||
|
||||
export type GoogleLoginRequestInput = z.input<typeof GoogleLoginRequestSchema>;
|
||||
|
||||
@@ -6,6 +6,7 @@ import { z } from "zod";
|
||||
|
||||
export const GuestLoginRequestSchema = z.object({
|
||||
deviceId: z.string(),
|
||||
isTestAccount: z.boolean().default(false),
|
||||
});
|
||||
|
||||
export type GuestLoginRequestInput = z.input<typeof GuestLoginRequestSchema>;
|
||||
|
||||
@@ -10,6 +10,7 @@ export const LoginRequestSchema = z.object({
|
||||
password: z.string(),
|
||||
platform: z.string(),
|
||||
guestId: z.string().default(""),
|
||||
isTestAccount: z.boolean().default(false),
|
||||
});
|
||||
|
||||
export type LoginRequestInput = z.input<typeof LoginRequestSchema>;
|
||||
|
||||
@@ -10,6 +10,7 @@ export const RegisterRequestSchema = z.object({
|
||||
password: z.string(),
|
||||
platform: z.string(),
|
||||
guestId: z.string().default(""),
|
||||
isTestAccount: z.boolean().default(false),
|
||||
});
|
||||
|
||||
export type RegisterRequestInput = z.input<typeof RegisterRequestSchema>;
|
||||
|
||||
Reference in New Issue
Block a user