Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
151ba77
Refactor biometrics into platform-aware module and add passkey support
dariusz-biela Mar 6, 2026
18f0cb7
Add passkey authentication support for MFA
dariusz-biela Mar 9, 2026
2852952
Add as const to PROMPT_NAMES for literal type inference
dariusz-biela Mar 9, 2026
40f40ef
Remove type assertions from WebAuthn.ts
dariusz-biela Mar 9, 2026
41f1caa
Remove type assertions from usePasskeys.ts
dariusz-biela Mar 9, 2026
2c2f281
Remove privateKey from BaseRegisterResult
dariusz-biela Mar 9, 2026
f4c0494
Remove console.debug calls from MFA components
dariusz-biela Mar 9, 2026
2f6cdba
Move PASSKEY_AUTH_TYPE out of SecureStore into WebAuthn module
dariusz-biela Mar 9, 2026
2bf98b4
Remove useCallback from usePasskeys — React Compiler handles memoization
dariusz-biela Mar 10, 2026
fdd40fe
Pass excludeCredentials to passkey registration to prevent duplicates
dariusz-biela Mar 10, 2026
d01468c
Extract shared challenge types from ED25519/ into Biometrics/challeng…
dariusz-biela Mar 10, 2026
7920c44
Split Biometrics module into NativeBiometrics, Passkeys, and shared
dariusz-biela Mar 10, 2026
2541cca
Rename helpers.test.ts to processing.test.ts and add passkey/scenario…
dariusz-biela Mar 11, 2026
c304bc1
Address review comments and unify processRegistration
dariusz-biela Mar 11, 2026
8171acc
Merge remote-tracking branch 'origin/main' into dariusz-biela/feat/3d…
dariusz-biela Mar 11, 2026
c9cbfa6
Add deviceVerificationType to UseBiometricsReturn for scenario valida…
dariusz-biela Mar 12, 2026
8e2846e
Simplify useServerCredentials — remove manual memoization and selecto…
dariusz-biela Mar 12, 2026
9e5d340
Extract COSE algorithm identifiers into CONST.COSE_ALGORITHM
dariusz-biela Mar 12, 2026
d82dfb5
Remove redundant getLocalCredentials helper — inline null coalescing …
dariusz-biela Mar 12, 2026
69022cd
Replace thrown errors with onResult callbacks for unexpected WebAuthn…
dariusz-biela Mar 12, 2026
2b7dbe3
Add EDDSA to cspell dictionary
dariusz-biela Mar 12, 2026
1c5c930
Add WEBAUTHN.REGISTRATION_REQUIRED reason and use it in usePasskeys
dariusz-biela Mar 12, 2026
3d3f29e
Use platform-aware useBiometrics in useBiometricRegistrationStatus
dariusz-biela Mar 12, 2026
db5ce51
Merge branch 'main' into dariusz-biela/feat/3ds/passkeys-mfa
dariusz-biela Mar 12, 2026
7e840f1
Remove mock for troubleshootMultifactorAuthentication
dariusz-biela Mar 12, 2026
44a6209
Minimize VALUES.ts diff: restore original EXPO order and keep JSDoc c…
dariusz-biela Mar 13, 2026
0c974a4
Remove unused MultifactorAuthenticationObserver and its callbacks
dariusz-biela Mar 13, 2026
d2bb248
Fix misleading SignedChallenge JSDoc comment
dariusz-biela Mar 13, 2026
5a38b35
Add JSDoc comments to WebAuthn passkey utility functions
dariusz-biela Mar 13, 2026
722f12b
Rename WebAuthn helpers to more descriptive names
dariusz-biela Mar 13, 2026
1bd390e
Consolidate VALUES imports through the barrel file
dariusz-biela Mar 13, 2026
9b58511
Restore JSDoc comments in processing.ts
dariusz-biela Mar 13, 2026
ab490f7
Merge remote-tracking branch 'origin/main' into dariusz-biela/feat/3d…
dariusz-biela Mar 13, 2026
8cd99cc
Extract inline useOnyx selector to a named function in useServerCrede…
dariusz-biela Mar 13, 2026
9671668
Address github-actions review comments
dariusz-biela Mar 13, 2026
3597356
Fix base64URLToArrayBuffer returning pooled ArrayBuffer bytes
dariusz-biela Mar 13, 2026
014f138
Use DOMException names directly as WebAuthn reason strings
dariusz-biela Mar 16, 2026
fd9e56b
Remove untranslated passkey strings from non-English locale files
dariusz-biela Mar 16, 2026
a360730
Rename getLocalPublicKey to getLocalCredentialID
dariusz-biela Mar 16, 2026
81a35ad
Replace Fingerprint Lottie with passkey-specific SVG illustration
dariusz-biela Mar 16, 2026
edfad56
Rename doesDeviceSupportBiometrics to doesDeviceSupportAuthentication…
dariusz-biela Mar 16, 2026
8844f29
Use generic wording in register and authorize JSDoc comments
dariusz-biela Mar 16, 2026
9a258a9
Rename resetKeysForAccount to deleteLocalKeysForAccount
dariusz-biela Mar 16, 2026
b426f5a
Remove redundant serverHasAnyCredentials field
dariusz-biela Mar 16, 2026
985c581
Add JSDoc comment to useServerCredentials hook
dariusz-biela Mar 16, 2026
4ea0f2f
Remove unused UseServerCredentialsReturn type export
dariusz-biela Mar 16, 2026
73b41fe
Use OTHER Marqeta authentication method for passkeys
dariusz-biela Mar 16, 2026
faf0250
Remove passkeys from AuthorizeTransaction allowed methods
dariusz-biela Mar 16, 2026
a6772bc
Add allowedAuthenticationMethods check to MFA flow initialization
dariusz-biela Mar 16, 2026
495e73f
Move useBiometrics to subfolder with platform file convention
dariusz-biela Mar 16, 2026
d607189
Move MFA credential IDs selector to src/selectors/Account.ts
dariusz-biela Mar 16, 2026
570daa7
Remove unused selectors and functions
dariusz-biela Mar 16, 2026
5a9c53a
Fix type error in useNavigateTo3DSAuthorizationChallenge
dariusz-biela Mar 16, 2026
1ac98a0
Make registrationChallenge required in register()
dariusz-biela Mar 16, 2026
7fc0d56
Rename publicKey to credentialID in signToken for consistency
dariusz-biela Mar 16, 2026
123ae78
Derive promptType from deviceVerificationType via PROMPT_TYPE_MAP
dariusz-biela Mar 16, 2026
56fe3d6
Clean up lint issues: remove unused import, isWeb variable, and fix i…
dariusz-biela Mar 16, 2026
ddc8d91
Fix failing tests: update renames, scenario config, and simplify mock
dariusz-biela Mar 16, 2026
12e258c
Fix prettier
dariusz-biela Mar 16, 2026
ca8e98a
Add passkey translations for verifyYourself and enableQuickVerification
dariusz-biela Mar 16, 2026
d41dd39
Add Spanish passkey translations for verifyYourself and enableQuickVe…
dariusz-biela Mar 16, 2026
2fece5d
Compress passkeys SVG illustration
dariusz-biela Mar 16, 2026
8e30110
Fix RevokePage test: rename localPublicKey to localCredentialID in mock
dariusz-biela Mar 17, 2026
f3c7b0d
Import Base64URLString type from @src/utils/Base64URL in NativeBiomet…
dariusz-biela Mar 17, 2026
2e8e3b5
Move decodeWebAuthnError from Passkeys/helpers.ts into Passkeys/WebAu…
dariusz-biela Mar 17, 2026
18bcfb3
Use buildAllowedCredentialDescriptors inside buildPublicKeyCredential…
dariusz-biela Mar 17, 2026
eab1219
Add await before onResult calls in usePasskeys for consistent async h…
dariusz-biela Mar 17, 2026
986fd5b
Merge remote-tracking branch 'origin/main' into dariusz-biela/feat/3d…
dariusz-biela Mar 17, 2026
98686fe
Use UNSUPPORTED_DEVICE reason for disallowed auth method and add desc…
dariusz-biela Mar 19, 2026
545b361
Filter out non-public-key credential params to fix Safari WebAuthn Ty…
dariusz-biela Mar 19, 2026
ba70b94
Merge branch 'main' into dariusz-biela/feat/3ds/passkeys-mfa
dariusz-biela Mar 19, 2026
76f81df
Merge branch 'main' into dariusz-biela/feat/3ds/passkeys-mfa
dariusz-biela Mar 19, 2026
3fb6ae5
Merge remote-tracking branch 'origin/main' into dariusz-biela/feat/3d…
dariusz-biela Mar 20, 2026
53de200
Fix PromptPage spinner: stable height matching button, size 28px
dariusz-biela Mar 20, 2026
82f7532
Fix AuthorizeTransactionActions spinner: stable height matching butto…
dariusz-biela Mar 20, 2026
4c4c70c
Replace OpenPadlock illustration with green variant for MFA success s…
dariusz-biela Mar 20, 2026
3fba7ec
Replace OpenPadlock illustration with green variant for MFA success s…
dariusz-biela Mar 20, 2026
a2742eb
Fix broken import path in OutcomePage after Biometrics types moved to…
dariusz-biela Mar 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@
"ecash",
"ecconnrefused",
"econn",
"EDDSA",
"EDIFACT",
"Egencia",
"Electromedical",
Expand Down
4 changes: 2 additions & 2 deletions jest/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import mockStorage from 'react-native-onyx/dist/storage/__mocks__';
import type Animated from 'react-native-reanimated';
import 'setimmediate';
import {TextDecoder, TextEncoder} from 'util';
import * as MockedSecureStore from '@src/libs/MultifactorAuthentication/Biometrics/SecureStore/index.web';
import * as MockedSecureStore from '@src/libs/MultifactorAuthentication/NativeBiometrics/SecureStore/index.web';
import '@src/polyfills/PromiseWithResolvers';
import mockFSLibrary from './setupMockFullstoryLib';
import setupMockImages from './setupMockImages';
Expand Down Expand Up @@ -126,7 +126,7 @@ jest.mock('react-native-share', () => ({
}));

