Compare commits

..

14 Commits

Author SHA1 Message Date
Owen Schwartz
b6c9046405 New translations en-us.json (Spanish) 2026-03-21 10:56:55 -07:00
Owen Schwartz
ea2ec84f08 New translations en-us.json (Norwegian Bokmal) 2026-03-21 10:56:54 -07:00
Owen Schwartz
40a14ac5f6 New translations en-us.json (Chinese Simplified) 2026-03-21 10:56:53 -07:00
Owen Schwartz
78169f087f New translations en-us.json (Turkish) 2026-03-21 10:56:51 -07:00
Owen Schwartz
4021107d08 New translations en-us.json (Russian) 2026-03-21 10:56:50 -07:00
Owen Schwartz
e78aaeb344 New translations en-us.json (Portuguese) 2026-03-21 10:56:48 -07:00
Owen Schwartz
0087ca997d New translations en-us.json (Polish) 2026-03-21 10:56:47 -07:00
Owen Schwartz
61d4d314d6 New translations en-us.json (Dutch) 2026-03-21 10:56:46 -07:00
Owen Schwartz
2e8b4ddbdb New translations en-us.json (Korean) 2026-03-21 10:56:44 -07:00
Owen Schwartz
3996b86f14 New translations en-us.json (Italian) 2026-03-21 10:56:43 -07:00
Owen Schwartz
7388ef8588 New translations en-us.json (German) 2026-03-21 10:56:42 -07:00
Owen Schwartz
bb2edb23e5 New translations en-us.json (Czech) 2026-03-21 10:56:40 -07:00
Owen Schwartz
4cad384476 New translations en-us.json (Bulgarian) 2026-03-21 10:56:39 -07:00
Owen Schwartz
ba07eb1303 New translations en-us.json (French) 2026-03-21 10:56:37 -07:00
18 changed files with 43 additions and 113 deletions

View File

@@ -1119,6 +1119,7 @@
"setupTokenDescription": "Въведете конфигурационния токен от сървърната конзола.",
"setupTokenRequired": "Необходим е конфигурационен токен",
"actionUpdateSite": "Актуализиране на сайт",
"actionResetSiteBandwidth": "Reset Organization Bandwidth",
"actionListSiteRoles": "Изброяване на позволените роли за сайта",
"actionCreateResource": "Създаване на ресурс",
"actionDeleteResource": "Изтриване на ресурс",

View File

@@ -1119,6 +1119,7 @@
"setupTokenDescription": "Zadejte nastavovací token z konzole serveru.",
"setupTokenRequired": "Je vyžadován token nastavení",
"actionUpdateSite": "Aktualizovat stránku",
"actionResetSiteBandwidth": "Reset Organization Bandwidth",
"actionListSiteRoles": "Seznam povolených rolí webu",
"actionCreateResource": "Vytvořit zdroj",
"actionDeleteResource": "Odstranit dokument",

View File

@@ -1119,6 +1119,7 @@
"setupTokenDescription": "Geben Sie das Setup-Token von der Serverkonsole ein.",
"setupTokenRequired": "Setup-Token ist erforderlich",
"actionUpdateSite": "Standorte aktualisieren",
"actionResetSiteBandwidth": "Reset Organization Bandwidth",
"actionListSiteRoles": "Erlaubte Standort-Rollen auflisten",
"actionCreateResource": "Ressource erstellen",
"actionDeleteResource": "Ressource löschen",

View File

@@ -1119,6 +1119,7 @@
"setupTokenDescription": "Ingrese el token de configuración desde la consola del servidor.",
"setupTokenRequired": "Se requiere el token de configuración",
"actionUpdateSite": "Actualizar sitio",
"actionResetSiteBandwidth": "Reset Organization Bandwidth",
"actionListSiteRoles": "Lista de roles permitidos del sitio",
"actionCreateResource": "Crear Recurso",
"actionDeleteResource": "Eliminar Recurso",

View File

