Skip to content

Commit f591b3f

Browse files
committed
wip: auth
1 parent b24a453 commit f591b3f

File tree

7 files changed

+136
-571
lines changed

7 files changed

+136
-571
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { defineRpcFunction } from '@vitejs/devtools-kit'
2+
3+
export interface DevToolsAuthInput {
4+
authId: string
5+
ua: string
6+
}
7+
8+
export interface DevToolsAuthReturn {
9+
isTrusted: boolean
10+
}
11+
12+
export const anonymousAuth = defineRpcFunction({
13+
name: 'vite:anonymous:auth',
14+
type: 'action',
15+
setup: (context) => {
16+
return {
17+
handler: (query: DevToolsAuthInput): DevToolsAuthReturn => {
18+
// TODO: Implement the auth logic
19+
return {
20+
isTrusted: false,
21+
}
22+
},
23+
}
24+
},
25+
})

packages/core/src/node/rpc/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { DevToolsTerminalSessionStreamChunkEvent, RpcDefinitionsFilter, RpcDefinitionsToFunctions } from '@vitejs/devtools-kit'
2+
import { anonymousAuth } from './anonymous/auth'
23
import { docksList } from './internal/docks-list'
34
import { docksOnLaunch } from './internal/docks-on-launch'
45
import { rpcServerList } from './internal/rpc-server-list'
@@ -13,6 +14,10 @@ export const builtinPublicRpcDecalrations = [
1314
openInFinder,
1415
] as const
1516

