mirror of
https://github.com/gitpod-io/gitpod.git
synced 2025-12-08 17:36:30 +00:00
This commit includes the following commits: - @iqqbot update dev image to nodejs v16lts - @iqqbot update dev-environment-image to use nodejs v16 - @iqqbot update component to nodejs v16 lts - [licensor] Adjust to v16 - [ts] Bump @types/node to ^16.11.0 accordingly - @aledbf Update typescript dependencies - @aledbf Update typescript configuration - @aledbf / @geropl Update typescript code - [server] Fix express/passport types - [db] typeorm upgrade 0.1.20 -> 0.2.22: fix compile and runtime issues - [db] typeorm upgrade 0.2.22 -> 0.2.38: fix compile and runtime issues - [dev] Upgrade amqplib and smaller libs - [dev] Upgrade uuid - [dev] Update probot - [dev] Final yarn.lock
104 lines
4.1 KiB
TypeScript
104 lines
4.1 KiB
TypeScript
/**
|
|
* Copyright (c) 2020 Gitpod GmbH. All rights reserved.
|
|
* Licensed under the GNU Affero General Public License (AGPL).
|
|
* See License-AGPL.txt in the project root for license information.
|
|
*/
|
|
|
|
import * as express from 'express';
|
|
import * as session from 'express-session';
|
|
import { SessionOptions } from 'express-session';
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
import { injectable, inject , postConstruct } from 'inversify';
|
|
|
|
import * as mysqlstore from 'express-mysql-session';
|
|
const MySQLStore = mysqlstore(session);
|
|
import { log } from '@gitpod/gitpod-protocol/lib/util/logging';
|
|
import { Config as DBConfig } from '@gitpod/gitpod-db/lib/config';
|
|
import { Config } from './config';
|
|
|
|
@injectable()
|
|
export class SessionHandlerProvider {
|
|
@inject(Config) protected readonly config: Config;
|
|
@inject(DBConfig) protected readonly dbConfig: DBConfig;
|
|
|
|
public sessionHandler: express.RequestHandler
|
|
|
|
@postConstruct()
|
|
public init() {
|
|
const options: SessionOptions = {} as SessionOptions
|
|
options.cookie = this.getCookieOptions(this.config);
|
|
options.genid = function (req: any) {
|
|
return uuidv4() // use UUIDs for session IDs
|
|
},
|
|
options.name = SessionHandlerProvider.getCookieName(this.config);
|
|
// options.proxy = true // TODO SSL Proxy
|
|
options.resave = true // TODO Check with store! See docu
|
|
options.rolling = true // default, new cookie and maxAge
|
|
options.secret = this.config.session.secret;
|
|
options.saveUninitialized = false // Do not save new cookie without content (uninitialized)
|
|
|
|
options.store = this.createStore();
|
|
|
|
this.sessionHandler = session(options);
|
|
}
|
|
|
|
protected getCookieOptions(config: Config): express.CookieOptions {
|
|
const hostName = config.hostUrl.url.host;
|
|
|
|
let domain = hostName;
|
|
if (config.devBranch) {
|
|
// Use cookie for base domain to allow cookies being sent via ingress proxy in preview environments
|
|
//
|
|
// Otherwise, clients (in this case Chrome) may ignore (as in: save it, but don't send it on consequent requests) the 'Set-Cookie:...' send with a redirect (302, to github oauth)
|
|
// For details, see:
|
|
// - RFC draft sameSite: http://httpwg.org/http-extensions/draft-ietf-httpbis-cookie-same-site.html
|
|
// - https://bugs.chromium.org/p/chromium/issues/detail?id=150066
|
|
// - google: chromium not sending cookies set with redirect
|
|
|
|
const hostParts = hostName.split('.');
|
|
const baseDomain = hostParts.slice(hostParts.length - 2).join('.');
|
|
domain = `.${baseDomain}`;
|
|
}
|
|
if (this.config.insecureNoDomain) {
|
|
domain = hostName.split(":")[0];
|
|
}
|
|
|
|
return {
|
|
path: "/", // default
|
|
httpOnly: true, // default
|
|
secure: false, // default, TODO SSL! Config proxy
|
|
maxAge: config.session.maxAgeMs, // configured in Helm chart, defaults to 3 days.
|
|
sameSite: "lax", // default: true. "Lax" needed for OAuth.
|
|
domain: `${domain}`
|
|
};
|
|
}
|
|
|
|
static getCookieName(config: Config) {
|
|
return config.hostUrl.toString()
|
|
.replace(/https?/, '')
|
|
.replace(/[\W_]+/g, "_");
|
|
}
|
|
|
|
public clearSessionCookie(res: express.Response, config: Config): void {
|
|
// http://expressjs.com/en/api.html#res.clearCookie
|
|
const name = SessionHandlerProvider.getCookieName(config);
|
|
const options = { ...this.getCookieOptions(config) };
|
|
delete options.expires;
|
|
delete options.maxAge;
|
|
res.clearCookie(name, options);
|
|
}
|
|
|
|
protected createStore(): any | undefined {
|
|
const options = {
|
|
...(this.dbConfig.dbConfig as any),
|
|
user: this.dbConfig.dbConfig.username,
|
|
database: 'gitpod-sessions',
|
|
createDatabaseTable: true
|
|
};
|
|
return new MySQLStore(options, undefined, (err) => {
|
|
if (err) {
|
|
log.debug('MySQL session store error: ', err);
|
|
}
|
|
});
|
|
}
|
|
} |