refactor: 收口推荐 runtime 鉴权计划
This commit is contained in:
@@ -585,6 +585,10 @@ import {
|
||||
buildPuzzleResultProfileId,
|
||||
buildPuzzleResultWorkId,
|
||||
} from './platformPuzzleIdentityModel';
|
||||
import {
|
||||
type PlatformPuzzleRuntimeAuthMode,
|
||||
resolvePlatformRecommendRuntimeAuthPlan,
|
||||
} from './platformRecommendRuntimeAuthModel';
|
||||
import {
|
||||
buildPlatformRpgAgentResultPublishGateView,
|
||||
resolvePlatformRpgAgentResultPreviewSourceLabel,
|
||||
@@ -624,7 +628,7 @@ type PuzzleRuntimeReturnStage =
|
||||
| 'puzzle-gallery-detail'
|
||||
| 'work-detail'
|
||||
| 'platform';
|
||||
type PuzzleRuntimeAuthMode = 'default' | 'isolated';
|
||||
type PuzzleRuntimeAuthMode = PlatformPuzzleRuntimeAuthMode;
|
||||
|
||||
type PuzzleOnboardingDraft = {
|
||||
promptText: string;
|
||||
@@ -686,6 +690,10 @@ const RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS =
|
||||
BACKGROUND_AUTH_REQUEST_OPTIONS;
|
||||
const RECOMMEND_PUZZLE_BACKGROUND_AUTH_OPTIONS =
|
||||
RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS;
|
||||
type RecommendRuntimeAuthUi =
|
||||
| { user?: { id?: string } | null }
|
||||
| null
|
||||
| undefined;
|
||||
async function buildRecommendRuntimeGuestOptions() {
|
||||
const { token } = await ensureRuntimeGuestToken();
|
||||
return {
|
||||
@@ -693,24 +701,35 @@ async function buildRecommendRuntimeGuestOptions() {
|
||||
runtimeGuestToken: token,
|
||||
};
|
||||
}
|
||||
function shouldUseRecommendRuntimeGuestAuth(
|
||||
authUi: { user?: { id?: string } | null } | null | undefined,
|
||||
function resolveCurrentRecommendRuntimeAuthPlan(
|
||||
authUi: RecommendRuntimeAuthUi,
|
||||
input: { embedded?: boolean; allowRuntimeGuestAuth?: boolean } = {},
|
||||
) {
|
||||
return !authUi?.user?.id?.trim() && !getStoredAccessToken();
|
||||
return resolvePlatformRecommendRuntimeAuthPlan({
|
||||
embedded: input.embedded,
|
||||
allowRuntimeGuestAuth: input.allowRuntimeGuestAuth,
|
||||
authUserId: authUi?.user?.id ?? null,
|
||||
hasStoredAccessToken: Boolean(getStoredAccessToken()),
|
||||
});
|
||||
}
|
||||
async function buildRecommendRuntimeAuthOptions(
|
||||
authUi: { user?: { id?: string } | null } | null | undefined,
|
||||
embedded?: boolean,
|
||||
async function buildRecommendRuntimeOptionsFromAuthPlan(
|
||||
plan: ReturnType<typeof resolvePlatformRecommendRuntimeAuthPlan>,
|
||||
) {
|
||||
if (!embedded) {
|
||||
return {};
|
||||
}
|
||||
|
||||
if (shouldUseRecommendRuntimeGuestAuth(authUi)) {
|
||||
if (plan.requestKind === 'runtime-guest') {
|
||||
return buildRecommendRuntimeGuestOptions();
|
||||
}
|
||||
|
||||
return RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS;
|
||||
if (plan.requestKind === 'background') {
|
||||
return RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
async function buildRecommendRuntimeAuthOptions(
|
||||
authUi: RecommendRuntimeAuthUi,
|
||||
embedded?: boolean,
|
||||
) {
|
||||
return buildRecommendRuntimeOptionsFromAuthPlan(
|
||||
resolveCurrentRecommendRuntimeAuthPlan(authUi, { embedded }),
|
||||
);
|
||||
}
|
||||
const PUZZLE_DRAFT_GENERATION_POINT_COST = 2;
|
||||
const MATCH3D_DRAFT_GENERATION_POINT_COST = 10;
|
||||
@@ -8106,19 +8125,22 @@ export function PlatformEntryFlowShellImpl({
|
||||
profileId: item.profileId,
|
||||
levelId: normalizedLevelId || null,
|
||||
};
|
||||
const canUseRuntimeGuestAuth =
|
||||
options.embedded || options.authMode === 'isolated';
|
||||
const useRuntimeGuestAuth =
|
||||
canUseRuntimeGuestAuth && shouldUseRecommendRuntimeGuestAuth(authUi);
|
||||
const runtimeGuestOptions = useRuntimeGuestAuth
|
||||
? await buildRecommendRuntimeGuestOptions()
|
||||
: {};
|
||||
const authMode = useRuntimeGuestAuth ? 'isolated' : 'default';
|
||||
const runtimeAuthOptions = useRuntimeGuestAuth
|
||||
? runtimeGuestOptions
|
||||
: canUseRuntimeGuestAuth
|
||||
? RECOMMEND_PUZZLE_BACKGROUND_AUTH_OPTIONS
|
||||
const authPlan = resolveCurrentRecommendRuntimeAuthPlan(authUi, {
|
||||
embedded: options.embedded,
|
||||
allowRuntimeGuestAuth:
|
||||
options.embedded || options.authMode === 'isolated',
|
||||
});
|
||||
const runtimeGuestOptions =
|
||||
authPlan.requestKind === 'runtime-guest'
|
||||
? await buildRecommendRuntimeGuestOptions()
|
||||
: {};
|
||||
const authMode = authPlan.puzzleRuntimeAuthMode;
|
||||
const runtimeAuthOptions =
|
||||
authPlan.requestKind === 'runtime-guest'
|
||||
? runtimeGuestOptions
|
||||
: authPlan.requestKind === 'background'
|
||||
? RECOMMEND_PUZZLE_BACKGROUND_AUTH_OPTIONS
|
||||
: {};
|
||||
const { run } =
|
||||
authMode === 'isolated'
|
||||
? await startPuzzleRun(startRunPayload, runtimeGuestOptions)
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import {
|
||||
resolvePlatformRecommendRuntimeAuthPlan,
|
||||
shouldUsePlatformRecommendRuntimeGuestAuth,
|
||||
} from './platformRecommendRuntimeAuthModel';
|
||||
|
||||
test('uses runtime guest auth for anonymous embedded recommendation runtime', () => {
|
||||
expect(
|
||||
resolvePlatformRecommendRuntimeAuthPlan({
|
||||
embedded: true,
|
||||
authUserId: null,
|
||||
hasStoredAccessToken: false,
|
||||
}),
|
||||
).toEqual({
|
||||
requestKind: 'runtime-guest',
|
||||
puzzleRuntimeAuthMode: 'isolated',
|
||||
});
|
||||
});
|
||||
|
||||
test('uses background auth for signed-in embedded recommendation runtime', () => {
|
||||
expect(
|
||||
resolvePlatformRecommendRuntimeAuthPlan({
|
||||
embedded: true,
|
||||
authUserId: 'user-1',
|
||||
hasStoredAccessToken: false,
|
||||
}),
|
||||
).toEqual({
|
||||
requestKind: 'background',
|
||||
puzzleRuntimeAuthMode: 'default',
|
||||
});
|
||||
});
|
||||
|
||||
test('uses background auth when embedded runtime has only a stored access token', () => {
|
||||
expect(
|
||||
resolvePlatformRecommendRuntimeAuthPlan({
|
||||
embedded: true,
|
||||
authUserId: null,
|
||||
hasStoredAccessToken: true,
|
||||
}),
|
||||
).toEqual({
|
||||
requestKind: 'background',
|
||||
puzzleRuntimeAuthMode: 'default',
|
||||
});
|
||||
});
|
||||
|
||||
test('does not alter auth for non-embedded runtime launches by default', () => {
|
||||
expect(
|
||||
resolvePlatformRecommendRuntimeAuthPlan({
|
||||
embedded: false,
|
||||
authUserId: null,
|
||||
hasStoredAccessToken: false,
|
||||
}),
|
||||
).toEqual({
|
||||
requestKind: 'none',
|
||||
puzzleRuntimeAuthMode: 'default',
|
||||
});
|
||||
});
|
||||
|
||||
test('uses isolated guest auth for anonymous puzzle isolated launch', () => {
|
||||
expect(
|
||||
resolvePlatformRecommendRuntimeAuthPlan({
|
||||
embedded: false,
|
||||
allowRuntimeGuestAuth: true,
|
||||
authUserId: null,
|
||||
hasStoredAccessToken: false,
|
||||
}),
|
||||
).toEqual({
|
||||
requestKind: 'runtime-guest',
|
||||
puzzleRuntimeAuthMode: 'isolated',
|
||||
});
|
||||
});
|
||||
|
||||
test('falls back to default puzzle auth when isolated launch has account auth', () => {
|
||||
expect(
|
||||
resolvePlatformRecommendRuntimeAuthPlan({
|
||||
embedded: false,
|
||||
allowRuntimeGuestAuth: true,
|
||||
authUserId: 'user-1',
|
||||
hasStoredAccessToken: false,
|
||||
}),
|
||||
).toEqual({
|
||||
requestKind: 'none',
|
||||
puzzleRuntimeAuthMode: 'default',
|
||||
});
|
||||
});
|
||||
|
||||
test('guest auth decision trims user id before treating account as signed in', () => {
|
||||
expect(
|
||||
shouldUsePlatformRecommendRuntimeGuestAuth({
|
||||
allowRuntimeGuestAuth: true,
|
||||
authUserId: ' ',
|
||||
hasStoredAccessToken: false,
|
||||
}),
|
||||
).toBe(true);
|
||||
});
|
||||
@@ -0,0 +1,58 @@
|
||||
export type PlatformRecommendRuntimeRequestKind =
|
||||
| 'none'
|
||||
| 'background'
|
||||
| 'runtime-guest';
|
||||
|
||||
export type PlatformPuzzleRuntimeAuthMode = 'default' | 'isolated';
|
||||
|
||||
export type PlatformRecommendRuntimeAuthPlan = {
|
||||
requestKind: PlatformRecommendRuntimeRequestKind;
|
||||
puzzleRuntimeAuthMode: PlatformPuzzleRuntimeAuthMode;
|
||||
};
|
||||
|
||||
export type PlatformRecommendRuntimeAuthInput = {
|
||||
embedded?: boolean;
|
||||
allowRuntimeGuestAuth?: boolean;
|
||||
authUserId?: string | null;
|
||||
hasStoredAccessToken?: boolean;
|
||||
};
|
||||
|
||||
function hasAccountAuth(input: {
|
||||
authUserId?: string | null;
|
||||
hasStoredAccessToken?: boolean;
|
||||
}) {
|
||||
return Boolean(input.authUserId?.trim() || input.hasStoredAccessToken);
|
||||
}
|
||||
|
||||
export function shouldUsePlatformRecommendRuntimeGuestAuth(
|
||||
input: Pick<
|
||||
PlatformRecommendRuntimeAuthInput,
|
||||
'allowRuntimeGuestAuth' | 'authUserId' | 'hasStoredAccessToken'
|
||||
>,
|
||||
) {
|
||||
return Boolean(input.allowRuntimeGuestAuth) && !hasAccountAuth(input);
|
||||
}
|
||||
|
||||
export function resolvePlatformRecommendRuntimeAuthPlan(
|
||||
input: PlatformRecommendRuntimeAuthInput,
|
||||
): PlatformRecommendRuntimeAuthPlan {
|
||||
const embedded = Boolean(input.embedded);
|
||||
const allowRuntimeGuestAuth = input.allowRuntimeGuestAuth ?? embedded;
|
||||
const useRuntimeGuestAuth = shouldUsePlatformRecommendRuntimeGuestAuth({
|
||||
allowRuntimeGuestAuth,
|
||||
authUserId: input.authUserId,
|
||||
hasStoredAccessToken: input.hasStoredAccessToken,
|
||||
});
|
||||
|
||||
if (useRuntimeGuestAuth) {
|
||||
return {
|
||||
requestKind: 'runtime-guest',
|
||||
puzzleRuntimeAuthMode: 'isolated',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
requestKind: embedded ? 'background' : 'none',
|
||||
puzzleRuntimeAuthMode: 'default',
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user