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"}
]
endDocumentation 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"