Skip to content

Conversation

@rafaella-martino
Copy link

@rafaella-martino rafaella-martino commented Aug 15, 2025

Summary:

  • Remove credential.js
  • Remove messenger.js
  • Centralize JS logic in one controller
  • Handle form responses in Rails controllers (when possible)
  • Resolve deprecation warning
  • Display error messages using alerts

Comment on lines 83 to 93

<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>
Copy link
Member

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?

Copy link
Author

@rafaella-martino rafaella-martino Aug 15, 2025

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?

Copy link
Member

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

Copy link
Contributor

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);
Copy link
Member

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?

Copy link
Author

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."

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good!

Copy link
Contributor

@santiagorodriguez96 santiagorodriguez96 left a 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 ❤️

Comment on lines 83 to 93

<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>
Copy link
Contributor

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

Comment on lines 29 to 37
<%= form.submit "Register using WebAuthn", class: "mdc-button mdc-button--raised" %>
<%= button_tag "Register using WebAuthn", type: "submit", class: "mdc-button mdc-button--raised" %>
Copy link
Contributor

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?

Copy link
Author

@rafaella-martino rafaella-martino Aug 18, 2025

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 🙂 .

Copy link
Member

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 🤔

Copy link
Contributor

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!

Copy link
Author

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, {
Copy link
Member

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?

Copy link
Author

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"
Copy link
Member

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree!

Copy link
Author

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"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when the sign in fails it renders:

Image

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import Rails from "@rails/ujs";

Rails.start();
import "@rails/request.js"
Copy link
Contributor

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?

Copy link
Author

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
Copy link
Contributor

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

Copy link
Author

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)

Copy link
Author

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...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

449c9cb

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?

Copy link
Contributor

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?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

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.

Comment on lines 31 to 40
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If something fails here, the index page will be rendered with a phantom credential (as we are initializing a credential for the user) that will go away when the page is refreshed

Image

Copy link
Author

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? 🙂

commit

Copy link
Contributor

@santiagorodriguez96 santiagorodriguez96 Sep 3, 2025

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 😕

Copy link
Author

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

Copy link
Contributor

@santiagorodriguez96 santiagorodriguez96 Sep 11, 2025

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 🙂

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed!
23a316e

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 },
Copy link
Contributor

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 },
Copy link
Contributor

@santiagorodriguez96 santiagorodriguez96 Oct 13, 2025

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 },
Copy link
Contributor

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 😕

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants