From 7613f74e05802733b006231cdce9dc343fe4b465 Mon Sep 17 00:00:00 2001 From: Michael Bromley Date: Mon, 25 May 2020 10:30:39 +0200 Subject: [PATCH] fix(asset-server-plugin): Fix mime type detection Fixes #341 --- .../e2e/asset-server-plugin.e2e-spec.ts | 58 +++++++++++++++++- .../e2e/fixtures/assets/test.gif | Bin 0 -> 735 bytes .../e2e/fixtures/assets/test.jpg | Bin 0 -> 4327 bytes .../e2e/fixtures/assets/test.png | Bin 0 -> 2368 bytes .../e2e/fixtures/assets/test.svg | 20 ++++++ .../e2e/fixtures/assets/test.tiff | Bin 0 -> 4896 bytes .../e2e/fixtures/assets/test.webp | Bin 0 -> 388 bytes packages/asset-server-plugin/src/plugin.ts | 26 ++++---- 8 files changed, 87 insertions(+), 17 deletions(-) create mode 100644 packages/asset-server-plugin/e2e/fixtures/assets/test.gif create mode 100644 packages/asset-server-plugin/e2e/fixtures/assets/test.jpg create mode 100644 packages/asset-server-plugin/e2e/fixtures/assets/test.png create mode 100644 packages/asset-server-plugin/e2e/fixtures/assets/test.svg create mode 100644 packages/asset-server-plugin/e2e/fixtures/assets/test.tiff create mode 100644 packages/asset-server-plugin/e2e/fixtures/assets/test.webp diff --git a/packages/asset-server-plugin/e2e/asset-server-plugin.e2e-spec.ts b/packages/asset-server-plugin/e2e/asset-server-plugin.e2e-spec.ts index d09f791b2b..30199dac03 100644 --- a/packages/asset-server-plugin/e2e/asset-server-plugin.e2e-spec.ts +++ b/packages/asset-server-plugin/e2e/asset-server-plugin.e2e-spec.ts @@ -1,3 +1,4 @@ +/* tslint:disable:no-non-null-assertion */ import { DefaultLogger, LogLevel, mergeConfig } from '@vendure/core'; import { createTestEnvironment } from '@vendure/testing'; import fs from 'fs-extra'; @@ -6,7 +7,7 @@ import fetch from 'node-fetch'; import path from 'path'; import { initialData } from '../../../e2e-common/e2e-initial-data'; -import { testConfig, TEST_SETUP_TIMEOUT_MS } from '../../../e2e-common/test-config'; +import { TEST_SETUP_TIMEOUT_MS, testConfig } from '../../../e2e-common/test-config'; import { AssetServerPlugin } from '../src/plugin'; import { CreateAssets, DeleteAsset, DeletionResult } from './graphql/generated-e2e-asset-server-plugin-types'; @@ -62,8 +63,8 @@ describe('AssetServerPlugin', () => { const { createAssets }: CreateAssets.Mutation = await adminClient.fileUploadMutation({ mutation: CREATE_ASSETS, filePaths: filesToUpload, - mapVariables: filePaths => ({ - input: filePaths.map(p => ({ file: null })), + mapVariables: (filePaths) => ({ + input: filePaths.map((p) => ({ file: null })), }), }); @@ -182,6 +183,57 @@ describe('AssetServerPlugin', () => { expect(fs.existsSync(previewFilePath)).toBe(false); }); }); + + describe('MIME type detection', () => { + let testImages: CreateAssets.CreateAssets[] = []; + + async function testMimeTypeOfAssetWithExt(ext: string, expectedMimeType: string) { + const testImage = testImages.find((i) => i.source.endsWith(ext))!; + const result = await fetch(testImage.source); + const contentType = result.headers.get('Content-Type'); + + expect(contentType).toBe(expectedMimeType); + } + + beforeAll(async () => { + const formats = ['gif', 'jpg', 'png', 'svg', 'tiff', 'webp']; + + const filesToUpload = formats.map((ext) => path.join(__dirname, `fixtures/assets/test.${ext}`)); + const { createAssets }: CreateAssets.Mutation = await adminClient.fileUploadMutation({ + mutation: CREATE_ASSETS, + filePaths: filesToUpload, + mapVariables: (filePaths) => ({ + input: filePaths.map((p) => ({ file: null })), + }), + }); + + testImages = createAssets; + }); + + it('gif', async () => { + await testMimeTypeOfAssetWithExt('gif', 'image/gif'); + }); + + it('jpg', async () => { + await testMimeTypeOfAssetWithExt('jpg', 'image/jpeg'); + }); + + it('png', async () => { + await testMimeTypeOfAssetWithExt('png', 'image/png'); + }); + + it('svg', async () => { + await testMimeTypeOfAssetWithExt('svg', 'image/svg+xml'); + }); + + it('tiff', async () => { + await testMimeTypeOfAssetWithExt('tiff', 'image/tiff'); + }); + + it('webp', async () => { + await testMimeTypeOfAssetWithExt('webp', 'image/webp'); + }); + }); }); export const CREATE_ASSETS = gql` diff --git a/packages/asset-server-plugin/e2e/fixtures/assets/test.gif b/packages/asset-server-plugin/e2e/fixtures/assets/test.gif new file mode 100644 index 0000000000000000000000000000000000000000..f1aa947bb3c232b4095913292f0dbe46e816c51b GIT binary patch literal 735 zcmZ?wbh9u|lw%NK_{P96fByV?_wFrNu%Mx#Au%zLi;JtLr|0L-pJHNSU%!6k%qN1X|fB$A+U{F+4tgWqOVPSD|b9?&q z>4ps(goTCq`1quxq{_?7SFKw0?%liQ=H?F{K6G|=GBYzznKEVl`t_Qcns#<}+1c4| z-@c8Diwh18K7Rc8r%#_sOG{6jIPvh|Ln9-jkdP2xU*EZN=N1(e9X@D+zI{sViw{YT1iAYU}Xna_MjyiYT$Sa#`P& z(`ybAvs6(te4(SiOhRPFYeq2>)2tmE5+5Gpml12aQo-=Jy@gT4&QLleA(oljlr7_k z!GX>eE`5g=8wwN~SZdF5gie`o;E-y&j?Co+>EpK4V74r3>w?O#U393XM(-o4EpPcpMDB zdNJ{6y4A>Vs3vkTa5VqOyREkH!-HM7)wuM&tlD_^z(N^w<2gkWl8^K&^Na0?c>D0o NEdBa*f0P9ntN|@1D3JgF literal 0 HcmV?d00001 diff --git a/packages/asset-server-plugin/e2e/fixtures/assets/test.jpg b/packages/asset-server-plugin/e2e/fixtures/assets/test.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8de712f904ba36d6159955fa191fbc74e1ad55e7 GIT binary patch literal 4327 zcmeHKd2kbD6n~q8gi;+@A}?* z-5Na9?? z$|RP3BgN14aQG#Or;WytXmESEYR2HEHy0v>L1i6NT1-*GE?rmn3cR%T6VO42Q#p@JItE)ELb+o6Tsl z7%dh(YUssiNODK?A#qTfhhj$b2rMtLT!@rCx~sW5$xh+UiI8|dCvl>mmpUBf0_S4`C=e^g7m=k-M}gT^P@uOM%<}#`jaIBLTI`lkMZQjY zlT~lAR<&KH$4nO5WJ;>y*?HZP``?u1D-h&eE_wnhN}Lc)9%?01n?wPYOe9UaJ@NtB zDPG{bbsok`CHW%flfrI+DXhUv?Np)9$A(xbO5&-qH6cbI&4$qi%(T@@*w3Jk2M2G& zZH@9JXpO-5_uvw;P8X(49dDrw+pqIjvWvPZ&{cu13UpPVs{&mW`2SU)qakKO*ae5N z-Hl&`{PMPLk{oF;!RVq=mug6&!|r`N=e6b~utRleUiY`I{82PFeqQ0lrfhn7#giqa zWlo$H02EaLPf%2u0D>V&kh`=gQ>T%dpKv^Q1T;_pIc|^0yDCen5PQ)stO0@)*CTd(+O91!XCd6L>}B8CFc~TX&T4($zuicqRSk;o8L6of1TjV?W7pt(?Mp`NNm zy-fMPb1%tU-9NdfAyrA>?n)hugG)^<8M*f6*`f46ag%S?&|zC+m#HB`uEfOePQ1RP zw({)K58wT@u%Yqm?OC^NRw?S#uerFpYDV zHov^$$f32`vY$(4>|0m+M%oV(%0Dg6+j8T#`6p+5blP>`VBcHIiUnfXjb4^?;uu?a zl&HKk{rr2>&_#C#%x;Oj5ZaK%X0317x24)sxufSE`tqW}oNvCJq+C8D<@%$On4{Gj zH*C5(`o@00binN-Ii>MMR4hEn20nu!>vAx)FKlDs_SCg7Q!ik=_Ify4wCRGr9Mi@67j|@7|mF zG+6MFm4&?p1VL83K#mYRoxo*lJ{R2WuG#O0p!rquut+?TzY!K=3Nj+WwxMLLLIrRL zV)Fd;d@DSS?rK za!g4uY9iaPB%Dno0-P`{j%wwz>PpRY`M?N@5uwn?RLbjgTps%ybR+T>T_wYCOe4co zGX=cyiW&H=Kw#gyL$rwMU1UE0_vs478)ay4ZZa@p+SE64`t=2xuv8UF5uzF_Ni9aX z$*2-vX>!8o3mh!hq6v{4xdK&cfV*rWgZh79)N3I9HP9bRz|^5&QK4)i%@kvF4(2Hk zDHYyic!I;GIrb)7WHmyrW3F! zKRzY_=`l=Uvk=eUKUj^$$`b&l5q{)H;BoyuY2KcmBszJj6wo#p#L8n+IS39|bSj-n zqB2QzW*F5QW_r3&=`eLF8xs|51qp&9ze_f*W&#V)`FuD~uE8;Ns%dI!iHD+zQ=_S2 zg50#W2?SGzVMJ^+h)qw`&1DmPV`JsO%2Wc_Hgc&F zRTF6BHRLH1W@1ugDA4N;OA?b?Zc#9r&e-(Kgl|K{ZvLJ-?Cz9 zm?g9Ctp1@}aD7)*))}h~v-d(uqjO(a#yOl>m{D$C9-e!Pt5~n>{aVB+yLV&kzh0V! z4C!Tif!m)h{`h`Lg1}PnynEO(SJ`Bl+>uD-NI7~#NvpQ_v!|)~SM%zkYd8H*Gr3vp ze$q{Je5q4-80pU}SJp*cDF2R)GF(_#{J2C_vudgB_l!|lNeo}08|##i9RHAhHtP1_ zmsj;MCyt%TJ9WV^Xw~6})z4@#_w%H^ev9k>zP5D%{gdThp?Nk1Wg`sYuywRq-+nvh z(9VjNQJX%DD2%E|Z?xbEf9kViQVczdKPYcPkGU34Om;@FX={Q{4vb_@v{UcYH=MS* zO1knKrsv(K-7fnNeak;%*je`$>Fd7!tQXqqp!#dLp}byodVwN8j+1-9x%3>fFug8R zwmDtrAd6i6?8G-M*XCulJ*YZ~V9V2fx)4A1e$i3s%X>d~c!7V41**U(4Fr)_8m~Fp z3ZG;Mnp@4|_=c_7+kL<%FfGKksb%7#!>bkUt$T=chYa_EocWfH@s+!+kGiU4$1fj0 zl<~!f`f8ml$I;%SS=U$;>cR215gf@}h^(8up#6En-7%|(=m0^;mBEy6xBqzlbIrh* z6WN#ZeA)Q$hOS9y=Z+ma)aoHcFui0%%c|BpI5^bQ)Z7io_B&ElRkcLM`Wck^Z_r>mnwXqkNl(Y61jcR2O1psv1ti~ACrL=4OC zIhUC^&)1qvCInj#FC6<Sl$|wPfRW-O8kMP(h%xLxMb6gd)Pr*_ z_dKaw;cH#4?`v+}KrULlcCDMOMNXxQMayuO^`*NlX8$r646K6uivy1y-H5G)zPQ=1 z)9HwX|LE>s2D$9HKbqEd>sCichxrQ7i4*hu0)v7UtvFU!SM>2x?rGuiGks|YG6#Aw zK5oaoCZQ+SFM}GJn#MsAot-T$Em0k>UahOZMIupL+#Vt9<@N08)7?2ww2sh7+Js&o zB0gdW3b*B!^>RbDMn`{n;8q;7toMUYvkY-b@L~JCUq + + + + + + + + + + + + + + + + + + + diff --git a/packages/asset-server-plugin/e2e/fixtures/assets/test.tiff b/packages/asset-server-plugin/e2e/fixtures/assets/test.tiff new file mode 100644 index 0000000000000000000000000000000000000000..ba1b97ffee3b924a5bf8be43513701694bb4325a GIT binary patch literal 4896 zcmeHLeNYtV8Gr6Tpr|NHOjW?;VrZb;Cm!Jr4wVA~mV*n>g3%F=yFKp8-R*XF@%U&( znpWaRszzI-Vz`Q04T*2c`NtZ0?$esp?la92kM+={MBJn+$p_un6k zzWd-o?Ip{$rkjhJrBbO*rz`#Ih7B9uP7B|Y)@d95?6U(kHS^zD*?jwU;Y&fHohiWq zM^2uc7gw_;;MSo-hf)@2=H=z(ss_yRY-rnAiKVGrx{E~!(59{mePo2t9x10YQ5wu02s!9{lMMXspN5G@Hy1K%` zLSJ9sm4{nDXAJw#o7BHc4?ed}79Jj6z50NDBlqdKeEF@-`?hc2{;E-{^-4I?Hb0D0 z|BR*w`}+Q9s;#dN4h>yjcOxVuMApOAzW1J3Sg|8z@y{Eomk}Ek<(F&T8o76`RLN*xVP6oLYI+o)=*x)s3`St>&~5lRcR{@XP)U<_hM)F7hx~gtofCbyy@fP zlOzfp(S%-XY;3%LU-h8l>ecmSWn0re{NCBx)2H{IH&tJ0YunvvlT_)If2&Boe0=uS z#w818R_H^U`uqB##Nx2w!NI|vo}TEc3+7|lkzWSfzI5r;%Cmx$jEq^PoMTto+uJLa zLAYd3TwL7N^9{CpqmNozT6XQ4`(;r7+EuHT2YfQ(RbsLD<)1upVp+FkiT})jJ9lbp zYxV0Qf34PN8UwD+@Ok}5#~O)-xdHlr{P-^i*KX67moMGY7`Wigci!5UeuQ#3216Gv z)Lyy&)6o6RyP9qe4GjfuKF3rIRs@_5+PkHztE-i4V9Uz~hDv{#7`Ff7pB{WZR-2df z$m{x=ooz51K;Q)e00_mOz=MMj3lV$ayaR7u9=ac{eLPr*I8fm2(&g!MJapdHa~{m= z&-38bh@bb!A4lZ{f@v<@jVQFxgWo_LJi(5}gLz+Ur7vV7@b(7yv`GLCr2U3>fFlZ> z@_rxBe!yQa_Jb@T&>6+a0`NtyoaN{YUJSsToq^O+2;rLSHDH4&Xp~>Ly<-A;7gc0M<(PlVce1vre``rjV&+O0_~s z$W&@&j2ep}Anlz#urB0@!wWP(GQp%87rRmwm(n6!k zBwCu_A7894w$pZ!GZ4jgn}bysYeWVUl~1Y>^JJ-raEWk*8d0uJPiQHIB$N`RL?%k` zC*m2CS)G}*!lR5UjmW}rv|1{4I-L?{w1i>`q;i!?C6y_p3WXRY#B7O!GZc#*>vYc+x7)vBp5>C)W2l~OejBDZW3% zGNo9d%zoS--W+HI=SOWnfamQ{DAHOPBxndo}66muV-yHA8G-s?Hm~ uk8sRx3)$AW9X{~x+4!BkefJVK;Fn3Y`|Cu2Y@rA9|08&LF#koskADNg=nnY+ literal 0 HcmV?d00001 diff --git a/packages/asset-server-plugin/e2e/fixtures/assets/test.webp b/packages/asset-server-plugin/e2e/fixtures/assets/test.webp new file mode 100644 index 0000000000000000000000000000000000000000..f827d6243c1797a8c651de7fbb9b75a3c772305d GIT binary patch literal 388 zcmV-~0ek*ZNk&F|0RRA3MM6+kP&goP0RRBd3ILq}Djon7006)eC8PjO9pnP^za=Zq ze-}R^w1|E?HA3z;K zf2rqY{>7MC_{K~#(214GULXMe|NbVj0(*N?$cyIQSA7gSh<(jJ|1QA=|Nq5$)Kr)c z`%+IQ?x)s`g;B@ta^!JEhh8Pi%YT-QN`L#4jBS!{^-L0SLcu+K;UG-3qZnGg)tY`o z9EksgU-|C4|DV!PC?kLoa|-9HN)cke;6xvB&e3f7Ne8BMz=v63?pd@oP;PJBeC-b= z1sfRjL(Bi2=VT$3j3mC$Z}BvcwY$+ermn(WTFXH+FaG2q-Q)ky1=;w~G4iYJNJPmC z?flF((;S$I_{z=y{|)U&whFI@|AA-X#=&xrKd7Hg!yc5f33PLP=H$^B{-(ZZOz!@x iAIaVYTu;j*NZ1AazmWg=Yph;uF>W;y^m)8>0000E4ac7V literal 0 HcmV?d00001 diff --git a/packages/asset-server-plugin/src/plugin.ts b/packages/asset-server-plugin/src/plugin.ts index cb8b2c86fb..ab772fbbc0 100644 --- a/packages/asset-server-plugin/src/plugin.ts +++ b/packages/asset-server-plugin/src/plugin.ts @@ -125,7 +125,7 @@ import { AssetServerOptions, ImageTransformPreset } from './types'; */ @VendurePlugin({ imports: [PluginCommonModule, TerminusModule], - configuration: config => AssetServerPlugin.configure(config), + configuration: (config) => AssetServerPlugin.configure(config), }) export class AssetServerPlugin implements OnVendureBootstrap, OnVendureClose { private server: Server; @@ -177,7 +177,7 @@ export class AssetServerPlugin implements OnVendureBootstrap, OnVendureClose { onVendureBootstrap(): void | Promise { if (AssetServerPlugin.options.presets) { for (const preset of AssetServerPlugin.options.presets) { - const existingIndex = this.presets.findIndex(p => p.name === preset.name); + const existingIndex = this.presets.findIndex((p) => p.name === preset.name); if (-1 < existingIndex) { this.presets.splice(existingIndex, 1, preset); } else { @@ -194,7 +194,7 @@ export class AssetServerPlugin implements OnVendureBootstrap, OnVendureClose { /** @internal */ onVendureClose(): Promise { - return new Promise(resolve => { + return new Promise((resolve) => { this.server.close(() => resolve()); }); } @@ -292,7 +292,7 @@ export class AssetServerPlugin implements OnVendureBootstrap, OnVendureClose { const height = h || ''; imageParamHash = this.md5(`_transform_w${width}_h${height}_m${mode}${focalPoint}`); } else if (preset) { - if (this.presets && !!this.presets.find(p => p.name === preset)) { + if (this.presets && !!this.presets.find((p) => p.name === preset)) { imageParamHash = this.md5(`_transform_pre_${preset}${focalPoint}`); } } @@ -305,9 +305,7 @@ export class AssetServerPlugin implements OnVendureBootstrap, OnVendureClose { } private md5(input: string): string { - return createHash('md5') - .update(input) - .digest('hex'); + return createHash('md5').update(input).digest('hex'); } private addSuffix(fileName: string, suffix: string): string { @@ -323,18 +321,18 @@ export class AssetServerPlugin implements OnVendureBootstrap, OnVendureClose { private getMimeType(fileName: string): string | undefined { const ext = path.extname(fileName); switch (ext) { - case 'jpg': - case 'jpeg': + case '.jpg': + case '.jpeg': return 'image/jpeg'; - case 'png': + case '.png': return 'image/png'; - case 'gif': + case '.gif': return 'image/gif'; - case 'svg': + case '.svg': return 'image/svg+xml'; - case 'tiff': + case '.tiff': return 'image/tiff'; - case 'webp': + case '.webp': return 'image/webp'; } }