A collection of commonly used fields implemented as custom Ecto types with the necessary validation, encryption, and/or hashing.
If available in Hex, the package can be installed
by adding fields
to your list of dependencies in mix.exs
:
def deps do
[
{:fields, "~> 0.1.2"}
]
end
Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/fields.
Each field can be used in place of an Ecto type when defining your schema.
schema "users" do
field(:email, Fields.EmailEncrypted)
field(:address, Fields.Address)
field(:postcode, Fields.Postcode)
field(:password, Fields.Password)
timestamps()
end
Each field is defined as an Ecto type, with the relevant callbacks. So when you call Ecto.Changeset.cast/4
in your schema's changeset function, the field will be correctly validated. For example, calling cast on the :email
field will ensure it is a valid format for an email address.
When you load one of the fields into your database, the corresponding dump/1
callback will be called, ensuring it is inserted into the database in the correct format. In the case of Fields.EmailEncrypted
, it will encrypt the email address using a give encryption key (set in your config file) before inserting it.
Likewise, when you load a field from the database, the load/1
callback will be called, giving you the data in the format you need. Fields.EmailEncrypted
will be decrypted back to plaintext.
Each Field optionally defines an input_type/0
function. This will return an atom representing the Phoenix.HTML.Form
input type to use for the Field. For example, Fields.DescriptionPlaintextUnlimited.input_type
returns :textarea
.
The fields DescriptionPlaintextUnlimited
and HtmlBody
use html_sanitize_ex
(https://github.com/rrrene/html_sanitize_ex) to remove scripts and help keep your
project safe. HtmlBody
is able to display basic html elements whilst
DescriptionPlaintextUnlimited
displays text. Remember to use raw
when rendering
the content of your DescriptionPlaintextUnlimited
and HtmlBody
fields so that
symbols such as & (ampersand) and Html are rendered correctly. E.g.
<p><%= raw @product.description %></p>
The currently existing fields are:
- Address
- AddressEncrypted
- DescriptionPlaintextUnlimited
- Encrypted
- EmailPlaintext
- EmailHash
- EmailEncrypted
- Hash
- HtmlBody
- Password
- PhoneNumber
- PhoneNumberEncrypted
- Postcode
- PostcodeEncrypted
- Url
If you use any of the Encrypted
fields, you will need to set a list of one or more encryption keys in your config:
config :fields, Fields.AES,
keys:
System.get_env("ENCRYPTION_KEYS")
# remove single-quotes around key list in .env
|> String.replace("'", "")
# split the CSV list of keys
|> String.split(",")
# decode the key.
|> Enum.map(fn key -> :base64.decode(key) end)
If you use any of the Hash
fields, you will need to set a secret key base:
config :fields, Fields,
secret_key_base: "rVOUu+QTva+VlRJJI3wSYONRoffFQH167DfiZcegvYY/PEasjPLKIDz7wPTvTPIP"