Skip to content

Commit 9438a3d

Browse files
mustard-mhroboquat
authored andcommitted
[server] add http endpoint workspacePageClose for beacon
1 parent 14a3dea commit 9438a3d

File tree

1 file changed

+78
-1
lines changed

1 file changed

+78
-1
lines changed

components/server/src/user/user-controller.ts

+78-1
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,12 @@ import { TosCookie } from "./tos-cookie";
2727
import { TosFlow } from "../terms/tos-flow";
2828
import { increaseLoginCounter } from "../../src/prometheus-metrics";
2929
import { v4 as uuidv4 } from "uuid";
30-
import { ScopedResourceGuard } from "../auth/resource-access";
30+
import { OwnerResourceGuard, ScopedResourceGuard } from "../auth/resource-access";
3131
import { OneTimeSecretServer } from "../one-time-secret-server";
3232
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";
3336

3437
@injectable()
3538
export class UserController {
@@ -46,6 +49,9 @@ export class UserController {
4649
@inject(LoginCompletionHandler) protected readonly loginCompletionHandler: LoginCompletionHandler;
4750
@inject(OneTimeSecretServer) protected readonly otsServer: OneTimeSecretServer;
4851
@inject(OneTimeSecretDB) protected readonly otsDb: OneTimeSecretDB;
52+
@inject(WorkspaceManagerClientProvider)
53+
protected readonly workspaceManagerClientProvider: WorkspaceManagerClientProvider;
54+
@inject(EnforcementControllerServerFactory) private readonly serverFactory: EnforcementControllerServerFactory;
4955

5056
get apiRouter(): express.Router {
5157
const router = express.Router();
@@ -281,6 +287,64 @@ export class UserController {
281287
res.sendStatus(200);
282288
},
283289
);
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+
);
284348
if (this.config.enableLocalApp) {
285349
router.get(
286350
"/auth/local-app",
@@ -705,4 +769,17 @@ export class UserController {
705769
log.debug({ sessionId: req.sessionID }, "The redirect URL does not match", { query: req.query });
706770
return;
707771
}
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+
}
708785
}

0 commit comments

Comments
 (0)