{"id":13508184,"url":"https://github.com/britton-jb/sentinel","last_synced_at":"2025-04-13T08:40:36.288Z","repository":{"id":54452407,"uuid":"50638633","full_name":"britton-jb/sentinel","owner":"britton-jb","description":"DEPRECATED - Phoenix Authentication library that wraps Guardian for extra functionality","archived":false,"fork":false,"pushed_at":"2017-12-30T15:29:59.000Z","size":349,"stargazers_count":106,"open_issues_count":16,"forks_count":19,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-27T00:13:31.395Z","etag":null,"topics":["authentication","elixir","guardian","phoenix-framework","ueberauth"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/britton-jb.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-01-29T04:59:44.000Z","updated_at":"2024-04-15T23:04:35.000Z","dependencies_parsed_at":"2022-08-13T16:10:19.189Z","dependency_job_id":null,"html_url":"https://github.com/britton-jb/sentinel","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/britton-jb%2Fsentinel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/britton-jb%2Fsentinel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/britton-jb%2Fsentinel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/britton-jb%2Fsentinel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/britton-jb","download_url":"https://codeload.github.com/britton-jb/sentinel/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248685899,"owners_count":21145384,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","elixir","guardian","phoenix-framework","ueberauth"],"created_at":"2024-08-01T02:00:49.377Z","updated_at":"2025-04-13T08:40:36.258Z","avatar_url":"https://github.com/britton-jb.png","language":"Elixir","funding_links":[],"categories":["Framework Components"],"sub_categories":[],"readme":"# Sentinel\n[![Build Status](https://travis-ci.org/britton-jb/sentinel.svg?branch=master)](https://travis-ci.org/britton-jb/sentinel)\n\n## Note\nCurrently master (this readme) and the latest hex release have diverged due\nto poor planning on my part while working on the next version of\nSentinel. It also currently interacts poorly with the new directory\nstructure of Phoenix 1.3. I'm currently working on an update to remedy\nthis, but cannot promise it will be released soon.\n\nIf you'd like to assist in developing the latest version of Sentinel\nplease reach out to me.\n\nThings I wish [Guardian](https://github.com/ueberauth/guardian) included\nout of the box, like [Ueberauth](\nhttps://github.com/ueberauth/ueberauth) integration, routing,\ninvitation flow, confirmation emails, and, password reset emails.\nIt's just a thin wrapper on Guardian but everybody shouldn't have to roll\nthis themselves when they build stuff.\n\nI do my best to follow [semantic versioning](http://semver.org/) with this\nrepo.\n\nSuggestions? See the [Contributing/Want something new?](#contributingwant-something-new)\nsection.\n\nWant an example app? Checkout [Sentinel\nExample](https://github.com/britton-jb/sentinel_example).\n\n## Installation\n\nHere's how to add it to your Phoenix project, and things you need to\nsetup:\n\n``` elixir\n# mix.exs\n\n# Requires Elixir ~\u003e 1.3\n\ndefp deps do\n  # ...\n  {:sentinel, \"~\u003e 2.0\"},\n  {:guardian_db, \"~\u003e 0.8.0\"}, # If you'd like to database back your tokens, and prevent replayability\n  # ...\nend\n```\n\n### Configure Guardian\nExample config:\n\n``` elixir\n# config/config.exs\n\nconfig :guardian, Guardian,\n  allowed_algos: [\"HS512\"], # optional\n  verify_module: Guardian.JWT,  # optional\n  issuer: \"MyApp\",\n  ttl: { 30, :days },\n  verify_issuer: true, # optional\n  secret_key: \"guardian_sekret\",\n  serializer: Sentinel.GuardianSerializer,\n  hooks: GuardianDb # optional if using guardiandb\n```\n\n[More info](https://github.com/ueberauth/guardian#installation)\n\n#### Optionally Configure GuardianDb\n``` elixir\nconfig :guardian_db, GuardianDb,\n  repo: MyApp.Repo\n```\n\nThe install task which ships with Sentinel, which you will run later in\nthis walkthrough, creates the migration for the GuardianDb tokens.\n\n### Configure Sentinel\n``` elixir\n# config/config.exs\n\nconfig :sentinel,\n  app_name: \"Test App\",\n  user_model: Sentinel.User, # should be your generated model\n  send_address: \"test@example.com\",\n  crypto_provider: Comeonin.Bcrypt,\n  repo: Sentinel.TestRepo,\n  ecto_repos: [Sentinel.TestRepo],\n  auth_handler: Sentinel.AuthHandler,\n  layout_view: MyApp.Layout, # your layout\n  layout: :app,\n  views: %{\n    email: Sentinel.EmailView, # your email view (optional)\n    error: Sentinel.ErrorView, # your error view (optional)\n    password: Sentinel.PasswordView, # your password view (optional)\n    session: Sentinel.SessionView, # your session view (optional)\n    shared: Sentinel.SharedView, # your shared view (optional)\n    user: Sentinel.UserView # your user view (optional)\n  },\n  router: Sentinel.TestRouter, # your router\n  endpoint: Sentinel.Endpoint, # your endpoint\n  invitable: true,\n  invitation_registration_url: \"http://localhost:4000\", # for api usage only\n  confirmable: :optional,\n  confirmable_redirect_url: \"http://localhost:4000\", # for api usage only\n  password_reset_url: \"http://localhost:4000\", # for api usage only\n  send_emails: true,\n  user_model_validator: {MyApp.Accounts, :custom_changeset}, # your custom validator\n  registrator_callback: {MyApp.Accounts, :setup} # your callback function (optional)\n```\n\nSee `config/test.exs` for an example of configuring Sentinel\n\n`invitation_registration_url`, `confirmable_redirect_url`, and\n`password_reset_url` are three configuration settings that must be set\nif using the API routing in order to have some place to be directed to\nafter completing the relevant server action. In most cases I'd\nanticipate this being a page of a SPA, Mobile App, or other client\ninterface.\n\n### Configure Ueberauth\n``` elixir\n# config/config.exs\n\nconfig :ueberauth, Ueberauth,\n  providers: [\n    identity: {\n      Ueberauth.Strategy.Identity,\n      [\n        param_nesting: \"user\",\n        callback_methods: [\"POST\"]\n      ]\n    },\n  ]\n```\n\nCurrently Sentinel is designed in such a way that the Identity Strategy\nmust set `params_nesting` as `\"user\"`. This is something that I would\nlike to modify in future versions.\n\nYou'd also want to add other Ueberauth provider configurations at this\npoint, as described in the respective provider documentation.\n\n### Configure Bamboo Mailer\n``` elixir\n# config/config.exs\n\nconfig :sentinel, Sentinel.Mailer,\n  adapter: Bamboo.TestAdapter\n```\n\n[More info](https://github.com/thoughtbot/bamboo/)\n\n\n### Run the install Mix task\nCreate the database using Ecto if it doesn't yet exist.\n\n``` elixir\nmix sentinel.install\n```\n\nThis will create a user model if it doesn't already exist, add a\nmigration for GuardianDb migration, and add a migration for Ueberauth\nprovider credentials.\n\nYou will want to delete the GuardianDb migration if you're choosing not\nto use it.\n\nCurrently the install task outputs the following warning:\n\n```\nwarning: the :datetime type in migrations is deprecated, please use\n:utc_datetime or :naive_datetime instead\n```\n\nThis is due to the fact that Phoenix's generators don't appear to\nsupport `utc_datetime` being passed in. Please modify the generated\nmigration accordingly. Phoenix's generators also appear to not support\nsetting `null: false` with the migration generator, so you will want\nto set that in the migration for the user email as well.\n\n### Mount the desired routes\n```elixir\ndefmodule MyApp.Router do\n  use MyApp.Web, :router\n  require Sentinel\n\n  # ...\n  # ...\n\n  scope \"/\" do\n    # pipe_through, browser, api, or your own pipeline depending on your needs\n    # pipe_through :browser\n    # pipe_through :api\n    Sentinel.mount_ueberauth\n  end\n\n  scope \"/\" do\n    pipe_through :browser\n    Sentinel.mount_html\n  end\n\n  scope \"/api\", as: :api do\n    pipe_through :api\n    Sentinel.mount_api\n  end\nend\n```\n\nBe aware that the routes mounted by the macro `Sentinel.mount_ueberauth`\nmust be mounted on the root of your URL, due to the way Ueberauth\nmatches against routes.\nTo illustrate, the route for requesting a given provider must be\n`example.com/auth/:provider`. If it is `example.com/api/auth/:provider`\nUeberauth will not properly register requests.\n\n**NOTE:** You will run into an issue here if you set the scope to\n`scope \"/\", MyApp.Router do`.\n\nThe generated routes are shown in `/lib/sentinel.ex`:\n\n#### Sentinel.mount_ueberauth\n\nmethod | path | description\n-------|------|------------\nGET | /login | Login page\nGET | /logout | Request logout\nGET | /auth/session/new | Login page\nPOST | /auth/session | Request authentication\nDELETE | /auth/session | Request logout\nGET | /auth/:provider | Request specific Ueberauth provider login page\nGET | /auth/:provider/callback | Callback URL for Ueberauth provider\nPOST | /auth/:provider/callback | Callback URL for Ueberauth provider\n\n#### Sentinel.mount_html\n\nmethod | path | description\n-------|------|------------\nGET | /user/new | New user page\nPOST | /user | Create new user\nGET | /user/:id/invited | Invited user registration form\nPUT | /user/:id/invited | Complete user invitation flow\nGET | /user/confirmation_instructions | Request resending confirmation instructions page\nPOST | /user/confirmation_instructions | Request confirmation instructions email\nGET | /user/confirmation | Confirm user email address from email\nGET | /password/new | Forgot password page\nPOST | /password/new | Request password reset email\nGET | /password/edit | Password reset page\nPUT | /password | Reset password\nGET | /account | Basic user edit page\nPUT | /account | Update user information\n\n#### Sentinel.mount_api\n\nmethod | path | description\n-------|------|------------\nGET | /user/:id/invited | Redirect user from email link to invited user registration form\nPUT | /user/:id/invited | Complete user invitation flow\nGET | /user/confirmation_instructions | Request resending confirmation instructions\nGET | /user/confirmation | Confirm user email address from email\nGET | /password/new | Request password reset email\nGET | /password/edit | Request password reset page from email\nPUT | /password | Reset password\nGET | /account | Requests user account\nPUT | /account | Update user information\nPUT | /account/password | Update user password separately\n\n## Overriding the Defaults\n\n### Confirmable\nBy default users are not required to confirm their account to login. If\nyou'd like to require confirmation set the `confirmable` configuration\nfield to `:required`. If you don't want confirmation emails sent, set\nthe field to `:false`. The default is `:optional`.\n\n### Invitable\nBy default, users are required to have a password upon creation. If\nyou'd like to enable users to create accounts on behalf of other users\nwithout a password you can set the `invitable` configuration field to\n`true`. This will result in the user being sent an email with a link to\n`GET users/:id/invited`, which you can complete by posting to the same\nURL, with the following params:\n\n``` json\n{\n  \"confirmation_token\": \"confirmation_token_from_email_provided_as_url_param\",\n  \"password_reset_token\": \"password_reset_token_from_email_provided_as_url_param\",\n  \"password\": \"newly_defined_user_password\"\n}\n```\n\n### Custom Routes\nIf you want to customize the routes, or use your own controller\nendpoints you can do that by overriding the individual routes listed.\n\n### Generate custom views\nIf you want to use custom views, you'll need copy over the views and templates\nto your application. Sentinel provides a mix task make this a one-liner:\n\n```shell\nmix sentinel.gen.views\n```\n\nThis mix task accepts a single argument of the specific context. This value can\nbe \"email\", \"error\", \"password\", \"session\", \"shared\", or \"user\". Once you copy\nover a context's view and templates, you must update the config to point to\nyour application's local files:\n\n```json\nconfig :sentinel, views: %{user: MyApp.Web.UserView}\n```\n\nThe keys for this views config map correspond with the list of contexts above.\n\n### Auth Error Handler\nIf you'd like to write your own custom authorization or authentication\nhandler change the `auth_handler` Sentinel configuration option\nto the module name of your handler.\n\nIt must define two functions, `unauthorized/2`, and `unauthenticated/2`,\nwhere the first parameter is the connection, and the second is\ninformation about the session.\n\n### Custom model validator\nIf you want to add custom changeset validations to the user model, you can do\nthat by specifying a user model validator: \n\n```elixir\nconfig :sentinel, user_model_validator: {MyApp.Accounts, :custom_changeset}\n```\nThis function must accept 2 arguments consisting of a changeset and a map of\nparams and *must* return a changeset. The params in the second argument will be\nthe raw params from the original request (not the ueberauth callback params).\n\n```elixir\ndef custom_changeset(changeset, attrs \\\\ %{}) do\n  changeset\n  |\u003e cast(attrs, [:my_attr])\n  |\u003e validate_required([:my_attr])\n  |\u003e validate_inclusion(:my_attr, [\"foo\", \"bar\"])\nend\n```\n\n## Contributing/Want something new?\nCreate an issue. Preferably with a PR. If you're super awesome\ninclude tests.\n\nAs you recall from the license, this is provided as is. I don't make any\nmoney on this, so I do support when I feel like it. That said, I want to\ndo my best to contribute to the Elixir/Phoenix community, so I'll do\nwhat I can.\n\nHaving said that if you bother to put up a PR I'll take a look, and\neither merge it, or let you know what needs to change before I do.\nHaving experienced sending in PRs and never hearing anything about\nthem, I know it sucks.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbritton-jb%2Fsentinel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbritton-jb%2Fsentinel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbritton-jb%2Fsentinel/lists"}