Execute batch uploads with metadata gates, encryption, and queue state.
Separate upload entries per file, ALTCHA on POST, and stripped-or-original fallback on metadata errors.
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
export const makeKeyFromFile = (file: File): string =>
|
||||
`${file.name}\0${file.size}\0${file.lastModified}`;
|
||||
@@ -0,0 +1,9 @@
|
||||
import type { UploadBatchSettingsForm } from '@/types/upload/UploadBatchSettingsForm';
|
||||
import type { UploadOptionsRequest } from '@/types/upload/UploadOptionsRequest';
|
||||
import { resolveUploadBatchExpiresAt } from '@/utils/upload/resolveUploadBatchExpiresAt';
|
||||
import { resolveUploadBatchMaxViews } from '@/utils/upload/resolveUploadBatchMaxViews';
|
||||
|
||||
export const buildUploadOptionsFromBatchSettings = (settings: UploadBatchSettingsForm): UploadOptionsRequest => ({
|
||||
expiresAt: resolveUploadBatchExpiresAt(settings.expiryPreset),
|
||||
maxViews: resolveUploadBatchMaxViews(settings.maxViewsPreset)
|
||||
});
|
||||
@@ -27,15 +27,10 @@ describe('buildZkUploadPrepareOptionsFromBatchSettings', () => {
|
||||
maxViewsPreset: '10' as const
|
||||
};
|
||||
|
||||
const result = buildZkUploadPrepareOptionsFromBatchSettings(settings);
|
||||
|
||||
expect(result).toEqual({
|
||||
ok: true,
|
||||
options: {
|
||||
expiresAt: '2026-06-02T00:00:00.000Z',
|
||||
maxViews: 10,
|
||||
passwordProtected: false
|
||||
}
|
||||
expect(buildZkUploadPrepareOptionsFromBatchSettings(settings)).toEqual({
|
||||
expiresAt: '2026-06-02T00:00:00.000Z',
|
||||
maxViews: 10,
|
||||
passwordProtected: false
|
||||
});
|
||||
});
|
||||
|
||||
@@ -46,29 +41,11 @@ describe('buildZkUploadPrepareOptionsFromBatchSettings', () => {
|
||||
password: 'batch-secret'
|
||||
};
|
||||
|
||||
const result = buildZkUploadPrepareOptionsFromBatchSettings(settings);
|
||||
|
||||
expect(result).toEqual({
|
||||
ok: true,
|
||||
options: {
|
||||
expiresAt: null,
|
||||
maxViews: null,
|
||||
passwordProtected: true,
|
||||
password: 'batch-secret'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('returns validation errors', () => {
|
||||
const settings = {
|
||||
...baseSettings,
|
||||
passwordEnabled: true,
|
||||
password: ''
|
||||
};
|
||||
|
||||
expect(buildZkUploadPrepareOptionsFromBatchSettings(settings)).toEqual({
|
||||
ok: false,
|
||||
error: 'Enter a password or turn off password protection.'
|
||||
expiresAt: null,
|
||||
maxViews: null,
|
||||
passwordProtected: true,
|
||||
password: 'batch-secret'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,39 +1,22 @@
|
||||
import type { UploadBatchSettingsForm } from '@/types/upload/UploadBatchSettingsForm';
|
||||
import type { ZkUploadPrepareOptionsResult } from '@/types/upload/ZkUploadPrepareOptionsResult';
|
||||
import { resolveUploadBatchExpiresAt } from '@/utils/upload/resolveUploadBatchExpiresAt';
|
||||
import { resolveUploadBatchMaxViews } from '@/utils/upload/resolveUploadBatchMaxViews';
|
||||
import { validateUploadBatchSettings } from '@/utils/upload/validateUploadBatchSettings';
|
||||
import type { ZkUploadPrepareOptions } from '@/types/upload/ZkUploadPrepareOptions';
|
||||
import { buildUploadOptionsFromBatchSettings } from '@/utils/upload/buildUploadOptionsFromBatchSettings';
|
||||
|
||||
export const buildZkUploadPrepareOptionsFromBatchSettings = (
|
||||
settings: UploadBatchSettingsForm
|
||||
): ZkUploadPrepareOptionsResult => {
|
||||
const validationError = validateUploadBatchSettings(settings);
|
||||
|
||||
if (validationError) {
|
||||
return { ok: false, error: validationError };
|
||||
}
|
||||
|
||||
const uploadOptions = {
|
||||
expiresAt: resolveUploadBatchExpiresAt(settings.expiryPreset),
|
||||
maxViews: resolveUploadBatchMaxViews(settings.maxViewsPreset)
|
||||
};
|
||||
): ZkUploadPrepareOptions => {
|
||||
const uploadOptions = buildUploadOptionsFromBatchSettings(settings);
|
||||
|
||||
if (settings.passwordEnabled) {
|
||||
return {
|
||||
ok: true,
|
||||
options: {
|
||||
...uploadOptions,
|
||||
passwordProtected: true,
|
||||
password: settings.password
|
||||
}
|
||||
...uploadOptions,
|
||||
passwordProtected: true,
|
||||
password: settings.password
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
ok: true,
|
||||
options: {
|
||||
...uploadOptions,
|
||||
passwordProtected: false
|
||||
}
|
||||
...uploadOptions,
|
||||
passwordProtected: false
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { CreateHotlinkUploadRequest } from '@/types/upload/CreateHotlinkUploadRequest';
|
||||
import type { PreparedHotlinkUploadRequest } from '@/types/upload/PreparedHotlinkUploadRequest';
|
||||
import type { UploadOptionsRequest } from '@/types/upload/UploadOptionsRequest';
|
||||
import { bytesToBase64 } from '@/utils/encoding/bytesToBase64';
|
||||
import { encryptHotlinkUpload } from '@/utils/upload/encryptHotlinkUpload';
|
||||
@@ -7,7 +7,7 @@ export const prepareHotlinkUploadRequest = async (
|
||||
plaintext: Uint8Array,
|
||||
mimeType: string,
|
||||
options: UploadOptionsRequest
|
||||
): Promise<{ request: CreateHotlinkUploadRequest; secret: string }> => {
|
||||
): Promise<PreparedHotlinkUploadRequest> => {
|
||||
const encrypted = await encryptHotlinkUpload(plaintext);
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { CreateZkUploadRequest } from '@/types/upload/CreateZkUploadRequest';
|
||||
import type { PreparedZkUploadRequest } from '@/types/upload/PreparedZkUploadRequest';
|
||||
import type { ZkUploadPrepareOptions } from '@/types/upload/ZkUploadPrepareOptions';
|
||||
import { bytesToBase64 } from '@/utils/encoding/bytesToBase64';
|
||||
import { bytesToBase64Url } from '@/utils/encoding/bytesToBase64Url';
|
||||
@@ -9,7 +9,7 @@ import { wrapZkDek } from '@/utils/upload/wrapZkDek';
|
||||
export const prepareZkUploadRequest = async (
|
||||
plaintext: Uint8Array,
|
||||
options: ZkUploadPrepareOptions
|
||||
): Promise<{ request: CreateZkUploadRequest; fragmentKey: string }> => {
|
||||
): Promise<PreparedZkUploadRequest> => {
|
||||
if (!options.passwordProtected) {
|
||||
const { dek, iv, ciphertext } = await encryptZkUpload(plaintext);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user