@@ -1119,6 +1119,7 @@
"setupTokenDescription": "Entrez le jeton de configuration depuis la console du serveur.",
"setupTokenRequired": "Le jeton de configuration est requis.",
"actionUpdateSite": "Mettre à jour un site",
"actionResetSiteBandwidth": "Reset Organization Bandwidth",
"actionListSiteRoles": "Lister les rôles autorisés du site",
"actionCreateResource": "Créer une ressource",
"actionDeleteResource": "Supprimer une ressource",

View File

@@ -1119,6 +1119,7 @@
"setupTokenDescription": "Inserisci il token di configurazione dalla console del server.",
"setupTokenRequired": "Il token di configurazione è richiesto",
"actionUpdateSite": "Aggiorna Sito",
"actionResetSiteBandwidth": "Reset Organization Bandwidth",
"actionListSiteRoles": "Elenca Ruoli Sito Consentiti",
"actionCreateResource": "Crea Risorsa",
"actionDeleteResource": "Elimina Risorsa",

View File

@@ -1119,6 +1119,7 @@
"setupTokenDescription": "서버 콘솔에서 설정 토큰 입력.",
"setupTokenRequired": "설정 토큰이 필요합니다",
"actionUpdateSite": "사이트 업데이트",
"actionResetSiteBandwidth": "Reset Organization Bandwidth",
"actionListSiteRoles": "허용된 사이트 역할 목록",
"actionCreateResource": "리소스 생성",
"actionDeleteResource": "리소스 삭제",

View File

@@ -1119,6 +1119,7 @@
"setupTokenDescription": "Skriv inn oppsetttoken fra serverkonsollen.",
"setupTokenRequired": "Oppsetttoken er nødvendig",
"actionUpdateSite": "Oppdater område",
"actionResetSiteBandwidth": "Reset Organization Bandwidth",
"actionListSiteRoles": "List opp tillatte områderoller",
"actionCreateResource": "Opprett ressurs",
"actionDeleteResource": "Slett ressurs",

View File

@@ -1119,6 +1119,7 @@
"setupTokenDescription": "Voer het setup-token in vanaf de serverconsole.",
"setupTokenRequired": "Setup-token is vereist",
"actionUpdateSite": "Site bijwerken",
"actionResetSiteBandwidth": "Reset Organization Bandwidth",
"actionListSiteRoles": "Toon toegestane sitenollen",
"actionCreateResource": "Bron maken",
"actionDeleteResource": "Document verwijderen",

View File

@@ -1119,6 +1119,7 @@
"setupTokenDescription": "Wprowadź token konfiguracji z konsoli serwera.",
"setupTokenRequired": "Wymagany jest token konfiguracji",
"actionUpdateSite": "Aktualizuj witrynę",
"actionResetSiteBandwidth": "Reset Organization Bandwidth",
"actionListSiteRoles": "Lista dozwolonych ról witryny",
"actionCreateResource": "Utwórz zasób",
"actionDeleteResource": "Usuń zasób",

View File

@@ -1119,6 +1119,7 @@
"setupTokenDescription": "Digite o token de configuração do console do servidor.",
"setupTokenRequired": "Token de configuração é necessário",
"actionUpdateSite": "Atualizar Site",
"actionResetSiteBandwidth": "Reset Organization Bandwidth",
"actionListSiteRoles": "Listar Funções Permitidas do Site",
"actionCreateResource": "Criar Recurso",
"actionDeleteResource": "Eliminar Recurso",

View File

@@ -1119,6 +1119,7 @@
"setupTokenDescription": "Введите токен настройки из консоли сервера.",
"setupTokenRequired": "Токен настройки обязателен",
"actionUpdateSite": "Обновить сайт",
"actionResetSiteBandwidth": "Reset Organization Bandwidth",
"actionListSiteRoles": "Список разрешенных ролей сайта",
"actionCreateResource": "Создать ресурс",
"actionDeleteResource": "Удалить ресурс",

