feat(auth): add psid field to various login request DTOs and schemas
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ export const LoginRequestSchema = z.object({
|
||||
password: z.string(),
|
||||
platform: z.string(),
|
||||
guestId: stringOrEmpty,
|
||||
psid: stringOrEmpty,
|
||||
isTestAccount: booleanOrFalse,
|
||||
});
|
||||
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user