summaryrefslogtreecommitdiff
path: root/packages/backend/src/config.ts
diff options
context:
space:
mode:
authorHazelnoot <acomputerdog@gmail.com>2025-05-11 23:22:41 -0400
committerHazelnoot <acomputerdog@gmail.com>2025-05-12 21:44:45 -0400
commitfb63167d854f277ffeb82da720580b3e99f9cc8c (patch)
treec060ff042e9f1b815206dedee64acd2dc60eec72 /packages/backend/src/config.ts
parentmerge: Add "is from local bubble instance" role condition (!1011) (diff)
downloadsharkey-fb63167d854f277ffeb82da720580b3e99f9cc8c.tar.gz
sharkey-fb63167d854f277ffeb82da720580b3e99f9cc8c.tar.bz2
sharkey-fb63167d854f277ffeb82da720580b3e99f9cc8c.zip
allow private IP ranges to specify allowed ports
Diffstat (limited to 'packages/backend/src/config.ts')
-rw-r--r--packages/backend/src/config.ts33
1 files changed, 31 insertions, 2 deletions
diff --git a/packages/backend/src/config.ts b/packages/backend/src/config.ts
index 92fc2b8a13..2a3184f9b4 100644
--- a/packages/backend/src/config.ts
+++ b/packages/backend/src/config.ts
@@ -8,9 +8,11 @@ import { fileURLToPath } from 'node:url';
import { dirname, resolve } from 'node:path';
import * as yaml from 'js-yaml';
import { globSync } from 'glob';
+import ipaddr from 'ipaddr.js';
import type * as Sentry from '@sentry/node';
import type * as SentryVue from '@sentry/vue';
import type { RedisOptions } from 'ioredis';
+import type { IPv4, IPv6 } from 'ipaddr.js';
type RedisOptionsSource = Partial<RedisOptions> & {
host?: string;
@@ -152,6 +154,33 @@ type Source = {
}
};
+export type PrivateNetwork = {
+ /**
+ * CIDR IP/netmask definition of the IP range to match.
+ */
+ cidr: [ip: IPv4 | IPv6, mask: number];
+
+ /**
+ * List of ports to match.
+ * If undefined, then all ports match.
+ * If empty, then NO ports match.
+ */
+ ports?: number[];
+};
+
+export function parsePrivateNetworks(patterns: string[]): PrivateNetwork[];
+export function parsePrivateNetworks(patterns: undefined): undefined;
+export function parsePrivateNetworks(patterns: string[] | undefined): PrivateNetwork[] | undefined;
+export function parsePrivateNetworks(patterns: string[] | undefined): PrivateNetwork[] | undefined {
+ return patterns?.map(e => {
+ const [ip, ports] = e.split('#') as [string, ...(string | undefined)[]];
+ return {
+ cidr: ipaddr.parseCIDR(ip),
+ ports: ports?.split(',').map(p => parseInt(p)),
+ };
+ });
+}
+
export type Config = {
url: string;
port: number;
@@ -190,7 +219,7 @@ export type Config = {
proxy: string | undefined;
proxySmtp: string | undefined;
proxyBypassHosts: string[] | undefined;
- allowedPrivateNetworks: string[] | undefined;
+ allowedPrivateNetworks: PrivateNetwork[] | undefined;
disallowExternalApRedirect: boolean;
maxFileSize: number;
maxNoteLength: number;
@@ -382,7 +411,7 @@ export function loadConfig(): Config {
proxy: config.proxy,
proxySmtp: config.proxySmtp,
proxyBypassHosts: config.proxyBypassHosts,
- allowedPrivateNetworks: config.allowedPrivateNetworks,
+ allowedPrivateNetworks: parsePrivateNetworks(config.allowedPrivateNetworks),
disallowExternalApRedirect: config.disallowExternalApRedirect ?? false,
maxFileSize: config.maxFileSize ?? 262144000,
maxNoteLength: config.maxNoteLength ?? 3000,