feat(auth): add psid field to various login request DTOs and schemas

This commit is contained in:
2026-07-10 16:33:29 +08:00
parent 4e06e08b15
commit dfcb06f5a9
13 changed files with 45 additions and 8 deletions
@@ -1,7 +1,5 @@
#!/usr/bin/env node
const crypto = require("node:crypto");
const GRAPH_API_VERSION = "v25.0";
const PSID = "27511427698460020";
const EXPECTED_ASID = "122111097783118257";
@@ -15,9 +13,9 @@ function assertConfigured(name, value) {
}
}
function createAppSecretProof(accessToken, appSecret) {
return crypto
.createHmac("sha256", appSecret.trim())
async function createAppSecretProof(accessToken, appSecret) {
const { createHmac } = await import("node:crypto");
return createHmac("sha256", appSecret.trim())
.update(accessToken.trim())
.digest("hex");
}
@@ -33,7 +31,7 @@ async function main() {
url.searchParams.set("access_token", PAGE_ACCESS_TOKEN);
url.searchParams.set(
"appsecret_proof",
createAppSecretProof(PAGE_ACCESS_TOKEN, APP_SECRET),
await createAppSecretProof(PAGE_ACCESS_TOKEN, APP_SECRET),
);
const response = await fetch(url);
@@ -11,6 +11,7 @@ export class FacebookLoginRequest {
declare readonly accessToken: string;
declare readonly platform: string;
declare readonly guestId: string;
declare readonly psid: string;
declare readonly isTestAccount: boolean;
private constructor(input: FacebookLoginRequestInput) {
@@ -10,6 +10,7 @@ import {
export class FbIdLoginRequest {
declare readonly fbId: string;
declare readonly avatarUrl: string;
declare readonly psid: string;
declare readonly isTestAccount: boolean;
private constructor(input: FbIdLoginRequestInput) {
@@ -11,6 +11,7 @@ export class GoogleLoginRequest {
declare readonly idToken: string;
declare readonly platform: string;
declare readonly guestId: string;
declare readonly psid: string;
declare readonly isTestAccount: boolean;
private constructor(input: GoogleLoginRequestInput) {
@@ -13,6 +13,7 @@ export class LoginRequest {
declare readonly password: string;
declare readonly platform: string;
declare readonly guestId: string;
declare readonly psid: string;
declare readonly isTestAccount: boolean;
private constructor(input: LoginRequestInput) {
+8
View File
@@ -73,6 +73,7 @@ export class AuthRepository implements IAuthRepository {
username?: string;
password: string;
guestId?: string;
psid?: string;
}): Promise<Result<LoginResponse>> {
return Result.wrap(async () => {
const email = input.email?.trim() ?? "";
@@ -84,6 +85,7 @@ export class AuthRepository implements IAuthRepository {
password: input.password,
platform: getAuthPlatform(),
guestId: input.guestId ?? "",
psid: input.psid ?? "",
}),
),
);
@@ -173,6 +175,7 @@ export class AuthRepository implements IAuthRepository {
async googleLogin(input: {
idToken: string;
guestId?: string;
psid?: string;
}): Promise<Result<LoginResponse>> {
return this._socialLogin(LoginStatus.Google, () =>
this.api.googleLogin(
@@ -181,6 +184,7 @@ export class AuthRepository implements IAuthRepository {
idToken: input.idToken,
platform: getAuthPlatform(),
guestId: input.guestId ?? "",
psid: input.psid ?? "",
}),
),
),
@@ -191,6 +195,7 @@ export class AuthRepository implements IAuthRepository {
async facebookLogin(input: {
accessToken: string;
guestId?: string;
psid?: string;
}): Promise<Result<LoginResponse>> {
return this._socialLogin(LoginStatus.Facebook, () =>
this.api.facebookLogin(
@@ -199,6 +204,7 @@ export class AuthRepository implements IAuthRepository {
accessToken: input.accessToken,
platform: getAuthPlatform(),
guestId: input.guestId ?? "",
psid: input.psid ?? "",
}),
),
),
@@ -209,6 +215,7 @@ export class AuthRepository implements IAuthRepository {
async facebookIdLogin(input: {
fbId: string;
avatarUrl?: string;
psid?: string;
}): Promise<Result<LoginResponse>> {
return this._socialLogin(LoginStatus.Facebook, () =>
this.api.facebookIdLogin(
@@ -216,6 +223,7 @@ export class AuthRepository implements IAuthRepository {
withTestAccountFlag({
fbId: input.fbId,
avatarUrl: input.avatarUrl ?? "",
psid: input.psid ?? "",
}),
),
),
@@ -36,6 +36,7 @@ export interface IAuthRepository {
username?: string;
password: string;
guestId?: string;
psid?: string;
}): Promise<Result<LoginResponse>>;
/** 退出真实用户登录并恢复游客态。 */
@@ -48,18 +49,21 @@ export interface IAuthRepository {
googleLogin(input: {
idToken: string;
guestId?: string;
psid?: string;
}): Promise<Result<LoginResponse>>;
/** Facebook 登录(accessToken 流程)。 */
facebookLogin(input: {
accessToken: string;
guestId?: string;
psid?: string;
}): Promise<Result<LoginResponse>>;
/** Facebook ID 登录(v7.0 新增,fbId 流程)。 */
facebookIdLogin(input: {
fbId: string;
avatarUrl?: string;
psid?: string;
}): Promise<Result<LoginResponse>>;
/** 刷新 token:先读本地的 refresh token,空则返回错误。 */
@@ -10,6 +10,7 @@ export const FacebookLoginRequestSchema = z.object({
accessToken: z.string(),
platform: z.string(),
guestId: stringOrEmpty,
psid: stringOrEmpty,
isTestAccount: booleanOrFalse,
});
@@ -9,6 +9,7 @@ import { booleanOrFalse, stringOrEmpty } from "../nullable-defaults";
export const FbIdLoginRequestSchema = z.object({
fbId: z.string(),
avatarUrl: stringOrEmpty,
psid: stringOrEmpty,
isTestAccount: booleanOrFalse,
});
@@ -10,6 +10,7 @@ export const GoogleLoginRequestSchema = z.object({
idToken: z.string(),
platform: z.string(),
guestId: stringOrEmpty,
psid: stringOrEmpty,
isTestAccount: booleanOrFalse,
});
+1
View File
@@ -12,6 +12,7 @@ export const LoginRequestSchema = z.object({
password: z.string(),
platform: z.string(),
guestId: stringOrEmpty,
psid: stringOrEmpty,
isTestAccount: booleanOrFalse,
});
+12 -2
View File
@@ -12,7 +12,7 @@ import { UserStorage } from "@/data/storage/user/user_storage";
import { deviceIdentifier, Logger, Result } from "@/utils";
import { hasCompleteBusinessAuthSession } from "@/lib/auth/auth_session";
import { readGuestId } from "./auth-helpers";
import { readGuestId, readPsid } from "./auth-helpers";
const log = new Logger("AuthActors");
@@ -25,10 +25,12 @@ export const emailLoginActor = fromPromise<LoginStatus, { email: string; passwor
passwordLength: input.password.length,
});
const guestId = await readGuestId();
const psid = await readPsid();
log.debug("[auth-machine] emailLoginActor calling authRepo.emailLogin", {
hasGuestId: !!guestId,
hasPsid: !!psid,
});
const result = await authRepo.emailLogin({ ...input, guestId });
const result = await authRepo.emailLogin({ ...input, guestId, psid });
log.debug("[auth-machine] emailLoginActor authRepo.emailLogin DONE", {
success: result.success,
hasData: result.success ? !!result.data : null,
@@ -62,6 +64,7 @@ export const emailRegisterThenLoginActor = fromPromise<
});
if (Result.isErr(registerResult)) throw registerResult.error;
const psid = await readPsid();
// 注册后自动登录(对齐 Dart 行为)
log.debug(
"[auth-machine] emailRegisterThenLoginActor calling authRepo.emailLogin (post-register)",
@@ -70,6 +73,7 @@ export const emailRegisterThenLoginActor = fromPromise<
email: input.email,
password: input.password,
guestId,
psid,
});
log.debug(
"[auth-machine] emailRegisterThenLoginActor authRepo.emailLogin DONE",
@@ -110,9 +114,11 @@ export const syncGoogleBackendActor = fromPromise<LoginStatus, { idToken: string
async ({ input }) => {
const authRepo = getAuthRepository();
const guestId = await readGuestId();
const psid = await readPsid();
const result = await authRepo.googleLogin({
idToken: input.idToken,
guestId,
psid,
});
if (Result.isErr(result)) throw result.error;
return "google" as LoginStatus;
@@ -125,9 +131,11 @@ export const syncFacebookBackendActor = fromPromise<
>(async ({ input }) => {
const authRepo = getAuthRepository();
const guestId = await readGuestId();
const psid = await readPsid();
const result = await authRepo.facebookLogin({
accessToken: input.accessToken,
guestId,
psid,
});
if (Result.isErr(result)) throw result.error;
@@ -252,9 +260,11 @@ export const checkAuthStatusActor = fromPromise<LoginStatus, void>(async () => {
if (asidR.success && asidR.data) {
const authRepo = getAuthRepository();
const avatarUrlR = await UserStorage.getInstance().getAvatarUrl();
const psid = await readPsid();
const result = await authRepo.facebookIdLogin({
fbId: asidR.data,
avatarUrl: avatarUrlR.success ? avatarUrlR.data ?? undefined : undefined,
psid,
});
if (Result.isErr(result)) {
+9
View File
@@ -13,3 +13,12 @@ export async function readGuestId(): Promise<string | undefined> {
}
return undefined;
}
/** 从本地存储读 PSID;读不到 / 失败时返回 undefined(不抛)。 */
export async function readPsid(): Promise<string | undefined> {
const r = await AuthStorage.getInstance().getPsid();
if (r.success && r.data != null) {
return r.data;
}
return undefined;
}