fix: 登录响应结构与 API 文档对齐
All checks were successful
CI/CD Pipeline / Code Quality (push) Successful in 20s
CI/CD Pipeline / Unit Tests (push) Successful in 14s
CI/CD Pipeline / Build & Deploy Test (push) Has been skipped
CI/CD Pipeline / Build & Deploy Production (push) Successful in 1m29s

- LoginResponse 的 tokens 嵌入 tokens 对象,移除平铺的 accessToken/refreshToken
- user 移除 xpTotal/streakDays(文档中未定义)
- refreshJwt 同时返回 accessToken 和 refreshToken,复用 signTokens
This commit is contained in:
Wang Zhuoxuan 2026-05-25 00:37:12 +08:00
parent b2e5b8f789
commit 6507d9e9ac
2 changed files with 10 additions and 16 deletions

View File

@ -18,15 +18,15 @@ export function buildLoginResponse(
refreshToken: string, refreshToken: string,
): LoginResponse { ): LoginResponse {
return { return {
accessToken,
refreshToken,
user: { user: {
id: user.id, id: user.id,
nickname: user.nickname ?? null, nickname: user.nickname ?? null,
avatarUrl: user.avatarUrl ?? null, avatarUrl: user.avatarUrl ?? null,
tier: user.tier ?? 'free', tier: user.tier ?? 'free',
xpTotal: user.xpTotal ?? 0, },
streakDays: user.streakDays ?? 0, tokens: {
accessToken,
refreshToken,
}, },
}; };
} }
@ -90,13 +90,7 @@ export async function findOrCreateHuawei(
return buildLoginResponse(user, tokens.accessToken, tokens.refreshToken); return buildLoginResponse(user, tokens.accessToken, tokens.refreshToken);
} }
export async function refreshJwt(app: FastifyInstance, refreshToken: string): Promise<{ accessToken: string }> { export async function refreshJwt(app: FastifyInstance, refreshToken: string): Promise<{ accessToken: string; refreshToken: string }> {
const decoded = app.jwt.verify<JwtPayload>(refreshToken); const decoded = app.jwt.verify<JwtPayload>(refreshToken);
const payload: JwtPayload = { return signTokens(app, decoded.userId, decoded.authType, decoded.tier ?? 'free');
userId: decoded.userId,
authType: decoded.authType,
tier: decoded.tier,
};
const accessToken = app.jwt.sign(payload, { expiresIn: '1h' });
return { accessToken };
} }

View File

@ -8,15 +8,15 @@ export interface JwtPayload {
} }
export interface LoginResponse { export interface LoginResponse {
accessToken: string;
refreshToken: string;
user: { user: {
id: string; id: string;
nickname: string | null; nickname: string | null;
avatarUrl: string | null; avatarUrl: string | null;
tier: string; tier: string;
xpTotal: number; };
streakDays: number; tokens: {
accessToken: string;
refreshToken: string;
}; };
} }