Skip to content

Commit

Permalink
Fix log in with PIN in Internet Identity page
Browse files Browse the repository at this point in the history
  • Loading branch information
lmuntaner committed Dec 9, 2024
1 parent 0a0ec83 commit 05134f0
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 30 deletions.
28 changes: 15 additions & 13 deletions src/frontend/src/components/authenticateBox/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,15 @@ export const authenticateBox = async ({
connection,
i18n,
templates,
allowPinAuthentication,
allowPinLogin,
allowPinRegistration,
autoSelectionIdentity,
}: {
connection: Connection;
i18n: I18n;
templates: AuthnTemplates;
allowPinAuthentication: boolean;
allowPinLogin: boolean;
allowPinRegistration: boolean;
autoSelectionIdentity?: bigint;
}): Promise<{
userNumber: bigint;
Expand All @@ -96,7 +98,7 @@ export const authenticateBox = async ({
recover: () => useRecovery(connection),
registerFlowOpts: await getRegisterFlowOpts({
connection,
allowPinAuthentication,
allowPinRegistration,
}),
verifyPinValidity: ({ userNumber, pinIdentityMaterial }) =>
pinIdentityAuthenticatorValidity({
Expand All @@ -106,7 +108,7 @@ export const authenticateBox = async ({
}),
retrievePinIdentityMaterial: ({ userNumber }) =>
idbRetrievePinIdentityMaterial({ userNumber }),
allowPinAuthentication,
allowPinLogin: allowPinLogin,
autoSelectIdentity,
});

Expand Down Expand Up @@ -176,7 +178,7 @@ export const authenticateBoxFlow = async <I>({
registerFlowOpts,
verifyPinValidity,
retrievePinIdentityMaterial,
allowPinAuthentication,
allowPinLogin,
autoSelectIdentity,
}: {
i18n: I18n;
Expand Down Expand Up @@ -204,7 +206,7 @@ export const authenticateBoxFlow = async <I>({
}: {
userNumber: bigint;
}) => Promise<I | undefined>;
allowPinAuthentication: boolean;
allowPinLogin: boolean;
autoSelectIdentity?: bigint;
verifyPinValidity: (opts: {
userNumber: bigint;
Expand Down Expand Up @@ -256,7 +258,7 @@ export const authenticateBoxFlow = async <I>({
loginPasskey,
loginPinIdentityMaterial,
verifyPinValidity,
allowPinAuthentication,
allowPinLogin,
});

// Prompt for an identity number
Expand Down Expand Up @@ -640,7 +642,7 @@ const pinIdentityToDerPubkey = async (
// Find and use a passkey, whether PIN or webauthn
const useIdentityFlow = async <I>({
userNumber,
allowPinAuthentication,
allowPinLogin,
retrievePinIdentityMaterial,
verifyPinValidity,
loginPasskey,
Expand All @@ -657,7 +659,7 @@ const useIdentityFlow = async <I>({
) => Promise<
LoginSuccess | AuthFail | WebAuthnFailed | UnknownUser | ApiError
>;
allowPinAuthentication: boolean;
allowPinLogin: boolean;
verifyPinValidity: (opts: {
userNumber: bigint;
pinIdentityMaterial: I;
Expand Down Expand Up @@ -718,7 +720,7 @@ const useIdentityFlow = async <I>({
isValid satisfies "valid";

// if there is a PIN but allowPinAuth is false, then error out
if (!allowPinAuthentication) {
if (!allowPinLogin) {
return { kind: "pinNotAllowed" };
}

Expand Down Expand Up @@ -767,16 +769,16 @@ const useIdentityFlow = async <I>({
export const useIdentity = ({
userNumber,
connection,
allowPinAuthentication,
allowPinLogin,
}: {
userNumber: bigint;
connection: Connection;
allowPinAuthentication: boolean;
allowPinLogin: boolean;
}) =>
useIdentityFlow({
userNumber,
retrievePinIdentityMaterial: idbRetrievePinIdentityMaterial,
allowPinAuthentication,
allowPinLogin,

verifyPinValidity: (opts) =>
pinIdentityAuthenticatorValidity({ ...opts, connection }),
Expand Down
6 changes: 3 additions & 3 deletions src/frontend/src/flows/authorize/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,9 @@ const authenticate = async (
dapp.hasOrigin(authContext.requestOrigin)
),
}),
// This allows logging in with a PIN but not registering with a PIN
allowPinAuthentication:
authContext.authRequest.allowPinAuthentication ?? true,
allowPinLogin: authContext.authRequest.allowPinAuthentication ?? true,
// Registration with PIN is not allowed anymore
allowPinRegistration: false,
autoSelectionIdentity: autoSelectionIdentity,
});

Expand Down
6 changes: 3 additions & 3 deletions src/frontend/src/flows/manage/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,7 @@ export const authFlowManage = async (connection: Connection) => {
const dapps = shuffleArray(getDapps());

const params = new URLSearchParams(window.location.search);
const allowPinAuthentication =
params.get(ENABLE_PIN_QUERY_PARAM_KEY) !== null;
const allowPinRegistration = params.get(ENABLE_PIN_QUERY_PARAM_KEY) !== null;

const identityBackground = new PreLoadImage(identityCardBackground);
// Go through the login flow, potentially creating an anchor.
Expand All @@ -110,7 +109,8 @@ export const authFlowManage = async (connection: Connection) => {
connection,
i18n,
templates: authnTemplateManage({ dapps }),
allowPinAuthentication,
allowPinLogin: true,
allowPinRegistration,
});

// Here, if the user is returning & doesn't have any recovery device, we prompt them to add
Expand Down
9 changes: 2 additions & 7 deletions src/frontend/src/flows/register/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { AuthnMethodData } from "$generated/internet_identity_types";
import { withLoader } from "$src/components/loader";
import { ENABLE_PIN_QUERY_PARAM_KEY } from "$src/config";
import {
PinIdentityMaterial,
constructPinIdentity,
Expand Down Expand Up @@ -241,20 +240,16 @@ export type RegisterFlowOpts = Parameters<typeof registerFlow>[0];

export const getRegisterFlowOpts = async ({
connection,
allowPinAuthentication,
allowPinRegistration,
}: {
connection: Connection;
allowPinAuthentication: boolean;
allowPinRegistration: boolean;
}): Promise<RegisterFlowOpts> => {
// Kick-off fetching "ua-parser-js";
const uaParser = loadUAParser();
const tempIdentity = await ECDSAKeyIdentity.generate({
extractable: false,
});
const params = new URLSearchParams(window.location.search);
// Only allow PIN if query param is set and the request allows it
const allowPinRegistration =
params.get(ENABLE_PIN_QUERY_PARAM_KEY) !== null && allowPinAuthentication;
return {
/** Check that the current origin is not the explicit canister id or a raw url.
* Explanation why we need to do this:
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/src/flows/verifiableCredentials/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ const verifyCredentials = async ({
const authResult = await useIdentity({
userNumber,
connection,
allowPinAuthentication: true,
allowPinLogin: true,
});

if ("tag" in authResult) {
Expand Down
6 changes: 4 additions & 2 deletions src/frontend/src/test-e2e/pinAuth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ test("Register and Log in with PIN identity", async () => {
await mainView.waitForDisplay(); // we should be logged in
await mainView.waitForTempKeyDisplay(DEFAULT_PIN_DEVICE_NAME);
await mainView.logout();
// We want to make sure that the query param is not needed for login
await browser.url(II_URL);
await FLOWS.loginPinAuthenticateView(userNumber, pin, browser);
await mainView.waitForTempKeyDisplay(DEFAULT_PIN_DEVICE_NAME);
}, APPLE_USER_AGENT);
Expand All @@ -59,8 +61,8 @@ test("Register with PIN and login without prefilled identity number", async () =
// clear storage, so that the identity number is not prefilled
await wipeStorage(browser);

// load the II page again
await browser.url(`${II_URL}?${ENABLE_PIN_QUERY_PARAM_KEY}`);
// We want to make sure that the query param is not needed for login
await browser.url(II_URL);
await FLOWS.loginPinWelcomeView(userNumber, pin, browser);
await mainView.waitForTempKeyDisplay(DEFAULT_PIN_DEVICE_NAME);
}, APPLE_USER_AGENT);
Expand Down
2 changes: 1 addition & 1 deletion src/showcase/src/flows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ export const iiFlows: Record<string, () => void> = {
connection: mockConnection,
});
},
allowPinAuthentication: true,
allowPinLogin: true,
loginPinIdentityMaterial: async ({ pin }) => {
toast.info(html`Valid PIN is '123456'`);
await withLoader(
Expand Down

0 comments on commit 05134f0

Please sign in to comment.