@@ -40,7 +40,8 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
40
40
const storage = new Storage ( output , ctx . globalState , ctx . secrets , ctx . globalStorageUri , ctx . logUri )
41
41
42
42
// This client tracks the current login and will be used through the life of
43
- // the plugin to poll workspaces for the current login.
43
+ // the plugin to poll workspaces for the current login, as well as being used
44
+ // in commands that operate on the current login.
44
45
const url = storage . getUrl ( )
45
46
const restClient = await makeCoderSdk ( url || "" , await storage . getSessionToken ( ) , storage )
46
47
@@ -57,33 +58,7 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
57
58
myWorkspacesProvider . setVisibility ( event . visible )
58
59
} )
59
60
60
- if ( url ) {
61
- restClient
62
- . getAuthenticatedUser ( )
63
- . then ( async ( user ) => {
64
- if ( user && user . roles ) {
65
- vscode . commands . executeCommand ( "setContext" , "coder.authenticated" , true )
66
- if ( user . roles . find ( ( role ) => role . name === "owner" ) ) {
67
- await vscode . commands . executeCommand ( "setContext" , "coder.isOwner" , true )
68
- }
69
-
70
- // Fetch and monitor workspaces, now that we know the client is good.
71
- myWorkspacesProvider . fetchAndRefresh ( )
72
- allWorkspacesProvider . fetchAndRefresh ( )
73
- }
74
- } )
75
- . catch ( ( error ) => {
76
- // This should be a failure to make the request, like the header command
77
- // errored.
78
- vscodeProposed . window . showErrorMessage ( "Failed to check user authentication: " + error . message )
79
- } )
80
- . finally ( ( ) => {
81
- vscode . commands . executeCommand ( "setContext" , "coder.loaded" , true )
82
- } )
83
- } else {
84
- vscode . commands . executeCommand ( "setContext" , "coder.loaded" , true )
85
- }
86
-
61
+ // Handle vscode:// URIs.
87
62
vscode . window . registerUriHandler ( {
88
63
handleUri : async ( uri ) => {
89
64
const params = new URLSearchParams ( uri . query )
@@ -127,12 +102,15 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
127
102
await storage . configureCli ( toSafeHost ( url ) , url , token )
128
103
129
104
vscode . commands . executeCommand ( "coder.open" , owner , workspace , agent , folder , openRecent )
105
+ } else {
106
+ throw new Error ( `Unknown path ${ uri . path } ` )
130
107
}
131
108
} ,
132
109
} )
133
110
111
+ // Register globally available commands. Many of these have visibility
112
+ // controlled by contexts, see `when` in the package.json.
134
113
const commands = new Commands ( vscodeProposed , restClient , storage )
135
-
136
114
vscode . commands . registerCommand ( "coder.login" , commands . login . bind ( commands ) )
137
115
vscode . commands . registerCommand ( "coder.logout" , commands . logout . bind ( commands ) )
138
116
vscode . commands . registerCommand ( "coder.open" , commands . open . bind ( commands ) )
@@ -153,38 +131,71 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
153
131
// Since the "onResolveRemoteAuthority:ssh-remote" activation event exists
154
132
// in package.json we're able to perform actions before the authority is
155
133
// resolved by the remote SSH extension.
156
- if ( ! vscodeProposed . env . remoteAuthority ) {
157
- return
158
- }
159
- const remote = new Remote ( vscodeProposed , storage , commands , ctx . extensionMode )
160
- try {
161
- await remote . setup ( vscodeProposed . env . remoteAuthority )
162
- } catch ( ex ) {
163
- if ( ex instanceof CertificateError ) {
164
- await ex . showModal ( "Failed to open workspace" )
165
- } else if ( isAxiosError ( ex ) ) {
166
- const msg = getErrorMessage ( ex , "" )
167
- const detail = getErrorDetail ( ex )
168
- const urlString = axios . getUri ( ex . response ?. config )
169
- let path = urlString
170
- try {
171
- path = new URL ( urlString ) . pathname
172
- } catch ( e ) {
173
- // ignore, default to full url
134
+ if ( vscodeProposed . env . remoteAuthority ) {
135
+ const remote = new Remote ( vscodeProposed , storage , commands , ctx . extensionMode )
136
+ try {
137
+ const details = await remote . setup ( vscodeProposed . env . remoteAuthority )
138
+ if ( details ) {
139
+ // Authenticate the plugin client which is used in the sidebar to display
140
+ // workspaces belonging to this deployment.
141
+ restClient . setHost ( details . url )
142
+ restClient . setSessionToken ( details . token )
174
143
}
175
- await vscodeProposed . window . showErrorMessage ( "Failed to open workspace" , {
176
- detail : `API ${ ex . response ?. config . method ?. toUpperCase ( ) } to '${ path } ' failed with code ${ ex . response ?. status } .\nMessage: ${ msg } \nDetail: ${ detail } ` ,
177
- modal : true ,
178
- useCustom : true ,
144
+ } catch ( ex ) {
145
+ if ( ex instanceof CertificateError ) {
146
+ await ex . showModal ( "Failed to open workspace" )
147
+ } else if ( isAxiosError ( ex ) ) {
148
+ const msg = getErrorMessage ( ex , "" )
149
+ const detail = getErrorDetail ( ex )
150
+ const urlString = axios . getUri ( ex . response ?. config )
151
+ let path = urlString
152
+ try {
153
+ path = new URL ( urlString ) . pathname
154
+ } catch ( e ) {
155
+ // ignore, default to full url
156
+ }
157
+ await vscodeProposed . window . showErrorMessage ( "Failed to open workspace" , {
158
+ detail : `API ${ ex . response ?. config . method ?. toUpperCase ( ) } to '${ path } ' failed with code ${ ex . response ?. status } .\nMessage: ${ msg } \nDetail: ${ detail } ` ,
159
+ modal : true ,
160
+ useCustom : true ,
161
+ } )
162
+ } else {
163
+ await vscodeProposed . window . showErrorMessage ( "Failed to open workspace" , {
164
+ detail : ( ex as string ) . toString ( ) ,
165
+ modal : true ,
166
+ useCustom : true ,
167
+ } )
168
+ }
169
+ // Always close remote session when we fail to open a workspace.
170
+ await remote . closeRemote ( )
171
+ }
172
+ }
173
+
174
+ // See if the plugin client is authenticated.
175
+ if ( restClient . getAxiosInstance ( ) . defaults . baseURL ) {
176
+ restClient
177
+ . getAuthenticatedUser ( )
178
+ . then ( async ( user ) => {
179
+ if ( user && user . roles ) {
180
+ vscode . commands . executeCommand ( "setContext" , "coder.authenticated" , true )
181
+ if ( user . roles . find ( ( role ) => role . name === "owner" ) ) {
182
+ await vscode . commands . executeCommand ( "setContext" , "coder.isOwner" , true )
183
+ }
184
+
185
+ // Fetch and monitor workspaces, now that we know the client is good.
186
+ myWorkspacesProvider . fetchAndRefresh ( )
187
+ allWorkspacesProvider . fetchAndRefresh ( )
188
+ }
179
189
} )
180
- } else {
181
- await vscodeProposed . window . showErrorMessage ( "Failed to open workspace" , {
182
- detail : ( ex as string ) . toString ( ) ,
183
- modal : true ,
184
- useCustom : true ,
190
+ . catch ( ( error ) => {
191
+ // This should be a failure to make the request, like the header command
192
+ // errored.
193
+ vscode . window . showErrorMessage ( "Failed to check user authentication: " + error . message )
185
194
} )
186
- }
187
- // Always close remote session when we fail to open a workspace.
188
- await remote . closeRemote ( )
195
+ . finally ( ( ) => {
196
+ vscode . commands . executeCommand ( "setContext" , "coder.loaded" , true )
197
+ } )
198
+ } else {
199
+ vscode . commands . executeCommand ( "setContext" , "coder.loaded" , true )
189
200
}
190
201
}
0 commit comments