From 93239a6433d55e9b7893edf166248bf4b4fc0981 Mon Sep 17 00:00:00 2001
From: Dan Schultzer <dan@dreamconception.com>
Date: Sun, 3 Mar 2019 10:46:06 -0800
Subject: [PATCH] Remove deprecations and up requirements

New minimum:

- Elixir 1.7
- Ecto 3.0
- Phoenix 1.4
---
 .travis.yml                                   |   4 +-
 CHANGELOG.md                                  | 397 +++---------------
 .../email_confirmation/ecto/context.ex        |   5 -
 .../email_confirmation/ecto/schema.ex         |   5 -
 lib/extensions/email_confirmation/plug.ex     |  21 -
 lib/extensions/invitation/plug.ex             |  16 -
 .../persistent_session/plug/cookie.ex         |  36 +-
 lib/extensions/reset_password/ecto/context.ex |   5 -
 lib/extensions/reset_password/plug.ex         |  24 --
 lib/mix/pow.ex                                |  50 +--
 lib/mix/pow/ecto/migration.ex                 |  19 +-
 lib/pow.ex                                    |  16 -
 lib/pow/ecto/context.ex                       |   8 -
 lib/pow/ecto/schema.ex                        |   4 -
 lib/pow/ecto/schema/changeset.ex              |  35 +-
 lib/pow/extension/base.ex                     |  52 +--
 lib/pow/extension/config.ex                   |  24 --
 lib/pow/extension/ecto/context/base.ex        |  15 -
 .../phoenix/controllers/controller/base.ex    |  21 +-
 .../controllers/controller_callbacks/base.ex  |   4 +-
 lib/pow/phoenix/html/bootstrap.ex             |  54 ---
 lib/pow/phoenix/html/form_template.ex         |  18 +-
 lib/pow/phoenix/router.ex                     |   7 -
 lib/pow/plug.ex                               |  12 -
 lib/pow/plug/base.ex                          |  23 +-
 lib/pow/plug/session.ex                       |  20 +-
 lib/pow/store/backend/ets_cache.ex            |  10 -
 lib/pow/store/backend/mnesia_cache.ex         |  24 --
 lib/pow/store/base.ex                         | 132 +-----
 lib/pow/store/credentials_cache.ex            |  31 +-
 mix.exs                                       |   6 +-
 mix.lock                                      |  10 +-
 .../persistent_session/plug/cookie_test.exs   |  35 +-
 test/mix/tasks/ecto/pow.ecto.install_test.exs |  10 +-
 .../phoenix/pow.phoenix.install_test.exs      |  10 +-
 test/pow/ecto/schema/changeset_test.exs       |  18 -
 test/pow/phoenix/html/form_template_test.exs  |  16 -
 test/pow/plug/session_test.exs                |  25 +-
 test/pow/store/backend/ets_cache_test.exs     |   7 -
 test/pow/store/backend/mnesia_cache_test.exs  |  36 --
 test/pow/store/base_test.exs                  |  19 -
 test/pow/store/credentials_cache_test.exs     |  23 -
 42 files changed, 100 insertions(+), 1207 deletions(-)
 delete mode 100644 lib/pow/extension/ecto/context/base.ex
 delete mode 100644 lib/pow/phoenix/html/bootstrap.ex

diff --git a/.travis.yml b/.travis.yml
index c8cdea00..9974037c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,11 +6,11 @@ services:
 jobs:
   include:
     - stage: test
-      elixir: 1.6
+      elixir: 1.7
       otp_release: 20.0
       script: &test_scripts
         - mix test
-        - MIX_ENV=test mix credo --ignore design.tagtodo
+        - MIX_ENV=test mix credo
     - stage: test
       elixir: 1.8
       script: *test_scripts
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c617704a..8f300b16 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,355 +1,58 @@
 # Changelog
 
-## v1.0.19 (TBA)
-
-**Warning:** This release will now sign and verify all tokens, causing previous tokens to no longer work. Any sessions and persistent sessions will be invalidated.
-
-### Enhancements
-
-* [`Pow.Plug.Session`] Now sets a global lock when renewing the session
-* [`PowPersistentSession.Plug.Cookie`] Now sets a global lock when authenticating the user
-* [`PowEmailConfirmation.Plug`] Added `PowEmailConfirmation.Plug.sign_confirmation_token/2` to sign the `email_confirmation_token` to prevent timing attacks
-* [`PowEmailConfirmation.Plug`] Added `PowEmailConfirmation.Plug.load_user_by_token/2` to verify the signed `email_confirmation_token` to prevent timing attacks
-* [`PowEmailConfirmation.Plug`] Added `PowEmailConfirmation.Plug.confirm_email/2` with map as second argument
-* [`PowInvitation.Plug`] Added `PowInvitation.Plug.sign_invitation_token/2` to sign the `invitation_token`
-* [`PowInvitation.Plug`] Added `PowInvitation.Plug.load_invited_user_by_token/2` to verify the signed `invitation_token` to prevent timing attacks
-* [`PowResetPassword.Plug`] Changed `PowResetPassword.Plug.create_reset_token/2` to sign the `:token`
-* [`PowResetPassword.Plug`] Added `PowResetPassword.Plug.load_user_by_token/2` to verify the signed token to prevent timing attacks
-* [`PowResetPassword.Plug`] Changed `PowResetPassword.Plug.update_user_password/2` so it decodes the signed token
-* [`PowPersistentSession.Plug.Cookie`] Now uses signed tokens to prevent timing attacks
-* [`Pow.Plug.Session`] Now uses signed session ID's to prevent timing attacks
-* [`Pow.Plug`] Added `Pow.Plug.sign_token/4` to sign tokens
-* [`Pow.Plug`] Added `Pow.Plug.verify_token/4` to decode and verify signed tokens
-* [`Pow.Plug.MessageVerifier`] Added `Pow.Plug.MessageVerifier` module to sign and verify messages
-* [`PowEmailConfirmation.Ecto.Context`] Added `PowEmailConfirmation.Ecto.Context.confirm_email/3`
-* [`PowEmailConfirmation.Ecto.Schema`] Added `confirm_email_changeset/2` and `pow_confirm_email_changeset/2` to the macro
-* [`PowEmailConfirmation.Ecto.Schema`] Added `PowEmailConfirmation.Ecto.Schema.confirm_email_changeset/2`
-* [`PowInvitation.Ecto.Schema`] Added `accept_invitation_changeset/2` and `pow_accept_invitation_changeset/2` to the macro
-* [`PowResetPassword.Ecto.Schema`] Added `reset_password_changeset/2` and `pow_reset_password_changeset/2` to the macro
-
-### Deprecations
-
-* [`PowEmailConfirmation.Plug`] `PowEmailConfirmation.Plug.confirm_email/2` with token param as second argument has been deprecated in favor of `PowEmailConfirmation.Plug.load_user_by_token/2`, and `PowEmailConfirmation.Plug.confirm_email/2` with map as second argument
-* [`PowInvitation.Plug`] `PowInvitation.Plug.invited_user_from_token/2` has been deprecated in favor of `PowInvitation.Plug.load_invited_user_by_token/2`
-* [`PowInvitation.Plug`] `PowInvitation.Plug.assign_invited_user/2` has been deprecated
-* [`PowResetPassword.Plug`] `PowResetPassword.Plug.user_from_token/2` has been deprecated in favor of `PowResetPassword.Plug.load_user_by_token/2`
-* [`PowResetPassword.Plug`] `PowResetPassword.Plug.assign_reset_password_user/2` has been deprecated
-* [`PowEmailConfirmation.Ecto.Context`] `PowEmailConfirmation.Ecto.Context.confirm_email/2` deprecated in favor of `PowEmailConfirmation.Ecto.Context.confirm_email/3`
-* [`PowEmailConfirmation.Ecto.Schema`] `PowEmailConfirmation.Ecto.Schema.confirm_email_changeset/1` deprecated in favor of `PowEmailConfirmation.Ecto.Schema.confirm_email_changeset/2`
-
-### Documentation
-
-* Updated the [API guide](guides/api.md) with signed tokens
-
-## v1.0.18 (2020-02-14)
-
-### Bug fixes
-
-* [`Pow.Phoenix.Routes`] Fixed bug where callback route methods is not using the overridden method
-* [`PowPersistentSession.Plug.Cookie`] `PowPersistentSession.Plug.Cookie.delete/2` now correctly pulls token during `:before_send` callback
-* [`Pow.Plug.Session`] `Pow.Plug.Session.delete/2` now correctly pulls session id during `:before_send` callback so `PowEmailConfirmation` will remove set session
-
-## v1.0.17 (2020-02-04)
-
-### Enhancements
-
-* [`Pow.Ecto.Context`] Calls to `Pow.Ecto.Context.get_by/2` replaced with `Pow.Operations.get_by/2` so custom users context module can be used. The following methods has been updated:
-  * `Pow.Ecto.Context.authenticate/2`
-  * `PowEmailConfirmation.Ecto.Context.get_by_confirmation_token/2`
-  * `PowInvitation.Ecto.Context.get_by_invitation_token/2`
-  * `PowResetPassword.Ecto.Context.get_by_email/2`
-* [`Pow.Ecto.Schema.Changeset`] `Pow.Ecto.Schema.Changeset.confirm_password_changeset/3` now adds the default `Ecto.Changeset.validate_confirmation/3` error instead of the previous `not same as password` error
-* [`Pow.Ecto.Schema.Changeset`] `Pow.Ecto.Schema.Changeset.confirm_password_changeset/3` now uses the `Ecto.Changeset.validate_confirmation/3` for validation and expects `:password_confirmation` instead of `:confirm_password` in params
-* [`Pow.Ecto.Schema.Changeset`] `Pow.Ecto.Schema.Changeset.new_password_changeset/3` now only requires the `:password_hash` if there have been no previous errors set in the changeset
-* [`Pow.Ecto.Schema`] No longer adds `:confirm_password` virtual field
-* [`Pow.Ecto.Schema`] Now has an `@after_compile` callback that ensures all required fields has been defined
-* [`PowInvitation.Phoenix.InvitationView`] Now renders `:password_confirmation` field instead of `:confirm_password`
-* [`PowResetPassword.Phoenix.ResetPasswordView`] Now renders `:password_confirmation` field instead of `:confirm_password`
-* [`Pow.Phoenix.RegistrationView`] Now renders `:password_confirmation` field instead of `:confirm_password`
-* [`PowEmailConfirmation.Ecto.Schema`] No longer validates if `:email` has been taken before setting `:unconfirmed_email`
-* [`PowEmailConfirmation.Phoenix.ControllerCallbacks`] Now prevents user enumeration for `PowInvitation.Phoenix.InvitationController.create/2`
-* [`PowPersistentSession.Plug.Cookie`] Changed default cookie name to `persistent_session`
-* [`PowPersistentSession.Plug.Cookie`] Removed renewal of cookie as the token will always expire
-* [`PowPersistentSession.Plug.Cookie`] No longer expires invalid cookies
-* [`Pow.Operations`] Added `Pow.Operations.fetch_primary_key_values/2`
-* [`PowPersistentSession.Plug.Base`] Now registers `:before_send` callbacks
-* [`PowPersistentSession.Plug.Cookie`] Now updates cookie and backend store in `:before_send` callback
-* [`Pow.Plug.Base`] Now registers `:before_send` callbacks
-* [`Pow.Plug.Session`] Now updates plug session and backend store in  `:before_send` callback
-* [`Pow.Plug`] Added `Pow.Plug.create/3`
-* [`Pow.Plug`] Added `Pow.Plug.delete/2`
-
-### Removed
-
-* [`PowResetPassword.Phoenix.ResetPasswordController`] Will no longer prevent information leak by checking if `PowEmailConfirmation` or registration routes are enabled; instead it'll by default prevent user enumeration, but can be disabled if `pow_prevent_user_enumeration: false` is set in `conn.private`
-
-### Bug fixes
-
-* [`PowPersistentSession.Plug.Base`] With custom `:persistent_session_store` now falls back to `:cache_store_backend` configuration option
-* [`PowResetPassword.Plug`] With custom `:reset_password_token_store` now falls back to `:cache_store_backend` configuration option
-* [`Pow.Plug.Base`] With custom `:credentials_cache_store` now falls back to `:cache_store_backend` configuration option
-
-### Deprecations
-
-* [`Pow.Ecto.Changeset`] `Pow.Ecto.Schema.Changeset.confirm_password_changeset/3` has deprecated use of `:confirm_password` in params in favor of `:password_confirmation`
-* [`Pow.Plug.Session`] `:session_store` option has been renamed to `:credentials_cache_store`
-* [`Pow.Plug`] `Pow.Plug.clear_authenticated_user/1` deprecated in favor of `Pow.Plug.delete/1`
-
-## v1.0.16 (2020-01-07)
-
-**Note:** This release contains an important security fix.
-
-### Enhancements
-
-* [`PowPersistentSession.Plug.Cookie`] Now supports `:persistent_session_cookie_opts` to customize any options that will be passed on to `Plug.Conn.put_resp_cookie/4`
-* [`PowResetPassword.Phoenix.ResetPasswordController`] Now uses `PowResetPassword.Phoenix.Messages.maybe_email_has_been_sent/1` with a generic response that tells the user the email has been sent only if an account was found
-* [`PowResetPassword.Phoenix.ResetPasswordController`] When a user doesn't exist will now return success message if `PowEmailConfirmation` extension is enabled
-* [`PowResetPassword.Phoenix.Messages`] Added `PowResetPassword.Phoenix.Messages.maybe_email_has_been_sent/1` and let `PowResetPassword.Phoenix.Messages.email_has_been_sent/1` fall back to it
-* [`PowEmailConfirmation.Phoenix.ControllerCallbacks`] When a user tries to sign up and the email has already been taken the default e-mail confirmation required message will be shown
-* [`Pow.Plug.Session`] Now renews the Plug session each time the Pow session is created or rolled
-
-### Bug fixes
-
-* [`Pow.Ecto.Schema.Changeset`] Fixed bug where `Pow.Ecto.Schema.Changeset.user_id_field_changeset/3` update with `nil` value caused an exception to be raised
-* [`PowPersistentSession.Plug.Cookie`] Now expires the cookie 10 seconds after the last request when authenticating to prevent multiple simultaneous requests deletes the cookie immediately
-
-### Documentation
-
-* Added mailer rate limitation section to [production checklist guide](guides/production_checklist.md)
-* [`Pow.Plug.Session`] Added section on session expiration to the docs
-* Updated instructions in [umbrella project guide](guides/umbrella_project.md) to Elixir 1.9
-* [`Pow.Store.Backend.Base`] Updated usage example with Cachex
-* Added [security practices page](guides/security_practices.md)
-
-## v1.0.15 (2019-11-20)
-
-### Enhancements
-
-* [`Pow.Extension.Base`] Extensions are now expected to have a base module with compile-time information whether certain modules are available to prevent unnecessary `Code.ensure_compiled?/1` calls:
-  * Added `Pow.Extension.Base` module
-  * Added `PowEmailConfirmation` module
-  * Added `PowInvitation` module
-  * Added `PowPersistentSession` module
-  * Added `PowResetPassword` module
-* [`PowPersistentSession.Plug.Cookie`] Added support for custom metadata:
-  * `PowPersistentSession.Plug.Cookie.create/3` now stores a metadata keyword list that can be populated
-  * `PowPersistentSession.Plug.Cookie.create/3` will now, instead of adding `:session_fingerprint` to the metadata, populate the `:session_metadata` keyword list with `:fingerprint`
-  * `PowPersistentSession.Plug.Cookie.authenticate/2` will now populate session metadata with what exists in `:session_metadata` key for the persistent session metadata
-  * `PowPersistentSession.Plug.Cookie.create/3` now ensures to delete the previous persistent session first, if one is found in cookies
-* [`Pow.Extension.Config`] Added `Pow.Extension.Config.extension_modules/2`
-
-### Bug fixes
-
-* [`Router.Phoenix.Router`] Fixed bug where resource routes were not filtered correctly according to the path bindings
-
-### Deprecations
-
-* [`Pow.Extension.Config`] Deprecated `Pow.Extension.Config.discover_modules/2`
-
-## v1.0.14 (2019-10-29)
+## v1.1.0 (TBA)
 
 ### Changes
 
