Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,26 @@
},
"cookieSecret": { "type": "string" },
"sessionMaxAgeHours": { "type": "number" },
"serverPort": {
"type": "number",
"description": "Port the proxy HTTP server listens on. Can also be set with the GIT_PROXY_SERVER_PORT environment variable, which takes precedence over this value."
},
"httpsServerPort": {
"type": "number",
"description": "Port the proxy HTTPS server listens on. Can also be set with the GIT_PROXY_HTTPS_SERVER_PORT environment variable, which takes precedence over this value."
},
"uiHost": {
"type": "string",
"description": "Host of the GitProxy UI. Can also be set with the GIT_PROXY_UI_HOST environment variable, which takes precedence over this value."
},
"uiPort": {
"type": "number",
"description": "Port the GitProxy UI/service HTTP server listens on. Can also be set with the GIT_PROXY_UI_PORT environment variable, which takes precedence over this value."
},
"httpsUiPort": {
"type": "number",
"description": "Port the GitProxy UI/service HTTPS server listens on. Can also be set with the GIT_PROXY_HTTPS_UI_PORT environment variable, which takes precedence over this value."
},
"api": {
"description": "Third party APIs",
"type": "object",
Expand Down
5 changes: 5 additions & 0 deletions proxy.config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
{
"cookieSecret": "cookie secret",
"sessionMaxAgeHours": 12,
"serverPort": 8000,
"httpsServerPort": 8443,
"uiHost": "http://localhost",
"uiPort": 8080,
"httpsUiPort": 8444,
"rateLimit": {
"windowMs": 60000,
"limit": 1000
Expand Down
15 changes: 10 additions & 5 deletions src/config/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,17 @@

import { ServerConfig } from './types';

// Server settings below default to `undefined` when the corresponding
// environment variable is unset so that the config file can provide the
// default. When an environment variable IS set it takes precedence over the
// config file (see mergeConfigurations in ./index.ts), mirroring
// GIT_PROXY_COOKIE_SECRET.
const {
GIT_PROXY_SERVER_PORT = 8000,
GIT_PROXY_HTTPS_SERVER_PORT = 8443,
GIT_PROXY_UI_HOST = 'http://localhost',
GIT_PROXY_UI_PORT = 8080,
GIT_PROXY_HTTPS_UI_PORT = 8444,
GIT_PROXY_SERVER_PORT,
GIT_PROXY_HTTPS_SERVER_PORT,
GIT_PROXY_UI_HOST,
GIT_PROXY_UI_PORT,
GIT_PROXY_HTTPS_UI_PORT,
GIT_PROXY_COOKIE_SECRET,
GIT_PROXY_MONGO_CONNECTION_STRING = 'mongodb://localhost:27017/git-proxy',
} = process.env;
Expand Down
30 changes: 30 additions & 0 deletions src/config/generated/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,16 @@ export interface GitProxyConfig {
* Provide custom URLs for the git proxy interfaces in case it cannot determine its own URL
*/
domains?: Domains;
/**
* Port the proxy HTTPS server listens on. Can also be set with the
* GIT_PROXY_HTTPS_SERVER_PORT environment variable, which takes precedence over this value.
*/
httpsServerPort?: number;
/**
* Port the GitProxy UI/service HTTPS server listens on. Can also be set with the
* GIT_PROXY_HTTPS_UI_PORT environment variable, which takes precedence over this value.
*/
httpsUiPort?: number;
/**
* List of plugins to integrate on GitProxy's push or pull actions. Each value is either a
* file path or a module name.
Expand All @@ -75,6 +85,11 @@ export interface GitProxyConfig {
* API Rate limiting configuration.
*/
rateLimit?: RateLimit;
/**
* Port the proxy HTTP server listens on. Can also be set with the GIT_PROXY_SERVER_PORT
* environment variable, which takes precedence over this value.
*/
serverPort?: number;
sessionMaxAgeHours?: number;
/**
* List of database sources. The first source in the configuration with enabled=true will be
Expand All @@ -97,6 +112,16 @@ export interface GitProxyConfig {
* TLS configuration for secure connections
*/
tls?: TLS;
/**
* Host of the GitProxy UI. Can also be set with the GIT_PROXY_UI_HOST environment variable,
* which takes precedence over this value.
*/
uiHost?: string;
/**
* Port the GitProxy UI/service HTTP server listens on. Can also be set with the
* GIT_PROXY_UI_PORT environment variable, which takes precedence over this value.
*/
uiPort?: number;
/**
* UI routes that require authentication (logged in or admin)
*/
Expand Down Expand Up @@ -791,16 +816,21 @@ const typeMap: any = {
{ json: 'cookieSecret', js: 'cookieSecret', typ: u(undefined, '') },
{ json: 'csrfProtection', js: 'csrfProtection', typ: u(undefined, true) },
{ json: 'domains', js: 'domains', typ: u(undefined, r('Domains')) },
{ json: 'httpsServerPort', js: 'httpsServerPort', typ: u(undefined, 3.14) },
{ json: 'httpsUiPort', js: 'httpsUiPort', typ: u(undefined, 3.14) },
{ json: 'plugins', js: 'plugins', typ: u(undefined, a('')) },
{ json: 'privateOrganizations', js: 'privateOrganizations', typ: u(undefined, a('any')) },
{ json: 'proxyUrl', js: 'proxyUrl', typ: u(undefined, '') },
{ json: 'rateLimit', js: 'rateLimit', typ: u(undefined, r('RateLimit')) },
{ json: 'serverPort', js: 'serverPort', typ: u(undefined, 3.14) },
{ json: 'sessionMaxAgeHours', js: 'sessionMaxAgeHours', typ: u(undefined, 3.14) },
{ json: 'sink', js: 'sink', typ: u(undefined, a(r('Database'))) },
{ json: 'sslCertPemPath', js: 'sslCertPemPath', typ: u(undefined, '') },
{ json: 'sslKeyPemPath', js: 'sslKeyPemPath', typ: u(undefined, '') },
{ json: 'tempPassword', js: 'tempPassword', typ: u(undefined, r('TempPassword')) },
{ json: 'tls', js: 'tls', typ: u(undefined, r('TLS')) },
{ json: 'uiHost', js: 'uiHost', typ: u(undefined, '') },
{ json: 'uiPort', js: 'uiPort', typ: u(undefined, 3.14) },
{ json: 'uiRouteAuth', js: 'uiRouteAuth', typ: u(undefined, r('UIRouteAuth')) },
{ json: 'upstreamProxy', js: 'upstreamProxy', typ: u(undefined, r('UpstreamProxy')) },
{ json: 'urlShortener', js: 'urlShortener', typ: u(undefined, '') },
Expand Down
67 changes: 65 additions & 2 deletions src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,18 @@ const REQUIRED_TOP_LEVEL_CONFIG_KEYS = [
'cookieSecret',
'csrfProtection',
'domains',
'httpsServerPort',
'httpsUiPort',
'plugins',
'privateOrganizations',
'rateLimit',
'serverPort',
'sessionMaxAgeHours',
'sink',
'tempPassword',
'tls',
'uiHost',
'uiPort',
'uiRouteAuth',
'upstreamProxy',
'urlShortener',
Expand Down Expand Up @@ -106,6 +111,22 @@ function cleanUndefinedValues(obj: any): any {
return cleaned;
}

/**
* Resolve a numeric server setting, giving precedence to the environment
* variable (when set) over the user config file and then the default config,
* mirroring the handling of GIT_PROXY_COOKIE_SECRET.
*/
function resolveServerPort(
envValue: string | undefined,
userValue: number | undefined,
defaultValue: number | undefined,
): number | undefined {
if (envValue !== undefined) {
return Number(envValue);
}
return userValue ?? defaultValue;
}

/**
* Load and merge default + user configuration with QuickType validation
* @return {FullGitProxyConfig} The merged and validated configuration
Expand Down Expand Up @@ -191,6 +212,28 @@ function mergeConfigurations(
serverConfig.GIT_PROXY_COOKIE_SECRET ||
userSettings.cookieSecret ||
defaultConfig.cookieSecret,
// Server settings: environment variable takes precedence over the config file.
serverPort: resolveServerPort(
serverConfig.GIT_PROXY_SERVER_PORT,
userSettings.serverPort,
defaultConfig.serverPort,
),
httpsServerPort: resolveServerPort(
serverConfig.GIT_PROXY_HTTPS_SERVER_PORT,
userSettings.httpsServerPort,
defaultConfig.httpsServerPort,
),
uiHost: serverConfig.GIT_PROXY_UI_HOST || userSettings.uiHost || defaultConfig.uiHost,
uiPort: resolveServerPort(
serverConfig.GIT_PROXY_UI_PORT,
userSettings.uiPort,
defaultConfig.uiPort,
),
httpsUiPort: resolveServerPort(
serverConfig.GIT_PROXY_HTTPS_UI_PORT,
userSettings.httpsUiPort,
defaultConfig.httpsUiPort,
),
};

assertHasRequiredTopLevelConfig(config);
Expand Down Expand Up @@ -226,9 +269,29 @@ export const getAuthorisedList = () => {
return config.authorisedList;
};

// Get GIT_PROXY_UI_PORT
// Get the UI/service HTTP port
export const getUIPort = (): number => {
return Number(serverConfig.GIT_PROXY_UI_PORT);
return loadFullConfiguration().uiPort;
};

// Get the proxy HTTP server port
export const getServerPort = (): number => {
return loadFullConfiguration().serverPort;
};

// Get the proxy HTTPS server port
export const getHttpsServerPort = (): number => {
return loadFullConfiguration().httpsServerPort;
};

// Get the UI host
export const getUIHost = (): string => {
return loadFullConfiguration().uiHost;
};

// Get the UI/service HTTPS port
export const getHttpsUIPort = (): number => {
return loadFullConfiguration().httpsUiPort;
};

// Gets a list of authorised repositories
Expand Down
10 changes: 5 additions & 5 deletions src/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
import { GitProxyConfig } from './generated/config';

export type ServerConfig = {
GIT_PROXY_SERVER_PORT: string | number;
GIT_PROXY_HTTPS_SERVER_PORT: string | number;
GIT_PROXY_UI_HOST: string;
GIT_PROXY_UI_PORT: string | number;
GIT_PROXY_HTTPS_UI_PORT: string | number;
GIT_PROXY_SERVER_PORT: string | undefined;
GIT_PROXY_HTTPS_SERVER_PORT: string | undefined;
GIT_PROXY_UI_HOST: string | undefined;
GIT_PROXY_UI_PORT: string | undefined;
GIT_PROXY_HTTPS_UI_PORT: string | undefined;
GIT_PROXY_COOKIE_SECRET: string | undefined;
GIT_PROXY_MONGO_CONNECTION_STRING: string;
};
Expand Down
8 changes: 4 additions & 4 deletions src/proxy/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,13 @@ import {
getTLSKeyPemPath,
getTLSCertPemPath,
getTLSEnabled,
getServerPort,
getHttpsServerPort,
} from '../config';
import { addUserCanAuthorise, addUserCanPush, createRepo, getRepos } from '../db';
import { PluginLoader } from '../plugin';
import chain from './chain';
import { Repo } from '../db/types';
import { serverConfig } from '../config/env';

const { GIT_PROXY_SERVER_PORT: proxyHttpPort, GIT_PROXY_HTTPS_SERVER_PORT: proxyHttpsPort } =
serverConfig;

interface ServerOptions {
inflate: boolean;
Expand Down Expand Up @@ -95,6 +93,8 @@ export class Proxy {
}

public async start() {
const proxyHttpPort = getServerPort();
const proxyHttpsPort = getHttpsServerPort();
await this.proxyPreparations();
this.expressApp = await this.createApp();
await new Promise<void>((resolve, reject) => {
Expand Down
13 changes: 5 additions & 8 deletions src/service/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,12 @@ import lusca from 'lusca';

import * as config from '../config';
import * as db from '../db';
import { serverConfig } from '../config/env';
import { Proxy } from '../proxy';
import routes from './routes';
import { configure } from './passport';

const limiter = rateLimit(config.getRateLimit());

const { GIT_PROXY_UI_PORT: uiPort, GIT_PROXY_HTTPS_UI_PORT: uiHttpsPort } = serverConfig;

const app: Express = express();
let _httpServer: http.Server | null = null;
let _httpsServer: https.Server | null = null;
Expand Down Expand Up @@ -199,17 +196,17 @@ async function start(proxy: Proxy) {
const app = await createApp(proxy);

_httpServer = http.createServer(app);
_httpServer.listen(uiPort);
_httpServer.listen(config.getUIPort());

console.log(`Service Listening on ${uiPort}`);
console.log(`Service Listening on ${config.getUIPort()}`);
app.emit('ready');

if (config.getTLSEnabled()) {
await new Promise<void>((resolve, reject) => {
const server = https.createServer(getServiceTLSOptions(), app);
server.on('error', reject);
server.listen(uiHttpsPort, () => {
console.log(`HTTPS Service Listening on ${uiHttpsPort}`);
server.listen(config.getHttpsUIPort(), () => {
console.log(`HTTPS Service Listening on ${config.getHttpsUIPort()}`);
resolve();
});
_httpsServer = server;
Expand All @@ -228,7 +225,7 @@ async function stop(): Promise<void> {
if (_httpServer) {
closePromises.push(
new Promise((resolve, reject) => {
console.log(`Stopping Service Listening on ${uiPort}`);
console.log(`Stopping Service Listening on ${config.getUIPort()}`);
_httpServer!.close((err) => {
if (err) {
reject(err);
Expand Down
7 changes: 2 additions & 5 deletions src/service/routes/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import express, { Request, Response, NextFunction } from 'express';
import { getPassport, authStrategies } from '../passport';
import { getAuthMethods } from '../../config';
import { getAuthMethods, getUIHost, getUIPort } from '../../config';

import * as db from '../../db';
import * as passportLocal from '../passport/local';
Expand All @@ -31,9 +31,6 @@ import { handleErrorAndLog } from '../../utils/errors';
const router = express.Router();
const passport = getPassport();

const { GIT_PROXY_UI_HOST: uiHost = 'http://localhost', GIT_PROXY_UI_PORT: uiPort = 3000 } =
process.env;

router.get('/', (_req: Request, res: Response) => {
res.status(200).json({
login: {
Expand Down Expand Up @@ -137,7 +134,7 @@ router.get('/openidconnect/callback', (req: Request, res: Response, next: NextFu
return res.status(500).end();
}
console.log('Logged in successfully. User:', user);
return res.redirect(`${uiHost}:${uiPort}/dashboard/profile`);
return res.redirect(`${getUIHost()}:${getUIPort()}/dashboard/profile`);
});
},
)(req, res, next);
Expand Down
13 changes: 8 additions & 5 deletions src/service/urls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,24 @@

import { Request } from 'express';

import { serverConfig } from '../config/env';
import * as config from '../config';

const { GIT_PROXY_SERVER_PORT: PROXY_HTTP_PORT, GIT_PROXY_UI_PORT: UI_PORT } = serverConfig;

export const getProxyURL = (req: Request): string => {
return (
config.getDomains().proxy ??
`${req.protocol}://${req.headers.host}`.replace(`:${UI_PORT}`, `:${PROXY_HTTP_PORT}`)
`${req.protocol}://${req.headers.host}`.replace(
`:${config.getUIPort()}`,
`:${config.getServerPort()}`,
)
);
};

export const getServiceUIURL = (req: Request): string => {
return (
config.getDomains().service ??
`${req.protocol}://${req.headers.host}`.replace(`:${PROXY_HTTP_PORT}`, `:${UI_PORT}`)
`${req.protocol}://${req.headers.host}`.replace(
`:${config.getServerPort()}`,
`:${config.getUIPort()}`,
)
);
};
Loading