mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-18 18:41:52 +08:00
fix: test & lint
This commit is contained in:
@@ -10,6 +10,8 @@ use sha2::{Digest, Sha256};
|
|||||||
|
|
||||||
use super::{BackendRuntime, error::napi_error, types::RuntimeBlobCompleteResult};
|
use super::{BackendRuntime, error::napi_error, types::RuntimeBlobCompleteResult};
|
||||||
|
|
||||||
|
const MAX_BLOB_SIZE: i64 = i32::MAX as i64;
|
||||||
|
|
||||||
fn object_missing_error(err: &napi::Error) -> bool {
|
fn object_missing_error(err: &napi::Error) -> bool {
|
||||||
let message = err.to_string();
|
let message = err.to_string();
|
||||||
message.contains("NoSuchKey") || message.contains("NotFound") || message.contains("not found")
|
message.contains("NoSuchKey") || message.contains("NotFound") || message.contains("not found")
|
||||||
@@ -110,6 +112,11 @@ async fn upsert_completed_blob(
|
|||||||
mime: &str,
|
mime: &str,
|
||||||
size: i64,
|
size: i64,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
if !(0..=MAX_BLOB_SIZE).contains(&size) {
|
||||||
|
return Err(napi_error("BlobComplete size exceeds limit"));
|
||||||
|
}
|
||||||
|
let size = i32::try_from(size).map_err(|_| napi_error("BlobComplete size exceeds limit"))?;
|
||||||
|
|
||||||
sqlx::query(
|
sqlx::query(
|
||||||
r#"
|
r#"
|
||||||
INSERT INTO blobs (workspace_id, key, mime, size, status, upload_id)
|
INSERT INTO blobs (workspace_id, key, mime, size, status, upload_id)
|
||||||
@@ -125,7 +132,7 @@ async fn upsert_completed_blob(
|
|||||||
.bind(workspace_id)
|
.bind(workspace_id)
|
||||||
.bind(key)
|
.bind(key)
|
||||||
.bind(mime)
|
.bind(mime)
|
||||||
.bind(size as i32)
|
.bind(size)
|
||||||
.execute(&runtime.pool().await?)
|
.execute(&runtime.pool().await?)
|
||||||
.await
|
.await
|
||||||
.map_err(|err| napi_error(format!("BlobComplete upsert metadata failed: {err}")))?;
|
.map_err(|err| napi_error(format!("BlobComplete upsert metadata failed: {err}")))?;
|
||||||
@@ -143,6 +150,10 @@ impl BackendRuntime {
|
|||||||
expected_size: i64,
|
expected_size: i64,
|
||||||
expected_mime: String,
|
expected_mime: String,
|
||||||
) -> Result<RuntimeBlobCompleteResult> {
|
) -> Result<RuntimeBlobCompleteResult> {
|
||||||
|
if !(0..=MAX_BLOB_SIZE).contains(&expected_size) {
|
||||||
|
return Ok(blob_complete_failure("size_too_large"));
|
||||||
|
}
|
||||||
|
|
||||||
let object_key = format!("{workspace_id}/{key}");
|
let object_key = format!("{workspace_id}/{key}");
|
||||||
let object = match self.object_storage_get(object_key.clone()).await {
|
let object = match self.object_storage_get(object_key.clone()).await {
|
||||||
Ok(Some(object)) => object,
|
Ok(Some(object)) => object,
|
||||||
@@ -151,6 +162,14 @@ impl BackendRuntime {
|
|||||||
Err(err) => return Err(err),
|
Err(err) => return Err(err),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if !(0..=MAX_BLOB_SIZE).contains(&object.metadata.content_length) {
|
||||||
|
match self.object_storage_delete(object_key).await {
|
||||||
|
Ok(()) => {}
|
||||||
|
Err(err) if object_missing_error(&err) => {}
|
||||||
|
Err(err) => return Err(err),
|
||||||
|
}
|
||||||
|
return Ok(blob_complete_failure("size_too_large"));
|
||||||
|
}
|
||||||
if object.metadata.content_length != expected_size {
|
if object.metadata.content_length != expected_size {
|
||||||
return Ok(blob_complete_failure("size_mismatch"));
|
return Ok(blob_complete_failure("size_mismatch"));
|
||||||
}
|
}
|
||||||
@@ -194,6 +213,10 @@ impl BackendRuntime {
|
|||||||
expected_size: i64,
|
expected_size: i64,
|
||||||
expected_mime: String,
|
expected_mime: String,
|
||||||
) -> Result<RuntimeBlobCompleteResult> {
|
) -> Result<RuntimeBlobCompleteResult> {
|
||||||
|
if !(0..=MAX_BLOB_SIZE).contains(&expected_size) {
|
||||||
|
return Ok(blob_complete_failure("size_too_large"));
|
||||||
|
}
|
||||||
|
|
||||||
let storage_key = format!("{workspace_id}/{key}");
|
let storage_key = format!("{workspace_id}/{key}");
|
||||||
let path = fs_object_path(&root, &bucket, &storage_key)?;
|
let path = fs_object_path(&root, &bucket, &storage_key)?;
|
||||||
let metadata = match read_fs_metadata(&path)? {
|
let metadata = match read_fs_metadata(&path)? {
|
||||||
@@ -201,6 +224,11 @@ impl BackendRuntime {
|
|||||||
None => return Ok(blob_complete_failure("not_found")),
|
None => return Ok(blob_complete_failure("not_found")),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if !(0..=MAX_BLOB_SIZE).contains(&metadata.content_length) {
|
||||||
|
let _ = fs::remove_file(&path);
|
||||||
|
let _ = fs::remove_file(PathBuf::from(format!("{}.metadata.json", path.display())));
|
||||||
|
return Ok(blob_complete_failure("size_too_large"));
|
||||||
|
}
|
||||||
if metadata.content_length != expected_size {
|
if metadata.content_length != expected_size {
|
||||||
return Ok(blob_complete_failure("size_mismatch"));
|
return Ok(blob_complete_failure("size_mismatch"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use super::{runtime_state::*, *};
|
|
||||||
|
|
||||||
use anyhow::{Context, Result as AnyResult, anyhow};
|
use anyhow::{Context, Result as AnyResult, anyhow};
|
||||||
|
|
||||||
|
use super::{runtime_state::*, *};
|
||||||
|
|
||||||
static PG_TEST_LOCK: std::sync::OnceLock<tokio::sync::Mutex<()>> = std::sync::OnceLock::new();
|
static PG_TEST_LOCK: std::sync::OnceLock<tokio::sync::Mutex<()>> = std::sync::OnceLock::new();
|
||||||
const TEST_VERIFICATION_TOKEN_TYPE: i32 = 99_999;
|
const TEST_VERIFICATION_TOKEN_TYPE: i32 = 99_999;
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import serverNativeModule, {
|
|||||||
type ActionEvent as NativeActionEventContract,
|
type ActionEvent as NativeActionEventContract,
|
||||||
type ActionRuntimeInput as NativeActionRuntimeInputContract,
|
type ActionRuntimeInput as NativeActionRuntimeInputContract,
|
||||||
type AssertSafeUrlRequest,
|
type AssertSafeUrlRequest,
|
||||||
|
type BackendRuntimeHealth,
|
||||||
type BuiltInPromptRenderContract,
|
type BuiltInPromptRenderContract,
|
||||||
type BuiltInPromptSessionContract,
|
type BuiltInPromptSessionContract,
|
||||||
type BuiltInPromptSpec,
|
type BuiltInPromptSpec,
|
||||||
@@ -45,6 +46,22 @@ import serverNativeModule, {
|
|||||||
type RequestedModelMatchResponse,
|
type RequestedModelMatchResponse,
|
||||||
type ResolvedEntitlement,
|
type ResolvedEntitlement,
|
||||||
type ResolveEntitlementInput,
|
type ResolveEntitlementInput,
|
||||||
|
type RuntimeBlobCleanupResult,
|
||||||
|
type RuntimeBlobCompleteResult,
|
||||||
|
type RuntimeByokLocalLeaseRecord,
|
||||||
|
type RuntimeDocCompactionResult,
|
||||||
|
type RuntimeMagicLinkOtpConsumeResult,
|
||||||
|
type RuntimeMultipartUploadInit,
|
||||||
|
type RuntimeMultipartUploadPart,
|
||||||
|
type RuntimeObjectGetResult,
|
||||||
|
type RuntimeObjectListEntry,
|
||||||
|
type RuntimeObjectMetadata,
|
||||||
|
type RuntimeObjectStorageHealth,
|
||||||
|
type RuntimeObjectStoragePutOptions,
|
||||||
|
type RuntimePresignedObjectRequest,
|
||||||
|
type RuntimeVerificationTokenRecord,
|
||||||
|
type RuntimeWorkspaceInviteLinkRecord,
|
||||||
|
type RuntimeWorkspaceStatsDailyRecalibrationResult,
|
||||||
type SafeFetchRequest,
|
type SafeFetchRequest,
|
||||||
type SafeFetchResponse,
|
type SafeFetchResponse,
|
||||||
type Tokenizer,
|
type Tokenizer,
|
||||||
@@ -52,6 +69,7 @@ import serverNativeModule, {
|
|||||||
|
|
||||||
export type {
|
export type {
|
||||||
AssertSafeUrlRequest,
|
AssertSafeUrlRequest,
|
||||||
|
BackendRuntimeHealth,
|
||||||
CapabilityAttachmentContract,
|
CapabilityAttachmentContract,
|
||||||
CapabilityModelCapability,
|
CapabilityModelCapability,
|
||||||
CommandResponse,
|
CommandResponse,
|
||||||
@@ -73,6 +91,22 @@ export type {
|
|||||||
RemoteMimeTypeRequest,
|
RemoteMimeTypeRequest,
|
||||||
ResolvedEntitlement,
|
ResolvedEntitlement,
|
||||||
ResolveEntitlementInput,
|
ResolveEntitlementInput,
|
||||||
|
RuntimeBlobCleanupResult,
|
||||||
|
RuntimeBlobCompleteResult,
|
||||||
|
RuntimeByokLocalLeaseRecord,
|
||||||
|
RuntimeDocCompactionResult,
|
||||||
|
RuntimeMagicLinkOtpConsumeResult,
|
||||||
|
RuntimeMultipartUploadInit,
|
||||||
|
RuntimeMultipartUploadPart,
|
||||||
|
RuntimeObjectGetResult,
|
||||||
|
RuntimeObjectListEntry,
|
||||||
|
RuntimeObjectMetadata,
|
||||||
|
RuntimeObjectStorageHealth,
|
||||||
|
RuntimeObjectStoragePutOptions,
|
||||||
|
RuntimePresignedObjectRequest,
|
||||||
|
RuntimeVerificationTokenRecord,
|
||||||
|
RuntimeWorkspaceInviteLinkRecord,
|
||||||
|
RuntimeWorkspaceStatsDailyRecalibrationResult,
|
||||||
SafeFetchRequest,
|
SafeFetchRequest,
|
||||||
SafeFetchResponse,
|
SafeFetchResponse,
|
||||||
};
|
};
|
||||||
@@ -180,6 +214,7 @@ export const readAllDocIdsFromRootDoc =
|
|||||||
export const AFFINE_PRO_PUBLIC_KEY = serverNativeModule.AFFINE_PRO_PUBLIC_KEY;
|
export const AFFINE_PRO_PUBLIC_KEY = serverNativeModule.AFFINE_PRO_PUBLIC_KEY;
|
||||||
export const AFFINE_PRO_LICENSE_AES_KEY =
|
export const AFFINE_PRO_LICENSE_AES_KEY =
|
||||||
serverNativeModule.AFFINE_PRO_LICENSE_AES_KEY;
|
serverNativeModule.AFFINE_PRO_LICENSE_AES_KEY;
|
||||||
|
export const BackendRuntime = serverNativeModule.BackendRuntime;
|
||||||
|
|
||||||
export type PermissionWorkspaceRole = 'external' | 'member' | 'admin' | 'owner';
|
export type PermissionWorkspaceRole = 'external' | 'member' | 'admin' | 'owner';
|
||||||
export type PermissionDocRole =
|
export type PermissionDocRole =
|
||||||
|
|||||||
Reference in New Issue
Block a user