@@ -252,6 +252,95 @@ describe('POST /api/v2/credentials', () => {
252252 expect ( body ) . not . toContain ( 'exact passphrase' )
253253 } )
254254
255+ it . each ( [ 'multiline wallet' , 'maximum-size JSON with escaped whitespace' ] ) (
256+ 'accepts an Oracle connection with %s through the serialized credential envelope' ,
257+ async ( variant ) => {
258+ const connection = JSON . stringify ( {
259+ host : 'database.example.com' ,
260+ protocol : 'tcps' ,
261+ serviceName : 'database' ,
262+ username : 'sim' ,
263+ password : 'write-only-password' ,
264+ walletContent : `-----BEGIN CERTIFICATE-----\n${ `${ 'A' . repeat ( 64 ) } \n` . repeat ( 4096 ) } -----END CERTIFICATE-----` ,
265+ } )
266+ const serviceAccountJson =
267+ variant === 'multiline wallet' ? connection : connection . padEnd ( 2 * 1024 * 1024 , '\n' )
268+ const response = await POST (
269+ new NextRequest ( 'http://localhost:3000/api/v2/credentials' , {
270+ method : 'POST' ,
271+ headers : { 'content-type' : 'application/json' } ,
272+ body : JSON . stringify ( {
273+ workspaceId : WORKSPACE_ID ,
274+ type : 'service_account' ,
275+ providerId : 'oracledb-service-account' ,
276+ credentials : JSON . stringify ( { serviceAccountJson } ) ,
277+ } ) ,
278+ } )
279+ )
280+
281+ expect ( response . status ) . toBe ( 201 )
282+ const body = await response . text ( )
283+ expect ( body ) . not . toContain ( 'write-only-password' )
284+ expect ( body ) . not . toContain ( 'BEGIN CERTIFICATE' )
285+ }
286+ )
287+
288+ it ( 'rejects an oversized Oracle connection at the nested field limit' , async ( ) => {
289+ const response = await POST (
290+ new NextRequest ( 'http://localhost:3000/api/v2/credentials' , {
291+ method : 'POST' ,
292+ headers : { 'content-type' : 'application/json' } ,
293+ body : JSON . stringify ( {
294+ workspaceId : WORKSPACE_ID ,
295+ type : 'service_account' ,
296+ providerId : 'oracledb-service-account' ,
297+ credentials : JSON . stringify ( {
298+ serviceAccountJson : '{}' . padEnd ( 2 * 1024 * 1024 + 1 , ' ' ) ,
299+ } ) ,
300+ } ) ,
301+ } )
302+ )
303+
304+ expect ( response . status ) . toBe ( 400 )
305+ expect ( await response . json ( ) ) . toMatchObject ( {
306+ error : {
307+ code : 'BAD_REQUEST' ,
308+ details : expect . arrayContaining ( [
309+ expect . objectContaining ( {
310+ path : [ 'credentials' , 'serviceAccountJson' ] ,
311+ message : expect . stringContaining ( '2097152' ) ,
312+ } ) ,
313+ ] ) ,
314+ } ,
315+ } )
316+ } )
317+
318+ it ( 'rejects excessive serialized envelope padding before credential verification' , async ( ) => {
319+ const response = await POST (
320+ new NextRequest ( 'http://localhost:3000/api/v2/credentials' , {
321+ method : 'POST' ,
322+ headers : { 'content-type' : 'application/json' } ,
323+ body : JSON . stringify ( {
324+ workspaceId : WORKSPACE_ID ,
325+ type : 'service_account' ,
326+ providerId : 'oracledb-service-account' ,
327+ credentials : JSON . stringify ( { serviceAccountJson : '{}' } ) . padEnd (
328+ 4 * 1024 * 1024 + 128 * 1024 + 1 ,
329+ ' '
330+ ) ,
331+ } ) ,
332+ } )
333+ )
334+
335+ expect ( response . status ) . toBe ( 400 )
336+ expect ( await response . json ( ) ) . toMatchObject ( {
337+ error : {
338+ code : 'BAD_REQUEST' ,
339+ details : expect . arrayContaining ( [ expect . objectContaining ( { path : [ 'credentials' ] } ) ] ) ,
340+ } ,
341+ } )
342+ } )
343+
255344 /**
256345 * `credentials create slack-custom-bot` used to fail twice over: discovery
257346 * demanded a client-generated id, and a caller who then supplied a slug was
0 commit comments