Skip to content

Commit

Permalink
fix: two factor confirmation card
Browse files Browse the repository at this point in the history
  • Loading branch information
Benehiko committed Sep 29, 2023
1 parent a752187 commit 0d0afed
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 9 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"homepage": "https://github.com/ory/elements#readme",
"devDependencies": {
"@babel/core": "7.18.10",
"@ory/client": "1.2.8",
"@ory/client": "1.2.10",
"@ory/integrations": "1.1.5",
"@playwright/experimental-ct-react": "1.38.0",
"@playwright/test": "1.38.0",
Expand Down
26 changes: 25 additions & 1 deletion src/react-components/ory/user-auth-card.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ import {
verificationFixture,
loginCodeFixture,
loginFixtureOAuth2,
loginConfirmWithTwoFactor,
} from "../../test"
import { UserAuthCard } from "./user-auth-card"
import { OAuth2LoginRequest } from "@ory/client"
import { OAuth2LoginRequest, UiNode, UiNodeInputAttributes } from "@ory/client"
import { isUiNodeInputAttributes } from "@ory/integrations/ui"

test("ory auth card login flow. signup disabled", async ({ mount }) => {
const component = await mount(
Expand Down Expand Up @@ -396,3 +398,25 @@ test("ory auth card with oauh client name", async ({ mount }) => {

await expect(component).toContainText("a-real-client-name")
})

test("ory auth card login two factor confirmation", async ({ mount }) => {
const component = await mount(
<UserAuthCard flowType="login" flow={loginConfirmWithTwoFactor} />,
)

await expect(component).toContainText("Confirm it's you", {
ignoreCase: true,
})
await expect(component).toHaveAttribute("data-testid", "login-auth-card")

const identifier = loginConfirmWithTwoFactor.ui.nodes.find(
({ attributes }) =>
isUiNodeInputAttributes(attributes) && attributes.name === "identifier",
)?.attributes as UiNodeInputAttributes

expect(identifier).not.toBeNull()
expect(String(identifier.value)).toContain("@ory.sh")
await expect(component).toContainText(
`You're logged in as:${identifier.value}`,
)
})
7 changes: 4 additions & 3 deletions src/react-components/ory/user-auth-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -211,14 +211,14 @@ export const UserAuthCard = ({
// we want the login section to handle passwordless as well when we have a 2FA screen.
const canShowPasswordless = () =>
!!$passwordless &&
(!isLoggedIn(flow as LoginFlow) ?? flowType === "registration")
(!isLoggedIn(flow as LoginFlow) || flowType === "registration")

// the current flow is a two factor flow if the user is logged in and has any of the second factor methods enabled.
const isTwoFactor = () =>
flowType === "login" &&
isLoggedIn(flow) &&
(hasTotp(flow.ui.nodes) ??
hasWebauthn(flow.ui.nodes) ??
(hasTotp(flow.ui.nodes) ||
hasWebauthn(flow.ui.nodes) ||
hasLookupSecret(flow.ui.nodes))

// we check if nodes have hidden identifier, so we can display "you're looged in as" information
Expand Down Expand Up @@ -465,6 +465,7 @@ export const UserAuthCard = ({
})}
/>
{twoFactorFlows()}
{showLoggedAccount && <LoggedInInfo flow={flow} />}
</>
)}

Expand Down
109 changes: 109 additions & 0 deletions src/test/fixtures/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -955,3 +955,112 @@ export const loginFixtureOAuth2: LoginFlow = {
requested_aal: "aal1",
state: "",
}

export const loginConfirmWithTwoFactor: LoginFlow = {
id: "e4e5b13b-9bd5-4bd1-8a63-1750d9f48647",
organization_id: null,
type: "browser",
expires_at: "2023-09-29T14:34:42.513317131Z",
issued_at: "2023-09-29T13:34:42.513317131Z",
request_url:
"http://localhost:4433/self-service/login/browser?aal=aal2&refresh=true&return_to=&organization=",
ui: {
action:
"http://localhost:4455/self-service/login?flow=e4e5b13b-9bd5-4bd1-8a63-1750d9f48647",
method: "POST",
nodes: [
{
type: "input",
group: "default",
attributes: {
name: "csrf_token",
type: "hidden",
value:
"iCA+nEJQI5nnQe4EumaNq2xbW4/5slDiPSI2Ky33LqqzpzO/hR41Vi3DnJhP7g+wsrfUQCHZmUqNjBeGcLXZ1w==",
required: true,
disabled: false,
node_type: "input",
},
messages: [],
meta: {},
},
{
type: "input",
group: "default",
attributes: {
name: "identifier",
type: "hidden",
value: "[email protected]",
disabled: false,
node_type: "input",
},
messages: [],
meta: {},
},
{
type: "input",
group: "webauthn",
attributes: {
name: "webauthn_login_trigger",
type: "button",
value: "",
disabled: false,
onclick:
'window.__oryWebAuthnLogin({"publicKey":{"challenge":"96kZd1xu1hmcjQA7mLiM4PrBTiZrVnTuFsDZwjwzgNk","timeout":120000,"rpId":"localhost","allowCredentials":[{"type":"public-key","id":"NvEfBTQBiQF6iv5plEpA2nC9xyjF_Ok09-2ZmAJ1zs8"}],"userVerification":"discouraged"}})',
node_type: "input",
},
messages: [],
meta: {
label: {
id: 1010008,
text: "Use security key",
type: "info",
},
},
},
{
type: "input",
group: "webauthn",
attributes: {
name: "webauthn_login",
type: "hidden",
value: "",
disabled: false,
node_type: "input",
},
messages: [],
meta: {},
},
{
type: "script",
group: "webauthn",
attributes: {
src: "http://localhost:4455/.well-known/ory/webauthn.js",
async: true,
referrerpolicy: "no-referrer",
crossorigin: "anonymous",
integrity:
"sha512-RI23aG5lwYTo7zknGdc++eHUMimUWhkyFzrGid6HkVSdUSjdESPtM3KufXGq/lo4Ut0jI9mDiZeT8tHoSvaHvg==",
type: "text/javascript",
id: "webauthn_script",
nonce: "4ff0f844-fd4a-45cf-9ab0-ddebf9bc7f92",
node_type: "script",
},
messages: [],
meta: {},
},
],
messages: [
{
id: 1010003,
text: "Please confirm this action by verifying that it is you.",
type: "info",
},
],
},
created_at: "2023-09-29T15:34:42.517067+02:00",
updated_at: "2023-09-29T15:34:42.517067+02:00",
refresh: true,
requested_aal: "aal2",
state: "choose_method",
}

0 comments on commit 0d0afed

Please sign in to comment.