-* Changed minmum password length to 8 (OWASP/NIST recommendations)
-* `Pow.Phoenix.Router` now only filters routes that has equal number of bindings
-* `Pow.Phoenix.Routes.user_not_authenticated_path/1` now only puts the `:request_path` param if the request is using "GET" method
-* The stores has been refactored so the command conforms with ETS store. This means that put commands now accept `{key, value}` record element(s), and keys may be list for easier lookup.
-  * `Pow.Store.Backend.Base` behaviour now requires to;
-    * Accept `Pow.Store.Backend.Base.record/0` values for `put/2`
-    * Accept `Pow.Store.Backend.Base.key/0` for `delete/2` and `get/2`
-    * Implement `all/2`
-    * Remove `keys/1`
-    * Remove `put/3`
-  * `Pow.Store.Backend.EtsCache` now uses `:ordered_set` instead of `:set` for efficiency
-  * `Pow.Store.Backend.MnesiaCache` now uses `:ordered_set` instead of `:set` for efficiency
-  * `Pow.Store.Backend.MnesiaCache` will delete all binary key records when initialized
-  * `Pow.Store.Base` behaviour now requires to;
-    * Accept erlang term value for keys in all methods
-    * Implement `put/3` instead of `put/4`
-    * Implement `delete/2` instead of `put/3`
-    * Implement `get/2` instead of `put/3`
-    * Remove `keys/2`
-  * `Pow.Store.Base.all/3` added
-  * `Pow.Store.Base.put/3` added
-  * `Pow.Store.Base` will use binary key rather than key list if `all/2` doesn't exist in the backend cache
-  * Added `Pow.Store.CredentialsCache.users/2`
-  * Added `Pow.Store.CredentialsCache.sessions/2`
-  * `Pow.Store.CredentialsCache` now adds a session key rather than appending to a list for the user key to prevent race condition
-* `Pow.Plug.Session.create/3` now stores a keyword list with metadata for the session rather than just a timestamp
-* `Pow.Plug.Session.fetch/2` and `Pow.Plug.Session.create/3` now assigns `:pow_session_metadata` in `conn.private` with the session metadata
-* `Pow.Plug.Session.create/3` will use the metadata found in `conn.private[:pow_session_metadata]` if it exists and otherwise add a randomly unique id for `:fingerprint`
-* `PowPersistentSession.Plug.Cookie.create/3` will use the value of `conn.private[:pow_session_metadata][:fingerprint]` if it exists as `:session_fingerprint` in the persistent session metadata
-* `PowPersistentSession.Plug.Cookie.authenticate/2` will assign `:fingerprint` to `conn.private[:pow_session_metadata]` if it exists in the persistent session metadata
-* `Pow.Store.CredentialsCache.put/3` will invalidate any other sessions with the same `:fingerprint` if any is set in session metadata
-* `PowResetPassword.Phoenix.ResetPasswordController.create/2` when a user doesn't exist will now only return success message if the registration routes has been disabled, otherwise the form with an error message will be returned
-* Added `PowResetPassword.Phoenix.Messages.user_not_found/1`
-
-### Bug fixes
-
-* Fixed bug where `Pow.Store.CredentialsCache` wasn't used due to how `Pow.Store.Base` macro worked
-* Fixed bug where `PowEmailConfirmation.Phoenix.ControllerCallbacks` couldn't deliver email
+- Requires Elixir 1.7 or higher
+- Requires Ecto 3.0 or higher
+- Requires Phoenix 1.4.7 or higher
 
 ### Deprecations
 
