本地 dev 不再把默认 CLI 配置里的远程 token 当作本地发布凭据
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 1m15s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 56s
Project CI / Backend tests (pull_request) Failing after 14s
Project CI / Frontend tests (pull_request) Successful in 1m57s
Project CI / Repository checks (pull_request) Failing after 16s
Project CI / AI game creator shell web tests (pull_request) Successful in 1m23s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 8m1s
Project CI / Native shell tests (pull_request) Successful in 5m45s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 8m37s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 1m15s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 56s
Project CI / Backend tests (pull_request) Failing after 14s
Project CI / Frontend tests (pull_request) Successful in 1m57s
Project CI / Repository checks (pull_request) Failing after 16s
Project CI / AI game creator shell web tests (pull_request) Successful in 1m23s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 8m1s
Project CI / Native shell tests (pull_request) Successful in 5m45s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 8m37s
- shouldTrustExistingSpacetimeToken:本地(loopback)服务器额外要求 token 由本机签发(JWT iss 为 localhost/127.0.0.1/::1);默认 CLI 配置里的远程账号 token 形如有效但验签必然失败,会在 pre-publish check 抛 401 InvalidSignature - 显式 shell 覆盖 GENARRATIVE_SPACETIME_TOKEN 的语义保持不变,仍然优先 - 单测:远程签发 token 在本地服务器上不被信任、本机签发 token 被信任 - 验证:scripts/dev.test.ts 70 passed - 未覆盖(后续):本机签发但已失效的旧 token(数据目录重建后签名失效,iss 仍为 localhost)仍需手工清理 dev-cli/cli.toml 与 dev-api-identities/local-node.json;自动自愈需要把发布调用改成非致命,因为当前 runForeground 失败会直接结束进程,调用层 catch 拿不到
This commit is contained in:
+37
-1
@@ -3259,19 +3259,54 @@ function shouldTrustExistingSpacetimeToken(
|
||||
return false;
|
||||
}
|
||||
|
||||
// 本地 standalone 只认自己签发的 token:远程账号的 token(默认 CLI 配置里那种)
|
||||
// 形如有效但验签必然失败,会在 pre-publish check 上抛 401 InvalidSize。
|
||||
// 因此先按签发者判断,再做「与环境/CLI 一致」这类弱判断。
|
||||
const shellToken = String(env.GENARRATIVE_SPACETIME_TOKEN ?? '').trim();
|
||||
if (shellToken && shellToken === normalizedToken) {
|
||||
// 显式覆盖(运维手动指定)优先,保持既有语义。
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!isLoopbackSpacetimeServer(serverUrl)) {
|
||||
const loopback = isLoopbackSpacetimeServer(serverUrl);
|
||||
if (!loopback) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 本地 standalone 只认自己签发的 token:默认 CLI 配置里那枚远程账号 token
|
||||
// 形如有效但验签必然失败(pre-publish check 401 InvalidSignature),不能信任。
|
||||
if (!isLocallyIssuedSpacetimeToken(normalizedToken)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const cliToken = resolveCliToken();
|
||||
return Boolean(cliToken && cliToken === normalizedToken);
|
||||
}
|
||||
|
||||
/// JWT 的 iss 是否指向本机服务器(localhost/127.0.0.1/::1 或 *.localhost)。
|
||||
function isLocallyIssuedSpacetimeToken(token) {
|
||||
try {
|
||||
const payload = String(token).split('.')[1];
|
||||
if (!payload) {
|
||||
return false;
|
||||
}
|
||||
const claims = JSON.parse(
|
||||
Buffer.from(payload, 'base64url').toString('utf8'),
|
||||
);
|
||||
const issuer = String(claims.iss ?? '').trim();
|
||||
if (issuer === 'localhost' || issuer.endsWith('.localhost')) {
|
||||
return true;
|
||||
}
|
||||
if (!issuer) {
|
||||
return false;
|
||||
}
|
||||
const url = new URL(issuer.includes('://') ? issuer : `http://${issuer}`);
|
||||
return ['127.0.0.1', 'localhost', '::1'].includes(url.hostname);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function isLoopbackSpacetimeServer(serverUrl) {
|
||||
try {
|
||||
const url = new URL(serverUrl);
|
||||
@@ -3544,6 +3579,7 @@ export {
|
||||
createWatchConfigs,
|
||||
DevRunner,
|
||||
isDirectModuleExecution,
|
||||
isLocallyIssuedSpacetimeToken,
|
||||
isSpacetimePublishPermissionError,
|
||||
isStaleExternalGenerationWorkerProcess,
|
||||
normalizeCargoVersionRequirement,
|
||||
|
||||
Reference in New Issue
Block a user