Skip to content

Commit a559ccf

Browse files
authored
Remove screen to select authentication method: passkey or pin (#2687)
* Remove screen to choose passkey or pin * Fix e2e test * Fix lint * Disable VC with pin * Fix dev-build test
1 parent 34df5ae commit a559ccf

File tree

8 files changed

+58
-127
lines changed

8 files changed

+58
-127
lines changed

demos/using-dev-build/specs/auth.e2e.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ describe("authentication", () => {
1010
await browser.$("#registerButton").click();
1111

1212
// Construct Identity (no-op)
13-
const constructIdentity = await browser.$(
14-
'[data-action="construct-identity"]'
15-
);
16-
await constructIdentity.waitForExist();
17-
await constructIdentity.click();
13+
// TODO: GIX-3138 Clean up after release
14+
// const constructIdentity = await browser.$(
15+
// '[data-action="construct-identity"]'
16+
// );
17+
// await constructIdentity.waitForExist();
18+
// await constructIdentity.click();
1819

1920
await browser.$("h1").waitForExist();
2021
const title = await browser.$("h1");

src/frontend/src/flows/register/index.ts

Lines changed: 19 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
import { AuthnMethodData } from "$generated/internet_identity_types";
22
import { withLoader } from "$src/components/loader";
3-
import {
4-
PinIdentityMaterial,
5-
constructPinIdentity,
6-
} from "$src/crypto/pinIdentity";
7-
import { tempKeyWarningBox } from "$src/flows/manage/tempKeys";
3+
import { PinIdentityMaterial } from "$src/crypto/pinIdentity";
84
import { idbStorePinIdentityMaterial } from "$src/flows/pin/idb";
9-
import { setPinFlow } from "$src/flows/pin/setPin";
105
import { registerDisabled } from "$src/flows/registerDisabled";
11-
import { I18n } from "$src/i18n";
126
import { setAnchorUsed } from "$src/storage";
13-
import {
14-
passkeyAuthnMethodData,
15-
pinAuthnMethodData,
16-
} from "$src/utils/authnMethodData";
7+
import { passkeyAuthnMethodData } from "$src/utils/authnMethodData";
178
import {
189
AlreadyInProgress,
1910
ApiError,
@@ -32,7 +23,6 @@ import {
3223
import { SignIdentity } from "@dfinity/agent";
3324
import { ECDSAKeyIdentity } from "@dfinity/identity";
3425
import { nonNullish } from "@dfinity/utils";
35-
import { TemplateResult } from "lit-html";
3626
import type { UAParser } from "ua-parser-js";
3727
import { precomputeFirst, promptCaptcha } from "./captcha";
3828
import { displayUserNumberWarmup } from "./finish";
@@ -43,9 +33,9 @@ export const registerFlow = async ({
4333
identityRegistrationStart,
4434
checkCaptcha,
4535
identityRegistrationFinish,
46-
storePinIdentity,
36+
storePinIdentity: _storePinIdentity,
4737
registrationAllowed,
48-
pinAllowed,
38+
pinAllowed: _pinAllowed,
4939
uaParser,
5040
}: {
5141
identityRegistrationStart: () => Promise<
@@ -108,78 +98,24 @@ export const registerFlow = async ({
10898
const flowStart = precomputeFirst(() => identityRegistrationStart());
10999

110100
const displayUserNumber = displayUserNumberWarmup();
111-
const savePasskeyResult = await savePasskeyOrPin({
112-
pinAllowed: await pinAllowed(),
113-
});
114-
if (savePasskeyResult === "canceled") {
115-
return "canceled";
116-
}
117-
const result_ = await (async () => {
118-
if (savePasskeyResult === "pin") {
119-
const pinResult = await setPinFlow();
120-
if (pinResult.tag === "canceled") {
121-
return "canceled";
122-
}
123-
124-
pinResult.tag satisfies "ok";
125-
126-
// XXX: this withLoader could be replaced with one that indicates what's happening (like the
127-
// "Hang tight, ..." spinner)
128-
const { identity, pinIdentityMaterial } = await withLoader(() =>
129-
constructPinIdentity(pinResult)
130-
);
131-
const alias = await inferPinAlias({
132-
userAgent: navigator.userAgent,
133-
uaParser,
134-
});
135-
return {
136-
identity,
137-
authnMethodData: pinAuthnMethodData({
138-
alias,
139-
pubKey: identity.getPublicKey().toDer(),
140-
}),
141-
finalizeIdentity: (userNumber: bigint) =>
142-
storePinIdentity({ userNumber, pinIdentityMaterial }),
143-
finishSlot: tempKeyWarningBox({ i18n: new I18n() }),
144-
authnMethod: "pin" as const,
145-
};
146-
} else {
147-
const identity = savePasskeyResult;
148-
const alias = await inferPasskeyAlias({
149-
authenticatorType: identity.getAuthenticatorAttachment(),
150-
userAgent: navigator.userAgent,
151-
uaParser,
152-
});
153-
return {
154-
identity,
155-
authnMethodData: passkeyAuthnMethodData({
156-
alias,
157-
pubKey: identity.getPublicKey().toDer(),
158-
credentialId: identity.rawId,
159-
authenticatorAttachment: identity.getAuthenticatorAttachment(),
160-
}),
161-
authnMethod: "passkey" as const,
162-
};
163-
}
164-
})();
165-
166-
if (result_ === "canceled") {
101+
const identity = await savePasskeyOrPin();
102+
if (identity === undefined) {
103+
// TODO: Return something meaningful if getting the identity fails
167104
return "canceled";
168105
}
106+
const alias = await inferPasskeyAlias({
107+
authenticatorType: identity.getAuthenticatorAttachment(),
108+
userAgent: navigator.userAgent,
109+
uaParser,
110+
});
169111

170-
const {
171-
identity,
172-
authnMethodData,
173-
finalizeIdentity,
174-
finishSlot,
175-
authnMethod,
176-
}: {
177-
identity: SignIdentity;
178-
authnMethodData: AuthnMethodData;
179-
finalizeIdentity?: (userNumber: bigint) => Promise<void>;
180-
finishSlot?: TemplateResult;
181-
authnMethod: "pin" | "passkey";
182-
} = result_;
112+
const authnMethodData = passkeyAuthnMethodData({
113+
alias,
114+
pubKey: identity.getPublicKey().toDer(),
115+
credentialId: identity.rawId,
116+
authenticatorAttachment: identity.getAuthenticatorAttachment(),
117+
});
118+
const authnMethod = "passkey" as const;
183119

184120
const startResult = await flowStart();
185121
if (startResult.kind !== "registrationFlowStepSuccess") {
@@ -214,7 +150,6 @@ export const registerFlow = async ({
214150
result.kind satisfies "loginSuccess";
215151

216152
const userNumber = result.userNumber;
217-
await finalizeIdentity?.(userNumber);
218153
// We don't want to nudge the user with the recovery phrase warning page
219154
// right after they've created their anchor.
220155
result.connection.updateIdentityMetadata({
@@ -227,7 +162,6 @@ export const registerFlow = async ({
227162
);
228163
await displayUserNumber({
229164
userNumber,
230-
marketingIntroSlot: finishSlot,
231165
});
232166
return { ...result, authnMethod };
233167
};

src/frontend/src/flows/register/passkey.ts

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -97,27 +97,15 @@ const savePasskeyTemplate = ({
9797
export const savePasskeyPage = renderPage(savePasskeyTemplate);
9898

9999
// Prompt the user to create a WebAuthn identity or a PIN identity (if allowed)
100-
export const savePasskeyOrPin = ({
101-
pinAllowed,
102-
}: {
103-
pinAllowed: boolean;
104-
}): Promise<IIWebAuthnIdentity | "pin" | "canceled"> => {
105-
return new Promise((resolve) =>
106-
savePasskeyPage({
107-
i18n: new I18n(),
108-
cancel: () => resolve("canceled"),
109-
scrollToTop: true,
110-
constructPasskey: async () => {
111-
try {
112-
const identity = await withLoader(() => constructIdentity({}));
113-
resolve(identity);
114-
} catch (e) {
115-
toast.error(errorMessage(e));
116-
}
117-
},
118-
constructPin: pinAllowed ? () => resolve("pin") : undefined,
119-
})
120-
);
100+
export const savePasskeyOrPin = async (): Promise<
101+
IIWebAuthnIdentity | undefined
102+
> => {
103+
try {
104+
return await withLoader(() => constructIdentity({}));
105+
} catch (e) {
106+
toast.error(errorMessage(e));
107+
return undefined;
108+
}
121109
};
122110

123111
// Return an appropriate error message depending on the (inferred) type of WebAuthn error

src/frontend/src/test-e2e/flows.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ import {
1515
export const FLOWS = {
1616
register: async function (browser: WebdriverIO.Browser): Promise<string> {
1717
const registerView = new RegisterView(browser);
18-
await registerView.waitForDisplay();
19-
await registerView.create();
18+
// TODO: GIX-3138 Clean up after release
19+
// await registerView.waitForDisplay();
20+
// await registerView.create();
2021
if (CAPTCHA_ENABLED) {
2122
await registerView.waitForRegisterConfirm();
2223
await registerView.confirmRegisterConfirm();

src/frontend/src/test-e2e/pinAuth.test.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ import {
2323

2424
const DEFAULT_PIN_DEVICE_NAME = "Chrome on Mac OS";
2525

26-
test("PIN registration not enabled on non-Apple device", async () => {
26+
// TODO: GIX-3138 Clean up after release
27+
// TODO: Test login with PIN only GIX-3139
28+
test.skip("PIN registration not enabled on non-Apple device", async () => {
2729
await runInBrowser(async (browser: WebdriverIO.Browser) => {
2830
await browser.url(II_URL);
2931
const welcomeView = new WelcomeView(browser);
@@ -38,7 +40,7 @@ test("PIN registration not enabled on non-Apple device", async () => {
3840
// The PIN auth feature is only enabled for Apple specific user agents, so tests set the user
3941
// agent to chrome on macOS
4042

41-
test("Register and Log in with PIN identity", async () => {
43+
test.skip("Register and Log in with PIN identity", async () => {
4244
await runInBrowser(async (browser: WebdriverIO.Browser) => {
4345
const pin = "123456";
4446

@@ -53,7 +55,7 @@ test("Register and Log in with PIN identity", async () => {
5355
}, APPLE_USER_AGENT);
5456
}, 300_000);
5557

56-
test("Register with PIN and login without prefilled identity number", async () => {
58+
test.skip("Register with PIN and login without prefilled identity number", async () => {
5759
await runInBrowser(async (browser: WebdriverIO.Browser) => {
5860
const pin = "123456";
5961
await browser.url(II_URL);
@@ -72,7 +74,7 @@ test("Register with PIN and login without prefilled identity number", async () =
7274
}, APPLE_USER_AGENT);
7375
}, 300_000);
7476

75-
test("Register and log in with PIN identity, retry on wrong PIN", async () => {
77+
test.skip("Register and log in with PIN identity, retry on wrong PIN", async () => {
7678
await runInBrowser(async (browser: WebdriverIO.Browser) => {
7779
const pin = "123456";
7880
const wrongPin = "456321";
@@ -98,7 +100,7 @@ test("Register and log in with PIN identity, retry on wrong PIN", async () => {
98100
}, APPLE_USER_AGENT);
99101
}, 300_000);
100102

101-
test("Should not prompt for PIN after deleting temp key", async () => {
103+
test.skip("Should not prompt for PIN after deleting temp key", async () => {
102104
await runInBrowser(async (browser: WebdriverIO.Browser) => {
103105
const pin = "123456";
104106
await addVirtualAuthenticator(browser);
@@ -121,7 +123,7 @@ test("Should not prompt for PIN after deleting temp key", async () => {
121123
}, APPLE_USER_AGENT);
122124
}, 300_000);
123125

124-
test("Log into client application using PIN registration flow", async () => {
126+
test.skip("Log into client application using PIN registration flow", async () => {
125127
await runInBrowser(async (browser: WebdriverIO.Browser) => {
126128
const pin = "123456";
127129

@@ -142,7 +144,7 @@ test("Log into client application using PIN registration flow", async () => {
142144
}, APPLE_USER_AGENT);
143145
}, 300_000);
144146

145-
test("Register with PIN then log into client application", async () => {
147+
test.skip("Register with PIN then log into client application", async () => {
146148
await runInBrowser(async (browser: WebdriverIO.Browser) => {
147149
const pin = "123456";
148150

src/frontend/src/test-e2e/pinAuthDisabled.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { FLOWS } from "./flows";
33
import { runInBrowser, switchToPopup } from "./util";
44
import { AuthenticateView, DemoAppView, RegisterView } from "./views";
55

6-
test("Cannot register with PIN if dapp disallows PIN", async () => {
6+
// TODO: GIX-3138 Clean up after release
7+
test.skip("Cannot register with PIN if dapp disallows PIN", async () => {
78
await runInBrowser(async (browser: WebdriverIO.Browser) => {
89
const demoAppView = new DemoAppView(browser);
910
await demoAppView.open(TEST_APP_NICE_URL, II_URL);
@@ -21,7 +22,7 @@ test("Cannot register with PIN if dapp disallows PIN", async () => {
2122
}, APPLE_USER_AGENT);
2223
}, 300_000);
2324

24-
test("Cannot auth with PIN if dapp disallows PIN", async () => {
25+
test.skip("Cannot auth with PIN if dapp disallows PIN", async () => {
2526
await runInBrowser(async (browser: WebdriverIO.Browser) => {
2627
const pin = "123456";
2728

src/frontend/src/test-e2e/verifiableCredentials/index.test.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,12 @@ const testConfigs: Array<{
6262
issuer: ISSUER_APP_URL_LEGACY,
6363
authType: "webauthn",
6464
},
65-
{
66-
relyingParty: TEST_APP_CANONICAL_URL,
67-
issuer: ISSUER_APP_URL,
68-
authType: "pin",
69-
},
65+
// TODO: Renable with PIN GIX-3139
66+
// {
67+
// relyingParty: TEST_APP_CANONICAL_URL,
68+
// issuer: ISSUER_APP_URL,
69+
// authType: "pin",
70+
// },
7071
];
7172

7273
testConfigs.forEach(({ relyingParty, issuer, authType }) => {

src/frontend/src/test-e2e/views.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ export class RenameView extends View {
5757
}
5858

5959
export class RegisterView extends View {
60+
// View: Passkey or PIN registration
61+
// TODO: GIX-3138 Clean up after release
62+
// At the moment it's used only in skipped tests.
6063
async waitForDisplay(): Promise<void> {
6164
await this.browser
6265
.$('[data-action="construct-identity"]')

0 commit comments

Comments
 (0)