This commit is contained in:
2026-04-22 23:44:57 +08:00
parent 76ac9d22a5
commit 84dc92646a
484 changed files with 9598 additions and 9135 deletions

View File

@@ -41,13 +41,13 @@ use crate::{
generate_character_visual, get_character_visual_job, publish_character_visual,
},
custom_world::{
create_custom_world_agent_session, execute_custom_world_agent_action,
get_custom_world_agent_card_detail, get_custom_world_agent_operation,
get_custom_world_agent_session, get_custom_world_gallery_detail, get_custom_world_library,
get_custom_world_library_detail, get_custom_world_works, list_custom_world_gallery,
publish_custom_world_library_profile, put_custom_world_library_profile,
stream_custom_world_agent_message, submit_custom_world_agent_message,
unpublish_custom_world_library_profile,
create_custom_world_agent_session, delete_custom_world_library_profile,
execute_custom_world_agent_action, get_custom_world_agent_card_detail,
get_custom_world_agent_operation, get_custom_world_agent_session,
get_custom_world_gallery_detail, get_custom_world_library, get_custom_world_library_detail,
get_custom_world_works, list_custom_world_gallery, publish_custom_world_library_profile,
put_custom_world_library_profile, stream_custom_world_agent_message,
submit_custom_world_agent_message, unpublish_custom_world_library_profile,
},
custom_world_ai::{
generate_custom_world_cover_image, generate_custom_world_entity,
@@ -359,6 +359,7 @@ pub fn build_router(state: AppState) -> Router {
"/api/runtime/custom-world-library/{profile_id}",
get(get_custom_world_library_detail)
.put(put_custom_world_library_profile)
.delete(delete_custom_world_library_profile)
.route_layer(middleware::from_fn_with_state(
state.clone(),
require_bearer_auth,

View File

@@ -59,7 +59,7 @@ pub async fn require_bearer_auth(
mut request: Request,
next: Next,
) -> Result<Response, AppError> {
if request.uri().path().starts_with("/api/runtime/big-fish/")
if allows_internal_forwarded_auth(request.uri().path())
&& let Some(claims) = try_build_internal_forwarded_claims(&state, request.headers())
{
request
@@ -187,6 +187,11 @@ fn extract_bearer_token(headers: &HeaderMap) -> Result<String, AppError> {
Ok(token.to_string())
}
fn allows_internal_forwarded_auth(path: &str) -> bool {
// Node 代理已经完成平台账号 JWT 校验Rust 运行时只信任这些明确的内部转发路径。
path.starts_with("/api/runtime/big-fish/") || path.starts_with("/api/runtime/puzzle/")
}
fn try_build_internal_forwarded_claims(
state: &AppState,
headers: &HeaderMap,
@@ -234,7 +239,7 @@ fn try_build_internal_forwarded_claims(
mod tests {
use super::{
INTERNAL_API_SECRET_HEADER, INTERNAL_AUTH_USER_ID_HEADER, RefreshSessionToken,
extract_bearer_token, try_build_internal_forwarded_claims,
allows_internal_forwarded_auth, extract_bearer_token, try_build_internal_forwarded_claims,
};
use crate::{config::AppConfig, state::AppState};
use axum::{
@@ -272,6 +277,15 @@ mod tests {
assert_eq!(token.token(), "refresh-token-01");
}
#[test]
fn internal_forwarded_auth_allows_node_proxy_runtime_paths() {
assert!(allows_internal_forwarded_auth(
"/api/runtime/big-fish/sessions"
));
assert!(allows_internal_forwarded_auth("/api/runtime/puzzle/works"));
assert!(!allows_internal_forwarded_auth("/api/auth/me"));
}
#[test]
fn internal_forwarded_claims_require_matching_secret() {
let mut config = AppConfig::default();

View File

@@ -178,6 +178,42 @@ pub async fn put_custom_world_library_profile(
))
}
pub async fn delete_custom_world_library_profile(
State(state): State<AppState>,
Extension(request_context): Extension<RequestContext>,
Extension(authenticated): Extension<AuthenticatedAccessToken>,
Path(profile_id): Path<String>,
) -> Result<Json<Value>, Response> {
let owner_user_id = authenticated.claims().user_id().to_string();
if profile_id.trim().is_empty() {
return Err(custom_world_error_response(
&request_context,
AppError::from_status(StatusCode::BAD_REQUEST).with_details(json!({
"provider": "custom-world-library",
"message": "profileId is required",
})),
));
}
let entries = state
.spacetime_client()
.delete_custom_world_profile(profile_id, owner_user_id, current_utc_micros())
.await
.map_err(|error| {
custom_world_error_response(&request_context, map_custom_world_client_error(error))
})?;
Ok(json_success_body(
Some(&request_context),
CustomWorldLibraryResponse {
entries: entries
.into_iter()
.map(map_custom_world_library_entry_response)
.collect(),
},
))
}
pub async fn publish_custom_world_library_profile(
State(state): State<AppState>,
Extension(request_context): Extension<RequestContext>,