Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitdd54255

Browse files
committed
feat: support RDP-specific deep links
1 parentc25ba00 commitdd54255

File tree

3 files changed

+89
-10
lines changed

3 files changed

+89
-10
lines changed

‎Coder-Desktop/Coder-Desktop/URLHandler.swift

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,65 @@ class URLHandler {
2020
guard deployment.host()== url.hostelse{
2121
throw.invalidAuthority(url.host()??"<none>")
2222
}
23+
letroute:CoderRoute
2324
do{
24-
switchtry router.match(url: url){
25-
caselet.open(workspace, agent, type):
26-
switch type{
27-
caselet.rdp(creds):
28-
handleRDP(workspace: workspace, agent: agent, creds: creds)
29-
}
30-
}
25+
route=try router.match(url: url)
3126
}catch{
3227
throw.matchError(url: url)
3328
}
3429

35-
func handleRDP(workspace _:String, agent _:String, creds _:RDPCredentials){
36-
// TODO: Handle RDP
30+
switch route{
31+
caselet.open(workspace, agent, type):
32+
switch type{
33+
caselet.rdp(creds):
34+
tryhandleRDP(workspace: workspace, agent: agent, creds: creds)
35+
}
36+
}
37+
}
38+
39+
privatefunc handleRDP(workspace:String, agent:String, creds:RDPCredentials)throws(URLError){
40+
guard vpn.state==.connectedelse{
41+
throw.openError(.coderConnectOffline)
42+
}
43+
44+
guardlet workspace= vpn.menuState.findWorkspace(name: workspace)else{
45+
throw.openError(.invalidWorkspace(workspace: workspace))
46+
}
47+
48+
guardlet agent= vpn.menuState.findAgent(workspaceID: workspace.id, name: agent)else{
49+
throw.openError(.invalidAgent(workspace: workspace.name, agent: agent))
50+
}
51+
52+
varrdpString="rdp:full address=s:\(agent.primaryHost):3389"
53+
iflet username= creds.username{
54+
rdpString+="&username=s:\(username)"
55+
}
56+
guardlet url=URL(string: rdpString)else{
57+
throw.openError(.couldNotCreateRDPURL(rdpString))
58+
}
59+
60+
letalert=NSAlert()
61+
alert.messageText="Opening RDP"
62+
alert.informativeText="Connecting to\(agent.primaryHost)."
63+
iflet username= creds.username{
64+
alert.informativeText+="\nUsername:\(username)"
65+
}
66+
if creds.password!=nil{
67+
alert.informativeText+="\nThe password will be copied to your clipboard."
68+
}
69+
70+
alert.alertStyle=.informational
71+
alert.addButton(withTitle:"Open")
72+
alert.addButton(withTitle:"Cancel")
73+
letresponse= alert.runModal()
74+
if response==.alertFirstButtonReturn{
75+
iflet password= creds.password{
76+
NSPasteboard.general.clearContents()
77+
NSPasteboard.general.setString(password, forType:.string)
78+
}
79+
NSWorkspace.shared.open(url)
80+
}else{
81+
// User cancelled
3782
}
3883
}
3984
}

‎Coder-Desktop/Coder-Desktop/VPN/MenuState.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ struct VPNMenuState {
5858
// or have any invalid UUIDs.
5959
varinvalidAgents:[Vpn_Agent]=[]
6060

61+
publicfunc findAgent(workspaceID:UUID, name:String)->Agent?{
62+
agents.first(where:{ $0.value.wsID== workspaceID && $0.value.name== name})?.value
63+
}
64+
65+
publicfunc findWorkspace(name:String)->Workspace?{
66+
workspaces
67+
.first(where:{ $0.value.name== name})?.value
68+
}
69+
6170
mutatingfunc upsertAgent(_ agent:Vpn_Agent){
6271
guard
6372
let id=UUID(uuidData: agent.id),

‎Coder-Desktop/VPNLib/CoderRouter.swift

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,40 @@ public enum RouterError: Error {
3333
case invalidAuthority(String)
3434
case matchError(url:URL)
3535
case noSession
36+
case openError(OpenError)
3637

37-
publicvardescription:String{
38+
vardescription:String{
3839
switchself{
3940
caselet.invalidAuthority(authority):
4041
"Authority '\(authority)' does not match the host of the current Coder deployment."
4142
caselet.matchError(url):
4243
"Failed to handle\(url.absoluteString) because the format is unsupported."
4344
case.noSession:
4445
"Not logged in."
46+
caselet.openError(error):
47+
error.description
48+
}
49+
}
50+
51+
varlocalizedDescription:String{ description}
52+
}
53+
54+
publicenumOpenError:Error{
55+
case invalidWorkspace(workspace:String)
56+
case invalidAgent(workspace:String, agent:String)
57+
case coderConnectOffline
58+
case couldNotCreateRDPURL(String)
59+
60+
publicvardescription:String{
61+
switchself{
62+
caselet.invalidWorkspace(ws):
63+
"Could not find workspace '\(ws)'. Does it exist?"
64+
case.coderConnectOffline:
65+
"Coder Connect must be running."
66+
caselet.invalidAgent(workspace: workspace, agent: agent):
67+
"Could not find agent '\(agent)' in workspace '\(workspace)'. Is the workspace running?"
68+
caselet.couldNotCreateRDPURL(rdpString):
69+
"Could not create construct RDP url from '\(rdpString)'."
4570
}
4671
}
4772

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp