Skip to content

Commit

Permalink
feat: add allowedHeaders
Browse files Browse the repository at this point in the history
  • Loading branch information
hersentino committed Dec 18, 2023
1 parent 9e9d5ff commit 23e79b9
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 3 deletions.
33 changes: 33 additions & 0 deletions docs/usage/self-hosted-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,39 @@ But before you disable templating completely, try the `allowedPostUpgradeCommand

## allowScripts

## allowedHeaders

List of headers that are allowed to be forwarded to the HTTP request. This is useful when the `registryUrlTemplate` employs a specific authentication system. By default, all headers starting with "X-" are allowed, but you can include additional headers using this option. If declared, it will override the default "X-" allowed headers. `allowedHeaders` is an array of RegExp represented as strings due to JSON serialization

```json
{
"hostRules": [
{
"matchHost": "https://domain.com/all-versions",
"headers": {
"X-Auth-Token": "secret"
}
}
]
}
```

or with custom `allowedHeaders`

```json
{
"allowedHeaders": ["^custom-header$"],
"hostRules": [
{
"matchHost": "https://domain.com/all-versions",
"headers": {
"custom-header": "secret"
}
}
]
}
```

## allowedPostUpgradeCommands

A list of regular expressions that decide which commands in `postUpgradeTasks` are allowed to run.
Expand Down
1 change: 1 addition & 0 deletions lib/config/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export class GlobalConfig {
// TODO: once global config work is complete, add a test to make sure this list includes all options with globalOnly=true (#9603)
private static readonly OPTIONS: (keyof RepoGlobalConfig)[] = [
'allowCustomCrateRegistries',
'allowedHeaders',
'allowedPostUpgradeCommands',
'allowPlugins',
'allowPostUpgradeCommandTemplating',
Expand Down
9 changes: 9 additions & 0 deletions lib/config/options/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ import { getVersioningList } from '../../modules/versioning';
import type { RenovateOptions } from '../types';

const options: RenovateOptions[] = [
{
name: 'allowedHeaders',
description:
'List of headers that are allowed to be forwarded to http request',
type: 'array',
default: ['^X-'],
subType: 'string',
globalOnly: true,
},
{
name: 'detectGlobalManagerConfig',
description:
Expand Down
8 changes: 6 additions & 2 deletions lib/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ export interface RepoGlobalConfig {
allowPlugins?: boolean;
allowPostUpgradeCommandTemplating?: boolean;
allowScripts?: boolean;
allowedHeaders?: (string | RegExp)[];
allowedPostUpgradeCommands?: string[];
binarySource?: 'docker' | 'global' | 'install' | 'hermit';
cacheHardTtlMinutes?: number;
Expand Down Expand Up @@ -401,12 +402,15 @@ export interface RenovateOptionBase {
}

export interface RenovateArrayOption<
T extends string | number | Record<string, unknown> = Record<string, unknown>,
T extends string | number | RegExp | Record<string, unknown> = Record<
string,
unknown
>,
> extends RenovateOptionBase {
default?: T[] | null;
mergeable?: boolean;
type: 'array';
subType?: 'string' | 'object' | 'number';
subType?: 'string' | 'object' | 'number' | 'regex';
supportedManagers?: string[] | 'all';
supportedPlatforms?: string[] | 'all';
}
Expand Down
8 changes: 7 additions & 1 deletion lib/util/http/host-rules.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import is from '@sindresorhus/is';
import { GlobalConfig } from '../../config/global';
import {
BITBUCKET_API_USING_HOST_TYPES,
GITEA_API_USING_HOST_TYPES,
Expand All @@ -9,6 +10,7 @@ import { logger } from '../../logger';
import { hasProxy } from '../../proxy';
import type { HostRule } from '../../types';
import * as hostRules from '../host-rules';
import keepFields from '../keep-fields';
import { parseUrl } from '../url';
import { dnsLookup } from './dns';
import { keepAliveAgents } from './keep-alive';
Expand Down Expand Up @@ -163,9 +165,13 @@ export function applyHostRule<GotOptions extends HostRulesGotOptions>(
}

if (hostRule.headers) {
const allowedHeaders = GlobalConfig.get('allowedHeaders')?.map(
(h) => new RegExp(h),
);

options.headers = {
...options.headers,
...hostRule.headers,
...keepFields(hostRule.headers, allowedHeaders),
};
}

Expand Down
20 changes: 20 additions & 0 deletions lib/util/keep-fields.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import keepField from './keep-fields';

describe('util/keep-fields', () => {
const allowedHeader = [/^X-/, 'foo'];
const headers = {
'X-Auth-Token': 'token',
test: 'test',
foo: 'bar',
someheader: 'value',
};

it('works', () => {
const result = keepField(headers, allowedHeader);

expect(result).toStrictEqual({
'X-Auth-Token': 'token',
foo: 'bar',
});
});
});
18 changes: 18 additions & 0 deletions lib/util/keep-fields.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export default function keepFields(
obj: Record<string, any>,
fieldsToKeep?: (string | RegExp)[],
): Record<string, any> {
if (fieldsToKeep === undefined) {
return {};
}
return Object.fromEntries(
Object.entries(obj).filter(([key]) => {
return fieldsToKeep.some((field) => {
if (field instanceof RegExp) {
return field.test(key);
}
return key === field;
});
}),
);
}

0 comments on commit 23e79b9

Please sign in to comment.