Giter Site home page Giter Site logo

liveshowy / webauthn_components Goto Github PK

View Code? Open in Web Editor NEW
137.0 4.0 7.0 124 KB

WebauthnComponents allows Phoenix developers to quickly add passwordless authentication to LiveView applications.

License: MIT License

Elixir 90.53% JavaScript 5.89% HTML 3.57%
javascript phoenix phoenix-framework phoenix-liveview

webauthn_components's People

Contributors

danielgpinheiro avatar ken-kost avatar kianmeng avatar mward-sudo avatar optikfluffel avatar type1fool avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

webauthn_components's Issues

[BUG] - migrations created non-deterministically

Description

Migrations are generated out of correct order, with the users table created after the migrations that depend on them.

Steps To Reproduce

Steps to reproduce the behavior:

  1. Run mix wac.install on a newly-generated Phoenix app, using Elixir 1.15.x.
  2. Generated migrations will (sometimes?) appear with the users table generated after the associated tables that require foreign key associations to that table. See listing:
priv/repo/migrations
❯
ls
.rw-r--r--  52 djp staff 2023-11-28 11:38 .formatter.exs
.rw-r--r-- 667 djp staff 2023-11-28 11:42 20231128004224_user_keys.exs
.rw-r--r-- 461 djp staff 2023-11-28 11:42 20231128004225_user_tokens.exs
.rw-r--r-- 300 djp staff 2023-11-28 11:42 20231128004226_users.exs
  1. Run mix ecto.migrate.
  2. See error:
mix ecto.migrate
Compiling 15 files (.ex)
Generated example app

11:42:39.934 [info] == Running 20231128004224 Example.Repo.Migrations.CreateUserKeys.change/0 forward

11:42:39.935 [info] create table user_keys
** (Postgrex.Error) ERROR 42P01 (undefined_table) relation "users" does not exist
    (ecto_sql 3.11.0) lib/ecto/adapters/sql.ex:1054: Ecto.Adapters.SQL.raise_sql_call_error/1
    (elixir 1.15.7) lib/enum.ex:1693: Enum."-map/2-lists^map/1-1-"/2
    (ecto_sql 3.11.0) lib/ecto/adapters/sql.ex:1161: Ecto.Adapters.SQL.execute_ddl/4
    (ecto_sql 3.11.0) lib/ecto/migration/runner.ex:348: Ecto.Migration.Runner.log_and_execute_ddl/3
    (elixir 1.15.7) lib/enum.ex:1693: Enum."-map/2-lists^map/1-1-"/2
    (ecto_sql 3.11.0) lib/ecto/migration/runner.ex:311: Ecto.Migration.Runner.perform_operation/3
    (stdlib 3.17.2.4) timer.erl:166: :timer.tc/1
    (ecto_sql 3.11.0) lib/ecto/migration/runner.ex:25: Ecto.Migration.Runner.run/8

Expected behavior

users table should always be created first.

AdditionalCcontext

Elixir 1.15.7
Erlang 24.x

Notify

Fix RP Configuration

Description

The 0.6.3 update (diff) (PR) introduced a bug with the origin configuration.

It appears that by using the socket's host_uri, Wax's rp: :auto results in a mismatch, which prevents a valid credential from being used during authentication.

Image

[BUG] - Does not work on Safari MacOS and iOS

Description

Running into issues where I can't use this on Safari. Both iOS and MacOS versions fail with different error messages.

On iOS I get a flash message when I go to the sign-in route that says "Passkeys not supported on this browser."

On MacOS I get errors in the console:

[debug] HANDLE EVENT "register" in MyPkAppWeb.AuthenticationLive
  Component: WebauthnComponents.RegistrationComponent
  Parameters: %{"value" => ""}
[debug] Replied in 542µs
[debug] HANDLE EVENT "error" in MyPkAppWeb.AuthenticationLive
  Component: WebauthnComponents.RegistrationComponent
  Parameters: %{"message" => "This request has been cancelled by the user.", "name" => "NotAllowedError", "stack" => ""}
[debug] Replied in 107µs
[warning] [unhandled_message: {MyPkAppWeb.AuthenticationLive, {:error, %{"message" => "This request has been cancelled by the user.", "name" => "NotAllowedError", "stack" => ""}}}]

To end on a positive note - both Firefox and Chrome on MacOS works as expected and across browsers! UX is 👌

Steps To Reproduce

Steps to reproduce the behavior:

  1. Instantiate a new Phoenix project
  2. Add deps
  3. Install deps and run ecto.create
  4. Run wac.install
  5. Start server
  6. Go to /sign-in
  7. Enter an email
  8. Click Sign Up button.

Expected behavior

I should be able to sign up and login like on Chrome and Firefox.

Desktop (please complete the following information)

  • OS: iOS, MacOS
  • Browser: Safari
  • Version: 17.3.1

Smartphone (please complete the following information)

  • Device: iPhone 15 Pro Max
  • OS: iOS
  • Browser: Safari
  • Version: 17

AdditionalCcontext

Add any other context about the problem here.

Notify

Improve Token Security

At the Denver Elixir meetup, one of the attendees (@RGENT) raised a concern about token security (video link).

In short, the token saved in sessionStorage may be accessed by 3rd party JS dependencies. Suggested mitigations include cookie storage and/or adding content security policy (CSP).