-* Deprecated `Pow.Store.Backend.EtsCache.keys/1`
-* Deprecated `Pow.Store.Backend.EtsCache.put/3`
-* Deprecated `Pow.Store.Backend.MnesiaCache.keys/1`
-* Deprecated `Pow.Store.Backend.MnesiaCache.put/3`
-* Deprecated `Pow.Store.Base.keys/2`
-* Deprecated `Pow.Store.Base.put/4`
-* Deprecated `Pow.Store.CredentialsCache.user_session_keys/3`
-* Deprecated `Pow.Store.CredentialsCache.sessions/3`
-
-## v1.0.13 (2019-08-25)
-
-* Updated `PowEmailConfirmation.Ecto.Schema.changeset/3` so;
-  * when `:email` is identical to `:unconfirmed_email` it won't generate new `:email_confirmation_token`
-  * when `:email` is identical to the persisted `:email` value both `:email_confirmation_token` and `:unconfirmed_email` will be set to `nil`
-  * when there is no `:email` value in the params nothing happens
-* Updated `PowEmailConfirmation.Ecto.Schema.confirm_email_changeset/1` so now `:email_confirmation_token` is set to `nil`
-* Updated `Pow.Ecto.Schema.Changeset.user_id_field_changeset/3` so the e-mail validator now accepts unicode e-mails
-* Added `PowEmailConfirmation.Ecto.Context.current_email_unconfirmed?/2` and `PowEmailConfirmation.Plug.pending_email_change?/1`
-* Added `:email_validator` configuration option to `Pow.Ecto.Schema.Changeset`
-* Added `Pow.Ecto.Schema.Changeset.validate_email/1`
-* Fixed bug in `PowEmailConfirmation.Phoenix.ControllerCallbacks.send_confirmation_email/2` where the confirmation e-mail wasn't send to the updated e-mail address
-
-## v1.0.12 (2019-08-16)
-
-* Added API integration guide
-* Added `:reset_password_token_store` configuration setting
-* To prevent timing attacks, `Pow.Ecto.Context.authenticate/2` now verifies password on a blank user struct when no user can be found for the provided user id, but will always return nil. The blank user struct has a nil `:password_hash` value. The struct will be passed along with a blank password to the `verify_password/2` method in the user schema module.
-* To prevent timing attacks, when `Pow.Ecto.Schema.Changeset.verify_password/3` receives a struct with a nil `:password_hash` value, it'll hash a blank password, but always return false.
-* To prevent timing attacks, the UUID is always generated in `PowResetPassword.Plug.create_reset_token/2` whether the user exists or not.
-* `PowPersistentSession.Plug.Base` now accepts `:persistent_session_ttl` which will pass the TTL to the cache backend and used for the max age of the sesion cookie in `PowPersistentSession.Plug.Cookie`
-* Deprecated `:persistent_session_cookie_max_age` configuration setting
-* `Pow.Store.Backend.MnesiaCache` can now auto join clusters
-* `Pow.Store.Backend.MnesiaCache.Unsplit` module added for self-healing after network split
-* Removed `:nodes` config option for `Pow.Store.Backend.MnesiaCache`
-
-## v1.0.11 (2019-06-13)
-
-* Fixed bug in router filters with Phoenix 1.4.7
-
-## v1.0.10 (2019-06-09)
-
-* Prevent browser cache of `Pow.Phoenix.SessionController.new/2`, `Pow.Phoenix.RegistrationController.new/2` and `PowInvitation.Phoenix.InvitationController.edit/2` by setting "Cache-Control" header unless it already has been customized
-* All links in docs generated with `mix docs` and on [hexdocs.pm](http://hexdocs.pm/pow/) now works
-* Generated docs now uses lower case file name except for `README`, `CONTRIBUTING` and `CHANGELOG`
-* Removed duplicate call for `Pow.Plug.Session.delete/2` in `Pow.Plug.Sesssion.create/3`
-
-## v1.0.9 (2019-06-04)
-
-### Changes
-
-* `Pow.Phoenix.Router` will now only add specific routes if there is no matching route already defined
-* Added `Pow.Plug.get_plug/1` and instead of `:mod`, `:plug` is used in config
-* `Pow.Ecto.Context.authenticate/2` now returns nil if user id or password is nil
-
-### Bug fixes
-
-* Fixed bug with exception raised in `Pow.Ecto.Schema.normalize_user_id_field_value/1` when calling `Pow.Ecto.Context.get_by/2` with a non binary user id
-* Fixed bug with exception raised in `Pow.Ecto.Schema.normalize_user_id_field_value/1` when calling `Pow.Ecto.Context.authenticate/2` with a non binary user id
-
-### Deprecations
-
-* Deprecated `Pow.Plug.get_mod/1`
-* Removed call to `Pow.Ecto.Context.repo/1`
-
-## v1.0.8 (2019-05-24)
-
-### Changes
-
-* Added support for layout in mails with `Pow.Phoenix.Mailer.Mail` by setting `conn.private[:pow_mailer_layout]` same way as the Phoenix layout with `conn.private[:phoenix_layout]`
-* Added `:prefix` repo opts support to use in multitenant apps
-* Removed `@changeset.data.__struct__.pow_user_id_field()` in template in favor of using `Pow.Ecto.Schema.user_id_field/1`
-
-### Bug fixes
-
-* Fixed bug in `Pow.Ecto.Schema.Changeset.current_password_changeset/3` where an exception would be thrown if the virtual `:current_password` field of the user struct was set and either the `:current_password` change was blank or identical
-
-### Deprecations
-
-* Deprecated `Mix.Pow.Ecto.Migration.create_migration_files/3` and moved it to `Mix.Pow.Ecto.Migration.create_migration_file/3`
-* Deprecated `Pow.Ecto.Context.repo/1` and moved it to `Pow.Config.repo!/1`
-* Deprecated `Pow.Ecto.Context.user_schema_mod/1` and moved it to `Pow.Config.user!/1`
-
-## v1.0.7 (2019-05-01)
-
-* Fixed bug with Phoenix 1.4.4 scoped routes
-
-## v1.0.6 (2019-04-19)
-
-* Fixed bug where custom layout setting raised exception in `Pow.Phoenix.ViewHelpers.layout/1`
-* Prevent users from changing their email to one already taken when the PowEmailConfirmation extension has been enabled
-
-## v1.0.5 (2019-04-09)
-
-* Added `extension_messages/1` to extension controllers and callbacks
-* Improved feedback for when no templates are generated for an extension with `mix pow.extension.phoenix.gen.templates` and `mix pow.extension.phoenix.mailer.gen.templates` tasks
-* Error flash is no longer overridden in `Pow.Phoenix.PlugErrorHandler` if the error message is nil
-* Fixed bug in the migration generator where `references/2` wasn't called with options
-* Support any `:plug` version below `2.0.0`
-* Deprecated `Pow.Extension.Ecto.Context.Base`
-
-## v1.0.4 (2019-03-13)
-
-* Added `PowInvitation` to the `mix pow.extension.phoenix.gen.templates` and `mix pow.extension.phoenix.mailer.gen.templates` tasks
-* Fixed issue in umbrella projects where extensions wasn't found in environment configuration
-* Fixed so `:namespace` environment config can be used as web app module name
-* Shell instructions will only be printed if the configuration is missing
-* Now requires that `:ecto` or `:phoenix` are included in the dependency list for the app to run respective mix tasks
-* Deprecated `Mix.Pow.context_app/0`
-* Deprecated `Mix.Pow.ensure_dep!/3`
-* Deprecated `Mix.Pow.context_base/1`
-
-## v1.0.3 (2019-03-09)
-
-### Changes
-
-* Added `PowInvitation` extension
-* Added support in `Pow.Ecto.Schema` for Ecto associations fields
-* Added support for adding custom methods with `Pow.Extension.Ecto.Schema` through `__using__/1` macro in extension ecto schema module
-* Help information raised with invalid schema arguments for `pow.install`, `pow.ecto.install`, `pow.ecto.gen.migration`, and `pow.ecto.gen.schema` mix tasks
-* `PowEmailConfirmation` now redirects unconfirmed users to `after_registration_path/1` or `after_sign_in_path/1` rather than `pow_session_path(conn, :new)`
-
-### Bug fixes
-
-* Correct shell instructions for `mix pow.install` task with custom schema
-* Fixed bug in `Pow.Extension.Phoenix.Router.Base` and `Pow.Extension.Phoenix.Messages` where the full extension name wasn't used to namespace methods
-
-### Deprecations
-
-* Deprecated `Pow.Extension.Config.underscore_extension/1`
-* Deprecated `PowResetPassword.Ecto.Context.password_changeset/2`
-* Deprecated `Pow.Ecto.Schema.filter_new_fields/2`
-* Deprecated `:messages_backend_fallback` setting for extension controllers
-* Removed deprecated macro `router_helpers/1` in `Pow.Phoenix.Controller`
-
-## v1.0.2 (2019-02-28)
-
-* Added flash error message about e-mail confirmation for when user changes e-mail with PowEmailConfirmation enabled
-* Added `new_password_changeset/3` and `confirm_password_changeset/3` to `Pow.Ecto.Schema.Changeset`
-* Redis cache store backend guide
-* Correct shell instructions for `mix pow.phoenix.gen.templates` task
-* Only load environment config in `Pow.Config.get/3` when no key is set in the provided config
-* Fixed issue in `Pow.Store.Backend.MnesiaCache.keys/1` and `Pow.Store.Backend.EtsCache.keys/1` so they now return keys without namespace
-* `Pow.Store.Backend.MnesiaCache.put/3` now raises an error if TTL is not provided
-
-### Breaking changes
-
-* `PowResetPassword.Plug.reset_password_token/1` has been removed
-
-## v1.0.1 (2019-01-27)
-
-* `pow.extension.ecto.gen.migrations` mix task will output warning when a migration file won't be generated for any particular extension
-* Leading and trailing whitespace is removed from the user id field value (in addition to forced lower case)
-* An exception is raised when `pow_routes/0` or `pow_extension_routes/0` are used inside router scopes with aliases
-* Mail view templates assigns now has `[user: user, conn: conn]` along with the template specific assigns
-* Mail view subject methods now gets the same assigns passed as mail view template assigns instead of only `[conn: conn]`
-* Added `pow_registration_routes/0`, `pow_session_routes/0` and `pow_scope/1` macros to the router module
-* Added guide on how to disable registration
-
-## v1.0.0 (2018-11-18)
-
-* Phoenix 1.4 support
-* Ecto 3.0 support
+- Removed deprecated method `PowResetPassword.Ecto.Context.password_changeset/2`
+- Removed deprecated method `Pow.Extension.Config.underscore_extension/1`
+- Removed deprecated method `Mix.Pow.context_app/0`
+- Removed deprecated method `Mix.Pow.ensure_dep!/3`
+- Removed deprecated method `Mix.Pow.context_base/1`
+- Removed deprecated method `Mix.Pow.Ecto.Migration.create_migration_files/3`
+- Removed deprecated method `Pow.Ecto.Context.repo/1`
+- Removed deprecated method `Pow.Ecto.Context.user_schema_mod/1`
+- Removed deprecated method `Pow.Plug.get_mod/1`
+- Removed deprecated method `Pow.Plug.clear_authenticated_user/1`
+- Removed deprecated method `Pow.Store.Backend.EtsCache.put/3`
+- Removed deprecated method `Pow.Store.Backend.EtsCache.keys/1`
+- Removed deprecated method `Pow.Store.Backend.MnesiaCache.put/3`
+- Removed deprecated method `Pow.Store.Backend.MnesiaCache.keys/1`
+- Removed deprecated method `Pow.Store.Base.keys/2`
+- Removed deprecated method `Pow.Store.Base.put/4`
+- Removed deprecated method `Pow.Store.CredentialsCache.sessions/3`
+- Removed deprecated method `Pow.Store.CredentialsCache.user_session_keys/3`
+- Removed deprecated method `Pow.Extension.Config.discover_modules/2`
+- Removed deprecated method `PowEmailConfirmation.Ecto.Context.confirm_email/2`
+- Removed deprecated method `PowEmailConfirmation.Ecto.Schema.confirm_email_changeset/1`
+- Removed deprecated method `PowEmailConfirmation.Plug.confirm_email/2`
+- Removed deprecated method `PowInvitation.Plug.invited_user_from_token/2`
+- Removed deprecated method `PowInvitation.Plug.assign_invited_user/2`
+- Removed deprecated method `PowResetPassword.Plug.assign_reset_password_user/2`
+- Removed deprecated method `PowResetPassword.Plug.user_from_token/2`
+- Removed deprecated `:session_store` configuration option for `Pow.Plug.Base`, `:credentials_cache_store` is used instead
+- Removed deprecated `:messages_backend_fallback` configuration option for `Pow.Extension.Phoenix.Controller.Base`
+- Removed deprecated `:persistent_session_cookie_max_age` configuration option for `PowPersistentSession.Plug.Cookie`
+- Removed deprecated `:nodes` configuration option for `Pow.Store.Backend.MnesiaCache`
+- Removed backwards compatibility in `Pow.Phoenix.Router` for routes generated with Phoenix `<= 1.4.6`
+- Removed deprecated Bootstrap support in `Pow.Phoenix.HTML.FormTemplate`
+- Removed deprecated module `Pow.Extension.Ecto.Context.Base`
+- `Pow.Plug.Base` no longer sets `:mod` in the `:pow_config` private plug key
+- `Pow.Plug.Session` no longer has backwards compatibility with `<= 1.0.13` session values
+- `Pow.Store.Base` no longer has backwards compability with binary key cache backends
+- `PowPersistentSession.Plug.Cookie` no longer has backwards compatibility with `<= 1.0.14` session values or `:session_fingerprint` metadata
+- `Pow.Store.Base` macro no longer adds or supports overriding the following methods:
+  - `put/4`
+  - `delete/3`
+  - `get/3`
+- `Pow.Store.Backend.MnesiaCache` no longer removes old deprecated records
+- `Pow.Store.CredentialsCache` no longer handles deletion of deprecated records
+- `Pow.Ecto.Schema.Changeset.confirm_password_changeset/3` no longer handles `:confirm_password` param
+- `Pow.Extension.Base` no longer handles dynamic lookup, a base module is now required for all extensions
+- `PowEmailConfirmation.Plug.confirm_email/2` no longer accepts binary (token) as second argument
diff --git a/lib/extensions/email_confirmation/ecto/context.ex b/lib/extensions/email_confirmation/ecto/context.ex
index 34b57026..aa3b0652 100644
--- a/lib/extensions/email_confirmation/ecto/context.ex
+++ b/lib/extensions/email_confirmation/ecto/context.ex
@@ -39,9 +39,4 @@ defmodule PowEmailConfirmation.Ecto.Context do
     |> user_mod.confirm_email_changeset(params)
     |> Context.do_update(config)
   end
-
-  # TODO: Remove by 1.1.0
-  @doc false
-  @deprecated "Use confirm_email/3 instead"
-  def confirm_email(user, config), do: confirm_email(user, %{}, config)
 end
diff --git a/lib/extensions/email_confirmation/ecto/schema.ex b/lib/extensions/email_confirmation/ecto/schema.ex
index 83a7455c..c9e1b4b7 100644
--- a/lib/extensions/email_confirmation/ecto/schema.ex
+++ b/lib/extensions/email_confirmation/ecto/schema.ex
@@ -172,9 +172,4 @@ defmodule PowEmailConfirmation.Ecto.Schema do
     |> Changeset.change(changes)
     |> Changeset.unique_constraint(:email)
   end
-
-  # TODO: Remove by 1.1.0
-  @deprecated "Use `confirm_email_changeset/2` instead"
-  @doc false
-  def confirm_email_changeset(changeset), do: confirm_email_changeset(changeset, %{})
 end
diff --git a/lib/extensions/email_confirmation/plug.ex b/lib/extensions/email_confirmation/plug.ex
index 642367b5..24959f69 100644
--- a/lib/extensions/email_confirmation/plug.ex
+++ b/lib/extensions/email_confirmation/plug.ex
@@ -81,16 +81,6 @@ defmodule PowEmailConfirmation.Plug do
       {:ok, user}         -> {:ok, user, maybe_renew_conn(conn, user, config)}
     end
   end
-  # TODO: Remove by 1.1.0
-  def confirm_email(conn, token) when is_binary(token) do
-    IO.warn "#{unquote(__MODULE__)}.confirm_email/2 called with token is deprecated, use `load_user_by_token/2` and `confirm_email/2` with map as second argument instead"
-
-    config = Plug.fetch_config(conn)
-
-    token
-    |> Context.get_by_confirmation_token(config)
-    |> maybe_confirm_email(conn, config)
-  end
 
   defp confirm_email_user(conn) do
     conn.assigns[:confirm_email_user]
@@ -110,15 +100,4 @@ defmodule PowEmailConfirmation.Plug do
 
     Keyword.equal?(clauses1, clauses2)
   end
-
-  # TODO: Remove by 1.1.0
-  defp maybe_confirm_email(nil, conn, _config), do: {:error, nil, conn}
-  defp maybe_confirm_email(user, conn, config) do
-    user
-    |> Context.confirm_email(%{}, config)
-    |> case do
-      {:error, changeset} -> {:error, changeset, conn}
-      {:ok, user}         -> {:ok, user, maybe_renew_conn(conn, user, config)}
-    end
-  end
 end
diff --git a/lib/extensions/invitation/plug.ex b/lib/extensions/invitation/plug.ex
index 63ec0589..412e28c8 100644
--- a/lib/extensions/invitation/plug.ex
+++ b/lib/extensions/invitation/plug.ex
@@ -95,20 +95,4 @@ defmodule PowInvitation.Plug do
       _any -> {:error, conn}
     end
   end
-
-  # TODO: Remove by 1.1.0
-  @doc false
-  @deprecated "Use `load_invited_user_by_token/2` instead"
-  def invited_user_from_token(conn, token) do
-    config = Plug.fetch_config(conn)
-
-    InvitationContext.get_by_invitation_token(token, config)
-  end
-
-  # TODO: Remove by 1.1.0
-  @doc false
-  @deprecated "No longer used"
-  def assign_invited_user(conn, user) do
-    Conn.assign(conn, :invited_user, user)
-  end
 end
diff --git a/lib/extensions/persistent_session/plug/cookie.ex b/lib/extensions/persistent_session/plug/cookie.ex
index 3bd9f94f..022f04f2 100644
--- a/lib/extensions/persistent_session/plug/cookie.ex
+++ b/lib/extensions/persistent_session/plug/cookie.ex
@@ -230,9 +230,6 @@ defmodule PowPersistentSession.Plug.Cookie do
       user -> {token, {user, metadata}}
     end
   end
-  # TODO: Remove by 1.1.0
-  defp fetch_user({token, user_id}, config),
-    do: fetch_user({token, {user_id, []}}, config)
 
   defp filter_invalid!([id: _value] = clauses), do: clauses
   defp filter_invalid!(clauses), do: raise "Invalid get_by clauses stored: #{inspect clauses}"
@@ -287,7 +284,7 @@ defmodule PowPersistentSession.Plug.Cookie do
   defp update_session_metadata(conn, metadata) do
     case Keyword.get(metadata, :session_metadata) do
       nil ->
-        fallback_session_fingerprint(conn, metadata)
+        conn
 
       session_metadata ->
         metadata = Map.get(conn.private, :pow_session_metadata, [])
@@ -296,22 +293,6 @@ defmodule PowPersistentSession.Plug.Cookie do
     end
   end
 
-  # TODO: Remove by 1.1.0
-  defp fallback_session_fingerprint(conn, metadata) do
-    case Keyword.get(metadata, :session_fingerprint) do
-      nil ->
-        conn
-
-      fingerprint ->
-        metadata =
-          conn.private
-          |> Map.get(:pow_session_metadata, [])
-          |> Keyword.put(:fingerprint, fingerprint)
-
-        Conn.put_private(conn, :pow_session_metadata, metadata)
-    end
-  end
-
   defp gen_token(config) do
     uuid = UUID.generate()
 
@@ -361,17 +342,8 @@ defmodule PowPersistentSession.Plug.Cookie do
   end
 
   defp max_age(config) do
-    # TODO: Remove by 1.1.0
-    case Config.get(config, :persistent_session_cookie_max_age) do
-      nil ->
-        config
-        |> PowPersistentSession.Plug.Base.ttl()
-        |> Integer.floor_div(1000)
-
-      max_age ->
-        IO.warn("use of `:persistent_session_cookie_max_age` config value in #{inspect unquote(__MODULE__)} is deprecated, please use `:persistent_session_ttl`")
-
-        max_age
-    end
+    config
+    |> PowPersistentSession.Plug.Base.ttl()
+    |> Integer.floor_div(1000)
   end
 end
diff --git a/lib/extensions/reset_password/ecto/context.ex b/lib/extensions/reset_password/ecto/context.ex
index afe83310..562702a5 100644
--- a/lib/extensions/reset_password/ecto/context.ex
+++ b/lib/extensions/reset_password/ecto/context.ex
@@ -1,7 +1,6 @@
 defmodule PowResetPassword.Ecto.Context do
   @moduledoc false
   alias Pow.{Config, Ecto.Context, Operations}
-  alias PowResetPassword.Ecto.Schema
 
   @spec get_by_email(binary(), Config.t()) :: Context.user() | nil
   def get_by_email(email, config), do: Operations.get_by([email: email], config)
@@ -12,8 +11,4 @@ defmodule PowResetPassword.Ecto.Context do
     |> user_mod.reset_password_changeset(params)
     |> Context.do_update(config)
   end
-
-  # TODO: Remove by 1.1.0
-  @deprecated "Use `PowResetPassword.Ecto.Schema.reset_password_changeset/2` instead"
-  def password_changeset(user, params), do: Schema.reset_password_changeset(user, params)
 end
diff --git a/lib/extensions/reset_password/plug.ex b/lib/extensions/reset_password/plug.ex
index a04cd43b..f86c6e3c 100644
--- a/lib/extensions/reset_password/plug.ex
+++ b/lib/extensions/reset_password/plug.ex
@@ -24,13 +24,6 @@ defmodule PowResetPassword.Plug do
     |> struct()
   end
 
-  # TODO: Remove by 1.1.0
-  @doc false
-  @deprecated "No longer used"
-  def assign_reset_password_user(conn, user) do
-    Conn.assign(conn, :reset_password_user, user)
-  end
-
   @doc """
   Finds a user for the provided params, creates a token, and stores the user
   for the token.
@@ -104,23 +97,6 @@ defmodule PowResetPassword.Plug do
     end
   end
 
-  # TODO: Remove by 1.1.0
-  @doc false
-  @deprecated "Use `load_user_by_token/2` instead"
-  def user_from_token(conn, token) do
-    {store, store_config} =
-      conn
-      |> Plug.fetch_config()
-      |> store()
-
-    store_config
-    |> store.get(token)
-    |> case do
-      :not_found -> nil
-      user       -> user
-    end
-  end
-
   @doc """
   Updates the password for the user fetched in the connection.
 
diff --git a/lib/mix/pow.ex b/lib/mix/pow.ex
index 034205a0..28af5d56 100644
--- a/lib/mix/pow.ex
+++ b/lib/mix/pow.ex
@@ -16,22 +16,6 @@ defmodule Mix.Pow do
     :ok
   end
 
-  # TODO: Remove by 1.1.0
-  @doc false
-  @deprecated "Use `ensure_ecto!` or `ensure_phoenix!` instead"
-  @spec ensure_dep!(binary(), atom(), OptionParser.argv()) :: :ok | no_return
-  def ensure_dep!(task, dep, _args) do
-    fetch_deps()
-    |> top_level_dep_in_deps?(dep)
-    |> case do
-      true ->
-        :ok
-
-      false ->
-        Mix.raise("mix #{task} can only be run inside an application directory that has #{inspect dep} as dependency")
-    end
-  end
-
   @doc """
   Raises an exception if application doesn't have Ecto as dependency.
   """
@@ -53,15 +37,7 @@ defmodule Mix.Pow do
     end)
   end
 
