-
Notifications
You must be signed in to change notification settings - Fork 41
Refactor JS #241
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Refactor JS #241
Conversation
… public_key_credential
|
|
||
| <div class="mdc-snackbar js-messenger"> | ||
| <div class="mdc-snackbar__surface"> | ||
| <div class="mdc-snackbar__label" role="status" aria-live="polite"> | ||
| </div> | ||
|
|
||
| <div class="mdc-snackbar__actions"> | ||
| <button type="button" title="dismiss" class="mdc-icon-button material-icons mdc-snackbar__dismiss">close</button> | ||
| </div> | ||
| </div> | ||
| </div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why we stop using the snackbar to show the messages?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we had to keep messenger.js, and all its logic, that don't seem very useful...
Using alerts is less code and the user experience is very similar 🙂.
Do you think we should keep the snackbar though?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m not convinced they’re all that similar
The snackbar feels consistent with the other demo UI components, and since it has a timeout, it doesn’t require the user to manually dismiss it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would try to keep it if we can – removing it seems out of the scope of the PR as I think the idea was to refactor the way the browser and our application interact with each other when performing a webauthn cermony
| } | ||
| }); | ||
| } catch (error) { | ||
| alert(error.message || error); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it okay to show the error if there's no message?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we could add a generic error message? Like the one we set before:
"Sorry, something wrong happened."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking great! Thank you ❤️
|
|
||
| <div class="mdc-snackbar js-messenger"> | ||
| <div class="mdc-snackbar__surface"> | ||
| <div class="mdc-snackbar__label" role="status" aria-live="polite"> | ||
| </div> | ||
|
|
||
| <div class="mdc-snackbar__actions"> | ||
| <button type="button" title="dismiss" class="mdc-icon-button material-icons mdc-snackbar__dismiss">close</button> | ||
| </div> | ||
| </div> | ||
| </div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would try to keep it if we can – removing it seems out of the scope of the PR as I think the idea was to refactor the way the browser and our application interact with each other when performing a webauthn cermony
app/views/registrations/new.html.erb
Outdated
| <%= form.submit "Register using WebAuthn", class: "mdc-button mdc-button--raised" %> | ||
| <%= button_tag "Register using WebAuthn", type: "submit", class: "mdc-button mdc-button--raised" %> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not using form.submit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When using form.submit, if we clicked Cancel when adding a new Credential the button was disabled.
This is because when using rails helper form.submit, the button stays disabled until the submit flow is over.
So, as we use prevent to intercept the controllers action, we should not use this helper 🙂 .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another option could be to re-enable the button from the javascript when it fails 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another option could be to re-enable the button from the javascript when it fails 🤔
I like this!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
|
||
| async get() { | ||
| try { | ||
| const optionsResponse = await fetch(this.optionsUrlValue, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what do you think about naming it response?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1c92613
Like it, I also changed optionsJson to credentialOptionsJson.
Are you okay with this change or is it too long?
As this is a Demo I believe variables should be understandable 🙂
| redirect_to root_path, notice: "Security Key registered successfully" | ||
| else | ||
| render json: "Couldn't register your Security Key", status: :unprocessable_content | ||
| redirect_to new_registration_path, alert: "Couldn't register your Security Key" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we use render here? I think that when we use redirect_to it responds with a 302 status code
See:
- https://www.mintbit.com/blog/difference-between-render-and-redirect-to-in-rails-controllers/
- https://api.rubyonrails.org/classes/ActionController/Redirecting.html#method-i-redirect_to:~:text=The%20status%20code%20can%20either%20be%20a%20standard%20HTTP%20Status%20code%20as%20an%20integer%2C%20or%20a%20symbol%20representing%20the%20downcased%2C%20underscored%20and%20symbolized%20description.%20Note%20that%20the%20status%20code%20must%20be%20a%203xx%20HTTP%20code%2C%20or%20redirection%20will%20not%20occur.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| redirect_to root_path, notice: "Security Key registered successfully" | ||
| else | ||
| render json: "Couldn't add your Security Key", status: :unprocessable_content | ||
| redirect_to root_path, alert: "Couldn't register your Security Key" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
app/javascript/application.js
Outdated
| import Rails from "@rails/ujs"; | ||
|
|
||
| Rails.start(); | ||
| import "@rails/request.js" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: should we move this up along with the rest of the imports?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| rescue WebAuthn::Error => e | ||
| render json: "Verification failed: #{e.message}", status: :unprocessable_content | ||
| flash[:alert] = "Verification failed: #{e.message}" | ||
| render "home/index", status: :unprocessable_content |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really like this pattern to be honest... 🤔
If something goes wrong when adding a passkey, the index page will be rendered but the url is /credentials so reloading the page will show the typical Confirm form resubmission alert
Not the end of the world but I wonder if there are other options here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we can find another way!
First, we used a redirect to handle this error flow. However, we changed it because the resulting status was 301, which didn’t reflect the unprocessable_content status we wanted in case of an exception.
But I believe the possibility of the user seeing the “Confirm form resubmission” prompt should be avoided. So maybe we should use the redirect with an alert again.
What do you think? 🙂
(pd: the alerts are not yet added to the index page, it is a will do)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However, by doing this we won't be having some log in the server informing this error...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I temporarily used redirect to handle this case, avoiding the alert when the user reloads the page.
Maybe this can be adjusted in another PR so it does not block this one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about keeping the behavior of the controllers as it was before and revisit the approach as part of a separate PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about doing it for all the responses of all the controllers. What do you think?
That'd make it so that all the controllers will still respond using json for now.
| if credential.update( | ||
| nickname: params[:credential_nickname], | ||
| nickname: credential_params[:nickname], | ||
| public_key: webauthn_credential.public_key, | ||
| sign_count: webauthn_credential.sign_count | ||
| ) | ||
| render json: { status: "ok" }, status: :ok | ||
| flash[:notice] = "Security Key registered successfully" | ||
| redirect_to root_path | ||
| else | ||
| render json: "Couldn't add your Security Key", status: :unprocessable_content | ||
| flash[:alert] = "Couldn't register your Security Key" | ||
| render "home/index", status: :unprocessable_content |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right!
We could destroy that instance in case the update action fails. I believe another solution would implicate more lines of code. What do you think? 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the problem is when the credential is not persisted (because it was just initialized) so I don't think that fixes the issue 😕
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, the credential is a new record. What do you think about using this method?
9e58703
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that we added back the redirect I don't think this is a problem anymore 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed!
23a316e
destroy initialized credential in case `create` credential action fails
| end | ||
| rescue WebAuthn::Error => e | ||
| render json: "Verification failed: #{e.message}", status: :unprocessable_content | ||
| render json: { message: "Verification failed: #{e.message}", redirect_to: registration_path }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm getting an error here – we should be using new_registration_path instead
| render json: { message: "Security Key authenticated successfully", redirect_to: root_path }, status: :ok | ||
| rescue WebAuthn::Error => e | ||
| render json: "Verification failed: #{e.message}", status: :unprocessable_content | ||
| render json: { message: "Verification failed: #{e.message}", redirect_to: session_path }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here! We should use new_session_path here instead
| render json: { message: "Security Key authenticated successfully", redirect_to: root_path }, status: :ok | ||
| rescue WebAuthn::Error => e | ||
| render json: "Verification failed: #{e.message}", status: :unprocessable_content | ||
| render json: { message: "Verification failed: #{e.message}", redirect_to: session_path }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not getting any of the messages rendered in the page 😕


Summary:
credential.jsRemovemessenger.js