feat: harden file sharing and integrity
This commit is contained in:
+71
-1
@@ -1,4 +1,15 @@
|
||||
import { ApiError, apiFetch, apiUrl, authHeaders, csrfToken, type ApiSettings, type DeltaDeletedItem, type FilesManagedFileLinkTarget } from "@govoplan/core-webui";
|
||||
import {
|
||||
ApiError,
|
||||
apiFetch,
|
||||
apiReferenceOptionProvider,
|
||||
apiUrl,
|
||||
authHeaders,
|
||||
csrfToken,
|
||||
type ApiSettings,
|
||||
type DeltaDeletedItem,
|
||||
type FilesManagedFileLinkTarget,
|
||||
type ReferenceOptionProvider
|
||||
} from "@govoplan/core-webui";
|
||||
export { fetchResourceAccessExplanation } from "@govoplan/core-webui";
|
||||
export type {
|
||||
AccessDecisionProvenanceItem,
|
||||
@@ -24,11 +35,16 @@ export type FileSpace = {
|
||||
|
||||
export type FileShare = {
|
||||
id: string;
|
||||
file_asset_id: string;
|
||||
target_type: string;
|
||||
target_id: string;
|
||||
permission: string;
|
||||
created_by_user_id?: string | null;
|
||||
created_at: string;
|
||||
expires_at?: string | null;
|
||||
revoked_at?: string | null;
|
||||
revoked_by_user_id?: string | null;
|
||||
active: boolean;
|
||||
};
|
||||
|
||||
export type FileSourceProvenance = {
|
||||
@@ -593,6 +609,12 @@ export function bulkDeleteFiles(settings: ApiSettings, fileIds: string[]): Promi
|
||||
}
|
||||
|
||||
export type FileBulkShareResponse = {shares: FileShare[];shared_count: number;};
|
||||
export type FileSharePayload = {
|
||||
target_type: "user" | "group" | "tenant" | "campaign";
|
||||
target_id: string;
|
||||
permission: "read" | "write" | "manage";
|
||||
expires_at?: string | null;
|
||||
};
|
||||
|
||||
export function virtualFolderResourceId(options: {tenantId: string;ownerType: "user" | "group";ownerId: string;path: string;}): string {
|
||||
return `virtual-folder:v1:${options.tenantId}:${options.ownerType}:${options.ownerId}:${base64Url(options.path.replace(/\\/g, "/").replace(/^\/+|\/+$/g, ""))}`;
|
||||
@@ -612,6 +634,54 @@ export function shareFilesWithTarget(settings: ApiSettings, fileIds: string[], t
|
||||
});
|
||||
}
|
||||
|
||||
export function listFileShares(
|
||||
settings: ApiSettings,
|
||||
fileId: string,
|
||||
options: { includeInactive?: boolean } = {}
|
||||
): Promise<{ shares: FileShare[] }> {
|
||||
const suffix = options.includeInactive ? "?include_inactive=true" : "";
|
||||
return apiFetch<{ shares: FileShare[] }>(
|
||||
settings,
|
||||
`/api/v1/files/${encodeURIComponent(fileId)}/shares${suffix}`
|
||||
);
|
||||
}
|
||||
|
||||
export function createFileShare(
|
||||
settings: ApiSettings,
|
||||
fileId: string,
|
||||
payload: FileSharePayload
|
||||
): Promise<FileShare> {
|
||||
return apiFetch<FileShare>(
|
||||
settings,
|
||||
`/api/v1/files/${encodeURIComponent(fileId)}/shares`,
|
||||
{ method: "POST", body: JSON.stringify(payload) }
|
||||
);
|
||||
}
|
||||
|
||||
export function revokeFileShare(
|
||||
settings: ApiSettings,
|
||||
fileId: string,
|
||||
shareId: string
|
||||
): Promise<FileShare> {
|
||||
return apiFetch<FileShare>(
|
||||
settings,
|
||||
`/api/v1/files/${encodeURIComponent(fileId)}/shares/${encodeURIComponent(shareId)}`,
|
||||
{ method: "DELETE" }
|
||||
);
|
||||
}
|
||||
|
||||
export function fileShareTargetProvider(
|
||||
settings: ApiSettings,
|
||||
fileId: string,
|
||||
targetType: "user" | "group"
|
||||
): ReferenceOptionProvider {
|
||||
return apiReferenceOptionProvider(
|
||||
settings,
|
||||
`/api/v1/files/${encodeURIComponent(fileId)}/share-target-options`,
|
||||
{ target_type: targetType }
|
||||
);
|
||||
}
|
||||
|
||||
export function evaluateFileConnectorPolicy(
|
||||
settings: ApiSettings,
|
||||
payload: {source_provenance: FileSourceProvenance;operation?: string;policy_sources?: FileConnectorPolicySource[];})
|
||||
|
||||
Reference in New Issue
Block a user