View File

@@ -1119,6 +1119,7 @@
"setupTokenDescription": "Sunucu konsolundan kurulum simgesini girin.",
"setupTokenRequired": "Kurulum simgesi gerekli",
"actionUpdateSite": "Siteyi Güncelle",
"actionResetSiteBandwidth": "Reset Organization Bandwidth",
"actionListSiteRoles": "İzin Verilen Site Rolleri Listele",
"actionCreateResource": "Kaynak Oluştur",
"actionDeleteResource": "Kaynağı Sil",

View File

@@ -1119,6 +1119,7 @@
"setupTokenDescription": "从服务器控制台输入设置令牌。",
"setupTokenRequired": "需要设置令牌",
"actionUpdateSite": "更新站点",
"actionResetSiteBandwidth": "Reset Organization Bandwidth",
"actionListSiteRoles": "允许站点角色列表",
"actionCreateResource": "创建资源",
"actionDeleteResource": "删除资源",

View File

@@ -1,7 +1,7 @@
import { drizzle as DrizzlePostgres } from "drizzle-orm/node-postgres";
import { Pool } from "pg";
import { readConfigFile } from "@server/lib/readConfigFile";
import { withReplicas } from "drizzle-orm/pg-core";
import { createPool } from "./poolConfig";
function createDb() {
const config = readConfigFile();
@@ -39,17 +39,12 @@ function createDb() {
// Create connection pools instead of individual connections
const poolConfig = config.postgres.pool;
const maxConnections = poolConfig?.max_connections || 20;
const idleTimeoutMs = poolConfig?.idle_timeout_ms || 30000;
const connectionTimeoutMs = poolConfig?.connection_timeout_ms || 5000;
const primaryPool = createPool(
const primaryPool = new Pool({
connectionString,
maxConnections,
idleTimeoutMs,
connectionTimeoutMs,
"primary"
);
max: poolConfig?.max_connections || 20,
idleTimeoutMillis: poolConfig?.idle_timeout_ms || 30000,
connectionTimeoutMillis: poolConfig?.connection_timeout_ms || 5000
});
const replicas = [];
@@ -60,16 +55,14 @@ function createDb() {
})
);
} else {
const maxReplicaConnections =
poolConfig?.max_replica_connections || 20;
for (const conn of replicaConnections) {
const replicaPool = createPool(
conn.connection_string,
maxReplicaConnections,
idleTimeoutMs,
connectionTimeoutMs,
"replica"
);
const replicaPool = new Pool({
connectionString: conn.connection_string,
max: poolConfig?.max_replica_connections || 20,
idleTimeoutMillis: poolConfig?.idle_timeout_ms || 30000,
connectionTimeoutMillis:
poolConfig?.connection_timeout_ms || 5000
});
replicas.push(
DrizzlePostgres(replicaPool, {
logger: process.env.QUERY_LOGGING == "true"

View File

@@ -1,9 +1,9 @@
import { drizzle as DrizzlePostgres } from "drizzle-orm/node-postgres";
import { Pool } from "pg";
import { readConfigFile } from "@server/lib/readConfigFile";
import { withReplicas } from "drizzle-orm/pg-core";
import { build } from "@server/build";
import { db as mainDb, primaryDb as mainPrimaryDb } from "./driver";
import { createPool } from "./poolConfig";
function createLogsDb() {
// Only use separate logs database in SaaS builds
@@ -42,17 +42,12 @@ function createLogsDb() {
// Create separate connection pool for logs database
const poolConfig = logsConfig?.pool || config.postgres?.pool;
const maxConnections = poolConfig?.max_connections || 20;
const idleTimeoutMs = poolConfig?.idle_timeout_ms || 30000;
const connectionTimeoutMs = poolConfig?.connection_timeout_ms || 5000;
const primaryPool = createPool(
const primaryPool = new Pool({
connectionString,
maxConnections,
idleTimeoutMs,
connectionTimeoutMs,
"logs-primary"
);
max: poolConfig?.max_connections || 20,
idleTimeoutMillis: poolConfig?.idle_timeout_ms || 30000,
connectionTimeoutMillis: poolConfig?.connection_timeout_ms || 5000
});
const replicas = [];
@@ -63,16 +58,14 @@ function createLogsDb() {
})
);
} else {
const maxReplicaConnections =
poolConfig?.max_replica_connections || 20;
for (const conn of replicaConnections) {
const replicaPool = createPool(
conn.connection_string,
maxReplicaConnections,
idleTimeoutMs,
connectionTimeoutMs,
"logs-replica"
);
const replicaPool = new Pool({
connectionString: conn.connection_string,
max: poolConfig?.max_replica_connections || 20,
idleTimeoutMillis: poolConfig?.idle_timeout_ms || 30000,
connectionTimeoutMillis:
poolConfig?.connection_timeout_ms || 5000
});
replicas.push(
DrizzlePostgres(replicaPool, {
logger: process.env.QUERY_LOGGING == "true"

View File

@@ -1,63 +0,0 @@
import { Pool, PoolConfig } from "pg";
import logger from "@server/logger";
export function createPoolConfig(
connectionString: string,
maxConnections: number,
idleTimeoutMs: number,
connectionTimeoutMs: number
): PoolConfig {
return {
connectionString,
max: maxConnections,
idleTimeoutMillis: idleTimeoutMs,
connectionTimeoutMillis: connectionTimeoutMs,
// TCP keepalive to prevent silent connection drops by NAT gateways,
// load balancers, and other intermediate network devices (e.g. AWS
// NAT Gateway drops idle TCP connections after ~350s)
keepAlive: true,
keepAliveInitialDelayMillis: 10000, // send first keepalive after 10s of idle
// Allow connections to be released and recreated more aggressively
// to avoid stale connections building up
allowExitOnIdle: false
};
}
export function attachPoolErrorHandlers(pool: Pool, label: string): void {
pool.on("error", (err) => {
// This catches errors on idle clients in the pool. Without this
// handler an unexpected disconnect would crash the process.
logger.error(
`Unexpected error on idle ${label} database client: ${err.message}`
);
});
pool.on("connect", (client) => {
// Set a statement timeout on every new connection so a single slow
// query can't block the pool forever
client.query("SET statement_timeout = '30s'").catch((err: Error) => {
logger.warn(
`Failed to set statement_timeout on ${label} client: ${err.message}`
);
});
});
}
export function createPool(
connectionString: string,
maxConnections: number,
idleTimeoutMs: number,
connectionTimeoutMs: number,
label: string
): Pool {
const pool = new Pool(
createPoolConfig(
connectionString,
maxConnections,
idleTimeoutMs,
connectionTimeoutMs
)
);
attachPoolErrorHandlers(pool, label);
return pool;
}

View File

@@ -275,8 +275,6 @@ export default function Page() {
}
}
const disabled = !isPaidUser(tierMatrix.orgOidc);
return (
<>
<div className="flex justify-between">
@@ -294,9 +292,6 @@ export default function Page() {
</Button>
</div>
<PaidFeaturesAlert tiers={tierMatrix.orgOidc} />
<fieldset disabled={disabled} className={disabled ? "opacity-50 pointer-events-none" : ""}>
<SettingsContainer>
<SettingsSection>
<SettingsSectionHeader>
@@ -817,10 +812,9 @@ export default function Page() {
</Button>
<Button
type="submit"
disabled={createLoading || disabled}
disabled={createLoading || !isPaidUser(tierMatrix.orgOidc)}
loading={createLoading}
onClick={() => {
if (disabled) return;
// log any issues with the form
console.log(form.formState.errors);
form.handleSubmit(onSubmit)();
@@ -829,7 +823,6 @@ export default function Page() {
{t("idpSubmit")}
</Button>
</div>
</fieldset>
</>
);
}