@@ -2021,6 +2021,210 @@ describe('Parse.File testing', () => {
20212021 }
20222022 } ) ;
20232023
2024+ describe ( 'maxUploadSize override' , ( ) => {
2025+ it ( 'allows streaming upload exceeding server limit with maxUploadSize override and master key' , async ( ) => {
2026+ await reconfigureServer ( { maxUploadSize : '10b' } ) ;
2027+ const headers = {
2028+ 'Content-Type' : 'application/octet-stream' ,
2029+ 'X-Parse-Application-Id' : 'test' ,
2030+ 'X-Parse-Master-Key' : 'test' ,
2031+ 'X-Parse-Upload-Mode' : 'stream' ,
2032+ 'X-Parse-File-Max-Upload-Size' : '1mb' ,
2033+ } ;
2034+ const response = await request ( {
2035+ method : 'POST' ,
2036+ headers : headers ,
2037+ url : 'http://localhost:8378/1/files/override-stream.txt' ,
2038+ body : 'this content is definitely longer than 10 bytes' ,
2039+ } ) ;
2040+ expect ( response . data . name ) . toContain ( 'override-stream' ) ;
2041+ expect ( response . data . url ) . toBeDefined ( ) ;
2042+ } ) ;
2043+
2044+ it ( 'allows buffered upload exceeding server limit with maxUploadSize override and master key' , async ( ) => {
2045+ await reconfigureServer ( { maxUploadSize : '10b' } ) ;
2046+ const headers = {
2047+ 'Content-Type' : 'application/octet-stream' ,
2048+ 'X-Parse-Application-Id' : 'test' ,
2049+ 'X-Parse-Master-Key' : 'test' ,
2050+ 'X-Parse-File-Max-Upload-Size' : '1mb' ,
2051+ } ;
2052+ const response = await request ( {
2053+ method : 'POST' ,
2054+ headers : headers ,
2055+ url : 'http://localhost:8378/1/files/override-buffer.txt' ,
2056+ body : 'this content is definitely longer than 10 bytes' ,
2057+ } ) ;
2058+ expect ( response . data . name ) . toContain ( 'override-buffer' ) ;
2059+ expect ( response . data . url ) . toBeDefined ( ) ;
2060+ } ) ;
2061+
2062+ it ( 'rejects maxUploadSize override without master key' , async ( ) => {
2063+ await reconfigureServer ( { maxUploadSize : '10b' } ) ;
2064+ const headers = {
2065+ 'Content-Type' : 'application/octet-stream' ,
2066+ 'X-Parse-Application-Id' : 'test' ,
2067+ 'X-Parse-REST-API-Key' : 'rest' ,
2068+ 'X-Parse-Upload-Mode' : 'stream' ,
2069+ 'X-Parse-File-Max-Upload-Size' : '1mb' ,
2070+ } ;
2071+ try {
2072+ await request ( {
2073+ method : 'POST' ,
2074+ headers : headers ,
2075+ url : 'http://localhost:8378/1/files/no-master.txt' ,
2076+ body : 'this content is longer than 10 bytes' ,
2077+ } ) ;
2078+ fail ( 'should have thrown' ) ;
2079+ } catch ( response ) {
2080+ expect ( response . status ) . toBe ( 403 ) ;
2081+ }
2082+ } ) ;
2083+
2084+ it ( 'rejects invalid maxUploadSize override value' , async ( ) => {
2085+ const headers = {
2086+ 'Content-Type' : 'application/octet-stream' ,
2087+ 'X-Parse-Application-Id' : 'test' ,
2088+ 'X-Parse-Master-Key' : 'test' ,
2089+ 'X-Parse-Upload-Mode' : 'stream' ,
2090+ 'X-Parse-File-Max-Upload-Size' : 'notasize' ,
2091+ } ;
2092+ try {
2093+ await request ( {
2094+ method : 'POST' ,
2095+ headers : headers ,
2096+ url : 'http://localhost:8378/1/files/bad-value.txt' ,
2097+ body : 'some data' ,
2098+ } ) ;
2099+ fail ( 'should have thrown' ) ;
2100+ } catch ( response ) {
2101+ expect ( response . data . code ) . toBe ( Parse . Error . FILE_SAVE_ERROR ) ;
2102+ expect ( response . data . error ) . toContain ( 'Invalid maxUploadSize override' ) ;
2103+ }
2104+ } ) ;
2105+
2106+ it ( 'rejects streaming upload exceeding the overridden maxUploadSize' , async ( ) => {
2107+ await reconfigureServer ( { maxUploadSize : '5b' } ) ;
2108+ const headers = {
2109+ 'Content-Type' : 'application/octet-stream' ,
2110+ 'X-Parse-Application-Id' : 'test' ,
2111+ 'X-Parse-Master-Key' : 'test' ,
2112+ 'X-Parse-Upload-Mode' : 'stream' ,
2113+ 'X-Parse-File-Max-Upload-Size' : '10b' ,
2114+ } ;
2115+ try {
2116+ await request ( {
2117+ method : 'POST' ,
2118+ headers : headers ,
2119+ url : 'http://localhost:8378/1/files/still-too-big.txt' ,
2120+ body : 'this content is definitely longer than 10 bytes' ,
2121+ } ) ;
2122+ fail ( 'should have thrown' ) ;
2123+ } catch ( response ) {
2124+ expect ( response . data . code ) . toBe ( Parse . Error . FILE_SAVE_ERROR ) ;
2125+ expect ( response . data . error ) . toContain ( 'exceeds' ) ;
2126+ }
2127+ } ) ;
2128+
2129+ it ( 'rejects maxUploadSize override with wrong master key' , async ( ) => {
2130+ const headers = {
2131+ 'Content-Type' : 'application/octet-stream' ,
2132+ 'X-Parse-Application-Id' : 'test' ,
2133+ 'X-Parse-Master-Key' : 'wrong-key' ,
2134+ 'X-Parse-Upload-Mode' : 'stream' ,
2135+ 'X-Parse-File-Max-Upload-Size' : '1mb' ,
2136+ } ;
2137+ try {
2138+ await request ( {
2139+ method : 'POST' ,
2140+ headers : headers ,
2141+ url : 'http://localhost:8378/1/files/wrong-key.txt' ,
2142+ body : 'some data' ,
2143+ } ) ;
2144+ fail ( 'should have thrown' ) ;
2145+ } catch ( response ) {
2146+ expect ( response . status ) . toBe ( 403 ) ;
2147+ }
2148+ } ) ;
2149+
2150+ it ( 'rejects maxUploadSize override with invalid application ID' , async ( ) => {
2151+ const headers = {
2152+ 'Content-Type' : 'application/octet-stream' ,
2153+ 'X-Parse-Application-Id' : 'invalid-app-id' ,
2154+ 'X-Parse-Master-Key' : 'test' ,
2155+ 'X-Parse-Upload-Mode' : 'stream' ,
2156+ 'X-Parse-File-Max-Upload-Size' : '1mb' ,
2157+ } ;
2158+ try {
2159+ await request ( {
2160+ method : 'POST' ,
2161+ headers : headers ,
2162+ url : 'http://localhost:8378/1/files/bad-app.txt' ,
2163+ body : 'some data' ,
2164+ } ) ;
2165+ fail ( 'should have thrown' ) ;
2166+ } catch ( response ) {
2167+ expect ( response . status ) . toBe ( 403 ) ;
2168+ }
2169+ } ) ;
2170+
2171+ it ( 'rejects maxUploadSize override when masterKeyIps blocks the IP' , async ( ) => {
2172+ await reconfigureServer ( { masterKeyIps : [ '10.0.0.1' ] } ) ;
2173+ const headers = {
2174+ 'Content-Type' : 'application/octet-stream' ,
2175+ 'X-Parse-Application-Id' : 'test' ,
2176+ 'X-Parse-Master-Key' : 'test' ,
2177+ 'X-Parse-Upload-Mode' : 'stream' ,
2178+ 'X-Parse-File-Max-Upload-Size' : '1mb' ,
2179+ } ;
2180+ try {
2181+ await request ( {
2182+ method : 'POST' ,
2183+ headers : headers ,
2184+ url : 'http://localhost:8378/1/files/blocked-ip.txt' ,
2185+ body : 'some data' ,
2186+ } ) ;
2187+ fail ( 'should have thrown' ) ;
2188+ } catch ( response ) {
2189+ expect ( response . status ) . toBe ( 403 ) ;
2190+ }
2191+ } ) ;
2192+
2193+ } ) ;
2194+
2195+ describe ( 'maxUploadSize override via SDK' , ( ) => {
2196+ it ( 'saves buffer file with maxUploadSize override and master key' , async ( ) => {
2197+ await reconfigureServer ( { maxUploadSize : '10b' } ) ;
2198+ const data = Buffer . alloc ( 100 , 'a' ) ;
2199+ const file = new Parse . File ( 'sdk-buffer-override.txt' , data , 'text/plain' ) ;
2200+ const result = await file . save ( { useMasterKey : true , maxUploadSize : '1mb' } ) ;
2201+ expect ( result . url ( ) ) . toBeDefined ( ) ;
2202+ expect ( result . name ( ) ) . toContain ( 'sdk-buffer-override' ) ;
2203+ } ) ;
2204+
2205+ it ( 'saves stream file with maxUploadSize override and master key' , async ( ) => {
2206+ await reconfigureServer ( { maxUploadSize : '10b' } ) ;
2207+ const { Readable } = require ( 'stream' ) ;
2208+ const stream = Readable . from ( Buffer . alloc ( 100 , 'b' ) ) ;
2209+ const file = new Parse . File ( 'sdk-stream-override.txt' , stream , 'text/plain' ) ;
2210+ const result = await file . save ( { useMasterKey : true , maxUploadSize : '1mb' } ) ;
2211+ expect ( result . url ( ) ) . toBeDefined ( ) ;
2212+ expect ( result . name ( ) ) . toContain ( 'sdk-stream-override' ) ;
2213+ } ) ;
2214+
2215+ it ( 'rejects maxUploadSize override without master key' , async ( ) => {
2216+ await reconfigureServer ( { maxUploadSize : '10b' } ) ;
2217+ const data = Buffer . alloc ( 100 , 'c' ) ;
2218+ const file = new Parse . File ( 'sdk-no-master.txt' , data , 'text/plain' ) ;
2219+ try {
2220+ await file . save ( { maxUploadSize : '1mb' } ) ;
2221+ fail ( 'should have thrown' ) ;
2222+ } catch ( error ) {
2223+ expect ( error . error ) . toBeDefined ( ) ;
2224+ }
2225+ } ) ;
2226+ } ) ;
2227+
20242228 it ( 'fires beforeSave trigger with request.stream = true on streaming upload' , async ( ) => {
20252229 let receivedStream ;
20262230 let receivedData ;
0 commit comments