-  # TODO: Remove by 1.1.0 and only support Elixir 1.7
-  defp fetch_deps do
-    System.version()
-    |> Version.match?("~> 1.6.0")
-    |> case do
-      true  -> apply(Dep, :loaded, [[]])
-      false -> apply(Dep, :load_on_environment, [[]])
-    end
-  end
+  defp fetch_deps, do: Dep.load_on_environment([])
 
   @doc """
   Raises an exception if application doesn't have Phoenix as dependency.
@@ -147,36 +123,12 @@ defmodule Mix.Pow do
     """)
   end
 
-  # TODO: Remove by 1.1.0
-  @doc false
-  @deprecated "Please use `Pow.Phoenix.parse_structure/1` instead"
-  @spec context_app :: atom() | no_return
-  def context_app do
-    this_app = otp_app()
-
-    this_app
-    |> Application.get_env(:generators, [])
-    |> Keyword.get(:context_app)
-    |> case do
-      nil          -> this_app
-      false        -> Mix.raise("No context_app configured for current application")
-      {app, _path} -> app
-      app          -> app
-    end
-  end
-
   @doc false
   @spec otp_app :: atom() | no_return
   def otp_app do
     Keyword.fetch!(Mix.Project.config(), :app)
   end
 
-  # TODO: Remove by 1.1.0
-  @doc false
-  @deprecated "Use `app_base/1` instead"
-  @spec context_base(atom()) :: atom()
-  def context_base(app), do: app_base(app)
-
   @doc """
   Fetches the context base module for the app.
   """
diff --git a/lib/mix/pow/ecto/migration.ex b/lib/mix/pow/ecto/migration.ex
index 94d00d39..0e0b1269 100644
--- a/lib/mix/pow/ecto/migration.ex
+++ b/lib/mix/pow/ecto/migration.ex
@@ -2,12 +2,7 @@ defmodule Mix.Pow.Ecto.Migration do
   @moduledoc """
   Utilities module for ecto migrations in mix tasks.
   """
-  alias Mix.Generator
-
-  # TODO: Remove by 1.1.0
-  @doc false
-  @deprecated "Use `create_migration_file/3`"
-  defdelegate create_migration_files(repo, name, content), to: __MODULE__, as: :create_migration_file
+  alias Mix.{EctoSQL, Generator}
 
   @doc """
   Creates a migration file for a repo.
@@ -17,7 +12,7 @@ defmodule Mix.Pow.Ecto.Migration do
     base_name = "#{Macro.underscore(name)}.exs"
     path      =
       repo
-      |> source_repo_priv()
+      |> EctoSQL.source_repo_priv()
       |> Path.join("migrations")
       |> maybe_create_directory()
     timestamp = timestamp(path)
@@ -68,14 +63,4 @@ defmodule Mix.Pow.Ecto.Migration do
 
   defp pad(i) when i < 10, do: <<?0, ?0 + i>>
   defp pad(i), do: to_string(i)
-
-  # TODO: Remove by 1.1.0 and only use Ecto 3.0
-  defp source_repo_priv(repo) do
-    mod =
-      if Pow.dependency_vsn_match?(:ecto, "< 3.0.0"),
-        do: Mix.Ecto,
-        else: Mix.EctoSQL
-
-    mod.source_repo_priv(repo)
-  end
 end
diff --git a/lib/pow.ex b/lib/pow.ex
index b8e6462c..614122b4 100644
--- a/lib/pow.ex
+++ b/lib/pow.ex
@@ -1,19 +1,3 @@
 defmodule Pow do
   @moduledoc false
-
-  @doc """
-  Checks for version requirement in dependencies.
-  """
-  @spec dependency_vsn_match?(atom(), binary()) :: boolean()
-  def dependency_vsn_match?(dep, req) do
-    case :application.get_key(dep, :vsn) do
-      {:ok, actual} ->
-        actual
-        |> List.to_string()
-        |> Version.match?(req)
-
-      _any ->
-        false
-    end
-  end
 end
diff --git a/lib/pow/ecto/context.ex b/lib/pow/ecto/context.ex
index e2de97a7..d7d34895 100644
--- a/lib/pow/ecto/context.ex
+++ b/lib/pow/ecto/context.ex
@@ -236,17 +236,9 @@ defmodule Pow.Ecto.Context do
     end
   end
 
-  # TODO: Remove by 1.1.0
-  @deprecated "Use `Pow.Config.repo!/1` instead"
-  defdelegate repo(config), to: Config, as: :repo!
-
   defp repo_opts(config, opts) do
     config
     |> Config.get(:repo_opts, [])
     |> Keyword.take(opts)
   end
-
-  # TODO: Remove by 1.1.0
-  @deprecated "Use `Pow.Config.user!/1` instead"
-  defdelegate user_schema_mod(config), to: Config, as: :user!
 end
diff --git a/lib/pow/ecto/schema.ex b/lib/pow/ecto/schema.ex
index 0edc51d7..3d170bfd 100644
--- a/lib/pow/ecto/schema.ex
+++ b/lib/pow/ecto/schema.ex
@@ -278,10 +278,6 @@ defmodule Pow.Ecto.Schema do
     Enum.filter(fields, &not Enum.member?(existing_fields, {elem(&1, 0), elem(&1, 1)}))
   end
 
-  # TODO: Remove by 1.1.0
-  @deprecated "No longer public method"
-  def filter_new_fields(fields, existing_fields), do: __filter_new_fields__(fields, existing_fields)
-
   @doc false
   defmacro __register_fields__ do
     quote do
diff --git a/lib/pow/ecto/schema/changeset.ex b/lib/pow/ecto/schema/changeset.ex
index ba051cf0..f19d5f17 100644
--- a/lib/pow/ecto/schema/changeset.ex
+++ b/lib/pow/ecto/schema/changeset.ex
@@ -87,7 +87,6 @@ defmodule Pow.Ecto.Schema.Changeset do
     |> maybe_validate_password_hash()
   end
 
-  # TODO: Remove `confirm_password` support by 1.1.0
   @doc """
   Validates the confirm password field.
 
@@ -96,39 +95,7 @@ defmodule Pow.Ecto.Schema.Changeset do
   `nil`.
   """
   @spec confirm_password_changeset(Ecto.Schema.t() | Changeset.t(), map(), Config.t()) :: Changeset.t()
-  def confirm_password_changeset(user_or_changeset, %{confirm_password: password_confirmation} = params, _config) do
-    params =
-      params
-      |> Map.delete(:confirm_password)
-      |> Map.put(:password_confirmation, password_confirmation)
-
-    do_confirm_password_changeset(user_or_changeset, params)
-  end
-  def confirm_password_changeset(user_or_changeset, %{"confirm_password" => password_confirmation} = params, _config) do
-    params =
-      params
-      |> Map.delete("confirm_password")
-      |> Map.put("password_confirmation", password_confirmation)
-
-    convert_confirm_password_param(user_or_changeset, params)
-  end
-  def confirm_password_changeset(user_or_changeset, params, _config),
-    do: do_confirm_password_changeset(user_or_changeset, params)
-
-  # TODO: Remove by 1.1.0
-  defp convert_confirm_password_param(user_or_changeset, params) do
-    IO.warn("warning: passing `confirm_password` value to `#{inspect unquote(__MODULE__)}.confirm_password_changeset/3` has been deprecated, please use `password_confirmation` instead")
-
-    changeset = do_confirm_password_changeset(user_or_changeset, params)
-    errors    = Enum.map(changeset.errors, fn
-      {:password_confirmation, error} -> {:confirm_password, error}
-      error                           -> error
-    end)
-
-    %{changeset | errors: errors}
-  end
-
-  defp do_confirm_password_changeset(user_or_changeset, params) do
+  def confirm_password_changeset(user_or_changeset, params, _config) do
     changeset = Changeset.cast(user_or_changeset, params, [:password])
 
     changeset
diff --git a/lib/pow/extension/base.ex b/lib/pow/extension/base.ex
index 91ce21d7..fe1021d8 100644
--- a/lib/pow/extension/base.ex
+++ b/lib/pow/extension/base.ex
@@ -2,9 +2,6 @@ defmodule Pow.Extension.Base do
   @moduledoc """
   Used to set up extensions to enable parts of extension for auto-discovery.
 
-  This exists to prevent unnecessary `Code.ensure_compiled?/1` calls, and will
-  let the extension define what modules it has.
-
   ## Usage
 
       defmodule MyCustomExtension do
@@ -51,59 +48,22 @@ defmodule Pow.Extension.Base do
 
   @doc """
   Checks whether an extension has a certain module.
-
-  If a base extension module doesn't exist, or is configured improperly,
-  `Code.ensure_compiled?/1` will be used instead to see whether the module
-  exists for the extension.
   """
   @spec has?(atom(), [any()]) :: boolean()
