Skip to content

Commit

Permalink
Make the "name" on addresses accessible; make "From" public
Browse files Browse the repository at this point in the history
  • Loading branch information
Flying-Toast committed Oct 26, 2023
1 parent e0229bf commit 759ccec
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 32 deletions.
16 changes: 14 additions & 2 deletions lib/yugo.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ defmodule Yugo do

alias Yugo.{Filter, Client}

@type address :: String.t()
@typedoc """
The first field is the name associated with the address, and the second field is the address itself.
e.g. `{"Bart", "bart@simpsons.family"}`
"""
@type address :: {nil | String.t(), String.t()}

@typedoc """
e.g. `"text/html"`, `"image/png"`, `"text/plain"`, etc.
Expand All @@ -20,14 +25,20 @@ defmodule Yugo do
A "onepart" body is a tuple in the form `{mime_type, params, content}`, where `mime_type` is a [`mime_type`](`t:mime_type/0`),
`params` is a string->string map, and `content` is a [`binary`](`t:binary/0`).
A "multipart" body consists of a *list* of [`body`s](`t:body/0`).
A "multipart" body consists of a *list* of [`body`s](`t:body/0`), which can themselves be either onepart or multipart.
"""
@type body :: {mime_type, %{optional(String.t()) => String.t()}, binary} | [body]

@type flag :: :seen | :answered | :flagged | :draft | :deleted

@typedoc """
An email message sent to a subscribed process.
# Difference between `sender` and `from`
Both "sender" and "from" are fields used by IMAP to indicate the origin of the email.
They are *usually* the same, but they can be different and they have different meanings:
- `from` - the author who physically wrote the email. `From` is typically the address you see when viewing the message in an email client.
- `sender` - the person who sent the email, potentially different than `from` if someone else sent the email on behalf of the author.
"""
@type email :: %{
bcc: [address],
Expand All @@ -39,6 +50,7 @@ defmodule Yugo do
message_id: nil | String.t(),
reply_to: [address],
sender: [address],
from: [address],
subject: nil | String.t(),
to: [address]
}
Expand Down
3 changes: 1 addition & 2 deletions lib/yugo/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -466,8 +466,7 @@ defmodule Yugo.Client do
defp package_message(msg) do
msg
|> Map.merge(msg.envelope)
# From is too easily spoofed, drop it so users use :sender instead
|> Map.drop([:from, :fetched, :body_structure, :envelope])
|> Map.drop([:fetched, :body_structure, :envelope])
|> Map.put(:body, normalize_structure(msg.body, msg.body_structure))
end

Expand Down
2 changes: 1 addition & 1 deletion lib/yugo/filter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ defmodule Yugo.Filter do
(message.envelope.subject != nil &&
Regex.match?(filter.subject_regex, message.envelope.subject)),
!filter.sender_regex ||
Enum.any?(message.envelope.sender, &Regex.match?(filter.sender_regex, &1)),
Enum.any?(message.envelope.sender, &Regex.match?(filter.sender_regex, elem(&1, 1))),
filter.has_flags == [] || Enum.all?(filter.has_flags, &Enum.member?(message.flags, &1)),
filter.lacks_flags == [] ||
Enum.all?(filter.lacks_flags, &(!Enum.member?(message.flags, &1)))
Expand Down
4 changes: 2 additions & 2 deletions lib/yugo/parser.ex
Original file line number Diff line number Diff line change
Expand Up @@ -284,10 +284,10 @@ defmodule Yugo.Parser do
end

defp parse_address(rest) do
{[_name, _adl, mailbox, host], rest} =
{[name, _adl, mailbox, host], rest} =
parse_list(rest, [&parse_nstring/1, &parse_nstring/1, &parse_nstring/1, &parse_nstring/1])

{"#{String.downcase(mailbox)}@#{String.downcase(host)}", rest}
{{name, "#{String.downcase(mailbox)}@#{String.downcase(host)}"}, rest}
end

