fix: iOS portrait photo saved as jpg extension (#21388)

remove bad merged settings

remove console log
This commit is contained in:
Alex 2025-09-02 14:26:12 -05:00 committed by GitHub
parent 28edf5664d
commit 4f7702c6bf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 36 additions and 21 deletions

View file

@ -12,7 +12,7 @@ import { AuthRequest } from 'src/middleware/auth.guard';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { AssetMediaService } from 'src/services/asset-media.service';
import { ImmichFile, UploadFile, UploadFiles } from 'src/types';
import { asRequest, mapToUploadFile } from 'src/utils/asset.util';
import { asUploadRequest, mapToUploadFile } from 'src/utils/asset.util';
export function getFile(files: UploadFiles, property: 'assetData' | 'sidecarData') {
const file = files[property]?.[0];
@ -99,18 +99,21 @@ export class FileUploadInterceptor implements NestInterceptor {
}
private fileFilter(request: AuthRequest, file: Express.Multer.File, callback: multer.FileFilterCallback) {
return callbackify(() => this.assetService.canUploadFile(asRequest(request, file)), callback);
return callbackify(() => this.assetService.canUploadFile(asUploadRequest(request, file)), callback);
}
private filename(request: AuthRequest, file: Express.Multer.File, callback: DiskStorageCallback) {
return callbackify(
() => this.assetService.getUploadFilename(asRequest(request, file)),
() => this.assetService.getUploadFilename(asUploadRequest(request, file)),
callback as Callback<string>,
);
}
private destination(request: AuthRequest, file: Express.Multer.File, callback: DiskStorageCallback) {
return callbackify(() => this.assetService.getUploadFolder(asRequest(request, file)), callback as Callback<string>);
return callbackify(
() => this.assetService.getUploadFolder(asUploadRequest(request, file)),
callback as Callback<string>,
);
}
private handleFile(request: AuthRequest, file: Express.Multer.File, callback: Callback<Partial<ImmichFile>>) {

View file

@ -25,6 +25,7 @@ const file1 = Buffer.from('d2947b871a706081be194569951b7db246907957', 'hex');
const uploadFile = {
nullAuth: {
auth: null,
body: {},
fieldName: UploadFieldName.ASSET_DATA,
file: {
uuid: 'random-uuid',
@ -37,6 +38,7 @@ const uploadFile = {
filename: (fieldName: UploadFieldName, filename: string) => {
return {
auth: authStub.admin,
body: {},
fieldName,
file: {
uuid: 'random-uuid',
@ -897,7 +899,10 @@ describe(AssetMediaService.name, () => {
describe('onUploadError', () => {
it('should queue a job to delete the uploaded file', async () => {
const request = { user: authStub.user1 } as AuthRequest;
const request = {
body: {},
user: authStub.user1,
} as AuthRequest;
const file = {
fieldname: UploadFieldName.ASSET_DATA,

View file

@ -24,20 +24,14 @@ import { AuthDto } from 'src/dtos/auth.dto';
import { AssetStatus, AssetType, AssetVisibility, CacheControl, JobName, Permission, StorageFolder } from 'src/enum';
import { AuthRequest } from 'src/middleware/auth.guard';
import { BaseService } from 'src/services/base.service';
import { UploadFile } from 'src/types';
import { UploadFile, UploadRequest } from 'src/types';
import { requireUploadAccess } from 'src/utils/access';
import { asRequest, getAssetFiles, onBeforeLink } from 'src/utils/asset.util';
import { asUploadRequest, getAssetFiles, onBeforeLink } from 'src/utils/asset.util';
import { isAssetChecksumConstraint } from 'src/utils/database';
import { getFilenameExtension, getFileNameWithoutExtension, ImmichFileResponse } from 'src/utils/file';
import { mimeTypes } from 'src/utils/mime-types';
import { fromChecksum } from 'src/utils/request';
interface UploadRequest {
auth: AuthDto | null;
fieldName: UploadFieldName;
file: UploadFile;
}
export interface AssetMediaRedirectResponse {
targetSize: AssetMediaSize | 'original';
}
@ -89,15 +83,15 @@ export class AssetMediaService extends BaseService {
throw new BadRequestException(`Unsupported file type ${filename}`);
}
getUploadFilename({ auth, fieldName, file }: UploadRequest): string {
getUploadFilename({ auth, fieldName, file, body }: UploadRequest): string {
requireUploadAccess(auth);
const originalExtension = extname(file.originalName);
const extension = extname(body.filename || file.originalName);
const lookup = {
[UploadFieldName.ASSET_DATA]: originalExtension,
[UploadFieldName.ASSET_DATA]: extension,
[UploadFieldName.SIDECAR_DATA]: '.xmp',
[UploadFieldName.PROFILE_DATA]: originalExtension,
[UploadFieldName.PROFILE_DATA]: extension,
};
return sanitize(`${file.uuid}${lookup[fieldName]}`);
@ -117,8 +111,8 @@ export class AssetMediaService extends BaseService {
}
async onUploadError(request: AuthRequest, file: Express.Multer.File) {
const uploadFilename = this.getUploadFilename(asRequest(request, file));
const uploadFolder = this.getUploadFolder(asRequest(request, file));
const uploadFilename = this.getUploadFilename(asUploadRequest(request, file));
const uploadFolder = this.getUploadFolder(asUploadRequest(request, file));
const uploadPath = `${uploadFolder}/${uploadFilename}`;
await this.jobRepository.queue({ name: JobName.FileDelete, data: { files: [uploadPath] } });

View file

@ -1,5 +1,7 @@
import { SystemConfig } from 'src/config';
import { VECTOR_EXTENSIONS } from 'src/constants';
import { UploadFieldName } from 'src/dtos/asset-media.dto';
import { AuthDto } from 'src/dtos/auth.dto';
import {
AssetMetadataKey,
AssetOrder,
@ -408,6 +410,16 @@ export interface UploadFile {
size: number;
}
export type UploadRequest = {
auth: AuthDto | null;
fieldName: UploadFieldName;
file: UploadFile;
body: {
filename?: string;
[key: string]: unknown;
};
};
export interface UploadFiles {
assetData: ImmichFile[];
sidecarData: ImmichFile[];

View file

@ -10,7 +10,7 @@ import { AccessRepository } from 'src/repositories/access.repository';
import { AssetRepository } from 'src/repositories/asset.repository';
import { EventRepository } from 'src/repositories/event.repository';
import { PartnerRepository } from 'src/repositories/partner.repository';
import { IBulkAsset, ImmichFile, UploadFile } from 'src/types';
import { IBulkAsset, ImmichFile, UploadFile, UploadRequest } from 'src/types';
import { checkAccess } from 'src/utils/access';
export const getAssetFile = (files: AssetFile[], type: AssetFileType | GeneratedImageType) => {
@ -190,9 +190,10 @@ export function mapToUploadFile(file: ImmichFile): UploadFile {
};
}
export const asRequest = (request: AuthRequest, file: Express.Multer.File) => {
export const asUploadRequest = (request: AuthRequest, file: Express.Multer.File): UploadRequest => {
return {
auth: request.user || null,
body: request.body,
fieldName: file.fieldname as UploadFieldName,
file: mapToUploadFile(file as ImmichFile),
};