@@ -442,6 +442,99 @@ describe('adapters/dev', () => {
442442 }
443443 } )
444444
445+ it ( 'the `auth: false` option overrides a gated `def.cli.auth` (hosted adapter defers to the host)' , async ( ) => {
446+ const devframe = defineDevframe ( {
447+ id : 'devframe-auth-option-off' ,
448+ name : 'Auth Option Off' ,
449+ version : '0.0.0' ,
450+ packageName : 'devframe-test' ,
451+ homepage : 'https://example.test' ,
452+ description : 'Test devframe.' ,
453+ // Standalone would gate; a hosted caller passes `auth: false` to defer.
454+ cli : { auth : true } ,
455+ setup : ( ctx : DevframeNodeContext ) => {
456+ ctx . rpc . register ( { name : 'test:probe' , type : 'query' , handler : ( ) => 'ok' } )
457+ } ,
458+ } )
459+ const host = '127.0.0.1'
460+ const port = await getPort ( { port : 19440 , host } )
461+ const handle = await createDevServer ( devframe , { host, port, openBrowser : false , auth : false } )
462+
463+ try {
464+ const client = connectWsClient ( host , port )
465+ const handshake = await client . $call ( 'anonymous:devframe:auth' as any , HANDSHAKE )
466+ expect ( handshake ) . toEqual ( { isTrusted : true } )
467+ await expect ( client . $call ( 'test:probe' as any ) ) . resolves . toBe ( 'ok' )
468+ client . $close ( )
469+ }
470+ finally {
471+ await handle . close ( )
472+ }
473+ } )
474+
475+ it ( 'the `auth: true` option forces the gate on even when `def.cli.auth` is false' , async ( ) => {
476+ const devframe = defineDevframe ( {
477+ id : 'devframe-auth-option-on' ,
478+ name : 'Auth Option On' ,
479+ version : '0.0.0' ,
480+ packageName : 'devframe-test' ,
481+ homepage : 'https://example.test' ,
482+ description : 'Test devframe.' ,
483+ cli : { auth : false } ,
484+ setup : ( ctx : DevframeNodeContext ) => {
485+ ctx . rpc . register ( { name : 'test:probe' , type : 'query' , handler : ( ) => 'ok' } )
486+ } ,
487+ } )
488+ const host = '127.0.0.1'
489+ const port = await getPort ( { port : 19450 , host } )
490+ // Silence the default OTP stdout banner for the test run.
491+ const spy = vi . spyOn ( console , 'log' ) . mockImplementation ( ( ) => { } )
492+ const handle = await createDevServer ( devframe , { host, port, openBrowser : false , auth : true } )
493+
494+ try {
495+ const client = connectWsClient ( host , port )
496+ // Gated: an empty handshake token is refused until a code is exchanged.
497+ const handshake = await client . $call ( 'anonymous:devframe:auth' as any , HANDSHAKE )
498+ expect ( handshake ) . toEqual ( { isTrusted : false } )
499+ const code = getTempAuthCode ( )
500+ const exchange = await client . $call ( 'anonymous:devframe:auth:exchange' as any , { code, ua : 'test' , origin : 'http://localhost' } ) as { authToken : string | null }
501+ expect ( exchange . authToken ) . toBeTruthy ( )
502+ client . $close ( )
503+ }
504+ finally {
505+ spy . mockRestore ( )
506+ await handle . close ( )
507+ }
508+ } )
509+
510+ it ( 'the `--no-auth` flag forces the gate off even when the `auth: true` option opts in' , async ( ) => {
511+ const devframe = defineDevframe ( {
512+ id : 'devframe-auth-flag-wins' ,
513+ name : 'Auth Flag Wins' ,
514+ version : '0.0.0' ,
515+ packageName : 'devframe-test' ,
516+ homepage : 'https://example.test' ,
517+ description : 'Test devframe.' ,
518+ setup : ( ctx : DevframeNodeContext ) => {
519+ ctx . rpc . register ( { name : 'test:probe' , type : 'query' , handler : ( ) => 'ok' } )
520+ } ,
521+ } )
522+ const host = '127.0.0.1'
523+ const port = await getPort ( { port : 19460 , host } )
524+ const handle = await createDevServer ( devframe , { host, port, openBrowser : false , auth : true , flags : { auth : false } } )
525+
526+ try {
527+ const client = connectWsClient ( host , port )
528+ const handshake = await client . $call ( 'anonymous:devframe:auth' as any , HANDSHAKE )
529+ expect ( handshake ) . toEqual ( { isTrusted : true } )
530+ await expect ( client . $call ( 'test:probe' as any ) ) . resolves . toBe ( 'ok' )
531+ client . $close ( )
532+ }
533+ finally {
534+ await handle . close ( )
535+ }
536+ } )
537+
445538 it ( 'resolveDevServerPort honors def.cli.port as the preferred default' , async ( ) => {
446539 const preferred = await getPort ( { port : 19500 , host : '127.0.0.1' } )
447540 const devframe = defineDevframe ( {
0 commit comments