-  def has?(extension, module_list) do
-    try do
-      has_extension_module?(extension, module_list)
-    rescue
-      # TODO: Remove or refactor by 1.1.0
-      _e in UndefinedFunctionError ->
-        IO.warn("no #{inspect extension} base module to check for #{inspect module_list} support found, please use #{inspect __MODULE__} to implement it")
-
-        [extension]
-        |> Kernel.++(module_list)
-        |> Module.concat()
-        |> Code.ensure_compiled?()
-    end
-  end
-
-  defp has_extension_module?(extension, ["Ecto", "Schema"]), do: extension.ecto_schema?()
-  defp has_extension_module?(extension, ["Phoenix", "ControllerCallbacks"]), do: extension.phoenix_controller_callbacks?()
-  defp has_extension_module?(extension, ["Phoenix", "Messages"]), do: extension.phoenix_messages?()
-  defp has_extension_module?(extension, ["Phoenix", "Router"]), do: extension.phoenix_router?()
+  def has?(extension, ["Ecto", "Schema"]), do: extension.ecto_schema?()
+  def has?(extension, ["Phoenix", "ControllerCallbacks"]), do: extension.phoenix_controller_callbacks?()
+  def has?(extension, ["Phoenix", "Messages"]), do: extension.phoenix_messages?()
+  def has?(extension, ["Phoenix", "Router"]), do: extension.phoenix_router?()
 
   @doc """
   Checks whether an extension has a certain module that has a `__using__/1`
   macro.
-
-  This calls `has?/2` first, If a base extension module doesn't exist, or is
-  configured improperly, `Kernel.macro_exported?/3` will be used instead to
-  check if the module has a `__using__/1` macro.
   """
   @spec use?(atom(), [any()]) :: boolean()
   def use?(extension, module_list) do
     case has?(extension, module_list) do
-      true  ->
-        try do
-          use_extension_module?(extension, module_list)
-        rescue
-          # TODO: Remove or refactor by 1.1.0
-          _e in UndefinedFunctionError ->
-            IO.warn("#{inspect extension} has been configured improperly")
-
-            [extension]
-            |> Kernel.++(module_list)
-            |> Module.concat()
-            |> Kernel.macro_exported?(:__using__, 1)
-        end
-
-      false ->
-        false
+      true  -> use_extension_module?(extension, module_list)
+      false -> false
     end
   end
 
diff --git a/lib/pow/extension/config.ex b/lib/pow/extension/config.ex
index 655c91d4..a8f63d26 100644
--- a/lib/pow/extension/config.ex
+++ b/lib/pow/extension/config.ex
@@ -25,28 +25,4 @@ defmodule Pow.Extension.Config do
     |> Enum.filter(&Base.has?(&1, module_list))
     |> Enum.map(&Module.concat([&1] ++ module_list))
   end
-
-  # TODO: Remove by 1.1.0
-  @deprecated "Use `extension_modules/2` instead"
-  def discover_modules(config, module_list) do
-    config
-    |> extensions()
-    |> extension_modules(module_list)
-  end
-
-  # TODO: Remove by 1.1.0
-  @doc """
-  Returns a binary of the extension atom.
-
-  This is usually used to create extension namespaces for methods to be used
-  in shared modules.
-  """
-  @deprecated "Create the namespace directly in your module"
-  @spec underscore_extension(atom()) :: binary()
-  def underscore_extension(extension) do
-    extension
-    |> Module.split()
-    |> List.first()
-    |> Macro.underscore()
-  end
 end
diff --git a/lib/pow/extension/ecto/context/base.ex b/lib/pow/extension/ecto/context/base.ex
deleted file mode 100644
index 69dee98d..00000000
--- a/lib/pow/extension/ecto/context/base.ex
+++ /dev/null
@@ -1,15 +0,0 @@
-defmodule Pow.Extension.Ecto.Context.Base do
-  # TODO: Remove by 1.1.0
-  @moduledoc false
-  alias Pow.Ecto.Context
-
-  @doc false
-  defmacro __using__(_opts) do
-    quote do
-      IO.warn("use #{unquote(__MODULE__)} is deprecated, please use methods in #{Context} instead")
-
-      defdelegate user_schema_mod(config), to: Context
-      defdelegate repo(config), to: Context
-    end
-  end
-end
diff --git a/lib/pow/extension/phoenix/controllers/controller/base.ex b/lib/pow/extension/phoenix/controllers/controller/base.ex
index 3ad61f6c..621f2c52 100644
--- a/lib/pow/extension/phoenix/controllers/controller/base.ex
+++ b/lib/pow/extension/phoenix/controllers/controller/base.ex
@@ -10,21 +10,21 @@ defmodule Pow.Extension.Phoenix.Controller.Base do
         # ...
       end
   """
-  alias Pow.{Config, Phoenix.Controller}
+  alias Pow.Phoenix.Controller
 
   @doc false
   defmacro __using__(config) do
     quote do
       use Controller, unquote(config)
 
-      unquote(__MODULE__).__define_helper_methods__(unquote(config))
+      unquote(__MODULE__).__define_helper_methods__()
     end
   end
 
   @doc false
-  defmacro __define_helper_methods__(config) do
+  defmacro __define_helper_methods__() do
     quote do
-      @messages_fallback unquote(__MODULE__).__messages_fallback__(unquote(config), __MODULE__, __ENV__)
+      @messages_fallback unquote(__MODULE__).__messages_fallback__(__MODULE__)
 
       @doc false
       def extension_messages(conn), do: unquote(__MODULE__).__messages_module__(conn, @messages_fallback)
@@ -51,17 +51,4 @@ defmodule Pow.Extension.Phoenix.Controller.Base do
     |> Enum.reverse()
     |> Module.concat()
   end
-
-  # TODO: Remove config fallback by 1.1.0
-  def __messages_fallback__(config, module, env) do
-    case Config.get(config, :messages_backend_fallback) do
-      nil    ->
-        __messages_fallback__(module)
-
-      module ->
-        IO.warn("Passing `:messages_backend_fallback` is deprecated", Macro.Env.stacktrace(env))
-
-        module
-    end
-  end
 end
diff --git a/lib/pow/extension/phoenix/controllers/controller_callbacks/base.ex b/lib/pow/extension/phoenix/controllers/controller_callbacks/base.ex
index 833f853e..92dd0806 100644
--- a/lib/pow/extension/phoenix/controllers/controller_callbacks/base.ex
+++ b/lib/pow/extension/phoenix/controllers/controller_callbacks/base.ex
@@ -19,14 +19,14 @@ defmodule Pow.Extension.Phoenix.ControllerCallbacks.Base do
   @callback before_respond(atom(), atom(), any(), Config.t()) :: any()
 
   @doc false
-  defmacro __using__(config) do
+  defmacro __using__(_config) do
     quote do
       @behaviour unquote(__MODULE__)
 
       require Base
       require Controller
 
-      Base.__define_helper_methods__(unquote(config))
+      Base.__define_helper_methods__()
       Controller.__define_helper_methods__()
 
       @before_compile unquote(__MODULE__)
diff --git a/lib/pow/phoenix/html/bootstrap.ex b/lib/pow/phoenix/html/bootstrap.ex
deleted file mode 100644
index b9c1a123..00000000
--- a/lib/pow/phoenix/html/bootstrap.ex
+++ /dev/null
@@ -1,54 +0,0 @@
-defmodule Pow.Phoenix.HTML.Bootstrap do
-  # TODO: Remove module by 1.1.0 and only support Phoenix 1.4.0
-
-  @moduledoc """
-  Module that helps build HTML for Phoenix with Bootstrap CSS.
-  """
-  import Pow.Phoenix.HTML.FormTemplate, only: [inspect_key: 1]
-
-  @form_template EEx.compile_string(
-    """
-    <%%= form_for @changeset, @action, [as: :user], fn f -> %>
-      <%%= if @changeset.action do %>
-        <div class="alert alert-danger">
-          <p>Oops, something went wrong! Please check the errors below.</p>
-        </div>
-      <%% end %>
-    <%= for {label, input, error} <- inputs, input do %>
-      <div class="form-group">
-        <%= label %>
-        <%= input %>
-        <%= error %>
-      </div>
-    <% end %>
-      <div class="form-group">
-        <%%= submit <%= inspect button_label %>, class: "btn btn-primary" %>
-      </div>
-    <%% end %>
-    """)
-
-  @doc """
-  Renders a form.
-  """
-  @spec render_form(list(), binary()) :: Macro.t()
-  def render_form(inputs, button_label) do
-    inputs = for {type, key} <- inputs, do: input(type, key)
-
-    unquote(@form_template)
-  end
-
-  defp input(:text, key) do
-    {label(key), ~s(<%= text_input f, #{inspect_key(key)}, class: "form-control" %>), error(key)}
-  end
-  defp input(:password, key) do
-    {label(key), ~s(<%= password_input f, #{inspect_key(key)}, class: "form-control" %>), error(key)}
-  end
-
-  defp label(key) do
-    ~s(<%= label f, #{inspect_key(key)}, class: "control-label" %>)
-  end
-
-  defp error(key) do
-    ~s(<%= error_tag f, #{inspect_key(key)} %>)
-  end
-end
diff --git a/lib/pow/phoenix/html/form_template.ex b/lib/pow/phoenix/html/form_template.ex
index 93d98f22..cef04c74 100644
--- a/lib/pow/phoenix/html/form_template.ex
+++ b/lib/pow/phoenix/html/form_template.ex
@@ -1,11 +1,7 @@
 defmodule Pow.Phoenix.HTML.FormTemplate do
   @moduledoc """
   Module that can build user form templates for Phoenix.
-
-  For Phoenix 1.3, or bootstrap templates, `Pow.Phoenix.HTML.Bootstrap` can be
-  used.
   """
-  alias Pow.Phoenix.HTML.Bootstrap
 
   @template EEx.compile_string(
     """
@@ -32,24 +28,12 @@ defmodule Pow.Phoenix.HTML.FormTemplate do
   ## Options
 
     * `:button_label` - the submit button label, defaults to "Submit".
-    * `:bootstrap` - to render form as bootstrap, defaults to false with
-      phoenix 1.4 and true with phoenix 1.3.
   """
   @spec render(list(), Keyword.t()) :: Macro.t()
   def render(inputs, opts \\ []) do
     button_label = Keyword.get(opts, :button_label, "Submit")
 
-    case bootstrap?(opts) do
-      true -> Bootstrap.render_form(inputs, button_label)
-      _any -> render_form(inputs, button_label)
-    end
-  end
-
-  # TODO: Remove bootstrap support by 1.1.0 and only support Phoenix 1.4.0
-  defp bootstrap?(opts) do
-    bootstrap = Pow.dependency_vsn_match?(:phoenix, "~> 1.3.0")
-
-    Keyword.get(opts, :bootstrap, bootstrap)
+    render_form(inputs, button_label)
   end
 
   defp render_form(inputs, button_label) do
diff --git a/lib/pow/phoenix/router.ex b/lib/pow/phoenix/router.ex
index af5adefe..cf4414dc 100644
--- a/lib/pow/phoenix/router.ex
+++ b/lib/pow/phoenix/router.ex
@@ -201,13 +201,6 @@ defmodule Pow.Phoenix.Router do
     |> case do
       %{plug_opts: _, helper: _} = route ->
         any_matching_routes?(phoenix_routes, route, [:plug_opts, :helper])
-
-      # TODO: Remove this match by 1.1.0, and up requirement for Phoenix to minimum 1.4.7
-      %{opts: _, helper: _} = route ->
-        any_matching_routes?(phoenix_routes, route, [:opts, :helper])
-
-      _any ->
-        false
     end
   end
 
diff --git a/lib/pow/plug.ex b/lib/pow/plug.ex
index ffc432c3..3b802952 100644
--- a/lib/pow/plug.ex
+++ b/lib/pow/plug.ex
@@ -99,12 +99,6 @@ defmodule Pow.Plug do
     end
   end
 
-  # TODO: Remove by 1.1.0
-  @doc false
-  @deprecated "Use `delete/1` instead"
-  @spec clear_authenticated_user(Conn.t()) :: {:ok, Conn.t()}
-  def clear_authenticated_user(conn), do: {:ok, delete(conn)}
-
   @doc """
   Creates a changeset from the current authenticated user.
   """
@@ -172,12 +166,6 @@ defmodule Pow.Plug do
     {:error, changeset, conn}
   end
 
-  # TODO: Remove by 1.1.0
-  @doc false
-  @deprecated "Use `get_plug/1` instead"
-  @spec get_mod(Config.t()) :: atom()
-  def get_mod(config), do: get_plug(config)
-
   @spec get_plug(Config.t()) :: atom()
   def get_plug(config) do
     config[:plug] || no_plug_error()
diff --git a/lib/pow/plug/base.ex b/lib/pow/plug/base.ex
index a42ab570..26550324 100644
--- a/lib/pow/plug/base.ex
+++ b/lib/pow/plug/base.ex
@@ -98,11 +98,7 @@ defmodule Pow.Plug.Base do
         Conn.put_private(conn, @before_send_private_key, callbacks)
       end
 
-      defp put_plug(config) do
-        config
-        |> Config.put(:plug, __MODULE__)
-        |> Config.put(:mod, __MODULE__) # TODO: Remove by 1.1.0, this is only for backwards compability
-      end
+      defp put_plug(config), do: Config.put(config, :plug, __MODULE__)
 
       @doc """
       Calls `fetch/2` and assigns the current user to the conn.
