1616// - a result left by a callback page whose editor is gone is delivered when the editor next starts,
1717// and an old one is not.
1818//
19- // node web/test/e2e-signin-tab.mjs --static <vscode-web dir> --extensions <built extensions dir>
20- // node web/test/e2e-signin-tab.mjs --dist <release dir>
19+ // node web/test/e2e-signin-tab.mjs --static <vscode-web dir> --extensions <built extensions dir> [--product <json>]
20+ // node web/test/e2e-signin-tab.mjs --dist <release dir> --stub-port <the account port it was built with>
2121import { spawn } from 'node:child_process' ;
2222import fs from 'node:fs' ;
2323import path from 'node:path' ;
@@ -44,7 +44,12 @@ const check = (name, ok, detail = '') => { results.push(ok); console.log(`${ok ?
4444const stub = await startStub ( { editorOrigin, port : args [ 'stub-port' ] ? Number ( args [ 'stub-port' ] ) : 0 } ) ;
4545const server = spawn ( process . execPath , [ path . join ( HERE , '..' , 'serve.mjs' ) , '--port' , String ( PORT ) , ...( DIST
4646 ? [ '--dist' , DIST ]
47- : [ '--static' , STATIC , '--extensions' , EXTS , '--extension-names' , 'levelcode-ai,levelcode-web' , '--account' , stub . origin ] ) ] , { stdio : 'inherit' } ) ;
47+ : [ '--static' , STATIC , '--extensions' , EXTS , '--extension-names' , 'levelcode-ai,levelcode-web' , '--account' , stub . origin ,
48+ ...( args . product ? [ '--product' , args . product ] : [ ] ) ] ) ] , { stdio : 'inherit' } ) ;
49+ // With the extension host on an origin of its own (--product with webEndpointUrlTemplate, or a release built with
50+ // --ext-host-origin) its fetches carry THAT origin, not the editor's.
51+ let hardened = / w e b E n d p o i n t U r l T e m p l a t e / . test ( args . product || '' ) ;
52+ if ( DIST ) { try { hardened = ! / \( s a m e o r i g i n / . test ( fs . readFileSync ( path . join ( DIST , 'build.json' ) , 'utf8' ) ) ; } catch { /* keep */ } }
4853let chrome ;
4954const finish = async ( code ) => { try { chrome && chrome . close ( ) ; } catch { } try { server . kill ( ) ; } catch { } try { await stub . close ( ) ; } catch { } process . exit ( code ) ; } ;
5055process . on ( 'SIGINT' , ( ) => finish ( 130 ) ) ;
6671 await page . waitFor ( ( ) => exchanges ( ) >= 1 , { ms : 90000 , label : 'code exchange' } ) . catch ( ( ) => null ) ;
6772 check ( 'the code was exchanged, with the verifier that was kept across the reload' , exchanges ( ) === 1 , 'exchanges: ' + exchanges ( ) ) ;
6873 const exch = stub . state . log . find ( ( e ) => e . path === '/api/levelcode/v1/auth/exchange' && e . method === 'POST' ) || { } ;
69- check ( 'the exchange came from the editor\'s origin (CORS answered)' , exch . origin === editorOrigin , 'from ' + exch . origin ) ;
74+ check ( hardened ? 'the exchange came from the extension host\'s own origin (CORS answered)' : 'the exchange came from the editor\'s origin (CORS answered)' ,
75+ hardened ? / ^ h t t p s ? : \/ \/ v - - [ a - z 0 - 9 ] + \. / . test ( exch . origin || '' ) : exch . origin === editorOrigin , 'from ' + exch . origin ) ;
7076 await workbenchReady ( page ) ;
7177 await page . waitFor ( ( ) => accountCalls ( ) >= 1 , { ms : 30000 , label : 'the account API with the new token' } ) . catch ( ( ) => null ) ;
7278 check ( 'the editor then used its session against the account API' , accountCalls ( ) >= 1 , 'calls: ' + accountCalls ( ) ) ;
0 commit comments