mirror of
https://github.com/stalwartlabs/mail-server.git
synced 2025-11-24 18:30:43 +08:00
Added OPTIONS handler for CORS pre-flight requests
This commit is contained in:
parent
d4fe318812
commit
9660f1f9e1
22 changed files with 66 additions and 36 deletions
|
|
@ -72,7 +72,13 @@ pub async fn parse_jmap_request(
|
|||
let (_in_flight, access_token) = match jmap.authenticate_headers(&req, remote_ip).await
|
||||
{
|
||||
Ok(Some(session)) => session,
|
||||
Ok(None) => return RequestError::unauthorized().into_http_response(),
|
||||
Ok(None) => {
|
||||
return if req.method() != Method::OPTIONS {
|
||||
RequestError::unauthorized().into_http_response()
|
||||
} else {
|
||||
().into_http_response()
|
||||
}
|
||||
}
|
||||
Err(err) => return err.into_http_response(),
|
||||
};
|
||||
|
||||
|
|
@ -164,6 +170,9 @@ pub async fn parse_jmap_request(
|
|||
return upgrade_websocket_connection(jmap, req, access_token, instance.clone())
|
||||
.await;
|
||||
}
|
||||
(_, &Method::OPTIONS) => {
|
||||
return ().into_http_response();
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
|
@ -192,6 +201,9 @@ pub async fn parse_jmap_request(
|
|||
Err(err) => err.into_http_response(),
|
||||
};
|
||||
}
|
||||
(_, &Method::OPTIONS) => {
|
||||
return ().into_http_response();
|
||||
}
|
||||
_ => (),
|
||||
},
|
||||
"auth" => {
|
||||
|
|
@ -240,6 +252,9 @@ pub async fn parse_jmap_request(
|
|||
Err(err) => err.into_http_response(),
|
||||
}
|
||||
}
|
||||
(_, &Method::OPTIONS) => {
|
||||
return ().into_http_response();
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
|
@ -610,3 +625,16 @@ impl ToHttpResponse for HtmlResponse {
|
|||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToHttpResponse for () {
|
||||
fn into_http_response(self) -> HttpResponse {
|
||||
hyper::Response::builder()
|
||||
.status(StatusCode::NO_CONTENT)
|
||||
.body(
|
||||
Full::new(Bytes::new())
|
||||
.map_err(|never| match never {})
|
||||
.boxed(),
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ impl<T: AsyncWrite + AsyncRead + Unpin + IsTls> Session<T> {
|
|||
.into_value(self)
|
||||
.map(|s| s.into_owned())
|
||||
{
|
||||
let mut mail_from = self.data.mail_from.as_mut().unwrap();
|
||||
let mail_from = self.data.mail_from.as_mut().unwrap();
|
||||
if new_address.contains('@') {
|
||||
mail_from.address_lcase = new_address.to_lowercase();
|
||||
mail_from.domain = mail_from.address_lcase.domain_part().to_string();
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ impl<T: AsyncWrite + AsyncRead + Unpin> Session<T> {
|
|||
.into_value(self)
|
||||
.map(|s| s.into_owned())
|
||||
{
|
||||
let mut rcpt = self.data.rcpt_to.last_mut().unwrap();
|
||||
let rcpt = self.data.rcpt_to.last_mut().unwrap();
|
||||
if new_address.contains('@') {
|
||||
rcpt.address_lcase = new_address.to_lowercase();
|
||||
rcpt.domain = rcpt.address_lcase.domain_part().to_string();
|
||||
|
|
|
|||
|
|
@ -105,7 +105,9 @@ private-key = "file://./tests/resources/tls_privatekey.pem"
|
|||
directory = "local"
|
||||
|
||||
[jmap.http]
|
||||
headers = ["Access-Control-Allow-Origin: *", "Access-Control-Allow-Methods: POST, GET, HEAD"]
|
||||
headers = ["Access-Control-Allow-Origin: *",
|
||||
"Access-Control-Allow-Methods: POST, GET, HEAD, OPTIONS",
|
||||
"Access-Control-Allow-Headers: *"]
|
||||
|
||||
[jmap.protocol]
|
||||
set.max-objects = 100000
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ async fn auth() {
|
|||
let mut ctx = ConfigContext::new(&[]);
|
||||
ctx.directory = Config::parse(DIRECTORY).unwrap().parse_directory().unwrap();
|
||||
|
||||
let mut config = &mut core.session.config.auth;
|
||||
let config = &mut core.session.config.auth;
|
||||
|
||||
config.require = r"[{if = 'remote-ip', eq = '10.0.0.1', then = true},
|
||||
{else = false}]"
|
||||
|
|
|
|||
|
|
@ -80,12 +80,12 @@ async fn data() {
|
|||
// Create temp dir for queue
|
||||
let mut qr = core.init_test_queue("smtp_data_test");
|
||||
let directory = Config::parse(DIRECTORY).unwrap().parse_directory().unwrap();
|
||||
let mut config = &mut core.session.config.rcpt;
|
||||
let config = &mut core.session.config.rcpt;
|
||||
config.directory = IfBlock::new(Some(MaybeDynValue::Static(
|
||||
directory.directories.get("local").unwrap().clone(),
|
||||
)));
|
||||
|
||||
let mut config = &mut core.session.config;
|
||||
let config = &mut core.session.config;
|
||||
config.data.add_auth_results = "[{if = 'remote-ip', eq = '10.0.0.3', then = true},
|
||||
{else = false}]"
|
||||
.parse_if(&ConfigContext::new(&[]));
|
||||
|
|
|
|||
|
|
@ -135,12 +135,12 @@ async fn dmarc() {
|
|||
// Create report channels
|
||||
let mut rr = core.init_test_report();
|
||||
let directory = Config::parse(DIRECTORY).unwrap().parse_directory().unwrap();
|
||||
let mut config = &mut core.session.config.rcpt;
|
||||
let config = &mut core.session.config.rcpt;
|
||||
config.directory = IfBlock::new(Some(MaybeDynValue::Static(
|
||||
directory.directories.get("local").unwrap().clone(),
|
||||
)));
|
||||
|
||||
let mut config = &mut core.session.config;
|
||||
let config = &mut core.session.config;
|
||||
config.data.add_auth_results = IfBlock::new(true);
|
||||
config.data.add_date = IfBlock::new(true);
|
||||
config.data.add_message_id = IfBlock::new(true);
|
||||
|
|
@ -148,7 +148,7 @@ async fn dmarc() {
|
|||
config.data.add_return_path = IfBlock::new(true);
|
||||
config.data.add_received_spf = IfBlock::new(true);
|
||||
|
||||
let mut config = &mut core.report.config;
|
||||
let config = &mut core.report.config;
|
||||
config.dkim.send = IfBlock::new(Some(Rate {
|
||||
requests: 1,
|
||||
period: Duration::from_secs(1),
|
||||
|
|
@ -157,7 +157,7 @@ async fn dmarc() {
|
|||
config.spf.send = config.dkim.send.clone();
|
||||
config.dmarc_aggregate.send = IfBlock::new(AggregateFrequency::Daily);
|
||||
|
||||
let mut config = &mut core.mail_auth;
|
||||
let config = &mut core.mail_auth;
|
||||
config.spf.verify_ehlo = "[{if = 'remote-ip', eq = '10.0.0.2', then = 'strict'},
|
||||
{ else = 'relaxed' }]"
|
||||
.parse_if(&ConfigContext::new(&[]));
|
||||
|
|
@ -168,7 +168,7 @@ async fn dmarc() {
|
|||
{ else = 'strict' }]"
|
||||
.parse_if(&ConfigContext::new(&[]));
|
||||
|
||||
let mut config = &mut core.report.config;
|
||||
let config = &mut core.report.config;
|
||||
config.spf.sign = "['rsa']"
|
||||
.parse_if::<Vec<DynValue<EnvelopeKey>>>(&ctx)
|
||||
.map_if_block(&ctx.signers, "", "")
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ async fn dnsrbl() {
|
|||
);
|
||||
|
||||
let mut qr = core.init_test_queue("smtp_dnsrbl_test");
|
||||
let mut config = &mut core.mail_auth.dnsbl;
|
||||
let config = &mut core.mail_auth.dnsbl;
|
||||
config.ip_lookup = vec![
|
||||
"zen.spamhaus.org".to_string(),
|
||||
"bl.spamcop.net".to_string(),
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ async fn ehlo() {
|
|||
Instant::now() + Duration::from_secs(5),
|
||||
);
|
||||
|
||||
let mut config = &mut core.session.config;
|
||||
let config = &mut core.session.config;
|
||||
config.data.max_message_size = r"[{if = 'remote-ip', eq = '10.0.0.1', then = 1024},
|
||||
{else = 2048}]"
|
||||
.parse_if(&ConfigContext::new(&[]));
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ use smtp::{
|
|||
#[tokio::test]
|
||||
async fn limits() {
|
||||
let mut core = SMTP::test();
|
||||
let mut config = &mut core.session.config;
|
||||
let config = &mut core.session.config;
|
||||
config.transfer_limit = r"[{if = 'remote-ip', eq = '10.0.0.1', then = 10},
|
||||
{else = 1024}]"
|
||||
.parse_if(&ConfigContext::new(&[]));
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ async fn mail() {
|
|||
Instant::now() + Duration::from_secs(5),
|
||||
);
|
||||
|
||||
let mut config = &mut core.session.config;
|
||||
let config = &mut core.session.config;
|
||||
config.ehlo.require = IfBlock::new(true);
|
||||
core.mail_auth.spf.verify_ehlo = IfBlock::new(VerifyStrategy::Relaxed);
|
||||
core.mail_auth.spf.verify_mail_from = r"[{if = 'remote-ip', eq = '10.0.0.2', then = 'strict'},
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ async fn milter_session() {
|
|||
tokio::time::sleep(Duration::from_millis(100)).await;
|
||||
let mut core = SMTP::test();
|
||||
let mut qr = core.init_test_queue("smtp_milter_test");
|
||||
let mut config = &mut core.session.config;
|
||||
let config = &mut core.session.config;
|
||||
config.rcpt.relay = IfBlock::new(true);
|
||||
config.data.milters = r#"[[session.data.milter]]
|
||||
hostname = "127.0.0.1"
|
||||
|
|
|
|||
|
|
@ -72,9 +72,9 @@ domains = ["foobar.org"]
|
|||
async fn rcpt() {
|
||||
let mut core = SMTP::test();
|
||||
|
||||
let mut config_ext = &mut core.session.config.extensions;
|
||||
let config_ext = &mut core.session.config.extensions;
|
||||
let directory = Config::parse(DIRECTORY).unwrap().parse_directory().unwrap();
|
||||
let mut config = &mut core.session.config.rcpt;
|
||||
let config = &mut core.session.config.rcpt;
|
||||
config.directory = IfBlock::new(Some(MaybeDynValue::Static(
|
||||
directory.directories.get("local").unwrap().clone(),
|
||||
)));
|
||||
|
|
|
|||
|
|
@ -155,12 +155,12 @@ async fn sign_and_seal() {
|
|||
);
|
||||
|
||||
let directory = Config::parse(DIRECTORY).unwrap().parse_directory().unwrap();
|
||||
let mut config = &mut core.session.config.rcpt;
|
||||
let config = &mut core.session.config.rcpt;
|
||||
config.directory = IfBlock::new(Some(MaybeDynValue::Static(
|
||||
directory.directories.get("local").unwrap().clone(),
|
||||
)));
|
||||
|
||||
let mut config = &mut core.session.config;
|
||||
let config = &mut core.session.config;
|
||||
config.data.add_auth_results = IfBlock::new(true);
|
||||
config.data.add_date = IfBlock::new(true);
|
||||
config.data.add_message_id = IfBlock::new(true);
|
||||
|
|
@ -168,7 +168,7 @@ async fn sign_and_seal() {
|
|||
config.data.add_return_path = IfBlock::new(true);
|
||||
config.data.add_received_spf = IfBlock::new(true);
|
||||
|
||||
let mut config = &mut core.mail_auth;
|
||||
let config = &mut core.mail_auth;
|
||||
let ctx = ConfigContext::new(&[]).parse_signatures();
|
||||
config.spf.verify_ehlo = IfBlock::new(VerifyStrategy::Relaxed);
|
||||
config.spf.verify_mail_from = config.spf.verify_ehlo.clone();
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ use smtp::{
|
|||
#[tokio::test]
|
||||
async fn throttle_inbound() {
|
||||
let mut core = SMTP::test();
|
||||
let mut config = &mut core.session.config;
|
||||
let config = &mut core.session.config;
|
||||
config.throttle.connect = r"[[throttle]]
|
||||
match = {if = 'remote-ip', eq = '10.0.0.1'}
|
||||
key = 'remote-ip'
|
||||
|
|
|
|||
|
|
@ -66,12 +66,12 @@ async fn vrfy_expn() {
|
|||
let ctx = ConfigContext::new(&[]);
|
||||
|
||||
let directory = Config::parse(DIRECTORY).unwrap().parse_directory().unwrap();
|
||||
let mut config = &mut core.session.config.rcpt;
|
||||
let config = &mut core.session.config.rcpt;
|
||||
config.directory = IfBlock::new(Some(MaybeDynValue::Static(
|
||||
directory.directories.get("local").unwrap().clone(),
|
||||
)));
|
||||
|
||||
let mut config = &mut core.session.config.extensions;
|
||||
let config = &mut core.session.config.extensions;
|
||||
config.vrfy = r"[{if = 'remote-ip', eq = '10.0.0.1', then = true},
|
||||
{else = false}]"
|
||||
.parse_if(&ctx);
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ async fn lookup_sql() {
|
|||
}
|
||||
|
||||
// Enable AUTH
|
||||
let mut config = &mut core.session.config.auth;
|
||||
let config = &mut core.session.config.auth;
|
||||
config.directory = r"'sql'"
|
||||
.parse_if::<Option<DynValue<EnvelopeKey>>>(&ctx)
|
||||
.map_if_block(&ctx.directory.directories, "", "")
|
||||
|
|
@ -122,7 +122,7 @@ async fn lookup_sql() {
|
|||
config.errors_wait = IfBlock::new(Duration::from_millis(5));
|
||||
|
||||
// Enable VRFY/EXPN/RCPT
|
||||
let mut config = &mut core.session.config.rcpt;
|
||||
let config = &mut core.session.config.rcpt;
|
||||
config.directory = r"'sql'"
|
||||
.parse_if::<Option<DynValue<EnvelopeKey>>>(&ctx)
|
||||
.map_if_block(&ctx.directory.directories, "", "")
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ async fn lmtp_delivery() {
|
|||
core.session.config.rcpt.relay = IfBlock::new(true);
|
||||
core.session.config.rcpt.max_recipients = IfBlock::new(100);
|
||||
core.session.config.extensions.dsn = IfBlock::new(true);
|
||||
let mut config = &mut core.queue.config;
|
||||
let config = &mut core.queue.config;
|
||||
config.retry = IfBlock::new(vec![Duration::from_millis(100)]);
|
||||
config.notify = "[{if = 'rcpt-domain', eq = 'foobar.org', then = ['100ms', '200ms']},
|
||||
{else = ['100ms']}]"
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ async fn smtp_delivery() {
|
|||
core.session.config.rcpt.relay = IfBlock::new(true);
|
||||
core.session.config.rcpt.max_recipients = IfBlock::new(100);
|
||||
core.session.config.extensions.dsn = IfBlock::new(true);
|
||||
let mut config = &mut core.queue.config;
|
||||
let config = &mut core.queue.config;
|
||||
config.retry = IfBlock::new(vec![Duration::from_millis(100)]);
|
||||
config.notify = "[{if = 'rcpt-domain', eq = 'foobar.org', then = ['100ms', '200ms']},
|
||||
{else = ['100ms']}]"
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ async fn generate_dsn() {
|
|||
// Load config
|
||||
let mut core = SMTP::test();
|
||||
let ctx = ConfigContext::new(&[]).parse_signatures();
|
||||
let mut config = &mut core.queue.config.dsn;
|
||||
let config = &mut core.queue.config.dsn;
|
||||
config.sign = "['rsa']"
|
||||
.parse_if::<Vec<DynValue<EnvelopeKey>>>(&ctx)
|
||||
.map_if_block(&ctx.signers, "", "")
|
||||
|
|
|
|||
|
|
@ -51,12 +51,12 @@ async fn queue_retry() {
|
|||
// Create temp dir for queue
|
||||
let mut qr = core.init_test_queue("smtp_queue_retry_test");
|
||||
|
||||
let mut config = &mut core.session.config.rcpt;
|
||||
let config = &mut core.session.config.rcpt;
|
||||
config.relay = IfBlock::new(true);
|
||||
let mut config = &mut core.session.config.extensions;
|
||||
let config = &mut core.session.config.extensions;
|
||||
config.deliver_by = IfBlock::new(Some(Duration::from_secs(86400)));
|
||||
config.future_release = IfBlock::new(Some(Duration::from_secs(86400)));
|
||||
let mut config = &mut core.queue.config;
|
||||
let config = &mut core.queue.config;
|
||||
config.retry = IfBlock::new(vec![
|
||||
Duration::from_millis(100),
|
||||
Duration::from_millis(200),
|
||||
|
|
|
|||
|
|
@ -39,11 +39,11 @@ async fn report_analyze() {
|
|||
let mut qr = core.init_test_queue("smtp_analyze_report_test");
|
||||
let report_dir = make_temp_dir("smtp_report_incoming", true);
|
||||
|
||||
let mut config = &mut core.session.config.rcpt;
|
||||
let config = &mut core.session.config.rcpt;
|
||||
config.relay = IfBlock::new(true);
|
||||
let mut config = &mut core.session.config.data;
|
||||
let config = &mut core.session.config.data;
|
||||
config.max_messages = IfBlock::new(1024);
|
||||
let mut config = &mut core.report.config.analysis;
|
||||
let config = &mut core.report.config.analysis;
|
||||
config.addresses = vec![
|
||||
AddressMatch::StartsWith("reports@".to_string()),
|
||||
AddressMatch::EndsWith("@dmarc.foobar.org".to_string()),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue