Compare commits
2 Commits
secrets-mc
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 137a4d42b0 | |||
|
|
ff2ea91e72 |
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -2065,7 +2065,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "secrets-mcp"
|
name = "secrets-mcp"
|
||||||
version = "0.5.15"
|
version = "0.5.17"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"askama",
|
"askama",
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ pub struct DatabaseConfig {
|
|||||||
pub url: String,
|
pub url: String,
|
||||||
pub ssl_mode: Option<PgSslMode>,
|
pub ssl_mode: Option<PgSslMode>,
|
||||||
pub ssl_root_cert: Option<PathBuf>,
|
pub ssl_root_cert: Option<PathBuf>,
|
||||||
pub enforce_strict_tls: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolve database URL from environment.
|
/// Resolve database URL from environment.
|
||||||
@@ -63,20 +62,10 @@ fn resolve_ssl_root_cert_from_env() -> Result<Option<PathBuf>> {
|
|||||||
Ok(Some(path))
|
Ok(Some(path))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_production_env() -> bool {
|
|
||||||
matches!(
|
|
||||||
env_var_non_empty("SECRETS_ENV")
|
|
||||||
.as_deref()
|
|
||||||
.map(|value| value.to_ascii_lowercase()),
|
|
||||||
Some(value) if value == "prod" || value == "production"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn resolve_db_config(override_url: &str) -> Result<DatabaseConfig> {
|
pub fn resolve_db_config(override_url: &str) -> Result<DatabaseConfig> {
|
||||||
Ok(DatabaseConfig {
|
Ok(DatabaseConfig {
|
||||||
url: resolve_db_url(override_url)?,
|
url: resolve_db_url(override_url)?,
|
||||||
ssl_mode: parse_ssl_mode_from_env()?,
|
ssl_mode: parse_ssl_mode_from_env()?,
|
||||||
ssl_root_cert: resolve_ssl_root_cert_from_env()?,
|
ssl_root_cert: resolve_ssl_root_cert_from_env()?,
|
||||||
enforce_strict_tls: is_production_env(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::str::FromStr;
|
|||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use serde_json::{Map, Value};
|
use serde_json::{Map, Value};
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
use sqlx::postgres::{PgConnectOptions, PgPoolOptions, PgSslMode};
|
use sqlx::postgres::{PgConnectOptions, PgPoolOptions};
|
||||||
|
|
||||||
use crate::config::DatabaseConfig;
|
use crate::config::DatabaseConfig;
|
||||||
|
|
||||||
@@ -18,18 +18,6 @@ fn build_connect_options(config: &DatabaseConfig) -> Result<PgConnectOptions> {
|
|||||||
options = options.ssl_root_cert(path);
|
options = options.ssl_root_cert(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.enforce_strict_tls
|
|
||||||
&& !matches!(
|
|
||||||
options.get_ssl_mode(),
|
|
||||||
PgSslMode::VerifyCa | PgSslMode::VerifyFull
|
|
||||||
)
|
|
||||||
{
|
|
||||||
anyhow::bail!(
|
|
||||||
"Refusing to start in production with weak PostgreSQL TLS mode. \
|
|
||||||
Set SECRETS_DATABASE_SSL_MODE=verify-ca or verify-full."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(options)
|
Ok(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "secrets-mcp"
|
name = "secrets-mcp"
|
||||||
version = "0.5.15"
|
version = "0.5.17"
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link rel="icon" href="/favicon.svg?v={{ version }}" type="image/svg+xml">
|
<link rel="icon" href="/favicon.svg?v={{ version }}" type="image/svg+xml">
|
||||||
<title>Secrets — 回收站</title>
|
<title data-i18n="pageTitle">Secrets — 回收站</title>
|
||||||
<style>
|
<style>
|
||||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||||
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600&family=Inter:wght@400;500;600&display=swap');
|
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600&family=Inter:wght@400;500;600&display=swap');
|
||||||
@@ -188,6 +188,7 @@
|
|||||||
(function () {
|
(function () {
|
||||||
I18N_PAGE = {
|
I18N_PAGE = {
|
||||||
'zh-CN': {
|
'zh-CN': {
|
||||||
|
pageTitle: 'Secrets — 回收站',
|
||||||
navMcp: 'MCP', navEntries: '条目', navTrash: '回收站', navAudit: '审计',
|
navMcp: 'MCP', navEntries: '条目', navTrash: '回收站', navAudit: '审计',
|
||||||
signOut: '退出', trashTitle: '回收站', trashSubtitle: '已删除条目会保留 3 个月,可在此恢复或永久删除。',
|
signOut: '退出', trashTitle: '回收站', trashSubtitle: '已删除条目会保留 3 个月,可在此恢复或永久删除。',
|
||||||
emptyTrash: '回收站为空。', colName: '名称', colType: '类型', colFolder: '文件夹',
|
emptyTrash: '回收站为空。', colName: '名称', colType: '类型', colFolder: '文件夹',
|
||||||
@@ -197,6 +198,7 @@
|
|||||||
mobileLabelDeletedAt: '删除时间', mobileLabelActions: '操作'
|
mobileLabelDeletedAt: '删除时间', mobileLabelActions: '操作'
|
||||||
},
|
},
|
||||||
'zh-TW': {
|
'zh-TW': {
|
||||||
|
pageTitle: 'Secrets — 回收站',
|
||||||
navMcp: 'MCP', navEntries: '條目', navTrash: '回收站', navAudit: '審計',
|
navMcp: 'MCP', navEntries: '條目', navTrash: '回收站', navAudit: '審計',
|
||||||
signOut: '退出', trashTitle: '回收站', trashSubtitle: '已刪除條目會保留 3 個月,可在此恢復或永久刪除。',
|
signOut: '退出', trashTitle: '回收站', trashSubtitle: '已刪除條目會保留 3 個月,可在此恢復或永久刪除。',
|
||||||
emptyTrash: '回收站為空。', colName: '名稱', colType: '類型', colFolder: '文件夾',
|
emptyTrash: '回收站為空。', colName: '名稱', colType: '類型', colFolder: '文件夾',
|
||||||
@@ -206,6 +208,7 @@
|
|||||||
mobileLabelDeletedAt: '刪除時間', mobileLabelActions: '操作'
|
mobileLabelDeletedAt: '刪除時間', mobileLabelActions: '操作'
|
||||||
},
|
},
|
||||||
en: {
|
en: {
|
||||||
|
pageTitle: 'Secrets — Trash',
|
||||||
navMcp: 'MCP', navEntries: 'Entries', navTrash: 'Trash', navAudit: 'Audit',
|
navMcp: 'MCP', navEntries: 'Entries', navTrash: 'Trash', navAudit: 'Audit',
|
||||||
signOut: 'Sign out', trashTitle: 'Trash', trashSubtitle: 'Deleted entries are kept for 3 months. Restore or permanently delete them here.',
|
signOut: 'Sign out', trashTitle: 'Trash', trashSubtitle: 'Deleted entries are kept for 3 months. Restore or permanently delete them here.',
|
||||||
emptyTrash: 'Trash is empty.', colName: 'Name', colType: 'Type', colFolder: 'Folder',
|
emptyTrash: 'Trash is empty.', colName: 'Name', colType: 'Type', colFolder: 'Folder',
|
||||||
|
|||||||
Reference in New Issue
Block a user