// Jest has no access to the native secure store module, so we mock it with the web implementation.
jest.mock('@src/libs/MultifactorAuthentication/Biometrics/SecureStore', () => MockedSecureStore);
jest.mock('@src/libs/MultifactorAuthentication/NativeBiometrics/SecureStore', () => MockedSecureStore);

jest.mock('react-native-reanimated', () => ({
...jest.requireActual<typeof Animated>('react-native-reanimated/mock'),
Expand Down
15 changes: 14 additions & 1 deletion src/CONST/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type {ValueOf} from 'type-fest';
import type {SearchFilterKey} from '@components/Search/types';
import type ResponsiveLayoutResult from '@hooks/useResponsiveLayout/types';
import type {MileageRate} from '@libs/DistanceRequestUtils';
import MULTIFACTOR_AUTHENTICATION_VALUES from '@libs/MultifactorAuthentication/Biometrics/VALUES';
import MULTIFACTOR_AUTHENTICATION_VALUES from '@libs/MultifactorAuthentication/VALUES';
import addTrailingForwardSlash from '@libs/UrlUtils';
import variables from '@styles/variables';
import ONYXKEYS from '@src/ONYXKEYS';
Expand Down Expand Up @@ -439,6 +439,19 @@ const CONST = {

MULTIFACTOR_AUTHENTICATION: MULTIFACTOR_AUTHENTICATION_VALUES,

/**
* COSE algorithm identifiers used in WebAuthn credential registration.
* @see https://www.iana.org/assignments/cose/cose.xhtml#algorithms
*/
COSE_ALGORITHM: {
/** EdDSA (ED25519) */
EDDSA: -8,
/** ES256 (ECDSA w/ SHA-256, P-256 curve) */
ES256: -7,
/** RS256 (RSASSA-PKCS1-v1_5 w/ SHA-256) */
RS256: -257,
},

/** WebAuthn/Passkey credential type */
PASSKEY_CREDENTIAL_TYPE: 'public-key',

Expand Down
2 changes: 2 additions & 0 deletions src/components/Icon/Illustrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import CreditCardEyes from '@assets/images/simple-illustrations/simple-illustrat
import CreditCardsNewGreen from '@assets/images/simple-illustrations/simple-illustration__creditcards--green.svg';
import EmailAddress from '@assets/images/simple-illustrations/simple-illustration__email-address.svg';
import EmptyShelves from '@assets/images/simple-illustrations/simple-illustration__empty-shelves.svg';
import EncryptionPasskeys from '@assets/images/simple-illustrations/simple-illustration__encryption-passkeys.svg';
import Encryption from '@assets/images/simple-illustrations/simple-illustration__encryption.svg';
import EnvelopeReceipt from '@assets/images/simple-illustrations/simple-illustration__envelopereceipt.svg';
import FastMoney from '@assets/images/simple-illustrations/simple-illustration__fastmoney.svg';
Expand Down Expand Up @@ -74,6 +75,7 @@ export {
ExpensifyCardCoins,
EmptyStateTravel,
Encryption,
EncryptionPasskeys,
EnvelopeReceipt,
ExpensifyApprovedLogo,
ExpensifyCardImage,
Expand Down
2 changes: 2 additions & 0 deletions src/components/Icon/chunks/illustrations.chunk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import DeniedTransactionHand from '@assets/images/multifactorAuthentication/deni
import EncryptionMan from '@assets/images/multifactorAuthentication/encryption-man.svg';
import HumptyDumpty from '@assets/images/multifactorAuthentication/humpty-dumpty.svg';
import MagnifyingGlassSpyMouthClosed from '@assets/images/multifactorAuthentication/magnifying-glass-spy-mouth-closed-cropped.svg';
import OpenPadlockGreen from '@assets/images/multifactorAuthentication/open-padlock-green.svg';
import OpenPadlock from '@assets/images/multifactorAuthentication/open-padlock.svg';
import RunOutOfTime from '@assets/images/multifactorAuthentication/running-out-of-time.svg';
import PendingTravel from '@assets/images/pending-travel.svg';
Expand Down Expand Up @@ -393,6 +394,7 @@ const Illustrations = {
// Multifactor Authentication Illustrations
MagnifyingGlassSpyMouthClosed,
OpenPadlock,
OpenPadlockGreen,
ApprovedTransactionHand,
DeniedTransactionHand,
RunOutOfTime,
Expand Down
Loading
Loading