@@ -550,7 +550,7 @@ describe('Oracle EPM guarded client', () => {
550550 }
551551 )
552552
553- it . each ( [ 'download' , 'Job Status' ] ) (
553+ it . each ( [ 'download' , 'Job Status' , 'exported/artifact' , 'imported/artifact' ] ) (
554554 'keeps %s links opaque and client-owned' ,
555555 async ( relation ) => {
556556 const download = routes . defineEndpoint ( {
@@ -626,7 +626,12 @@ describe('Oracle EPM guarded client', () => {
626626 'https://epm.example.com/gateway/SyntheticAlpha/rest/v3/files%2Fabc?token=x' ,
627627 'https://epm.example.com/gateway/SyntheticAlpha/rest/v3/files%5Cabc?token=x' ,
628628 'https://epm.example.com/gateway/SyntheticAlpha/rest/v3/files\\abc?token=x' ,
629- ] . flatMap ( ( href ) => [ 'download' , 'Job Status' ] . map ( ( relation ) => ( { relation, href } ) ) )
629+ ] . flatMap ( ( href ) =>
630+ [ 'download' , 'Job Status' , 'exported/artifact' , 'imported/artifact' ] . map ( ( relation ) => ( {
631+ relation,
632+ href,
633+ } ) )
634+ )
630635 ) ( 'rejects unsafe $relation link $href' , ( { relation, href } ) => {
631636 const policy = routes . defineReturnedLinkPolicy ( {
632637 relation,
@@ -650,44 +655,62 @@ describe('Oracle EPM guarded client', () => {
650655 expect ( mockSecureFetch ) . not . toHaveBeenCalled ( )
651656 } )
652657
653- it . each ( [ 'download' , 'Job Status' ] ) ( 'rejects an incorrect %s link method' , ( relation ) => {
654- const policy = routes . defineReturnedLinkPolicy ( {
655- relation,
656- method : 'GET' ,
657- version : 'v3' ,
658- path : [ oracleEpmLiteral ( 'files' ) , oracleEpmPathParameter ( 'fileId' , { maxBytes : 32 } ) ] ,
659- response : 'stream' ,
660- timeoutMs : 5_000 ,
661- maxResponseBytes : 4_096 ,
662- preserveGatewayBasePath : true ,
663- } )
664- const client = createOracleEpmClient ( {
665- instanceUrl : 'https://epm.example.com/gateway' ,
666- accessToken : Buffer . from ( 'u:p' ) . toString ( 'base64' ) ,
667- } )
668- expect ( ( ) =>
669- client . validateReturnedLink ( policy , {
670- rel : relation ,
671- method : 'POST' ,
672- href : 'https://epm.example.com/gateway/SyntheticAlpha/rest/v3/files/abc' ,
658+ it . each ( [ 'download' , 'Job Status' , 'exported/artifact' , 'imported/artifact' ] ) (
659+ 'rejects an incorrect %s link method' ,
660+ ( relation ) => {
661+ const policy = routes . defineReturnedLinkPolicy ( {
662+ relation,
663+ method : 'GET' ,
664+ version : 'v3' ,
665+ path : [ oracleEpmLiteral ( 'files' ) , oracleEpmPathParameter ( 'fileId' , { maxBytes : 32 } ) ] ,
666+ response : 'stream' ,
667+ timeoutMs : 5_000 ,
668+ maxResponseBytes : 4_096 ,
669+ preserveGatewayBasePath : true ,
673670 } )
674- ) . toThrow ( )
675- expect ( mockValidateUrl ) . not . toHaveBeenCalled ( )
676- expect ( mockSecureFetch ) . not . toHaveBeenCalled ( )
677- } )
671+ const client = createOracleEpmClient ( {
672+ instanceUrl : 'https://epm.example.com/gateway' ,
673+ accessToken : Buffer . from ( 'u:p' ) . toString ( 'base64' ) ,
674+ } )
675+ expect ( ( ) =>
676+ client . validateReturnedLink ( policy , {
677+ rel : relation ,
678+ method : 'POST' ,
679+ href : 'https://epm.example.com/gateway/SyntheticAlpha/rest/v3/files/abc' ,
680+ } )
681+ ) . toThrow ( )
682+ expect ( mockValidateUrl ) . not . toHaveBeenCalled ( )
683+ expect ( mockSecureFetch ) . not . toHaveBeenCalled ( )
684+ }
685+ )
678686
679687 it . each ( [
680- 'job status' ,
681- 'Job status' ,
682- ' Job Status' ,
683- 'Job Status ' ,
684- 'Job Status' ,
685- 'Job\tStatus' ,
686- 'Job Status\n' ,
687- 'download' ,
688- ] ) ( 'rejects nonmatching relation %j before DNS or network access' , ( rel ) => {
688+ ...[
689+ 'job status' ,
690+ 'Job status' ,
691+ ' Job Status' ,
692+ 'Job Status ' ,
693+ 'Job Status' ,
694+ 'Job\tStatus' ,
695+ 'Job Status\n' ,
696+ 'download' ,
697+ ] . map ( ( rel ) => ( { relation : 'Job Status' , rel } ) ) ,
698+ ...[
699+ 'Exported/artifact' ,
700+ 'exported/Artifact' ,
701+ ' exported/artifact' ,
702+ 'exported/artifact ' ,
703+ 'exported/artifact\n' ,
704+ 'exported%2Fartifact' ,
705+ 'exported\\artifact' ,
706+ 'exported//artifact' ,
707+ 'exported/artifact/extra' ,
708+ 'imported/artifact' ,
709+ 'self' ,
710+ ] . map ( ( rel ) => ( { relation : 'exported/artifact' , rel } ) ) ,
711+ ] ) ( 'rejects $rel for $relation before DNS or network access' , ( { relation, rel } ) => {
689712 const policy = routes . defineReturnedLinkPolicy ( {
690- relation : 'Job Status' ,
713+ relation,
691714 method : 'GET' ,
692715 endpoint : getJob ,
693716 preserveGatewayBasePath : true ,
0 commit comments