fix: 登录皮肤站后自动认证默认玩家,修复创建实例误报需要登录
Axolotl desktop CI / guardrails (push) Has been cancelled
Axolotl desktop CI / desktop (macos-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (ubuntu-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (windows-latest) (push) Has been cancelled
Axolotl desktop CI / website (push) Has been cancelled
Repository checks / typos (push) Has been cancelled
Repository checks / tombi (push) Has been cancelled
Rust checks / shear (push) Has been cancelled
Sync source to CNB / Sync Git ref (push) Has been cancelled
Axolotl desktop CI / guardrails (push) Has been cancelled
Axolotl desktop CI / desktop (macos-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (ubuntu-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (windows-latest) (push) Has been cancelled
Axolotl desktop CI / website (push) Has been cancelled
Repository checks / typos (push) Has been cancelled
Repository checks / tombi (push) Has been cancelled
Rust checks / shear (push) Has been cancelled
Sync source to CNB / Sync Git ref (push) Has been cancelled
- requireHostedGameAccount 在无游戏账户但皮肤站已登录时,自动认证第一个非 Mojang 玩家 - 新增测试覆盖该自动认证流程
This commit is contained in:
1 parent
214066ae5f
commit
91e63fdb2c
2 files changed
+139
-3
No files matched your search
@@ -605,3 +605,110 @@ test('skin updates are restricted to known non-Mojang players and validated resu
|
||||
setSkinSiteFrame(null)
|
||||
resetSkinSiteSession()
|
||||
})
|
||||
|
||||
test('hosted create auto-authenticates the first skin site player when no game account exists', async () => {
|
||||
const previousWindow = Object.getOwnPropertyDescriptor(globalThis, 'window')
|
||||
const calls: Array<{ command: string; args: Record<string, unknown> }> = []
|
||||
let accounts: Array<{
|
||||
account_type: string
|
||||
yggdrasil?: { api_root: string }
|
||||
}> = []
|
||||
const frame = {
|
||||
postMessage(data: { type: string; requestId: string }) {
|
||||
if (data.type === 'starlight-pack-token-request') {
|
||||
receiveSkinSiteMessage(
|
||||
{
|
||||
origin: SKIN_SITE_ORIGIN,
|
||||
source: frame,
|
||||
data: {
|
||||
type: 'starlight-pack-token-result',
|
||||
requestId: data.requestId,
|
||||
token: 'site.jwt.secret',
|
||||
},
|
||||
} as MessageEvent,
|
||||
frame,
|
||||
)
|
||||
return
|
||||
}
|
||||
if (data.type === 'starlight-skin-players-request') {
|
||||
receiveSkinSiteMessage(
|
||||
{
|
||||
origin: SKIN_SITE_ORIGIN,
|
||||
source: frame,
|
||||
data: {
|
||||
type: 'starlight-skin-players-result',
|
||||
requestId: data.requestId,
|
||||
ok: true,
|
||||
players: [
|
||||
{
|
||||
uuid: '11111111-1111-1111-1111-111111111111',
|
||||
name: 'AutoPlayer',
|
||||
isMojang: false,
|
||||
skinState: 'empty',
|
||||
},
|
||||
],
|
||||
},
|
||||
} as MessageEvent,
|
||||
frame,
|
||||
)
|
||||
}
|
||||
},
|
||||
} as unknown as Window
|
||||
Object.defineProperty(globalThis, 'window', {
|
||||
configurable: true,
|
||||
value: {
|
||||
__TAURI_INTERNALS__: {
|
||||
async invoke(command: string, args: Record<string, unknown>) {
|
||||
calls.push({ command, args })
|
||||
if (command === 'plugin:install|hosted_has_game_account') {
|
||||
return accounts.some(
|
||||
(account) =>
|
||||
account.account_type === 'microsoft' ||
|
||||
(account.account_type === 'yggdrasil' &&
|
||||
account.yggdrasil?.api_root.replace(/\/+$/, '') ===
|
||||
'https://skin.starlight.cool/yggdrasil'),
|
||||
)
|
||||
}
|
||||
if (command === 'plugin:auth|login_skin_site_player') {
|
||||
accounts = [
|
||||
{
|
||||
account_type: 'yggdrasil',
|
||||
yggdrasil: { api_root: 'https://skin.starlight.cool/yggdrasil' },
|
||||
},
|
||||
]
|
||||
return null
|
||||
}
|
||||
if (command === 'plugin:instance|instance_get') return null
|
||||
return command === 'plugin:install|hosted_create' ? 'auto-instance' : null
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
try {
|
||||
resetSkinSiteSession()
|
||||
setSkinSiteFrame(frame)
|
||||
receiveSkinSiteMessage(
|
||||
{
|
||||
origin: SKIN_SITE_ORIGIN,
|
||||
source: frame,
|
||||
data: {
|
||||
type: 'starlight-skin-session',
|
||||
status: 'signed-in',
|
||||
user: { uuid: 'site-user', username: 'Site' },
|
||||
},
|
||||
} as MessageEvent,
|
||||
frame,
|
||||
)
|
||||
await requestSkinSitePlayers().catch(() => {})
|
||||
assert.equal(await hostedCreate(), 'auto-instance')
|
||||
assert.ok(
|
||||
calls.some(({ command }) => command === 'plugin:auth|login_skin_site_player'),
|
||||
'expected automatic player authentication',
|
||||
)
|
||||
} finally {
|
||||
resetSkinSiteSession()
|
||||
setSkinSiteFrame(null)
|
||||
if (previousWindow) Object.defineProperty(globalThis, 'window', previousWindow)
|
||||
else delete (globalThis as { window?: unknown }).window
|
||||
}
|
||||
})
|
||||
@@ -2,10 +2,13 @@ import { invoke } from '@tauri-apps/api/core'
|
||||
|
||||
import {
|
||||
requestSkinSiteDownloadToken,
|
||||
requestSkinSitePlayers,
|
||||
skinSitePlayers,
|
||||
skinSiteStatus,
|
||||
skinSiteUser,
|
||||
waitForSkinSiteSession,
|
||||
} from '../composables/skin-site-session.ts'
|
||||
import { authenticateInstancePlayer } from './instance-player.ts'
|
||||
|
||||
export const HOSTED_ACCOUNT_REQUIRED_MESSAGE = '您需要登录正版或皮肤站账号后才能操作'
|
||||
|
||||
@@ -24,10 +27,36 @@ function startHostedPackAttempt(instanceId: string) {
|
||||
}
|
||||
|
||||
export async function requireHostedGameAccount(): Promise<void> {
|
||||
const available = await invokeHosted<boolean>('plugin:install|hosted_has_game_account')
|
||||
if (!available) {
|
||||
throw new Error(HOSTED_ACCOUNT_REQUIRED_MESSAGE)
|
||||
if (await invokeHosted<boolean>('plugin:install|hosted_has_game_account')) return
|
||||
|
||||
// No game credential yet, but a signed-in skin site already lists the
|
||||
// user's players. Authenticate the first one automatically so the user
|
||||
// does not have to pick a player manually before creating an instance.
|
||||
await waitForSkinSiteSession()
|
||||
if (skinSiteStatus.value === 'signed-in' && skinSiteUser.value) {
|
||||
if (skinSitePlayers.value.length === 0) {
|
||||
await requestSkinSitePlayers().catch(() => {})
|
||||
}
|
||||
const player =
|
||||
skinSitePlayers.value.find((candidate) => !candidate.isMojang) ?? skinSitePlayers.value[0]
|
||||
if (player) {
|
||||
try {
|
||||
await authenticateInstancePlayer({
|
||||
id: player.uuid,
|
||||
name: player.name,
|
||||
account_type: 'yggdrasil',
|
||||
skin_site_user: skinSiteUser.value.uuid,
|
||||
})
|
||||
} catch {
|
||||
// Fall through to the login-required error below.
|
||||
}
|
||||
if (await invokeHosted<boolean>('plugin:install|hosted_has_game_account')) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(HOSTED_ACCOUNT_REQUIRED_MESSAGE)
|
||||
}
|
||||
|
||||
export function clearHostedSession(): Promise<void> {
|
||||
|
||||
Reference in new issue
Block a user