@@ -27,9 +27,12 @@ import { TosCookie } from "./tos-cookie";
27
27
import { TosFlow } from "../terms/tos-flow" ;
28
28
import { increaseLoginCounter } from "../../src/prometheus-metrics" ;
29
29
import { v4 as uuidv4 } from "uuid" ;
30
- import { ScopedResourceGuard } from "../auth/resource-access" ;
30
+ import { OwnerResourceGuard , ScopedResourceGuard } from "../auth/resource-access" ;
31
31
import { OneTimeSecretServer } from "../one-time-secret-server" ;
32
32
import { trackSignup } from "../analytics" ;
33
+ import { WorkspaceManagerClientProvider } from "@gitpod/ws-manager/lib/client-provider" ;
34
+ import { EnforcementControllerServerFactory } from "./enforcement-endpoint" ;
35
+ import { ClientMetadata } from "../websocket/websocket-connection-manager" ;
33
36
34
37
@injectable ( )
35
38
export class UserController {
@@ -46,6 +49,9 @@ export class UserController {
46
49
@inject ( LoginCompletionHandler ) protected readonly loginCompletionHandler : LoginCompletionHandler ;
47
50
@inject ( OneTimeSecretServer ) protected readonly otsServer : OneTimeSecretServer ;
48
51
@inject ( OneTimeSecretDB ) protected readonly otsDb : OneTimeSecretDB ;
52
+ @inject ( WorkspaceManagerClientProvider )
53
+ protected readonly workspaceManagerClientProvider : WorkspaceManagerClientProvider ;
54
+ @inject ( EnforcementControllerServerFactory ) private readonly serverFactory : EnforcementControllerServerFactory ;
49
55
50
56
get apiRouter ( ) : express . Router {
51
57
const router = express . Router ( ) ;
@@ -281,6 +287,64 @@ export class UserController {
281
287
res . sendStatus ( 200 ) ;
282
288
} ,
283
289
) ;
290
+
291
+ router . post (
292
+ "/auth/workspacePageClose/:instanceID" ,
293
+ async ( req : express . Request , res : express . Response , next : express . NextFunction ) => {
294
+ if ( ! req . isAuthenticated ( ) || ! User . is ( req . user ) ) {
295
+ res . sendStatus ( 401 ) ;
296
+ log . warn ( "unauthenticated workspacePageClose" , { instanceId : req . params . instanceID } ) ;
297
+ return ;
298
+ }
299
+
300
+ const user = req . user as User ;
301
+ if ( user . blocked ) {
302
+ res . sendStatus ( 403 ) ;
303
+ log . warn ( "blocked user attempted to workspacePageClose" , {
304
+ instanceId : req . params . instanceID ,
305
+ userId : user . id ,
306
+ } ) ;
307
+ return ;
308
+ }
309
+
310
+ const instanceID = req . params . instanceID ;
311
+ if ( ! instanceID ) {
312
+ res . sendStatus ( 400 ) ;
313
+ log . warn ( "attempted to workspacePageClose without instance ID" , {
314
+ instanceId : req . params . instanceID ,
315
+ userId : user . id ,
316
+ } ) ;
317
+ return ;
318
+ }
319
+ const sessionId = req . body . sessionId ;
320
+ const server = this . createGitpodServer ( user ) ;
321
+ try {
322
+ await server . sendHeartBeat ( { } , { wasClosed : true , instanceId : instanceID } ) ;
323
+ /** no await */ server
324
+ . trackEvent (
325
+ { } ,
326
+ {
327
+ event : "ide_close_signal" ,
328
+ properties : {
329
+ sessionId,
330
+ instanceId : instanceID ,
331
+ clientKind : "supervisor-frontend" ,
332
+ } ,
333
+ } ,
334
+ )
335
+ . catch ( ( err ) =>
336
+ log . warn ( { userId : user . id } , "workspacePageClose: failed to track ide close signal" , err ) ,
337
+ ) ;
338
+ res . sendStatus ( 200 ) ;
339
+ } catch ( e ) {
340
+ log . error ( "workspacePageClose failed" , e ) ;
341
+ res . sendStatus ( 500 ) ;
342
+ return ;
343
+ } finally {
344
+ server . dispose ( ) ;
345
+ }
346
+ } ,
347
+ ) ;
284
348
if ( this . config . enableLocalApp ) {
285
349
router . get (
286
350
"/auth/local-app" ,
@@ -705,4 +769,17 @@ export class UserController {
705
769
log . debug ( { sessionId : req . sessionID } , "The redirect URL does not match" , { query : req . query } ) ;
706
770
return ;
707
771
}
772
+
773
+ private createGitpodServer ( user : User ) {
774
+ const server = this . serverFactory ( ) ;
775
+ server . initialize (
776
+ undefined ,
777
+ user ,
778
+ new OwnerResourceGuard ( user . id ) ,
779
+ ClientMetadata . from ( user . id ) ,
780
+ undefined ,
781
+ { } ,
782
+ ) ;
783
+ return server ;
784
+ }
708
785
}
0 commit comments