diff --git a/app/assets/javascripts/discourse/app/components/login-buttons.hbs b/app/assets/javascripts/discourse/app/components/login-buttons.hbs index 2b03fb31d76..779f2bbd6e9 100644 --- a/app/assets/javascripts/discourse/app/components/login-buttons.hbs +++ b/app/assets/javascripts/discourse/app/components/login-buttons.hbs @@ -17,7 +17,7 @@ {{/each}} {{#if this.canUsePasskeys}} - + {{/if}} \ No newline at end of file diff --git a/app/assets/javascripts/discourse/app/components/modal/login.hbs b/app/assets/javascripts/discourse/app/components/modal/login.hbs index 0c1d1c9717b..acb9696aea8 100644 --- a/app/assets/javascripts/discourse/app/components/modal/login.hbs +++ b/app/assets/javascripts/discourse/app/components/modal/login.hbs @@ -31,6 +31,8 @@ @loginName={{this.loginName}} @loginNameChanged={{this.loginNameChanged}} @canLoginLocalWithEmail={{this.canLoginLocalWithEmail}} + @canUsePasskeys={{this.canUsePasskeys}} + @passkeyLogin={{this.passkeyLogin}} @loginPassword={{this.loginPassword}} @secondFactorMethod={{this.secondFactorMethod}} @secondFactorToken={{this.secondFactorToken}} @@ -67,7 +69,10 @@ {{/unless}} {{/if}} diff --git a/app/assets/javascripts/discourse/app/components/modal/login.js b/app/assets/javascripts/discourse/app/components/modal/login.js index 6f4fb54e290..a8685290cb5 100644 --- a/app/assets/javascripts/discourse/app/components/modal/login.js +++ b/app/assets/javascripts/discourse/app/components/modal/login.js @@ -5,10 +5,14 @@ import { schedule } from "@ember/runloop"; import { inject as service } from "@ember/service"; import { isEmpty } from "@ember/utils"; import { ajax } from "discourse/lib/ajax"; +import { popupAjaxError } from "discourse/lib/ajax-error"; import cookie, { removeCookie } from "discourse/lib/cookie"; import { areCookiesEnabled } from "discourse/lib/utilities"; import { wavingHandURL } from "discourse/lib/waving-hand-url"; -import { isWebauthnSupported } from "discourse/lib/webauthn"; +import { + getPasskeyCredential, + isWebauthnSupported, +} from "discourse/lib/webauthn"; import { findAll } from "discourse/models/login-method"; import { SECOND_FACTOR_METHODS } from "discourse/models/user"; import escape from "discourse-common/lib/escape"; @@ -109,6 +113,34 @@ export default class Login extends Component { ); } + @action + async passkeyLogin(mediation = "optional") { + try { + const response = await ajax("/session/passkey/challenge.json"); + + const publicKeyCredential = await getPasskeyCredential( + response.challenge, + (errorMessage) => this.dialog.alert(errorMessage), + mediation + ); + + if (publicKeyCredential) { + const authResult = await ajax("/session/passkey/auth.json", { + type: "POST", + data: { publicKeyCredential }, + }); + + if (authResult && !authResult.error) { + window.location.reload(); + } else { + this.dialog.alert(authResult.error); + } + } + } catch (e) { + popupAjaxError(e); + } + } + @action preloadLogin() { const prefillUsername = document.querySelector( diff --git a/app/assets/javascripts/discourse/app/components/modal/login/local-login-form.hbs b/app/assets/javascripts/discourse/app/components/modal/login/local-login-form.hbs index b0ba7ed72e6..6df03d904c9 100644 --- a/app/assets/javascripts/discourse/app/components/modal/login/local-login-form.hbs +++ b/app/assets/javascripts/discourse/app/components/modal/login/local-login-form.hbs @@ -1,12 +1,12 @@
-
+
this.dialog.alert(errorMessage) - ); - - const authResult = await ajax("/session/passkey/auth.json", { - type: "POST", - data: { publicKeyCredential }, - }); - - if (authResult && !authResult.error) { - window.location.reload(); - } else { - this.dialog.alert(authResult.error); - } - } catch (e) { - popupAjaxError(e); - } - } -