11import type { WebSocketRpcClientOptions } from '@vitejs/devtools-rpc/presets/ws/client'
22import type { BirpcReturn , EventOptions } from 'birpc'
3- import type { ConnectionMeta , DevToolsRpcClientFunctions , DevToolsRpcServerFunctions } from '../types'
4- import type { DevToolsClientContext , DevToolsClientRpcHost } from './docks'
3+ import type { ConnectionMeta , DevToolsRpcClientFunctions , DevToolsRpcServerFunctions , EventEmitter } from '../types'
4+ import type { DevToolsClientContext , DevToolsClientRpcHost , RpcClientEvents } from './docks'
55import { createRpcClient } from '@vitejs/devtools-rpc'
66import { createWsRpcPreset } from '@vitejs/devtools-rpc/presets/ws/client'
77import { RpcFunctionsCollectorBase } from 'birpc-x'
8+ import { UAParser } from 'my-ua-parser'
9+ import { createEventEmitter } from '../utils/events'
810import { nanoid } from '../utils/nanoid'
911import { promiseWithResolver } from '../utils/promise'
1012
@@ -25,10 +27,15 @@ export interface DevToolsRpcClientOptions {
2527}
2628
2729export interface DevToolsRpcClient {
30+ /**
31+ * The events of the client
32+ */
33+ events : EventEmitter < RpcClientEvents >
34+
2835 /**
2936 * Whether the client is trusted
3037 */
31- readonly isTrusted : boolean
38+ readonly isTrusted : boolean | null
3239 /**
3340 * The connection meta
3441 */
@@ -40,7 +47,12 @@ export interface DevToolsRpcClient {
4047 *
4148 * @param timeout - The timeout in milliseconds, default to 60 seconds
4249 */
43- ensureTrusted : ( timeout ?: number ) => Promise < void >
50+ ensureTrusted : ( timeout ?: number ) => Promise < boolean >
51+
52+ /**
53+ * Request trust from the server
54+ */
55+ requestTrust : ( ) => Promise < boolean >
4456
4557 /**
4658 * Call a RPC function on the server
@@ -109,6 +121,7 @@ export async function getDevToolsRpcClient(
109121 baseURL = '/.devtools/' ,
110122 rpcOptions = { } ,
111123 } = options
124+ const events = createEventEmitter < RpcClientEvents > ( )
112125 const bases = Array . isArray ( baseURL ) ? baseURL : [ baseURL ]
113126 let connectionMeta : ConnectionMeta | undefined = options . connectionMeta || findConnectionMetaFromWindows ( )
114127
@@ -142,21 +155,10 @@ export async function getDevToolsRpcClient(
142155 const authId = getConnectionAuthIdFromWindows ( )
143156
144157 let isTrusted = false
145- const trustedPromise = promiseWithResolver < void > ( )
158+ const trustedPromise = promiseWithResolver < boolean > ( )
146159
147160 const clientRpc : DevToolsClientRpcHost = new RpcFunctionsCollectorBase < DevToolsRpcClientFunctions , DevToolsClientContext > ( context )
148161
149- // Builtin rpc functions
150- clientRpc . register ( {
151- name : 'vite:anonymous:trusted' ,
152- type : 'event' ,
153- handler : ( ) => {
154- isTrusted = true
155- trustedPromise . resolve ( )
156- return true
157- } ,
158- } )
159-
160162 // Create the RPC client
161163 const serverRpc = createRpcClient < DevToolsRpcServerFunctions , DevToolsRpcClientFunctions > (
162164 clientRpc . functions ,
@@ -169,15 +171,35 @@ export async function getDevToolsRpcClient(
169171 } ,
170172 )
171173
172- // TODO: implement the trust logic
173- serverRpc . $call ( 'vite:anonymous:auth' , {
174- authId,
175- ua : navigator . userAgent ,
176- } )
174+ async function requestTrust ( ) {
175+ if ( isTrusted )
176+ return true
177+
178+ const info = new UAParser ( navigator . userAgent ) . getResult ( )
179+ const ua = [
180+ info . browser . name ,
181+ info . browser . version ,
182+ '|' ,
183+ info . os . name ,
184+ info . os . version ,
185+ info . device . type ,
186+ ] . filter ( i => i ) . join ( ' ' )
187+
188+ const result = await serverRpc
189+ . $call ( 'vite:anonymous:auth' , {
190+ authId,
191+ ua,
192+ } )
193+
194+ isTrusted = result . isTrusted
195+ trustedPromise . resolve ( isTrusted )
196+ events . emit ( 'rpc:is-trusted:updated' , isTrusted )
197+ return result . isTrusted
198+ }
177199
178- async function ensureTrusted ( timeout = 60_000 ) : Promise < void > {
200+ async function ensureTrusted ( timeout = 60_000 ) : Promise < boolean > {
179201 if ( isTrusted )
180- trustedPromise . resolve ( )
202+ trustedPromise . resolve ( true )
181203
182204 if ( timeout <= 0 )
183205 return trustedPromise . promise
@@ -192,14 +214,18 @@ export async function getDevToolsRpcClient(
192214 clear = ( ) => clearTimeout ( id )
193215 } ) ,
194216 ] )
217+
218+ return isTrusted
195219 }
196220
197221 const rpc : DevToolsRpcClient = {
222+ events,
198223 get isTrusted ( ) {
199224 return isTrusted
200225 } ,
201226 connectionMeta,
202227 ensureTrusted,
228+ requestTrust,
203229 call : ( ...args : any ) : any => {
204230 // @ts -expect-error casting
205231 return serverRpc . call ( ...args )
@@ -217,6 +243,7 @@ export async function getDevToolsRpcClient(
217243
218244 // @ts -expect-error assign to readonly property
219245 context . rpc = rpc
246+ requestTrust ( )
220247
221248 return rpc
222249}
0 commit comments