sander-io / hasura-jwt-auth

Hasura JWT auth using PostgreSQL
MIT License
84 stars 9 forks source link

Volatile functions for signup and change_password? #5

Open richcorbs opened 5 years ago

richcorbs commented 5 years ago

This is an awesome approach. I love it and wish it were part of Hasura main.

When VOLATILE stored procedures are available (soon I hope) will you add support for signup and change_password functions?

richcorbs commented 5 years ago

Wow, now I see the encrypt password trigger! Clever.

This is even more amazing than I thought. Thank you for this!

sanderhahn commented 5 years ago

Thank you for your kind words :) Of course its the flexible design of Hasura and PostgreSQL that makes it possible! Will see if i can update the code to support password change once volatile is supported. https://github.com/hasura/graphql-engine/issues/1514

richcorbs commented 5 years ago

Is the "before save trigger" a workaround until volatile functions are available?

sanderhahn commented 5 years ago

Think that at the moment the limitation is: generating a random password on the server and returning that value while also storing it encrypted. This is also necessary to make something like access_tokens work, have not figured out how to do this properly.

Think that for both signup and password reset you will need some external service to present a form and send a mail with a verification token. Once you are already using an external service it might be more convenient to have that also perform these manipulations using direct sql connection or a special Hasura role.

sanderhahn commented 5 years ago

Signup and password reset flow could be something like this:

However think that it requires an email service and a website that hosts the signup form/change password form and verification actions.

richcorbs commented 5 years ago

Yep I can see that. I was thinking more simply and probably used the wrong words. I meant the ability for the user to change their password and create a password which the trigger solves.

The points you make are good and valid and not something I'd personally expect/need to have out of the box starting a new project.

On Sun, Aug 25, 2019, 3:16 AM Sander Hahn notifications@github.com wrote:

Think that at the moment the limitation is: generating a random password on the server and returning that value while also storing it encrypted. This is also necessary to make something like access_tokens work, have not figured out how to do this properly.

Think that for both signup and password reset you will need some external service to present a form and send a mail with a verification token. Once you are already using an external service it might be more convenient to have that also perform these manipulations using direct sql connection or a special Hasura role.

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/sander-io/hasura-jwt-auth/issues/5?email_source=notifications&email_token=AADKXL7AG6SLJ6KHQUPGSNTQGJEWNA5CNFSM4IPHHDZKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD5CPVVA#issuecomment-524614356, or mute the thread https://github.com/notifications/unsubscribe-auth/AADKXL2YNNC6ZRVNKG7E7YDQGJEWNANCNFSM4IPHHDZA .

sanderhahn commented 5 years ago

At the moment its possible for users to update their own email/password using:

mutation {
  update_hasura_user(_set: {cleartext_password: "changed_password"}, where: {}) {
    returning {
      id
    }
  }
}

Tested this using the metadata from the Quickstart, that allows updating the email and the password for the currently active user.

User update permissions 2019-08-27 12-08-07

cpursley commented 4 years ago

As @richcorbs mentioned, this is an awesome approach.

Any thoughts on how to do account verification?

My immediate thought was on the user table, add two columns: verification_token and verified. The verification_token can be a uuid that gets generation on record creation and verified a boolean that by default is false.

Then have a verify_hasura_user Postgres function and corresponding Hasura mutation that looks up the user by the verification_token and then sets the verified column to true. Modify the hasura_auth function to fail if verified field has false value.

A url containing the GraphQL mutation along with the verification_token would be sent to the user to click in an email.

Thoughts?

richcorbs commented 4 years ago

Seems legit to me. I use a similar method for password resets.

cpursley commented 4 years ago

@richcorbs ~ how did you get around the VOLATILE restriction?

richcorbs commented 4 years ago

Ah, right. I'm not using a function for password resets.

On Wed, Dec 18, 2019 at 3:07 PM Chase Pursley notifications@github.com wrote:

@richcorbs https://github.com/richcorbs ~ how did you get around the VOLATILE restriction?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/sander-io/hasura-jwt-auth/issues/5?email_source=notifications&email_token=AADKXL4FPTLNFJKTVZDYQXDQZKNK3A5CNFSM4IPHHDZKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHHU5VI#issuecomment-567234261, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADKXL4N67FPL6MVC7L35QTQZKNK3ANCNFSM4IPHHDZA .

cpursley commented 4 years ago

I ended up with something like this:

create or replace function account_verify() returns trigger as $$
begin
    if old.verified is not true and
       new.verify_token is not null and
       new.verify_token = old.verification_token
       then
        new.verify_token = '';
        new.verified = true;
    end if;
    new.verify_token = '';
    return new;
end;
$$ language 'plpgsql';

create trigger account_verify_trigger
before update of verify_token on user_account
for each row execute procedure account_verify();

Where the hasura update account function (same as used for changing password) takes the verify_token param to match against the verification_token param via trigger. I'm also now checking if verified = true in the hasura_auth function to prevent unverified users from getting a jwt token.

Any ideas on how to beef this up ~ make it more secure / reliable?