17+
export const builtinAnonymousRpcDecalrations = [
18+
anonymousAuth,
19+
] as const
20+
1621
// @keep-sorted
1722
export const builtinInternalRpcDecalrations = [
1823
docksList,
@@ -24,6 +29,7 @@ export const builtinInternalRpcDecalrations = [
2429

2530
export const builtinRpcDecalrations = [
2631
...builtinPublicRpcDecalrations,
32+
...builtinAnonymousRpcDecalrations,
2733
...builtinInternalRpcDecalrations,
2834
] as const
2935

packages/kit/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
"birpc-x": "catalog:deps"
4545
},
4646
"devDependencies": {
47+
"nanoid": "^5.1.6",
4748
"tsdown": "catalog:build",
4849
"vite": "catalog:build"
4950
}

packages/kit/src/client/rpc.ts

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import type { WebSocketRpcClientOptions } from '@vitejs/devtools-rpc/presets/ws/client'
2-
import type { BirpcOptions, BirpcReturn } from 'birpc'
2+
import type { BirpcReturn, EventOptions } from 'birpc'
33
import type { ConnectionMeta, DevToolsRpcClientFunctions, DevToolsRpcServerFunctions } from '../types'
44
import type { DevToolsClientContext, DevToolsClientRpcHost } from './docks'
55
import { createRpcClient } from '@vitejs/devtools-rpc'
66
import { createWsRpcPreset } from '@vitejs/devtools-rpc/presets/ws/client'
77
import { RpcFunctionsCollectorBase } from 'birpc-x'
8+
import { nanoid } from 'nanoid'
89

910
const CONNECTION_META_KEY = '__VITE_DEVTOOLS_CONNECTION_META__'
11+
const CONNECTION_AUTH_ID_KEY = '__VITE_DEVTOOLS_CONNECTION_AUTH_ID__'
1012

1113
function isNumeric(str: string | number | undefined) {
1214
if (str == null)
@@ -18,7 +20,7 @@ export interface DevToolsRpcClientOptions {
1820
connectionMeta?: ConnectionMeta
1921
baseURL?: string[]
2022
wsOptions?: Partial<WebSocketRpcClientOptions>
21-
rpcOptions?: Partial<BirpcOptions<DevToolsRpcServerFunctions>>
23+
rpcOptions?: EventOptions<DevToolsRpcServerFunctions, DevToolsRpcClientFunctions>
2224
}
2325

2426
export type DevToolsRpcClient = BirpcReturn<DevToolsRpcServerFunctions, DevToolsRpcClientFunctions>
@@ -27,13 +29,39 @@ export interface ClientRpcReturn {
2729
connectionMeta: ConnectionMeta
2830
rpc: DevToolsRpcClient
2931
clientRpc: DevToolsClientRpcHost
32+
readonly isTrusted: boolean
33+
}
34+
35+
function getConnectionAuthIdFromWindows(): string {
36+
const getters = [
37+
() => localStorage.getItem(CONNECTION_AUTH_ID_KEY),
38+
() => (window as any)?.[CONNECTION_AUTH_ID_KEY],
39+
() => (globalThis as any)?.[CONNECTION_AUTH_ID_KEY],
40+
() => (parent.window as any)?.[CONNECTION_AUTH_ID_KEY],
41+
]
42+
43+
for (const getter of getters) {
44+
try {
45+
const value = getter()
46+
if (value) {
47+
if (!localStorage.getItem(CONNECTION_AUTH_ID_KEY))
48+
localStorage.setItem(CONNECTION_AUTH_ID_KEY, value)
49+
return value
50+
}
51+
}
52+
catch {}
53+
}
54+
55+
const uid = nanoid()
56+
localStorage.setItem(CONNECTION_AUTH_ID_KEY, uid)
57+
return uid
3058
}
3159

3260
function findConnectionMetaFromWindows(): ConnectionMeta | undefined {
3361
const getters = [
34-
() => (window as any)[CONNECTION_META_KEY],
35-
() => (globalThis as any)[CONNECTION_META_KEY],
36-
() => (parent.window as any)[CONNECTION_META_KEY],
62+
() => (window as any)?.[CONNECTION_META_KEY],
63+
() => (globalThis as any)?.[CONNECTION_META_KEY],
64+
() => (parent.window as any)?.[CONNECTION_META_KEY],
3765
]
3866

3967
for (const getter of getters) {
@@ -83,22 +111,54 @@ export async function getDevToolsRpcClient(
83111
const context: DevToolsClientContext = {
84112
rpc: undefined!,
85113
}
114+
const authId = getConnectionAuthIdFromWindows()
115+
116+
let isTrusted = false
86117
const clientRpc: DevToolsClientRpcHost = new RpcFunctionsCollectorBase<DevToolsRpcClientFunctions, DevToolsClientContext>(context)
118+
119+
// Builtin rpc functions
120+
clientRpc.register({
121+
name: 'vite:anonymous:trusted',
122+
type: 'event',
123+
handler: () => {
124+
isTrusted = true
125+
return true
126+
},
127+
})
128+
129+
// Create the RPC client
87130
const rpc = createRpcClient<DevToolsRpcServerFunctions, DevToolsRpcClientFunctions>(
88131
clientRpc.functions,
89132
{
90133
preset: createWsRpcPreset({
91134
url,
92135
...options.wsOptions,
93136
}),
94-
rpcOptions,
137+
rpcOptions: {
138+
...rpcOptions,
139+
meta: {
140+
authId,
141+
get isTrusted() {
142+
return isTrusted
143+
},
144+
},
145+
},
95146
},
96147
)
97148
// @ts-expect-error assign to readonly property
98149
context.rpc = rpc
99150

151+
// TODO: implement the trust logic
152+
rpc.$call('vite:anonymous:auth', {
153+
authId,
154+
ua: navigator.userAgent,
155+
})
156+
100157
return {
101158
connectionMeta,
159+
get isTrusted() {
160+
return isTrusted
161+
},
102162
rpc,
103163
clientRpc,
104164
}

packages/rpc/src/client.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
import type { BirpcOptions, BirpcReturn } from 'birpc'
1+
import type { BirpcOptions, BirpcReturn, ChannelOptions } from 'birpc'
22
import { createBirpc } from 'birpc'
33

44
export function createRpcClient<
5-
ServerFunctions = Record<string, never>,
6-
ClientFunctions extends object = Record<string, never>,
5+
ServerFunctions,
6+
ClientFunctions extends object,
77
>(
88
functions: ClientFunctions,
99
options: {
10-
preset: BirpcOptions<ServerFunctions>
11-
rpcOptions?: Partial<BirpcOptions<ServerFunctions>>
10+
preset: ChannelOptions
11+
rpcOptions?: Partial<BirpcOptions<ServerFunctions, ClientFunctions>>
1212
},
1313
): BirpcReturn<ServerFunctions, ClientFunctions> {
1414
const { preset, rpcOptions = {} } = options

packages/rpc/src/presets/ws/client.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { ChannelOptions } from 'birpc'
12
import type { RpcClientPreset } from '..'
23
import { parse, stringify } from 'structured-clone-es'
34
import { defineRpcClientPreset } from '..'
@@ -11,12 +12,7 @@ export interface WebSocketRpcClientOptions {
1112

1213
function NOOP() {}
1314

14-
export const createWsRpcPreset: RpcClientPreset<(options: WebSocketRpcClientOptions) => {
15-
on: (handler: (data: string) => void) => void
16-
post: (data: string) => void
17-
serialize: (obj: any) => string
18-
deserialize: (str: string) => unknown
19-
}> = defineRpcClientPreset((options: WebSocketRpcClientOptions) => {
15+
export const createWsRpcPreset: RpcClientPreset<(options: WebSocketRpcClientOptions) => ChannelOptions> = defineRpcClientPreset((options: WebSocketRpcClientOptions) => {
2016
const ws = new WebSocket(options.url)
2117
const {
2218
onConnected = NOOP,

0 commit comments

Comments
 (0)