Because these component interact exclusively via WebSockets, cookies may not be an option here. CSP is likely the better solution, though other alternatives may exist.

Resources

Split Components

To support multiple keys for user accounts and MFA usage, and to separate concerns, the components need to be split up.

Acceptance Criteria

  • Must move registration to new RegistrationComponent
  • Must move authentication to new AuthenticationComponent
  • Must move token to new TokenComponent
  • Must move support to new SupportComponent
  • Must move registration to new registration_hook.js
  • Must move authentication to new authentication_hook.js
  • Must move token to new token_hook.js
  • Must move support checks to support_hook.js
  • Must remove PasskeyComponent

Context

Support Multiple Keys Per User

Often, a user may want to register additional keys after creating an account for backup or survivorship purposes. The Passkey package should provide an API for registering additional keys when an application wants to support this feature.

Acceptance Criteria

  • Must add SecondaryPasskey LiveComponent
  • Must pass user.id & user.displayName to handlePasskeyRegistration in passkey_hook.js
  • Must update demo app to illustrate component usage
  • TBD

Incorrect mix task for migrations

I believe the two mix commands in README.MD to generate the database structures should be using mix phx.gen.context rather than ecto.gen.migration

Update Packages

Acceptance Criteria

  • Must run mix hex.outdated to list outdated deps
  • Must update Phoenix LiveView to 0.18.x
  • Must update Wax to latest version
  • May update other pkgs

Document Implementation in Existing Apps

As of v0.6.0, WebauthnComponents can be used to easily scaffold Passkey authentication in new Phoenix apps. For existing applications with password-based authentication or 0Auth, more extensive documentation is needed.

Add Passkey Button

Acceptance Criteria

  • Must add new button type=button
  • Must be labeled "Sign in with Passkey"
  • May use key icon (mini variant)

Resources

  • Heroicons
    • Options: finger print, key*, cloud, face smile

Add Generator for MyApp.Hooks.User

Assigning and authenticating users with tokens in LiveView is a tedious process to implement. If possible, a generator for LiveView on_mount hooks would help developers get up to speed quickly, assuming requirements are met (see #15).

Acceptance Criteria

  • Must raise if User, UserKey, UserToken, or UserProfile schemas don't exist
  • Must generate :assign_user hook
  • Must generate :require_user hook
  • Must document considerations and customizability

Store Token in Cookie

Instead of setting the token in JS SessionStorage, add a session controller which saves the token in a cookie.

This may eliminate the need for connected?(socket) checks.

Update the demo app to test & document usage.

Add Generator for User, UserKey, UserToken, & UserProfile

With discoverable credentials, username and email data is not required up front. And, schemas for UserKey, UserToken, and UserProfile may differ in surprising ways from traditional applications.

So, custom generators may helpful for developers implementing Passkey support for the first time.

Acceptance Criteria

  • Must interpolate app and module names
  • Must generate Users context
  • Must generate User schema
  • Must generate UserKeys context
  • Must generate UserKey schema
  • Must generate UserTokens context
  • Must generate UserToken schema
  • Must generate context tests
  • Must document considerations and customizations

Bonus

  • If user schema already exists, prompt for appropriate action
    • For now, it may be wise to only allow the generator to run when there is no existing auth code.

Support Resident Keys

Acceptance Criteria

  • Must add Passkey Component
  • Must add Passkey JS hook
  • Must allow user to register or authenticate without entering username/email/password

Resources

[REQUEST] - Passkeys input autofill (Conditional UI)

Is your feature request related to a problem? Please describe.

I'm always frustrated when I need to input again and again my email when I need sign-in. Enabling Passkey Autofill with mediation: "conditional" and autocomplete="username webauthn" on email input, helps that.

Describe the solution you'd like

Implements Conditional UI to enable Passkey autofill

Additional context

Sign in with a passkey through form autofill
Add passkeys to the browser autofill
Explainer: WebAuthn Conditional UI

Notify

Build Form Fields from Changeset

User Story

As a user of this component, I would like to provide my own changeset from my custom LiveView and see the form render fields based on the changeset's required fields.

Acceptance Criteria

  • Must define new changeset prop of type struct
  • Must define default changeset
  • Must list required fields and their types
  • Must generate form fields based on changeset fields and types

Send the session token with the LiveView connect params, so that on_mount hooks and live_session can load/require users before any specific LiveView mount.

Is your feature request related to a problem? Please describe.

I've found this library to be a great start to adding passkeys to my application, but specific implementations make it challenging to add as-is. The token component is great, but when I have push navigation the current setup means that I have to check in all of my handle_params as well as all of my handle_event callbacks to know whether a user is already loaded, and every single live view I make needs to copy the same 3+ handle_info callbacks in order to work.

This might be more for the example repo than for the library itself, but if the hooks were broken apart a bit more it might be more clear how to use connect params to load a user in on_mount.

Describe the solution you'd like

  • Break out at least one utility function from the token hook, for getting and setting the session token.
  • (maybe) split the token component into two, one of which handles logout. This would mean that logged-in liveviews would only need to implement callbacks for token deletion, rather than all token callbacks.

Describe alternatives you've considered

I've instead used this library as a reference for writing my own components and hooks. If you find security issues or more complete integration code, I'll need to follow your fixes and apply them to my code.

Additional context

This is great work! It and your conference presentation were really helpful for me to add passkey support to my app.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.