@@ -154,27 +150,12 @@ defmodule Pow.Plug.Base do
 
   @spec store(Config.t()) :: {module(), Config.t()}
   def store(config) do
-    config
-    |> Config.get(:credentials_cache_store)
-    |> Kernel.||(fallback_store(config))
-    |> case do
+    case Config.get(config, :credentials_cache_store) do
       {store, store_config} -> {store, store_opts(config, store_config)}
       nil                   -> {CredentialsCache, store_opts(config)}
     end
   end
 
-  # TODO: Remove by 1.1.0
-  defp fallback_store(config) do
-    case Config.get(config, :session_store) do
-      nil ->
-        nil
-
-      value ->
-        IO.warn("use of `:session_store` config value is deprecated, use `:credentials_cache_store` instead")
-        value
-    end
-  end
-
   defp store_opts(config, store_config \\ []) do
     Keyword.put_new(store_config, :backend, Config.get(config, :cache_store_backend, EtsCache))
   end
diff --git a/lib/pow/plug/session.ex b/lib/pow/plug/session.ex
index 365d1f29..46ddc635 100644
--- a/lib/pow/plug/session.ex
+++ b/lib/pow/plug/session.ex
@@ -141,9 +141,9 @@ defmodule Pow.Plug.Session do
   defp fetch(conn, session_id, config) do
     {store, store_config} = store(config)
 
-    {session_id, store.get(store_config, session_id)}
-    |> convert_old_session_value()
-    |> handle_fetched_session_value(conn, config)
+    store_config
+    |> store.get(session_id)
+    |> renew_stale_session(session_id, conn, config)
   end
 
   @doc """
@@ -233,18 +233,10 @@ defmodule Pow.Plug.Session do
     end)
   end
 
-  # TODO: Remove by 1.1.0
-  defp convert_old_session_value({session_id, {user, timestamp}}) when is_number(timestamp), do: {session_id, {user, inserted_at: timestamp}}
-  defp convert_old_session_value(any), do: any
+  defp renew_stale_session(:not_found, _session_id, conn, _config), do: {conn, nil}
+  defp renew_stale_session({user, metadata}, session_id, conn, config) when is_list(metadata) do
+    conn = Conn.put_private(conn, :pow_session_metadata, metadata)
 
-  defp handle_fetched_session_value({_session_id, :not_found}, conn, _config), do: {conn, nil}
-  defp handle_fetched_session_value({session_id, {user, metadata}}, conn, config) when is_list(metadata) do
-    conn
-    |> Conn.put_private(:pow_session_metadata, metadata)
-    |> renew_stale_session(session_id, user, metadata, config)
-  end
-
-  defp renew_stale_session(conn, session_id, user, metadata, config) do
     metadata
     |> Keyword.get(:inserted_at)
     |> session_stale?(config)
diff --git a/lib/pow/store/backend/ets_cache.ex b/lib/pow/store/backend/ets_cache.ex
index 12f2ea42..315daec2 100644
--- a/lib/pow/store/backend/ets_cache.ex
+++ b/lib/pow/store/backend/ets_cache.ex
@@ -162,14 +162,4 @@ defmodule Pow.Store.Backend.EtsCache do
 
     Map.delete(invalidators, key)
   end
-
-  # TODO: Remove by 1.1.0
-  @deprecated "Use `put/2` instead"
-  @doc false
-  def put(config, key, value), do: put(config, {key, value})
-
-  # TODO: Remove by 1.1.0
-  @deprecated "Use `all/2` instead"
-  @doc false
-  def keys(config), do: all(config, :_)
 end
diff --git a/lib/pow/store/backend/mnesia_cache.ex b/lib/pow/store/backend/mnesia_cache.ex
index 93533c03..5306572b 100644
--- a/lib/pow/store/backend/mnesia_cache.ex
+++ b/lib/pow/store/backend/mnesia_cache.ex
@@ -97,12 +97,6 @@ defmodule Pow.Store.Backend.MnesiaCache do
 
   @spec start_link(Config.t()) :: GenServer.on_start()
   def start_link(config) do
-    # TODO: Remove by 1.1.0
-    case Config.get(config, :nodes) do
-      nil    -> :ok
-      _nodes -> IO.warn("use of `:nodes` config value for #{inspect unquote(__MODULE__)} is no longer used")
-    end
-
     GenServer.start_link(__MODULE__, config, name: __MODULE__)
   end
 
@@ -425,14 +419,6 @@ defmodule Pow.Store.Backend.MnesiaCache do
             |> unwrap()
             |> append_invalidator(invalidators, ttl, config)
 
-          # TODO: Remove by 1.1.0
-          {@mnesia_cache_tab, key, {_key, _value, _config, expire}}, invalidators when is_binary(key) and is_number(expire) ->
-            Logger.warn("[#{inspect __MODULE__}] Deleting old record #{inspect key}")
-
-            :mnesia.delete({@mnesia_cache_tab, key})
-
-            invalidators
-
           {@mnesia_cache_tab, key, _value}, invalidators ->
             Logger.warn("[#{inspect __MODULE__}] Found unexpected record #{inspect key}, please delete it")
 
@@ -462,14 +448,4 @@ defmodule Pow.Store.Backend.MnesiaCache do
   @spec raise_ttl_error :: no_return
   defp raise_ttl_error,
     do: Config.raise_error("`:ttl` configuration option is required for #{inspect(__MODULE__)}")
-
-  # TODO: Remove by 1.1.0
-  @deprecated "Use `put/2` instead"
-  @doc false
-  def put(config, key, value), do: put(config, {key, value})
-
-  # TODO: Remove by 1.1.0
-  @deprecated "Use `all/2` instead"
-  @doc false
-  def keys(config), do: all(config, :_)
 end
diff --git a/lib/pow/store/base.ex b/lib/pow/store/base.ex
index c9bf1749..89a9321c 100644
--- a/lib/pow/store/base.ex
+++ b/lib/pow/store/base.ex
@@ -16,7 +16,7 @@ defmodule Pow.Store.Base do
       end
   """
   alias Pow.Config
-  alias Pow.Store.Backend.{EtsCache, MnesiaCache, Base}
+  alias Pow.Store.Backend.{EtsCache, Base}
 
   @type key :: Base.key()
   @type record :: Base.record()
@@ -61,155 +61,33 @@ defmodule Pow.Store.Base do
       end
 
       defoverridable unquote(__MODULE__)
-
-      # TODO: Remove by 1.1.0
-      @doc false
-      def put(config, backend_config, key, value) do
-        config
-        |> merge_backend_config(backend_config)
-        |> put(key, value)
-      end
-
-      defp merge_backend_config(config, backend_config) do
-        backend_config = Keyword.take(backend_config, [:ttl, :namespace])
-
-        Keyword.merge(config, backend_config)
-      end
-
-      # TODO: Remove by 1.1.0
-      @doc false
-      def delete(config, backend_config, key) do
-        config
-        |> merge_backend_config(backend_config)
-        |> delete(key)
-      end
-
-      # TODO: Remove by 1.1.0
-      @doc false
-      def get(config, backend_config, key) do
-        config
-        |> merge_backend_config(backend_config)
-        |> get(key)
-      end
-
-      # TODO: Remove by 1.1.0
-      defoverridable put: 4, delete: 3, get: 3
     end
   end
 
   @spec put(Config.t(), Config.t(), record() | [record()]) :: :ok
   def put(config, backend_config, record_or_records) do
-    # TODO: Update by 1.1.0
-    backwards_compatible_call(store(config), :put, [backend_config, record_or_records])
+    store(config).put(backend_config, record_or_records)
   end
 
   @doc false
   @spec delete(Config.t(), Config.t(), key()) :: :ok
   def delete(config, backend_config, key) do
-    # TODO: Update by 1.1.0
-    backwards_compatible_call(store(config), :delete, [backend_config, key])
+    store(config).delete(backend_config, key)
   end
 
   @doc false
   @spec get(Config.t(), Config.t(), key()) :: any() | :not_found
   def get(config, backend_config, key) do
-    # TODO: Update by 1.1.0
-    backwards_compatible_call(store(config), :get, [backend_config, key])
+    store(config).get(backend_config, key)
   end
 
   @doc false
   @spec all(Config.t(), Config.t(), key_match()) :: [record()]
   def all(config, backend_config, key_match) do
-    # TODO: Update by 1.1.0
-    backwards_compatible_call(store(config), :all, [backend_config, key_match])
+    store(config).all(backend_config, key_match)
   end
 
   defp store(config) do
     Config.get(config, :backend, EtsCache)
   end
-
-  # TODO: Remove by 1.1.0
-  defp backwards_compatible_call(store, method, args) do
-    store
-    |> has_binary_keys?()
-    |> case do
-      false ->
-        apply(store, method, args)
-
-      true ->
-        IO.warn("binary key for backend stores is depecated, update `#{store}` to accept erlang terms instead")
-
-        case method do
-          :put    -> binary_key_put(store, args)
-          :get    -> binary_key_get(store, args)
-          :delete -> binary_key_delete(store, args)
-          :all    -> binary_key_all(store, args)
-        end
-    end
-  end
-
-  # TODO: Remove by 1.1.0
-  defp has_binary_keys?(store) when store in [EtsCache, MnesiaCache], do: false
-  defp has_binary_keys?(store) do
-    {:module, ^store} = Code.ensure_loaded(store)
-
-    not function_exported?(store, :all, 2)
-  end
-
-  # TODO: Remove by 1.1.0
-  defp binary_key_put(store, [backend_config, record_or_records]) do
-    record_or_records
-    |> List.wrap()
-    |> Enum.each(fn {key, value} ->
-      key = binary_key(key)
-
-      store.put(backend_config, key, value)
-    end)
-  end
-
-  # TODO: Remove by 1.1.0
-  defp binary_key_get(store, [backend_config, key]) do
-    key = binary_key(key)
-
-    store.get(backend_config, key)
-  end
-
-  # TODO: Remove by 1.1.0
-  defp binary_key_delete(store, [backend_config, key]) do
-    key = binary_key(key)
-
-    store.delete(backend_config, key)
-  end
-
-  # TODO: Remove by 1.1.0
-  defp binary_key_all(store, [backend_config, match_spec]) do
-    match_spec = :ets.match_spec_compile([{match_spec, [], [:"$_"]}])
-
-    backend_config
-    |> store.keys()
-    |> Enum.map(&:erlang.binary_to_term/1)
-    |> :ets.match_spec_run(match_spec)
-    |> Enum.map(&{&1, binary_key_get(store, [backend_config, &1])})
-  end
-
-  # TODO: Remove by 1.1.0
-  defp binary_key(key) do
-    key
-    |> List.wrap()
-    |> :erlang.term_to_binary()
-  end
-
-  # TODO: Remove by 1.1.0
-  @doc false
-  @deprecated "Use `put/3` instead"
-  def put(config, backend_config, key, value) do
-    put(config, backend_config, {key, value})
-  end
-
-  # TODO: Remove by 1.1.0
-  @doc false
-  @deprecated "Use `all/2` instead"
-  def keys(config, backend_config) do
-    store(config).keys(backend_config)
-  end
 end
