mirror of
https://github.com/qingchencloud/clawpanel.git
synced 2026-06-21 07:23:56 +08:00
fix(hermes): persist Slack signing secret to SLACK_SIGNING_SECRET env
Channel save removed signing_secret from YAML (matching app_token migration) but never wrote it to ~/.hermes/.env. Saving Slack config from the panel permanently wiped the signing secret, breaking webhook signature verification. Read path now prefers SLACK_SIGNING_SECRET from env, matching bot/app tokens. Co-authored-by: 晴天 <1186258278@users.noreply.github.com>
This commit is contained in:
@@ -6313,6 +6313,7 @@ export function buildHermesChannelConfigValues(config = {}, envValues = {}) {
|
||||
putHermesString(form, extra, 'app_token')
|
||||
form.appToken = hermesEnvValue(envValues, 'SLACK_APP_TOKEN') || form.appToken || ''
|
||||
putHermesString(form, extra, 'signing_secret')
|
||||
form.signingSecret = hermesEnvValue(envValues, 'SLACK_SIGNING_SECRET') || form.signingSecret || ''
|
||||
putHermesString(form, extra, 'webhook_path')
|
||||
} else if (platform === 'feishu') {
|
||||
for (const key of ['app_id', 'app_secret', 'domain', 'connection_mode', 'webhook_path', 'reaction_notifications']) {
|
||||
@@ -6772,6 +6773,7 @@ export function buildHermesChannelEnvUpdates(platform, form = {}) {
|
||||
} else if (platform === 'slack') {
|
||||
updates.SLACK_BOT_TOKEN = String(form.botToken || '').trim()
|
||||
updates.SLACK_APP_TOKEN = String(form.appToken || '').trim()
|
||||
updates.SLACK_SIGNING_SECRET = String(form.signingSecret || '').trim()
|
||||
updates.SLACK_ALLOWED_USERS = csvEnvValue(form.allowFrom)
|
||||
if (Object.hasOwn(form, 'requireMention')) updates.SLACK_REQUIRE_MENTION = boolEnvValue(form.requireMention)
|
||||
} else if (platform === 'feishu') {
|
||||
|
||||
@@ -3402,6 +3402,13 @@ fn build_hermes_channel_config_values(
|
||||
.unwrap_or_default();
|
||||
form.insert("appToken".to_string(), Value::String(app_token));
|
||||
insert_json_string_if_present(&mut form, &extra, "signing_secret", "signingSecret");
|
||||
let signing_secret = hermes_env_value(env_values, "SLACK_SIGNING_SECRET")
|
||||
.or_else(|| json_form_string(&form, "signingSecret"))
|
||||
.unwrap_or_default();
|
||||
form.insert(
|
||||
"signingSecret".to_string(),
|
||||
Value::String(signing_secret),
|
||||
);
|
||||
insert_json_string_if_present(&mut form, &extra, "webhook_path", "webhookPath");
|
||||
}
|
||||
"feishu" => {
|
||||
@@ -11182,6 +11189,10 @@ fn build_hermes_channel_env_updates(platform: &str, form: &Value) -> Vec<(String
|
||||
"SLACK_APP_TOKEN",
|
||||
form_string(form, "appToken").unwrap_or_default(),
|
||||
);
|
||||
push(
|
||||
"SLACK_SIGNING_SECRET",
|
||||
form_string(form, "signingSecret").unwrap_or_default(),
|
||||
);
|
||||
push("SLACK_ALLOWED_USERS", csv_env_value(form, "allowFrom"));
|
||||
if let Some(value) = form_bool(form, "requireMention") {
|
||||
push("SLACK_REQUIRE_MENTION", bool_env_value(value));
|
||||
@@ -11431,6 +11442,7 @@ fn write_hermes_channel_env(platform: &str, form: &Value) -> Result<(), String>
|
||||
"slack" => vec![
|
||||
"SLACK_BOT_TOKEN",
|
||||
"SLACK_APP_TOKEN",
|
||||
"SLACK_SIGNING_SECRET",
|
||||
"SLACK_ALLOWED_USERS",
|
||||
"SLACK_REQUIRE_MENTION",
|
||||
],
|
||||
@@ -24515,6 +24527,21 @@ platforms:
|
||||
config["platforms"]["slack"]["extra"]["unknown_option"].as_str(),
|
||||
Some("keep-me")
|
||||
);
|
||||
|
||||
let env = build_hermes_channel_env_updates(
|
||||
"slack",
|
||||
&json!({
|
||||
"enabled": true,
|
||||
"botToken": "xoxb-new",
|
||||
"appToken": "xapp-new",
|
||||
"signingSecret": "new-signing-secret",
|
||||
"webhookPath": "/slack/events",
|
||||
}),
|
||||
);
|
||||
assert!(env.contains(&(
|
||||
"SLACK_SIGNING_SECRET".to_string(),
|
||||
"new-signing-secret".to_string()
|
||||
)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -358,6 +358,38 @@ test('Hermes 渠道保存会从 YAML 清理旧凭证,避免覆盖 .env 运行
|
||||
assert.equal(next.platforms.slack.extra.signing_secret, undefined)
|
||||
assert.equal(next.platforms.slack.extra.webhook_path, '/slack/events')
|
||||
assert.equal(next.platforms.slack.extra.unknown_option, 'keep-me')
|
||||
|
||||
const env = buildHermesChannelEnvUpdates('slack', {
|
||||
enabled: true,
|
||||
botToken: 'xoxb-new',
|
||||
appToken: 'xapp-new',
|
||||
signingSecret: 'new-signing-secret',
|
||||
webhookPath: '/slack/events',
|
||||
})
|
||||
assert.equal(env.SLACK_BOT_TOKEN, 'xoxb-new')
|
||||
assert.equal(env.SLACK_APP_TOKEN, 'xapp-new')
|
||||
assert.equal(env.SLACK_SIGNING_SECRET, 'new-signing-secret')
|
||||
})
|
||||
|
||||
test('Hermes Slack 读取会从 .env 回填 signing secret', () => {
|
||||
const values = buildHermesChannelConfigValues({
|
||||
platforms: {
|
||||
slack: {
|
||||
enabled: true,
|
||||
extra: {
|
||||
webhook_path: '/slack/events',
|
||||
},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
SLACK_SIGNING_SECRET: 'env-signing-secret',
|
||||
SLACK_BOT_TOKEN: 'xoxb-env',
|
||||
SLACK_APP_TOKEN: 'xapp-env',
|
||||
})
|
||||
|
||||
assert.equal(values.slack.signingSecret, 'env-signing-secret')
|
||||
assert.equal(values.slack.botToken, 'xoxb-env')
|
||||
assert.equal(values.slack.appToken, 'xapp-env')
|
||||
})
|
||||
|
||||
test('Hermes 钉钉保存会使用运行时实际读取的字段', () => {
|
||||
|
||||
Reference in New Issue
Block a user