mirror of
https://github.com/fosrl/pangolin.git
synced 2026-02-19 11:26:37 +00:00
Move docker podman question and add hybird question
Allow empty config Continue to adjust config for hybrid
This commit is contained in:
@@ -24,8 +24,8 @@ export const SESSION_COOKIE_EXPIRES =
|
||||
60 *
|
||||
60 *
|
||||
config.getRawConfig().server.dashboard_session_length_hours;
|
||||
export const COOKIE_DOMAIN =
|
||||
"." + new URL(config.getRawConfig().app.dashboard_url).hostname;
|
||||
export const COOKIE_DOMAIN = config.getRawConfig().app.dashboard_url ?
|
||||
"." + new URL(config.getRawConfig().app.dashboard_url!).hostname : undefined;
|
||||
|
||||
export function generateSessionToken(): string {
|
||||
const bytes = new Uint8Array(20);
|
||||
|
||||
@@ -6,6 +6,11 @@ import logger from "@server/logger";
|
||||
import SMTPTransport from "nodemailer/lib/smtp-transport";
|
||||
|
||||
function createEmailClient() {
|
||||
if (config.isHybridMode()) {
|
||||
// LETS NOT WORRY ABOUT EMAILS IN HYBRID
|
||||
return;
|
||||
}
|
||||
|
||||
const emailConfig = config.getRawConfig().email;
|
||||
if (!emailConfig) {
|
||||
logger.warn(
|
||||
|
||||
@@ -96,7 +96,11 @@ export class Config {
|
||||
if (!this.rawConfig) {
|
||||
throw new Error("Config not loaded. Call load() first.");
|
||||
}
|
||||
license.setServerSecret(this.rawConfig.server.secret);
|
||||
if (this.rawConfig.hybrid) {
|
||||
// LETS NOT WORRY ABOUT THE SERVER SECRET WHEN HYBRID
|
||||
return;
|
||||
}
|
||||
license.setServerSecret(this.rawConfig.server.secret!);
|
||||
|
||||
await this.checkKeyStatus();
|
||||
}
|
||||
|
||||
@@ -16,21 +16,28 @@ export const configSchema = z
|
||||
dashboard_url: z
|
||||
.string()
|
||||
.url()
|
||||
.optional()
|
||||
.pipe(z.string().url())
|
||||
.transform((url) => url.toLowerCase()),
|
||||
.transform((url) => url.toLowerCase())
|
||||
.optional(),
|
||||
log_level: z
|
||||
.enum(["debug", "info", "warn", "error"])
|
||||
.optional()
|
||||
.default("info"),
|
||||
save_logs: z.boolean().optional().default(false),
|
||||
log_failed_attempts: z.boolean().optional().default(false),
|
||||
telmetry: z
|
||||
telemetry: z
|
||||
.object({
|
||||
anonymous_usage: z.boolean().optional().default(true)
|
||||
})
|
||||
.optional()
|
||||
.default({})
|
||||
}).optional().default({
|
||||
log_level: "info",
|
||||
save_logs: false,
|
||||
log_failed_attempts: false,
|
||||
telemetry: {
|
||||
anonymous_usage: true
|
||||
}
|
||||
}),
|
||||
hybrid: z
|
||||
.object({
|
||||
@@ -122,9 +129,25 @@ export const configSchema = z
|
||||
trust_proxy: z.number().int().gte(0).optional().default(1),
|
||||
secret: z
|
||||
.string()
|
||||
.optional()
|
||||
.transform(getEnvOrYaml("SERVER_SECRET"))
|
||||
.pipe(z.string().min(8))
|
||||
.optional()
|
||||
}).optional().default({
|
||||
integration_port: 3003,
|
||||
external_port: 3000,
|
||||
internal_port: 3001,
|
||||
next_port: 3002,
|
||||
internal_hostname: "pangolin",
|
||||
session_cookie_name: "p_session_token",
|
||||
resource_access_token_param: "p_token",
|
||||
resource_access_token_headers: {
|
||||
id: "P-Access-Token-Id",
|
||||
token: "P-Access-Token"
|
||||
},
|
||||
resource_session_request_param: "resource_session_request_param",
|
||||
dashboard_session_length_hours: 720,
|
||||
resource_session_length_hours: 720,
|
||||
trust_proxy: 1
|
||||
}),
|
||||
postgres: z
|
||||
.object({
|
||||
@@ -282,6 +305,10 @@ export const configSchema = z
|
||||
if (data.flags?.disable_config_managed_domains) {
|
||||
return true;
|
||||
}
|
||||
// If hybrid is defined, domains are not required
|
||||
if (data.hybrid) {
|
||||
return true;
|
||||
}
|
||||
if (keys.length === 0) {
|
||||
return false;
|
||||
}
|
||||
@@ -290,6 +317,32 @@ export const configSchema = z
|
||||
{
|
||||
message: "At least one domain must be defined"
|
||||
}
|
||||
)
|
||||
.refine(
|
||||
(data) => {
|
||||
// If hybrid is defined, server secret is not required
|
||||
if (data.hybrid) {
|
||||
return true;
|
||||
}
|
||||
// If hybrid is not defined, server secret must be defined
|
||||
return data.server?.secret !== undefined && data.server.secret.length > 0;
|
||||
},
|
||||
{
|
||||
message: "Server secret must be defined"
|
||||
}
|
||||
)
|
||||
.refine(
|
||||
(data) => {
|
||||
// If hybrid is defined, dashboard_url is not required
|
||||
if (data.hybrid) {
|
||||
return true;
|
||||
}
|
||||
// If hybrid is not defined, dashboard_url must be defined
|
||||
return data.app.dashboard_url !== undefined && data.app.dashboard_url.length > 0;
|
||||
},
|
||||
{
|
||||
message: "Dashboard URL must be defined"
|
||||
}
|
||||
);
|
||||
|
||||
export function readConfigFile() {
|
||||
|
||||
@@ -16,7 +16,7 @@ class TelemetryClient {
|
||||
private intervalId: NodeJS.Timeout | null = null;
|
||||
|
||||
constructor() {
|
||||
const enabled = config.getRawConfig().app.telmetry.anonymous_usage;
|
||||
const enabled = config.getRawConfig().app.telemetry.anonymous_usage;
|
||||
this.enabled = enabled;
|
||||
const dev = process.env.ENVIRONMENT !== "prod";
|
||||
|
||||
|
||||
@@ -36,16 +36,16 @@ import { verifyTotpCode } from "@server/auth/totp";
|
||||
|
||||
// The RP ID is the domain name of your application
|
||||
const rpID = (() => {
|
||||
const url = new URL(config.getRawConfig().app.dashboard_url);
|
||||
const url = config.getRawConfig().app.dashboard_url ? new URL(config.getRawConfig().app.dashboard_url!) : undefined;
|
||||
// For localhost, we must use 'localhost' without port
|
||||
if (url.hostname === 'localhost') {
|
||||
if (url?.hostname === 'localhost' || !url) {
|
||||
return 'localhost';
|
||||
}
|
||||
return url.hostname;
|
||||
})();
|
||||
|
||||
const rpName = "Pangolin";
|
||||
const origin = config.getRawConfig().app.dashboard_url;
|
||||
const origin = config.getRawConfig().app.dashboard_url || "localhost";
|
||||
|
||||
// Database-based challenge storage (replaces in-memory storage)
|
||||
// Challenges are stored in the webauthnChallenge table with automatic expiration
|
||||
|
||||
@@ -8,7 +8,7 @@ export async function copyInConfig() {
|
||||
const endpoint = config.getRawConfig().gerbil.base_endpoint;
|
||||
const listenPort = config.getRawConfig().gerbil.start_port;
|
||||
|
||||
if (!config.getRawConfig().flags?.disable_config_managed_domains) {
|
||||
if (!config.getRawConfig().flags?.disable_config_managed_domains && config.getRawConfig().domains) {
|
||||
await copyInDomains();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { eq } from "drizzle-orm";
|
||||
import { generateRandomString, RandomReader } from "@oslojs/crypto/random";
|
||||
import moment from "moment";
|
||||
import logger from "@server/logger";
|
||||
import config from "@server/lib/config";
|
||||
|
||||
const random: RandomReader = {
|
||||
read(bytes: Uint8Array): void {
|
||||
@@ -22,6 +23,11 @@ function generateId(length: number): string {
|
||||
}
|
||||
|
||||
export async function ensureSetupToken() {
|
||||
if (config.isHybridMode()) {
|
||||
// LETS NOT WORRY ABOUT THE SERVER SECRET WHEN HYBRID
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Check if a server admin already exists
|
||||
const [existingAdmin] = await db
|
||||
|
||||
Reference in New Issue
Block a user