UNPKG

@theia/core

Version:

Theia is a cloud & desktop IDE framework implemented in TypeScript.

74 lines 4.05 kB
import * as http from 'http'; import express = require('express'); import { MaybePromise } from '../../common'; import { BackendApplicationContribution, EarlyExpressMiddleware } from '../backend-application'; import { WsRequestValidatorContribution } from '../ws-request-validators'; export declare const BrowserConnectionToken: unique symbol; export declare const BROWSER_TOKEN_COOKIE_NAME = "theia-connection-token"; export interface BrowserConnectionToken { value: string; } export declare const HttpConnectionValidator: unique symbol; /** * Express middleware provider that rejects HTTP requests lacking a valid connection token. * * The connection-token cookie is only *bootstrapped* globally (see * {@link BrowserConnectionTokenBackendContribution}); enforcement is opt-in per route. * Security-sensitive HTTP endpoints (e.g. the filesystem upload/download routes) should * inject this and apply {@link validateRequest} as route middleware. Non-sensitive routes * (the initial HTML page, static assets) must not use it, as they legitimately have no * cookie yet on the very first page load. */ export interface HttpConnectionValidator { /** * Express middleware that calls `next()` when the request carries a valid connection-token * cookie (or when running in Electron) and responds with `403` otherwise. */ validateRequest(req: express.Request, res: express.Response, next: express.NextFunction): void; } /** * Validates WebSocket and HTTP requests using a cookie-based connection token. * * In browser deployments, the server generates a random token at startup and sets it * as a `SameSite=Strict; HttpOnly` cookie on the first page load. Cross-origin pages * cannot obtain or send this cookie, so their requests are rejected. * * The cookie is *bootstrapped* for every HTTP request (via {@link expressMiddleware}) so that * browsers always receive it, but HTTP requests are only *rejected* on routes that opt in to * enforcement via {@link validateRequest} (see {@link HttpConnectionValidator}). WebSocket * upgrades are always validated (see {@link allowWsUpgrade}). * * This complements the origin validator: non-browser callers that omit the Origin * header (e.g. Node.js scripts) still cannot reach the backend without the cookie. * * Skipped in Electron deployments (which use their own `ElectronSecurityToken`). */ export declare class BrowserConnectionTokenBackendContribution implements BackendApplicationContribution, WsRequestValidatorContribution, HttpConnectionValidator { protected readonly browserConnectionToken: BrowserConnectionToken; protected readonly earlyMiddleware: EarlyExpressMiddleware; /** * Register the cookie middleware during `initialize()` via `EarlyExpressMiddleware` * so it runs before `express.static()` (which is registered later during `configure()`). * This ensures the browser receives the token cookie on the initial page load. */ initialize(): void; /** * Validate the connection token cookie on WebSocket upgrade requests. * Non-browser callers that omit the Origin header (e.g. Node.js scripts) * cannot provide the `SameSite=Strict` cookie either, so they are rejected. */ allowWsUpgrade(request: http.IncomingMessage): MaybePromise<boolean>; /** * Reject the request with `403` unless it carries a valid connection-token cookie. * Always allows the request in Electron deployments, consistent with {@link allowWsUpgrade}. */ validateRequest(req: express.Request, res: express.Response, next: express.NextFunction): void; protected expressMiddleware(req: express.Request, res: express.Response, next: express.NextFunction): void; protected getTokenFromCookie(req: http.IncomingMessage): string | undefined; protected isTokenValid(token: string): boolean; } /** * Creates a new browser connection token. */ export declare function createBrowserConnectionToken(): BrowserConnectionToken; //# sourceMappingURL=browser-connection-token.d.ts.map