mirror of
https://github.com/fosrl/pangolin.git
synced 2025-10-30 06:07:25 +00:00
213 lines
6.6 KiB
TypeScript
213 lines
6.6 KiB
TypeScript
/*
|
|
* This file is part of a proprietary work.
|
|
*
|
|
* Copyright (c) 2025 Fossorial, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This file is licensed under the Fossorial Commercial License.
|
|
* You may not use this file except in compliance with the License.
|
|
* Unauthorized use, copying, modification, or distribution is strictly prohibited.
|
|
*
|
|
* This file is not licensed under the AGPLv3.
|
|
*/
|
|
|
|
import fs from "fs";
|
|
import yaml from "js-yaml";
|
|
import { privateConfigFilePath1 } from "@server/lib/consts";
|
|
import { z } from "zod";
|
|
import { colorsSchema } from "@server/lib/colorsSchema";
|
|
import { build } from "@server/build";
|
|
|
|
const portSchema = z.number().positive().gt(0).lte(65535);
|
|
|
|
export const privateConfigSchema = z.object({
|
|
app: z
|
|
.object({
|
|
region: z.string().optional().default("default"),
|
|
base_domain: z.string().optional()
|
|
})
|
|
.optional()
|
|
.default({
|
|
region: "default"
|
|
}),
|
|
server: z
|
|
.object({
|
|
encryption_key_path: z
|
|
.string()
|
|
.optional()
|
|
.default("./config/encryption.pem")
|
|
.pipe(z.string().min(8)),
|
|
resend_api_key: z.string().optional(),
|
|
reo_client_id: z.string().optional(),
|
|
fossorial_api_key: z.string().optional()
|
|
})
|
|
.optional()
|
|
.default({
|
|
encryption_key_path: "./config/encryption.pem"
|
|
}),
|
|
redis: z
|
|
.object({
|
|
host: z.string(),
|
|
port: portSchema,
|
|
password: z.string().optional(),
|
|
db: z.number().int().nonnegative().optional().default(0),
|
|
replicas: z
|
|
.array(
|
|
z.object({
|
|
host: z.string(),
|
|
port: portSchema,
|
|
password: z.string().optional(),
|
|
db: z.number().int().nonnegative().optional().default(0)
|
|
})
|
|
)
|
|
.optional()
|
|
// tls: z
|
|
// .object({
|
|
// reject_unauthorized: z
|
|
// .boolean()
|
|
// .optional()
|
|
// .default(true)
|
|
// })
|
|
// .optional()
|
|
})
|
|
.optional(),
|
|
gerbil: z
|
|
.object({
|
|
local_exit_node_reachable_at: z
|
|
.string()
|
|
.optional()
|
|
.default("http://gerbil:3004")
|
|
})
|
|
.optional()
|
|
.default({}),
|
|
flags: z
|
|
.object({
|
|
enable_redis: z.boolean().optional().default(false),
|
|
use_pangolin_dns: z.boolean().optional().default(false)
|
|
})
|
|
.optional()
|
|
.default({}),
|
|
branding: z
|
|
.object({
|
|
app_name: z.string().optional(),
|
|
background_image_path: z.string().optional(),
|
|
colors: z
|
|
.object({
|
|
light: colorsSchema.optional(),
|
|
dark: colorsSchema.optional()
|
|
})
|
|
.optional(),
|
|
logo: z
|
|
.object({
|
|
light_path: z.string().optional(),
|
|
dark_path: z.string().optional(),
|
|
auth_page: z
|
|
.object({
|
|
width: z.number().optional(),
|
|
height: z.number().optional()
|
|
})
|
|
.optional(),
|
|
navbar: z
|
|
.object({
|
|
width: z.number().optional(),
|
|
height: z.number().optional()
|
|
})
|
|
.optional()
|
|
})
|
|
.optional(),
|
|
favicon_path: z.string().optional(),
|
|
footer: z
|
|
.array(
|
|
z.object({
|
|
text: z.string(),
|
|
href: z.string().optional()
|
|
})
|
|
)
|
|
.optional(),
|
|
login_page: z
|
|
.object({
|
|
subtitle_text: z.string().optional(),
|
|
title_text: z.string().optional()
|
|
})
|
|
.optional(),
|
|
signup_page: z
|
|
.object({
|
|
subtitle_text: z.string().optional(),
|
|
title_text: z.string().optional()
|
|
})
|
|
.optional(),
|
|
resource_auth_page: z
|
|
.object({
|
|
show_logo: z.boolean().optional(),
|
|
hide_powered_by: z.boolean().optional(),
|
|
title_text: z.string().optional(),
|
|
subtitle_text: z.string().optional()
|
|
})
|
|
.optional(),
|
|
emails: z
|
|
.object({
|
|
signature: z.string().optional(),
|
|
colors: z
|
|
.object({
|
|
primary: z.string().optional()
|
|
})
|
|
.optional()
|
|
})
|
|
.optional()
|
|
})
|
|
.optional(),
|
|
stripe: z
|
|
.object({
|
|
secret_key: z.string(),
|
|
webhook_secret: z.string(),
|
|
s3Bucket: z.string(),
|
|
s3Region: z.string().default("us-east-1"),
|
|
localFilePath: z.string()
|
|
})
|
|
.optional()
|
|
});
|
|
|
|
export function readPrivateConfigFile() {
|
|
if (build == "oss") {
|
|
return {};
|
|
}
|
|
|
|
// test if the config file is there
|
|
if (!fs.existsSync(privateConfigFilePath1)) {
|
|
// console.warn(
|
|
// `Private configuration file not found at ${privateConfigFilePath1}. Using default configuration.`
|
|
// );
|
|
// load the default values of the zod schema and return those
|
|
return privateConfigSchema.parse({});
|
|
}
|
|
|
|
const loadConfig = (configPath: string) => {
|
|
try {
|
|
const yamlContent = fs.readFileSync(configPath, "utf8");
|
|
if (yamlContent.trim() === "") {
|
|
return {};
|
|
}
|
|
const config = yaml.load(yamlContent);
|
|
return config;
|
|
} catch (error) {
|
|
if (error instanceof Error) {
|
|
throw new Error(
|
|
`Error loading configuration file: ${error.message}`
|
|
);
|
|
}
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
let environment: any = {};
|
|
if (fs.existsSync(privateConfigFilePath1)) {
|
|
environment = loadConfig(privateConfigFilePath1);
|
|
}
|
|
|
|
if (!environment) {
|
|
throw new Error("No private configuration file found.");
|
|
}
|
|
|
|
return environment;
|
|
}
|