Inbound email: a provider POSTs a normalized JSON message to
POST /api/v1/email-inbound/{app_id}/{trigger_id}; the public receiver
verifies the optional HMAC signature, builds a TriggerEvent::Email, and
enqueues an outbox row the dispatcher delivers like any async trigger.
Handlers see ctx.event.email = #{from,to,cc,subject,text,html,
received_at,message_id}.
- migration 0024: widen triggers.kind + outbox.source_kind CHECKs to
'email'; new email_trigger_details table.
- TriggerKind::Email, TriggerDetails::Email{has_inbound_secret},
OutboxSourceKind::Email, TriggerEvent::Email; dispatcher routes the
email row via the generic resolve_trigger path.
- Admin POST /apps/{id}/triggers/email (validate_trigger_target; module
+ cross-app rejection). inbound_secret is stored ENCRYPTED via the
master key (deviation from the brief's plaintext default; decrypted
per inbound request — see HANDBACK §7).
- Dashboard: email trigger form on the Triggers tab + webhook URL +
expected-payload help.
- 8 DB-gated e2e tests (202/401/404/422/cross-app/handler-fire) +
receiver unit tests (HMAC verify, secret round-trip, payload parse).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
48 lines
1002 B
TOML
48 lines
1002 B
TOML
[package]
|
|
name = "picloud"
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
rust-version.workspace = true
|
|
license.workspace = true
|
|
|
|
[lints]
|
|
workspace = true
|
|
|
|
[lib]
|
|
path = "src/lib.rs"
|
|
|
|
[[bin]]
|
|
name = "picloud"
|
|
path = "src/main.rs"
|
|
|
|
[dependencies]
|
|
picloud-shared.workspace = true
|
|
picloud-executor-core.workspace = true
|
|
picloud-orchestrator-core.workspace = true
|
|
picloud-manager-core.workspace = true
|
|
|
|
tokio.workspace = true
|
|
async-trait.workspace = true
|
|
axum.workspace = true
|
|
tower.workspace = true
|
|
tower-http.workspace = true
|
|
sqlx.workspace = true
|
|
serde.workspace = true
|
|
serde_json.workspace = true
|
|
anyhow.workspace = true
|
|
thiserror.workspace = true
|
|
tracing.workspace = true
|
|
tracing-subscriber.workspace = true
|
|
figment.workspace = true
|
|
|
|
[dev-dependencies]
|
|
axum-test = "17"
|
|
serde.workspace = true
|
|
serde_json.workspace = true
|
|
uuid.workspace = true
|
|
chrono.workspace = true
|
|
# Compute inbound-email HMAC signatures in the e2e receiver tests.
|
|
hmac.workspace = true
|
|
sha2.workspace = true
|
|
hex.workspace = true
|