sfdsfsdf
This commit is contained in:
2026-04-03 18:45:09 +02:00
parent ecae89a79d
commit 983b67e6fc
4 changed files with 36 additions and 13 deletions

View File

@@ -85,11 +85,15 @@ export const config = {
.map((e) => e.trim().toLowerCase()) .map((e) => e.trim().toLowerCase())
.filter(Boolean), .filter(Boolean),
// Gitea Webhook (Deployment) // Gitea Webhook (Deployment) — trim: trailing newlines in .env break HMAC/Bearer match
gitea: { gitea: (() => {
webhookSecret: process.env.GITEA_WEBHOOK_SECRET || '', const secret = (process.env.GITEA_WEBHOOK_SECRET || '').trim()
webhookAuthToken: process.env.GITEA_WEBHOOK_AUTH_TOKEN || process.env.GITEA_WEBHOOK_SECRET || '', const auth = (process.env.GITEA_WEBHOOK_AUTH_TOKEN || '').trim()
}, return {
webhookSecret: secret,
webhookAuthToken: auth || secret,
}
})(),
/** HMAC secret for Gmail/Outlook OAuth state (recommended in production) */ /** HMAC secret for Gmail/Outlook OAuth state (recommended in production) */
oauthStateSecret: process.env.OAUTH_STATE_SECRET || '', oauthStateSecret: process.env.OAUTH_STATE_SECRET || '',

View File

@@ -59,9 +59,9 @@ app.use('/api', limiters.api)
// Static files // Static files
app.use(express.static(join(__dirname, '..', 'public'))) app.use(express.static(join(__dirname, '..', 'public')))
// Gitea webhook: raw body for X-Gitea-Signature verification (must be before JSON parser) // Gitea webhook: raw body for X-Gitea-Signature (must match signed bytes exactly).
// Limit 2mb so large Gitea payloads (full repo JSON) don't get rejected and cause 502 // type: () => true — Gitea may send application/json; charset=utf-8 or similar; strict 'application/json' can skip parsing and leave body empty.
app.use('/api/webhook', express.raw({ type: 'application/json', limit: '2mb' })) app.use('/api/webhook', express.raw({ type: () => true, limit: '2mb' }))
app.use('/api/webhook', webhookRoutes) app.use('/api/webhook', webhookRoutes)
// Body parsing (BEFORE routes, AFTER static) // Body parsing (BEFORE routes, AFTER static)

View File

@@ -1,5 +1,5 @@
{ {
"name": "email-sorter-server", "name": "mailflow-server",
"version": "2.0.0", "version": "2.0.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
@@ -1096,6 +1096,15 @@
"url": "https://opencollective.com/express" "url": "https://opencollective.com/express"
} }
}, },
"node_modules/imapflow/node_modules/nodemailer": {
"version": "7.0.13",
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-7.0.13.tgz",
"integrity": "sha512-PNDFSJdP+KFgdsG3ZzMXCgquO7I6McjY2vlqILjtJd0hy8wEvtugS9xKRF2NWlPNGxvLCXlTNIae4serI7dinw==",
"license": "MIT-0",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/inherits": { "node_modules/inherits": {
"version": "2.0.4", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
@@ -1425,6 +1434,15 @@
"node-fetch-native-with-agent": "1.7.2" "node-fetch-native-with-agent": "1.7.2"
} }
}, },
"node_modules/node-cron": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/node-cron/-/node-cron-4.2.1.tgz",
"integrity": "sha512-lgimEHPE/QDgFlywTd8yTR61ptugX3Qer29efeyWw2rv259HtGBNn1vZVmp8lB9uo9wC0t/AT4iGqXxia+CJFg==",
"license": "ISC",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/node-fetch": { "node_modules/node-fetch": {
"version": "2.7.0", "version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
@@ -1474,9 +1492,9 @@
} }
}, },
"node_modules/nodemailer": { "node_modules/nodemailer": {
"version": "7.0.13", "version": "8.0.4",
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-7.0.13.tgz", "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-8.0.4.tgz",
"integrity": "sha512-PNDFSJdP+KFgdsG3ZzMXCgquO7I6McjY2vlqILjtJd0hy8wEvtugS9xKRF2NWlPNGxvLCXlTNIae4serI7dinw==", "integrity": "sha512-k+jf6N8PfQJ0Fe8ZhJlgqU5qJU44Lpvp2yvidH3vp1lPnVQMgi4yEEMPXg5eJS1gFIJTVq1NHBk7Ia9ARdSBdQ==",
"license": "MIT-0", "license": "MIT-0",
"engines": { "engines": {
"node": ">=6.0.0" "node": ">=6.0.0"

View File

@@ -66,7 +66,8 @@ router.post('/gitea', asyncHandler(async (req, res) => {
try { try {
validateGiteaWebhook(req) validateGiteaWebhook(req)
} catch (err) { } catch (err) {
if (err.name === 'AuthorizationError' || err.statusCode === 401) throw err // AuthorizationError uses statusCode 403, not 401 — do not rely on err.name (can be wrong on some engines)
if (err instanceof AuthorizationError) throw err
log.error('Gitea Webhook: Validierung fehlgeschlagen', { error: err.message }) log.error('Gitea Webhook: Validierung fehlgeschlagen', { error: err.message })
return res.status(401).json({ error: 'Webhook validation failed' }) return res.status(401).json({ error: 'Webhook validation failed' })
} }