diff --git a/lib/pow/store/credentials_cache.ex b/lib/pow/store/credentials_cache.ex
index 933c3c10..4e618f43 100644
--- a/lib/pow/store/credentials_cache.ex
+++ b/lib/pow/store/credentials_cache.ex
@@ -36,14 +36,11 @@ defmodule Pow.Store.CredentialsCache do
   List all existing sessions for the user fetched from the backend store.
   """
   @spec sessions(Config.t(), map()) :: [binary()]
-  def sessions(config, user), do: fetch_sessions(config, backend_config(config), user)
-
-  # TODO: Refactor by 1.1.0
-  defp fetch_sessions(config, backend_config, user) do
+  def sessions(config, user) do
     {struct, id} = user_to_struct_id!(user, [])
 
     config
-    |> Base.all(backend_config, [struct, :user, id, :session, :_])
+    |> Base.all(backend_config(config), [struct, :user, id, :session, :_])
     |> Enum.map(fn {[^struct, :user, ^id, :session, session_id], _value} ->
       session_id
     end)
@@ -102,10 +99,6 @@ defmodule Pow.Store.CredentialsCache do
         Base.delete(config, backend_config, session_id)
         Base.delete(config, backend_config, session_key)
 
-      # TODO: Remove by 1.1.0
-      {user, _metadata} when is_map(user) ->
-        Base.delete(config, backend_config, session_id)
-
       :not_found ->
         :ok
     end
@@ -122,10 +115,6 @@ defmodule Pow.Store.CredentialsCache do
     with {user_key, metadata} when is_list(user_key) <- Base.get(config, backend_config, session_id),
          user when is_map(user)                      <- Base.get(config, backend_config, user_key) do
       {user, metadata}
-    else
-      # TODO: Remove by 1.1.0
-      {user, metadata} when is_map(user) -> {user, metadata}
-      :not_found -> :not_found
     end
   end
 
@@ -174,20 +163,4 @@ defmodule Pow.Store.CredentialsCache do
 
   @spec raise_error(binary()) :: no_return()
   defp raise_error(message), do: raise message
-
-  # TODO: Remove by 1.1.0
-  @doc false
-  @deprecated "Use `users/2` or `sessions/2` instead"
-  def user_session_keys(config, backend_config, struct) do
-    config
-    |> Base.all(backend_config, [struct, :user, :_, :session, :_])
-    |> Enum.map(fn {key, _value} ->
-      key
-    end)
-  end
-
-  # TODO: Remove by 1.1.0
-  @doc false
-  @deprecated "Use `sessions/2` instead"
-  def sessions(config, backend_config, user), do: fetch_sessions(config, backend_config, user)
 end
diff --git a/mix.exs b/mix.exs
index e0226e0a..36497565 100644
--- a/mix.exs
+++ b/mix.exs
@@ -7,7 +7,7 @@ defmodule Pow.MixProject do
     [
       app: :pow,
       version: @version,
-      elixir: "~> 1.6",
+      elixir: "~> 1.7",
       elixirc_paths: elixirc_paths(Mix.env()),
       start_permanent: Mix.env() == :prod,
       compilers: [:phoenix] ++ Mix.compilers(),
@@ -35,8 +35,8 @@ defmodule Pow.MixProject do
 
   defp deps do
     [
-      {:ecto, "~> 2.2 or ~> 3.0"},
-      {:phoenix, "~> 1.3.0 or ~> 1.4.0"},
+      {:ecto, "~> 3.0"},
+      {:phoenix, "~> 1.4.7"},
       {:phoenix_html, ">= 2.0.0 and <= 3.0.0"},
       {:plug, ">= 1.5.0 and < 2.0.0", optional: true},
 
diff --git a/mix.lock b/mix.lock
index d5186a8c..c3dfe7af 100644
--- a/mix.lock
+++ b/mix.lock
@@ -3,25 +3,25 @@
   "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm", "4a0850c9be22a43af9920a71ab17c051f5f7d45c209e40269a1938832510e4d9"},
   "cowboy": {:hex, :cowboy, "2.7.0", "91ed100138a764355f43316b1d23d7ff6bdb0de4ea618cb5d8677c93a7a2f115", [:rebar3], [{:cowlib, "~> 2.8.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "04fd8c6a39edc6aaa9c26123009200fc61f92a3a94f3178c527b70b767c6e605"},
   "cowlib": {:hex, :cowlib, "2.8.0", "fd0ff1787db84ac415b8211573e9a30a3ebe71b5cbff7f720089972b2319c8a4", [:rebar3], [], "hexpm", "79f954a7021b302186a950a32869dbc185523d99d3e44ce430cd1f3289f41ed4"},
-  "credo": {:hex, :credo, "1.2.2", "f57faf60e0a12b0ba9fd4bad07966057fde162b33496c509b95b027993494aab", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8f2623cd8c895a6f4a55ef10f3fdf6a55a9ca7bef09676bd835551687bf8a740"},
+  "credo": {:hex, :credo, "1.2.3", "fbd11a840e45dc42e650401e16acd2a39dde080240b974e146cc65e81ada1cd3", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "3c07d51ff43748bb959752ede70e40557cdcb7d61615e47ae1e9e108e0b1ceec"},
   "db_connection": {:hex, :db_connection, "2.2.1", "caee17725495f5129cb7faebde001dc4406796f12a62b8949f4ac69315080566", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm", "2b02ece62d9f983fcd40954e443b7d9e6589664380e5546b2b9b523cd0fb59e1"},
   "decimal": {:hex, :decimal, "1.8.1", "a4ef3f5f3428bdbc0d35374029ffcf4ede8533536fa79896dd450168d9acdf3c", [:mix], [], "hexpm", "3cb154b00225ac687f6cbd4acc4b7960027c757a5152b369923ead9ddbca7aec"},
   "earmark": {:hex, :earmark, "1.4.3", "364ca2e9710f6bff494117dbbd53880d84bebb692dafc3a78eb50aa3183f2bfd", [:mix], [], "hexpm", "8cf8a291ebf1c7b9539e3cddb19e9cef066c2441b1640f13c34c1d3cfc825fec"},
-  "ecto": {:hex, :ecto, "3.3.2", "002aa428c752a8ee4bb65baa9d1041f0514d7435d2e21d58cb6aa69a1076721d", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "c651e3ea0919241da314f518404b84449c8569525c4d4cf0f3d16f1d5d0a560c"},
-  "ecto_sql": {:hex, :ecto_sql, "3.3.3", "7d8962d39f16181c1df1bbd0f64aa392bd9ce0b9f8ff5ff21d43dca3d624eee7", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.4 or ~> 3.3.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.3.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3d5b8e14836d930448d79ab6ac325501c3c62caed83c34791d5af77718766795"},
+  "ecto": {:hex, :ecto, "3.3.4", "95b05c82ae91361475e5491c9f3ac47632f940b3f92ae3988ac1aad04989c5bb", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "9b96cbb83a94713731461ea48521b178b0e3863d310a39a3948c807266eebd69"},
+  "ecto_sql": {:hex, :ecto_sql, "3.3.4", "aa18af12eb875fbcda2f75e608b3bd534ebf020fc4f6448e4672fcdcbb081244", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.4 or ~> 3.3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.3.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5eccbdbf92e3c6f213007a82d5dbba4cd9bb659d1a21331f89f408e4c0efd7a8"},
   "ex_doc": {:hex, :ex_doc, "0.21.3", "857ec876b35a587c5d9148a2512e952e24c24345552259464b98bfbb883c7b42", [:mix], [{:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "0db1ee8d1547ab4877c5b5dffc6604ef9454e189928d5ba8967d4a58a801f161"},
   "jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fdf843bca858203ae1de16da2ee206f53416bbda5dc8c9e78f43243de4bc3afe"},
   "makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "a10c6eb62cca416019663129699769f0c2ccf39428b3bb3c0cb38c718a0c186d"},
   "makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "d4b316c7222a85bbaa2fd7c6e90e37e953257ad196dc229505137c5e505e9eff"},
   "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm", "6cbe761d6a0ca5a31a0931bf4c63204bceb64538e664a8ecf784a9a6f3b875f1"},
   "nimble_parsec": {:hex, :nimble_parsec, "0.5.3", "def21c10a9ed70ce22754fdeea0810dafd53c2db3219a0cd54cf5526377af1c6", [:mix], [], "hexpm", "589b5af56f4afca65217a1f3eb3fee7e79b09c40c742fddc1c312b3ac0b3399f"},
-  "phoenix": {:hex, :phoenix, "1.4.13", "67271ad69b51f3719354604f4a3f968f83aa61c19199343656c9caee057ff3b8", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.8.1 or ~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ab765a0feddb81fc62e2116c827b5f068df85159c162bee760745276ad7ddc1b"},
+  "phoenix": {:hex, :phoenix, "1.4.15", "5c39c330f46a33d752c6feceb25629ee8e62a158b997fea62bca59a59b28e3ea", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.8.1 or ~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fd649bf11a76e42366096dc25737f89e8d4adedcbba6e969ae97f349f3cde5e7"},
   "phoenix_ecto": {:hex, :phoenix_ecto, "4.1.0", "a044d0756d0464c5a541b4a0bf4bcaf89bffcaf92468862408290682c73ae50d", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "c5e666a341ff104d0399d8f0e4ff094559b2fde13a5985d4cb5023b2c2ac558b"},
   "phoenix_html": {:hex, :phoenix_html, "2.14.0", "d8c6bc28acc8e65f8ea0080ee05aa13d912c8758699283b8d3427b655aabe284", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "b0bb30eda478a06dbfbe96728061a93833db3861a49ccb516f839ecb08493fbb"},
   "phoenix_pubsub": {:hex, :phoenix_pubsub, "1.1.2", "496c303bdf1b2e98a9d26e89af5bba3ab487ba3a3735f74bf1f4064d2a845a3e", [:mix], [], "hexpm", "1f13f9f0f3e769a667a6b6828d29dec37497a082d195cc52dbef401a9b69bf38"},
   "plug": {:hex, :plug, "1.9.0", "8d7c4e26962283ff9f8f3347bd73838e2413fbc38b7bb5467d5924f68f3a5a4a", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "9902eda2c52ada2a096434682e99a2493f5d06a94d6ac6bcfff9805f952350f1"},
   "plug_cowboy": {:hex, :plug_cowboy, "2.1.2", "8b0addb5908c5238fac38e442e81b6fcd32788eaa03246b4d55d147c47c5805e", [:mix], [{:cowboy, "~> 2.5", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "7d722581ce865a237e14da6d946f92704101740a256bd13ec91e63c0b122fc70"},
-  "plug_crypto": {:hex, :plug_crypto, "1.1.0", "854843d59062bf104ffe48fd92ad25a26fa3cc47558a13dd14c3025dc987542e", [:mix], [], "hexpm", "aef0a3aef2e4cda1c50b33cb25a56575117c9b25caaec8a7eb2dd7ce6ce13de5"},
+  "plug_crypto": {:hex, :plug_crypto, "1.1.2", "bdd187572cc26dbd95b87136290425f2b580a116d3fb1f564216918c9730d227", [:mix], [], "hexpm", "6b8b608f895b6ffcfad49c37c7883e8df98ae19c6a28113b02aa1e9c5b22d6b5"},
   "postgrex": {:hex, :postgrex, "0.15.3", "5806baa8a19a68c4d07c7a624ccdb9b57e89cbc573f1b98099e3741214746ae4", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "4737ce62a31747b4c63c12b20c62307e51bb4fcd730ca0c32c280991e0606c90"},
   "ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm", "451d8527787df716d99dc36162fca05934915db0b6141bbdac2ea8d3c7afc7d7"},
   "telemetry": {:hex, :telemetry, "0.4.1", "ae2718484892448a24470e6aa341bc847c3277bfb8d4e9289f7474d752c09c7f", [:rebar3], [], "hexpm", "4738382e36a0a9a2b6e25d67c960e40e1a2c95560b9f936d8e29de8cd858480f"},
diff --git a/test/extensions/persistent_session/plug/cookie_test.exs b/test/extensions/persistent_session/plug/cookie_test.exs
index 68727be8..235a0fbc 100644
--- a/test/extensions/persistent_session/plug/cookie_test.exs
+++ b/test/extensions/persistent_session/plug/cookie_test.exs
@@ -24,7 +24,7 @@ defmodule PowPersistentSession.Plug.CookieTest do
 
   test "call/2 sets pow_persistent_session plug in conn", %{conn: conn, config: config} do
     conn            = run_plug(conn)
-    expected_config = [mod: Session, plug: Session] ++ config
+    expected_config = [plug: Session] ++ config
 
     assert {Cookie, ^expected_config} = conn.private[:pow_persistent_session]
     refute conn.resp_cookies[@cookie_key]
@@ -221,39 +221,6 @@ defmodule PowPersistentSession.Plug.CookieTest do
     end
   end
 
-  # TODO: Remove by 1.1.0
-  test "call/2 is backwards-compatible with just user fetch clause", %{conn: conn, ets: ets} do
-    user = %User{id: 1}
-    id   = store_in_cache(conn, "test", [id: user.id], backend: ets)
-    conn =
-      conn
-      |> persistent_cookie(@cookie_key, id)
-      |> run_plug()
-
-    assert Plug.current_user(conn) == user
-    assert %{value: new_id, max_age: @max_age, path: "/"} = conn.resp_cookies[@cookie_key]
-    refute new_id == id
-    assert get_from_cache(conn, id, backend: ets) == :not_found
-    assert get_from_cache(conn, new_id, backend: ets) == {[id: 1], []}
-  end
-
-  # TODO: Remove by 1.1.0
-  test "call/2 is backwards-compatible with `:session_fingerprint` metadata", %{conn: conn, ets: ets} do
-    user = %User{id: 1}
-    id   = store_in_cache(conn, "test", {[id: user.id], session_fingerprint: "fingerprint"}, backend: ets)
-    conn =
-      conn
-      |> persistent_cookie(@cookie_key, id)
-      |> run_plug()
-
-    assert Plug.current_user(conn) == user
-    assert %{value: new_id, max_age: @max_age, path: "/"} = conn.resp_cookies[@cookie_key]
-    refute new_id == id
-    assert get_from_cache(conn, id, backend: ets) == :not_found
-    assert get_from_cache(conn, new_id, backend: ets) == {[id: 1], session_metadata: [fingerprint: "fingerprint"]}
-    assert conn.private[:pow_session_metadata][:fingerprint] == "fingerprint"
-  end
-
   test "create/3 with custom TTL", %{conn: conn, config: config} do
     config = Keyword.put(config, :persistent_session_ttl, 1000)
     conn   =
diff --git a/test/mix/tasks/ecto/pow.ecto.install_test.exs b/test/mix/tasks/ecto/pow.ecto.install_test.exs
index 5d681fff..48f61617 100644
--- a/test/mix/tasks/ecto/pow.ecto.install_test.exs
+++ b/test/mix/tasks/ecto/pow.ecto.install_test.exs
@@ -90,7 +90,7 @@ defmodule Mix.Tasks.Pow.Ecto.InstallTest do
 
       Mix.Project.in_project(:missing_top_level_ecto_dep, ".", fn _ ->
         # Insurance that we do test for top level ecto inclusion
-        assert Enum.any?(deps(), fn
+        assert Enum.any?(Mix.Dep.load_on_environment([]), fn
           %{app: :ecto_sql} -> true
           _ -> false
         end), "Ecto not loaded by dependency"
@@ -118,12 +118,4 @@ defmodule Mix.Tasks.Pow.Ecto.InstallTest do
       end)
     end
   end
-
-  # TODO: Refactor to just use Elixir 1.7 or higher by Pow 1.1.0
-  defp deps do
-    case Kernel.function_exported?(Mix.Dep, :load_on_environment, 1) do
-     true -> apply(Mix.Dep, :load_on_environment, [[]])
-     false -> apply(Mix.Dep, :loaded, [[]])
-    end
-  end
 end
diff --git a/test/mix/tasks/phoenix/pow.phoenix.install_test.exs b/test/mix/tasks/phoenix/pow.phoenix.install_test.exs
index fa48a801..44a04352 100644
--- a/test/mix/tasks/phoenix/pow.phoenix.install_test.exs
+++ b/test/mix/tasks/phoenix/pow.phoenix.install_test.exs
@@ -106,7 +106,7 @@ defmodule Mix.Tasks.Pow.Phoenix.InstallTest do
 
       Mix.Project.in_project(:missing_top_level_phoenix_dep, ".", fn _ ->
         # Insurance that we do test for top level phoenix inclusion
-        assert Enum.any?(deps(), fn
+        assert Enum.any?(Mix.Dep.load_on_environment([]), fn
           %{app: :phoenix} -> true
           _ -> false
         end), "Phoenix not loaded by dependency"
@@ -207,12 +207,4 @@ defmodule Mix.Tasks.Pow.Phoenix.InstallTest do
       end)
     end)
   end
-
-  # TODO: Refactor to just use Elixir 1.7 or higher by Pow 1.1.0
-  defp deps do
-    case Kernel.function_exported?(Mix.Dep, :load_on_environment, 1) do
-     true -> apply(Mix.Dep, :load_on_environment, [[]])
-     false -> apply(Mix.Dep, :loaded, [[]])
-    end
-  end
 end
diff --git a/test/pow/ecto/schema/changeset_test.exs b/test/pow/ecto/schema/changeset_test.exs
index 13c88a62..878ed5cb 100644
--- a/test/pow/ecto/schema/changeset_test.exs
+++ b/test/pow/ecto/schema/changeset_test.exs
@@ -184,24 +184,6 @@ defmodule Pow.Ecto.Schema.ChangesetTest do
       assert changeset.errors[:password_hash] == {"can't be blank", [validation: :required]}
     end
 
-    # TODO: Remove by 1.1.0
-    test "handle `confirm_password` conversion" do
-      params =
-        @valid_params
-        |> Map.delete("password_confirmation")
-        |> Map.put("confirm_password", "secret1234")
-      changeset = User.changeset(%User{}, params)
-
-      assert changeset.valid?
-
-      params    = Map.put(params, "confirm_password", "invalid")
-      changeset = User.changeset(%User{}, params)
-
-      refute changeset.valid?
-      assert changeset.errors[:confirm_password] == {"does not match confirmation", [validation: :confirmation]}
-      refute changeset.errors[:password_confirmation]
-    end
-
     test "can use custom password hash methods" do
       password_hash = &(&1 <> "123")
       password_verify = &(&1 == &2 <> "123")
diff --git a/test/pow/phoenix/html/form_template_test.exs b/test/pow/phoenix/html/form_template_test.exs
index d69e9f1c..76707dc1 100644
--- a/test/pow/phoenix/html/form_template_test.exs
+++ b/test/pow/phoenix/html/form_template_test.exs
@@ -19,20 +19,4 @@ defmodule Pow.Phoenix.HTML.FormTemplateTest do
     assert html =~ "<%= password_input f, :password %>"
     assert html =~ "<%= error_tag f, :password %>"
   end
-
-  test "render/2 with bootstrap" do
-    html = FormTemplate.render([
-      {:text, {:changeset, :pow_user_id_field}},
-      {:password, :password},
-      {:password, :password_confirmation}
-    ], bootstrap: true)
-
-    assert html =~ "<div class=\"form-group\">"
-    assert html =~ "<%= label f, Pow.Ecto.Schema.user_id_field(@changeset), class: \"control-label\" %>"
-    assert html =~ "<%= text_input f, Pow.Ecto.Schema.user_id_field(@changeset), class: \"form-control\" %>"
-    assert html =~ "<%= error_tag f, Pow.Ecto.Schema.user_id_field(@changeset) %>"
-    assert html =~ "<%= label f, :password, class: \"control-label\" %>"
-    assert html =~ "<%= password_input f, :password, class: \"form-control\" %>"
-    assert html =~ "<%= error_tag f, :password %>"
-  end
 end
diff --git a/test/pow/plug/session_test.exs b/test/pow/plug/session_test.exs
index d0b89cea..e3087621 100644
--- a/test/pow/plug/session_test.exs
+++ b/test/pow/plug/session_test.exs
@@ -26,7 +26,7 @@ defmodule Pow.Plug.SessionTest do
 
   test "call/2 sets plug in :pow_config", %{conn: conn} do
     conn = run_plug(conn)
-    expected_config = [mod: Session, plug: Session] ++ @default_opts
+    expected_config = [plug: Session] ++ @default_opts
 
     assert is_nil(conn.assigns[:current_user])
     assert conn.private[:pow_config] == expected_config
@@ -230,29 +230,6 @@ defmodule Pow.Plug.SessionTest do
     assert conn.assigns[:current_user] == @user
   end
 
-  # TODO: Remove by 1.1.0
-  test "backwards compatible", %{conn: conn} do
-    ttl             = 100
-    config          = Keyword.put(@default_opts, :session_ttl_renewal, ttl)
-    stale_timestamp = :os.system_time(:millisecond) - ttl - 1
-    session_id      = sign_token("token")
-
-    @store_config
-    |> Keyword.put(:namespace, "credentials")
-    |> EtsCacheMock.put({"token", {@user, stale_timestamp}})
-
-    conn =
-      conn
-      |> Conn.fetch_session()
-      |> Conn.put_session(config[:session_key], session_id)
-      |> run_plug(config)
-
-    assert new_session_id = get_session_id(conn)
-    assert new_session_id != session_id
-
-    assert conn.assigns[:current_user] == @user
-  end
-
   describe "create/2" do
     test "deletes existing and creates new session id", %{conn: new_conn} do
       conn =
diff --git a/test/pow/store/backend/ets_cache_test.exs b/test/pow/store/backend/ets_cache_test.exs
index 07113ba0..a282f1dc 100644
--- a/test/pow/store/backend/ets_cache_test.exs
+++ b/test/pow/store/backend/ets_cache_test.exs
@@ -66,11 +66,4 @@ defmodule Pow.Store.Backend.EtsCacheTest do
     assert EtsCache.get(config, "key1") == :not_found
     assert EtsCache.get(config, "key2") == :not_found
   end
-
-  # TODO: Remove by 1.1.0
-  test "backwards compatible" do
-    assert EtsCache.put(@default_config, "key", "value") == :ok
-    :timer.sleep(50)
-    assert EtsCache.keys(@default_config) == [{"key", "value"}]
-  end
 end
diff --git a/test/pow/store/backend/mnesia_cache_test.exs b/test/pow/store/backend/mnesia_cache_test.exs
index 07087e8b..84d14ec9 100644
--- a/test/pow/store/backend/mnesia_cache_test.exs
+++ b/test/pow/store/backend/mnesia_cache_test.exs
@@ -112,13 +112,6 @@ defmodule Pow.Store.Backend.MnesiaCacheTest do
       :timer.sleep(50)
       assert MnesiaCache.get(config, "key") == :not_found
     end
-
-    # TODO: Remove by 1.1.0
-    test "backwards compatible" do
-      assert MnesiaCache.put(@default_config, "key", "value") == :ok
-      :timer.sleep(50)
-      assert MnesiaCache.keys(@default_config) == [{"key", "value"}]
-    end
   end
 
   defp start(config) do
@@ -334,33 +327,4 @@ defmodule Pow.Store.Backend.MnesiaCacheTest do
     true = :rpc.call(node_a, Node, :connect, [node_b])
     :timer.sleep(500)
   end
-
-  # TODO: Remove by 1.1.0
-  describe "backwards compatible" do
-    setup do
-      :mnesia.kill()
-
-      File.rm_rf!("tmp/mnesia")
-      File.mkdir_p!("tmp/mnesia")
-
-      :ok
-    end
-
-    test "removes old entries" do
-      :ok = :mnesia.start()
-      {:atomic, :ok} = :mnesia.change_table_copy_type(:schema, node(), :disc_copies)
-      {:atomic, :ok} = :mnesia.create_table(MnesiaCache, type: :set, disc_copies: [node()])
-      :ok = :mnesia.wait_for_tables([MnesiaCache], :timer.seconds(15))
-
-      key = "#{@default_config[:namespace]}:key1"
-
-      :ok = :mnesia.dirty_write({MnesiaCache, key, {"key1", "test", @default_config, :os.system_time(:millisecond) + 100}})
-
-      :stopped = :mnesia.stop()
-
-      start(@default_config)
-
-      assert :mnesia.dirty_read({MnesiaCache, key}) == []
-    end
-  end
 end
diff --git a/test/pow/store/base_test.exs b/test/pow/store/base_test.exs
index 80f9e6e6..4353eaae 100644
--- a/test/pow/store/base_test.exs
+++ b/test/pow/store/base_test.exs
@@ -74,23 +74,4 @@ defmodule Pow.Store.BaseTest do
       "#{Pow.Config.get(config, :namespace, "cache")}:#{key}"
     end
   end
-
-  # TODO: Remove by 1.1.0
-  test "backwards compatible with binary keys support" do
-    config = [backend: BackwardsCompabilityMock]
-
-    assert BaseMock.put(config, [BackwardsCompabilityMock, :id, 2], :value) == :ok
-    binary_key = "default_namespace:#{:erlang.term_to_binary([BackwardsCompabilityMock, :id, 2])}"
-    assert_received {:put, ^binary_key, :value}
-
-    assert BaseMock.get(config, [BackwardsCompabilityMock, :id, 2]) == :value
-    assert_received {:get, ^binary_key}
-
-    assert BaseMock.delete(config, [BackwardsCompabilityMock, :id, 2]) == :ok
-    assert_received {:delete, ^binary_key}
-
-    assert BaseMock.all(config, [BackwardsCompabilityMock | :_]) == [{[BackwardsCompabilityMock, :id, 2], :value}]
-    assert BaseMock.all(config, [BackwardsCompabilityMock, :id, :_]) == [{[BackwardsCompabilityMock, :id, 2], :value}]
-    assert BaseMock.all(config, [BackwardsCompabilityMock, :id, 3]) == []
-  end
 end
diff --git a/test/pow/store/credentials_cache_test.exs b/test/pow/store/credentials_cache_test.exs
index 58cab840..a429e1f1 100644
--- a/test/pow/store/credentials_cache_test.exs
+++ b/test/pow/store/credentials_cache_test.exs
@@ -96,29 +96,6 @@ defmodule Pow.Store.CredentialsCacheTest do
     assert ets.get(@backend_config, [CompositePrimaryFieldsUser, :user, [another_id: 2, some_id: 1]]) == user
   end
 
-  # TODO: Remove by 1.1.0
-  test "backwards compatible", %{ets: ets} do
-    user_1 = %User{id: 1}
-    timestamp = :os.system_time(:millisecond)
-
-    ets.put(@backend_config, {"key_1", {user_1, inserted_at: timestamp}})
-
-    assert CredentialsCache.get(@config, @backend_config, "key_1") == {user_1, inserted_at: timestamp}
-    assert CredentialsCache.delete(@config, @backend_config, "key_1") == :ok
-    assert CredentialsCache.get(@config, @backend_config, "key_1") == :not_found
-
-    assert CredentialsCache.user_session_keys(@config, @backend_config, User) == []
-
-    user_2 = %UsernameUser{id: 1}
-
-    CredentialsCache.put(@config, @backend_config, "key_1", {user_1, a: 1})
-    CredentialsCache.put(@config, @backend_config, "key_2", {user_1, a: 1})
-    CredentialsCache.put(@config, @backend_config, "key_3", {user_2, a: 1})
-
-    assert CredentialsCache.user_session_keys(@config, @backend_config, User) == [[Pow.Test.Ecto.Users.User, :user, 1, :session, "key_1"], [Pow.Test.Ecto.Users.User, :user, 1, :session, "key_2"]]
-    assert CredentialsCache.user_session_keys(@config, @backend_config, UsernameUser) == [[Pow.Test.Ecto.Users.UsernameUser, :user, 1, :session, "key_3"]]
-  end
-
   describe "with EtsCache backend" do
     setup do
       start_supervised!({EtsCache, []})