defp parse_address_list(rest) do
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule Yugo.MixProject do
def project do
[
app: :yugo,
version: "0.3.1",
version: "1.0.0",
elixir: "~> 1.14",
start_permanent: Mix.env() == :prod,
deps: deps(),
Expand Down
40 changes: 24 additions & 16 deletions test/yugo/client_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,11 @@ defmodule Yugo.ClientTest do
flags: [:seen],
in_reply_to: nil,
message_id: "fjaelwkjfi oaf<$ ))) \"",
reply_to: ["marge@simpsons-family.com"],
sender: ["marge@simpsons-family.com"],
reply_to: [{"Marge", "marge@simpsons-family.com"}],
sender: [{"Marge Simpson", "marge@simpsons-family.com"}],
subject: nil,
to: ["homer@simpsons-family.com"]
to: [{"HOMIEEEE", "homer@simpsons-family.com"}],
from: [{"Marge Simpson", "marge@simpsons-family.com"}]
}
end
end
Expand Down Expand Up @@ -90,10 +91,11 @@ defmodule Yugo.ClientTest do
flags: [],
in_reply_to: nil,
message_id: "Fjaewlk jflkewajf i3ajf0943aF $#AF $#FA#$ F#AF {123}",
reply_to: ["bobjones@example.org"],
sender: ["bobjones@example.org"],
reply_to: [{"Bob Jones", "bobjones@example.org"}],
sender: [{"Bob Jones", "bobjones@example.org"}],
subject: "Foo Bar Baz Buzz Biz Boz",
to: ["foo@bar.com"]
to: [{nil, "foo@bar.com"}],
from: [{"Bob Jones", "bobjones@example.org"}]
}
end
end
Expand All @@ -120,15 +122,19 @@ defmodule Yugo.ClientTest do
%{
bcc: [],
body: {"text/plain", %{}, "hello"},
cc: ["foo@bar.com", "bar@foo.com", "fizz@buzz.com"],
cc: [{nil, "foo@bar.com"}, {"barfoo", "bar@foo.com"}, {"", "fizz@buzz.com"}],
date: ~U[2022-12-07 13:02:41Z],
flags: [],
in_reply_to: "123 abc 456",
message_id: "",
reply_to: ["marge@simpsons-family.com"],
sender: ["marge@simpsons-family.com", "bob@bobs-email.com"],
reply_to: [{"Marge", "marge@simpsons-family.com"}],
sender: [
{"Marge Simpson", "marge@simpsons-family.com"},
{nil, "bob@bobs-email.com"}
],
subject: "Hello! (subject)",
to: ["homer@simpsons-family.com"]
to: [{"HOMIEEEE", "homer@simpsons-family.com"}],
from: [{"Marge Simpson", "marge@simpsons-family.com"}]
}
end
end
Expand Down Expand Up @@ -170,10 +176,11 @@ defmodule Yugo.ClientTest do
flags: [],
in_reply_to: nil,
message_id: "<><><><><>",
reply_to: ["foo@bar.com"],
sender: ["person@domain.com"],
reply_to: [{nil, "foo@bar.com"}],
sender: [{nil, "person@domain.com"}],
subject: "An HTML email",
to: ["bar@foo.com"]
to: [{nil, "bar@foo.com"}],
from: [{"Aych T. Emmel", "person@domain.com"}]
}
end
end
Expand Down Expand Up @@ -223,10 +230,11 @@ defmodule Yugo.ClientTest do
flags: [],
in_reply_to: nil,
message_id: nil,
reply_to: ["marge@simpsons-family.com"],
sender: ["marge@simpsons-family.com"],
reply_to: [{"Marge", "marge@simpsons-family.com"}],
sender: [{"Marge Simpson", "marge@simpsons-family.com"}],
subject: nil,
to: ["homer@simpsons-family.com"]
to: [{"HOMIEEEE", "homer@simpsons-family.com"}],
from: [{"Marge Simpson", "marge@simpsons-family.com"}]
}
end
end
Expand Down
13 changes: 10 additions & 3 deletions test/yugo/filter_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,15 @@ defmodule Yugo.FilterTest do
|> Filter.sender_matches(~r/bob/)

assert not Filter.accepts?(f, %{envelope: %{sender: []}})
assert not Filter.accepts?(f, %{envelope: %{sender: ["foo@bar.com", "baz@biz.com"]}})
assert Filter.accepts?(f, %{envelope: %{sender: ["foo@bar.com", "bob@example.com"]}})
assert Filter.accepts?(f, %{envelope: %{sender: ["zzz@foo.bob"]}})

assert not Filter.accepts?(f, %{
envelope: %{sender: [{nil, "foo@bar.com"}, {"bizbaz", "baz@biz.com"}]}
})

assert Filter.accepts?(f, %{
envelope: %{sender: [{nil, "foo@bar.com"}, {nil, "bob@example.com"}]}
})

assert Filter.accepts?(f, %{envelope: %{sender: [{nil, "zzz@foo.bob"}]}})
end
end
10 changes: 5 additions & 5 deletions test/yugo/parser_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,15 @@ defmodule Yugo.ParserTest do
{12, :envelope,
%{
bcc: [],
cc: ["minutes@cnri.reston.va.us", "klensin@mit.edu"],
cc: [{nil, "minutes@cnri.reston.va.us"}, {"John Klensin", "klensin@mit.edu"}],
date: ~U[1996-07-16 19:23:25Z],
from: ["gray@cac.washington.edu"],
from: [{"Terry Gray", "gray@cac.washington.edu"}],
in_reply_to: nil,
message_id: "<B27397-0100000@cac.washington.edu>",
reply_to: ["gray@cac.washington.edu"],
sender: ["gray@cac.washington.edu"],
reply_to: [{"Terry Gray", "gray@cac.washington.edu"}],
sender: [{"Terry Gray", "gray@cac.washington.edu"}],
subject: "IMAP4rev1 WG mtg summary and minutes",
to: ["imap@cac.washington.edu"]
to: [{nil, "imap@cac.washington.edu"}]
}},
fetch: {12, :flags, ["\\Seen"]}
] =
Expand Down

0 comments on commit 759ccec

Please sign in to comment.