mirror of
https://github.com/immich-app/immich
synced 2025-10-17 18:19:27 +00:00
feat(server): Add support for client-side hashing (#2072)
* Modify controller DTOs * Can check duplicates on server side * Remove deviceassetid and deviceid * Remove device ids from file uploader * Add db migration for removed device ids * Don't sanitize checksum * Convert asset checksum to string * Make checksum not optional for asset * Use enums when rejecting duplicates * Cleanup * Return of the device id, but optional * Don't use deviceId for upload folder * Use checksum in thumb path * Only use asset id in thumb path * Openapi generation * Put deviceAssetId back in asset response dto * Add missing checksum in test fixture * Add another missing checksum in test fixture * Cleanup asset repository * Add back previous /exists endpoint * Require checksum to not be null * Correctly set deviceId in db * Remove index * Fix compilation errors * Make device id nullabel in asset response dto * Reduce PR scope * Revert asset service * Reorder imports * Reorder imports * Reduce PR scope * Reduce PR scope * Reduce PR scope * Reduce PR scope * Reduce PR scope * Update openapi * Reduce PR scope * refactor: asset bulk upload check * chore: regenreate open-api * chore: fix tests * chore: tests * update migrations and regenerate api * Feat: use checksum in web file uploader * Change to wasm-crypto * Use crypto api for checksumming in web uploader * Minor cleanup of file upload * feat(web): pause and resume jobs * Make device asset id not nullable again * Cleanup * Device id not nullable in response dto * Update API specs * Bump api specs * Remove old TODO comment * Remove NOT NULL constraint on checksum index * Fix requested pubspec changes * Remove unneeded import * Update server/apps/immich/src/api-v1/asset/asset.service.ts Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> * Update server/apps/immich/src/api-v1/asset/asset-repository.ts Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> * Remove unneeded check * Update server/apps/immich/src/api-v1/asset/asset-repository.ts Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> * Remove hashing in the web uploader * Cleanup file uploader * Remove varchar from asset entity fields * Return 200 from bulk upload check * Put device asset id back into asset repository * Merge migrations * Revert pubspec lock * Update openapi specs * Merge upstream changes * Fix failing asset service tests * Fix formatting issue * Cleanup migrations * Remove newline from pubspec * Revert newline * Checkout main version * Revert again * Only return AssetCheck --------- Co-authored-by: Jason Rasmussen <jrasm91@gmail.com> Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com>
This commit is contained in:
parent
49b74e9091
commit
1b54c4f8e7
33 changed files with 1396 additions and 58 deletions
164
web/src/api/open-api/api.ts
generated
164
web/src/api/open-api/api.ts
generated
|
|
@ -346,6 +346,96 @@ export interface AllJobStatusResponseDto {
|
|||
*/
|
||||
'recognize-faces-queue': JobStatusDto;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
* @interface AssetBulkUploadCheckDto
|
||||
*/
|
||||
export interface AssetBulkUploadCheckDto {
|
||||
/**
|
||||
*
|
||||
* @type {Array<AssetBulkUploadCheckItem>}
|
||||
* @memberof AssetBulkUploadCheckDto
|
||||
*/
|
||||
'assets': Array<AssetBulkUploadCheckItem>;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
* @interface AssetBulkUploadCheckItem
|
||||
*/
|
||||
export interface AssetBulkUploadCheckItem {
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof AssetBulkUploadCheckItem
|
||||
*/
|
||||
'id': string;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof AssetBulkUploadCheckItem
|
||||
*/
|
||||
'checksum': string;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
* @interface AssetBulkUploadCheckResponseDto
|
||||
*/
|
||||
export interface AssetBulkUploadCheckResponseDto {
|
||||
/**
|
||||
*
|
||||
* @type {Array<AssetBulkUploadCheckResult>}
|
||||
* @memberof AssetBulkUploadCheckResponseDto
|
||||
*/
|
||||
'results': Array<AssetBulkUploadCheckResult>;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
* @interface AssetBulkUploadCheckResult
|
||||
*/
|
||||
export interface AssetBulkUploadCheckResult {
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof AssetBulkUploadCheckResult
|
||||
*/
|
||||
'id': string;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof AssetBulkUploadCheckResult
|
||||
*/
|
||||
'action': AssetBulkUploadCheckResultActionEnum;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof AssetBulkUploadCheckResult
|
||||
*/
|
||||
'reason'?: AssetBulkUploadCheckResultReasonEnum;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof AssetBulkUploadCheckResult
|
||||
*/
|
||||
'assetId'?: string;
|
||||
}
|
||||
|
||||
export const AssetBulkUploadCheckResultActionEnum = {
|
||||
Accept: 'accept',
|
||||
Reject: 'reject'
|
||||
} as const;
|
||||
|
||||
export type AssetBulkUploadCheckResultActionEnum = typeof AssetBulkUploadCheckResultActionEnum[keyof typeof AssetBulkUploadCheckResultActionEnum];
|
||||
export const AssetBulkUploadCheckResultReasonEnum = {
|
||||
Duplicate: 'duplicate',
|
||||
UnsupportedFormat: 'unsupported-format'
|
||||
} as const;
|
||||
|
||||
export type AssetBulkUploadCheckResultReasonEnum = typeof AssetBulkUploadCheckResultReasonEnum[keyof typeof AssetBulkUploadCheckResultReasonEnum];
|
||||
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
|
|
@ -4120,6 +4210,50 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration
|
|||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Checks if assets exist by checksums
|
||||
* @param {AssetBulkUploadCheckDto} assetBulkUploadCheckDto
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
bulkUploadCheck: async (assetBulkUploadCheckDto: AssetBulkUploadCheckDto, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'assetBulkUploadCheckDto' is not null or undefined
|
||||
assertParamExists('bulkUploadCheck', 'assetBulkUploadCheckDto', assetBulkUploadCheckDto)
|
||||
const localVarPath = `/asset/bulk-upload-check`;
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||
let baseOptions;
|
||||
if (configuration) {
|
||||
baseOptions = configuration.baseOptions;
|
||||
}
|
||||
|
||||
const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};
|
||||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication cookie required
|
||||
|
||||
// authentication api_key required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration)
|
||||
|
||||
// authentication bearer required
|
||||
// http bearer authentication required
|
||||
await setBearerAuthToObject(localVarHeaderParameter, configuration)
|
||||
|
||||
|
||||
|
||||
localVarHeaderParameter['Content-Type'] = 'application/json';
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
localVarRequestOptions.data = serializeDataIfNeeded(assetBulkUploadCheckDto, localVarRequestOptions, configuration)
|
||||
|
||||
return {
|
||||
url: toPathString(localVarUrlObj),
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Check duplicated asset before uploading - for Web upload used
|
||||
* @param {CheckDuplicateAssetDto} checkDuplicateAssetDto
|
||||
|
|
@ -5312,6 +5446,16 @@ export const AssetApiFp = function(configuration?: Configuration) {
|
|||
const localVarAxiosArgs = await localVarAxiosParamCreator.addAssetsToSharedLink(addAssetsDto, key, options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
/**
|
||||
* Checks if assets exist by checksums
|
||||
* @param {AssetBulkUploadCheckDto} assetBulkUploadCheckDto
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async bulkUploadCheck(assetBulkUploadCheckDto: AssetBulkUploadCheckDto, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<AssetBulkUploadCheckResponseDto>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.bulkUploadCheck(assetBulkUploadCheckDto, options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
/**
|
||||
* Check duplicated asset before uploading - for Web upload used
|
||||
* @param {CheckDuplicateAssetDto} checkDuplicateAssetDto
|
||||
|
|
@ -5595,6 +5739,15 @@ export const AssetApiFactory = function (configuration?: Configuration, basePath
|
|||
addAssetsToSharedLink(addAssetsDto: AddAssetsDto, key?: string, options?: any): AxiosPromise<SharedLinkResponseDto> {
|
||||
return localVarFp.addAssetsToSharedLink(addAssetsDto, key, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* Checks if assets exist by checksums
|
||||
* @param {AssetBulkUploadCheckDto} assetBulkUploadCheckDto
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
bulkUploadCheck(assetBulkUploadCheckDto: AssetBulkUploadCheckDto, options?: any): AxiosPromise<AssetBulkUploadCheckResponseDto> {
|
||||
return localVarFp.bulkUploadCheck(assetBulkUploadCheckDto, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* Check duplicated asset before uploading - for Web upload used
|
||||
* @param {CheckDuplicateAssetDto} checkDuplicateAssetDto
|
||||
|
|
@ -5856,6 +6009,17 @@ export class AssetApi extends BaseAPI {
|
|||
return AssetApiFp(this.configuration).addAssetsToSharedLink(addAssetsDto, key, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if assets exist by checksums
|
||||
* @param {AssetBulkUploadCheckDto} assetBulkUploadCheckDto
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof AssetApi
|
||||
*/
|
||||
public bulkUploadCheck(assetBulkUploadCheckDto: AssetBulkUploadCheckDto, options?: AxiosRequestConfig) {
|
||||
return AssetApiFp(this.configuration).bulkUploadCheck(assetBulkUploadCheckDto, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check duplicated asset before uploading - for Web upload used
|
||||
* @param {CheckDuplicateAssetDto} checkDuplicateAssetDto
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue