@bifold/core 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (252) hide show
  1. package/lib/commonjs/components/inputs/BiometryControl.js.map +1 -1
  2. package/lib/commonjs/components/misc/CredentialCard.js +3 -2
  3. package/lib/commonjs/components/misc/CredentialCard.js.map +1 -1
  4. package/lib/commonjs/components/misc/FauxHeader.js +89 -0
  5. package/lib/commonjs/components/misc/FauxHeader.js.map +1 -0
  6. package/lib/commonjs/components/misc/QRScanner.js +1 -1
  7. package/lib/commonjs/components/misc/QRScanner.js.map +1 -1
  8. package/lib/commonjs/components/modals/DeveloperModal.js +43 -0
  9. package/lib/commonjs/components/modals/DeveloperModal.js.map +1 -0
  10. package/lib/commonjs/components/views/PushNotificationsContent.js.map +1 -1
  11. package/lib/commonjs/components/views/PushNotificationsDisabledContent.js.map +1 -1
  12. package/lib/commonjs/contexts/auth.js +24 -3
  13. package/lib/commonjs/contexts/auth.js.map +1 -1
  14. package/lib/commonjs/hooks/chat-messages.js +1 -1
  15. package/lib/commonjs/hooks/chat-messages.js.map +1 -1
  16. package/lib/commonjs/hooks/developer-mode.js +31 -0
  17. package/lib/commonjs/hooks/developer-mode.js.map +1 -0
  18. package/lib/commonjs/hooks/lockout.js +80 -0
  19. package/lib/commonjs/hooks/lockout.js.map +1 -0
  20. package/lib/commonjs/hooks/onboarding.js +23 -0
  21. package/lib/commonjs/hooks/onboarding.js.map +1 -0
  22. package/lib/commonjs/index.js +24 -0
  23. package/lib/commonjs/index.js.map +1 -1
  24. package/lib/commonjs/localization/en/index.js +2 -1
  25. package/lib/commonjs/localization/en/index.js.map +1 -1
  26. package/lib/commonjs/localization/fr/index.js +2 -1
  27. package/lib/commonjs/localization/fr/index.js.map +1 -1
  28. package/lib/commonjs/localization/pt-br/index.js +2 -1
  29. package/lib/commonjs/localization/pt-br/index.js.map +1 -1
  30. package/lib/commonjs/modules/openid/components/OpenIDCredentialCard.js +4 -5
  31. package/lib/commonjs/modules/openid/components/OpenIDCredentialCard.js.map +1 -1
  32. package/lib/commonjs/modules/openid/display.js +6 -3
  33. package/lib/commonjs/modules/openid/display.js.map +1 -1
  34. package/lib/commonjs/modules/openid/metadata.js +2 -1
  35. package/lib/commonjs/modules/openid/metadata.js.map +1 -1
  36. package/lib/commonjs/modules/openid/screens/OpenIDProofChangeCredential.js +128 -0
  37. package/lib/commonjs/modules/openid/screens/OpenIDProofChangeCredential.js.map +1 -0
  38. package/lib/commonjs/modules/openid/screens/OpenIDProofPresentation.js +99 -44
  39. package/lib/commonjs/modules/openid/screens/OpenIDProofPresentation.js.map +1 -1
  40. package/lib/commonjs/modules/openid/types.js.map +1 -1
  41. package/lib/commonjs/modules/openid/utils/utils.js +0 -14
  42. package/lib/commonjs/modules/openid/utils/utils.js.map +1 -1
  43. package/lib/commonjs/navigators/DeliveryStack.js +8 -0
  44. package/lib/commonjs/navigators/DeliveryStack.js.map +1 -1
  45. package/lib/commonjs/navigators/OnboardingScreens.js +0 -8
  46. package/lib/commonjs/navigators/OnboardingScreens.js.map +1 -1
  47. package/lib/commonjs/navigators/OnboardingStack.js +3 -4
  48. package/lib/commonjs/navigators/OnboardingStack.js.map +1 -1
  49. package/lib/commonjs/navigators/TabStack.js +11 -4
  50. package/lib/commonjs/navigators/TabStack.js.map +1 -1
  51. package/lib/commonjs/navigators/defaultStackOptions.js +2 -1
  52. package/lib/commonjs/navigators/defaultStackOptions.js.map +1 -1
  53. package/lib/commonjs/screens/Biometry.js.map +1 -1
  54. package/lib/commonjs/screens/NameWallet.js +4 -3
  55. package/lib/commonjs/screens/NameWallet.js.map +1 -1
  56. package/lib/commonjs/screens/OnboardingPages.js +8 -38
  57. package/lib/commonjs/screens/OnboardingPages.js.map +1 -1
  58. package/lib/commonjs/screens/PINChange.js +5 -1
  59. package/lib/commonjs/screens/PINChange.js.map +1 -1
  60. package/lib/commonjs/screens/PINCreate.js +4 -1
  61. package/lib/commonjs/screens/PINCreate.js.map +1 -1
  62. package/lib/commonjs/screens/PINEnter.js +114 -292
  63. package/lib/commonjs/screens/PINEnter.js.map +1 -1
  64. package/lib/commonjs/screens/PINVerify.js +181 -0
  65. package/lib/commonjs/screens/PINVerify.js.map +1 -0
  66. package/lib/commonjs/screens/PushNotifications.js.map +1 -1
  67. package/lib/commonjs/screens/Settings.js +9 -18
  68. package/lib/commonjs/screens/Settings.js.map +1 -1
  69. package/lib/commonjs/screens/ToggleBiometry.js +16 -24
  70. package/lib/commonjs/screens/ToggleBiometry.js.map +1 -1
  71. package/lib/commonjs/theme.js +2 -1
  72. package/lib/commonjs/theme.js.map +1 -1
  73. package/lib/commonjs/types/navigators.js +1 -0
  74. package/lib/commonjs/types/navigators.js.map +1 -1
  75. package/lib/commonjs/utils/oca.js +46 -17
  76. package/lib/commonjs/utils/oca.js.map +1 -1
  77. package/lib/module/components/inputs/BiometryControl.js.map +1 -1
  78. package/lib/module/components/misc/CredentialCard.js +3 -2
  79. package/lib/module/components/misc/CredentialCard.js.map +1 -1
  80. package/lib/module/components/misc/FauxHeader.js +80 -0
  81. package/lib/module/components/misc/FauxHeader.js.map +1 -0
  82. package/lib/module/components/misc/QRScanner.js +1 -1
  83. package/lib/module/components/misc/QRScanner.js.map +1 -1
  84. package/lib/module/components/modals/DeveloperModal.js +36 -0
  85. package/lib/module/components/modals/DeveloperModal.js.map +1 -0
  86. package/lib/module/components/views/PushNotificationsContent.js.map +1 -1
  87. package/lib/module/components/views/PushNotificationsDisabledContent.js.map +1 -1
  88. package/lib/module/contexts/auth.js +22 -1
  89. package/lib/module/contexts/auth.js.map +1 -1
  90. package/lib/module/hooks/chat-messages.js +1 -1
  91. package/lib/module/hooks/chat-messages.js.map +1 -1
  92. package/lib/module/hooks/developer-mode.js +24 -0
  93. package/lib/module/hooks/developer-mode.js.map +1 -0
  94. package/lib/module/hooks/lockout.js +70 -0
  95. package/lib/module/hooks/lockout.js.map +1 -0
  96. package/lib/module/hooks/onboarding.js +16 -0
  97. package/lib/module/hooks/onboarding.js.map +1 -0
  98. package/lib/module/index.js +4 -1
  99. package/lib/module/index.js.map +1 -1
  100. package/lib/module/localization/en/index.js +2 -1
  101. package/lib/module/localization/en/index.js.map +1 -1
  102. package/lib/module/localization/fr/index.js +2 -1
  103. package/lib/module/localization/fr/index.js.map +1 -1
  104. package/lib/module/localization/pt-br/index.js +2 -1
  105. package/lib/module/localization/pt-br/index.js.map +1 -1
  106. package/lib/module/modules/openid/components/OpenIDCredentialCard.js +4 -4
  107. package/lib/module/modules/openid/components/OpenIDCredentialCard.js.map +1 -1
  108. package/lib/module/modules/openid/display.js +6 -3
  109. package/lib/module/modules/openid/display.js.map +1 -1
  110. package/lib/module/modules/openid/metadata.js +2 -1
  111. package/lib/module/modules/openid/metadata.js.map +1 -1
  112. package/lib/module/modules/openid/screens/OpenIDProofChangeCredential.js +121 -0
  113. package/lib/module/modules/openid/screens/OpenIDProofChangeCredential.js.map +1 -0
  114. package/lib/module/modules/openid/screens/OpenIDProofPresentation.js +100 -45
  115. package/lib/module/modules/openid/screens/OpenIDProofPresentation.js.map +1 -1
  116. package/lib/module/modules/openid/types.js.map +1 -1
  117. package/lib/module/modules/openid/utils/utils.js +1 -12
  118. package/lib/module/modules/openid/utils/utils.js.map +1 -1
  119. package/lib/module/navigators/DeliveryStack.js +8 -0
  120. package/lib/module/navigators/DeliveryStack.js.map +1 -1
  121. package/lib/module/navigators/OnboardingScreens.js +0 -8
  122. package/lib/module/navigators/OnboardingScreens.js.map +1 -1
  123. package/lib/module/navigators/OnboardingStack.js +4 -5
  124. package/lib/module/navigators/OnboardingStack.js.map +1 -1
  125. package/lib/module/navigators/TabStack.js +11 -4
  126. package/lib/module/navigators/TabStack.js.map +1 -1
  127. package/lib/module/navigators/defaultStackOptions.js +2 -1
  128. package/lib/module/navigators/defaultStackOptions.js.map +1 -1
  129. package/lib/module/screens/Biometry.js.map +1 -1
  130. package/lib/module/screens/NameWallet.js +4 -3
  131. package/lib/module/screens/NameWallet.js.map +1 -1
  132. package/lib/module/screens/OnboardingPages.js +8 -38
  133. package/lib/module/screens/OnboardingPages.js.map +1 -1
  134. package/lib/module/screens/PINChange.js +5 -1
  135. package/lib/module/screens/PINChange.js.map +1 -1
  136. package/lib/module/screens/PINCreate.js +4 -1
  137. package/lib/module/screens/PINCreate.js.map +1 -1
  138. package/lib/module/screens/PINEnter.js +116 -294
  139. package/lib/module/screens/PINEnter.js.map +1 -1
  140. package/lib/module/screens/PINVerify.js +172 -0
  141. package/lib/module/screens/PINVerify.js.map +1 -0
  142. package/lib/module/screens/PushNotifications.js.map +1 -1
  143. package/lib/module/screens/Settings.js +7 -16
  144. package/lib/module/screens/Settings.js.map +1 -1
  145. package/lib/module/screens/ToggleBiometry.js +15 -23
  146. package/lib/module/screens/ToggleBiometry.js.map +1 -1
  147. package/lib/module/theme.js +2 -1
  148. package/lib/module/theme.js.map +1 -1
  149. package/lib/module/types/navigators.js +1 -0
  150. package/lib/module/types/navigators.js.map +1 -1
  151. package/lib/module/utils/oca.js +43 -15
  152. package/lib/module/utils/oca.js.map +1 -1
  153. package/lib/typescript/src/components/inputs/BiometryControl.d.ts.map +1 -1
  154. package/lib/typescript/src/components/misc/CredentialCard.d.ts.map +1 -1
  155. package/lib/typescript/src/components/misc/FauxHeader.d.ts +8 -0
  156. package/lib/typescript/src/components/misc/FauxHeader.d.ts.map +1 -0
  157. package/lib/typescript/src/components/modals/DeveloperModal.d.ts +7 -0
  158. package/lib/typescript/src/components/modals/DeveloperModal.d.ts.map +1 -0
  159. package/lib/typescript/src/contexts/auth.d.ts +1 -0
  160. package/lib/typescript/src/contexts/auth.d.ts.map +1 -1
  161. package/lib/typescript/src/hooks/developer-mode.d.ts +4 -0
  162. package/lib/typescript/src/hooks/developer-mode.d.ts.map +1 -0
  163. package/lib/typescript/src/hooks/lockout.d.ts +9 -0
  164. package/lib/typescript/src/hooks/lockout.d.ts.map +1 -0
  165. package/lib/typescript/src/hooks/onboarding.d.ts +2 -0
  166. package/lib/typescript/src/hooks/onboarding.d.ts.map +1 -0
  167. package/lib/typescript/src/index.d.ts +5 -2
  168. package/lib/typescript/src/index.d.ts.map +1 -1
  169. package/lib/typescript/src/localization/en/index.d.ts +1 -0
  170. package/lib/typescript/src/localization/en/index.d.ts.map +1 -1
  171. package/lib/typescript/src/localization/fr/index.d.ts +1 -0
  172. package/lib/typescript/src/localization/fr/index.d.ts.map +1 -1
  173. package/lib/typescript/src/localization/pt-br/index.d.ts +1 -0
  174. package/lib/typescript/src/localization/pt-br/index.d.ts.map +1 -1
  175. package/lib/typescript/src/modules/openid/components/OpenIDCredentialCard.d.ts.map +1 -1
  176. package/lib/typescript/src/modules/openid/display.d.ts.map +1 -1
  177. package/lib/typescript/src/modules/openid/metadata.d.ts +8 -1
  178. package/lib/typescript/src/modules/openid/metadata.d.ts.map +1 -1
  179. package/lib/typescript/src/modules/openid/screens/OpenIDProofChangeCredential.d.ts +6 -0
  180. package/lib/typescript/src/modules/openid/screens/OpenIDProofChangeCredential.d.ts.map +1 -0
  181. package/lib/typescript/src/modules/openid/screens/OpenIDProofPresentation.d.ts.map +1 -1
  182. package/lib/typescript/src/modules/openid/types.d.ts +9 -0
  183. package/lib/typescript/src/modules/openid/types.d.ts.map +1 -1
  184. package/lib/typescript/src/modules/openid/utils/utils.d.ts +1 -3
  185. package/lib/typescript/src/modules/openid/utils/utils.d.ts.map +1 -1
  186. package/lib/typescript/src/navigators/DeliveryStack.d.ts.map +1 -1
  187. package/lib/typescript/src/navigators/OnboardingScreens.d.ts +0 -1
  188. package/lib/typescript/src/navigators/OnboardingScreens.d.ts.map +1 -1
  189. package/lib/typescript/src/navigators/OnboardingStack.d.ts.map +1 -1
  190. package/lib/typescript/src/navigators/TabStack.d.ts.map +1 -1
  191. package/lib/typescript/src/navigators/defaultStackOptions.d.ts.map +1 -1
  192. package/lib/typescript/src/screens/Biometry.d.ts.map +1 -1
  193. package/lib/typescript/src/screens/OnboardingPages.d.ts +1 -1
  194. package/lib/typescript/src/screens/OnboardingPages.d.ts.map +1 -1
  195. package/lib/typescript/src/screens/PINChange.d.ts.map +1 -1
  196. package/lib/typescript/src/screens/PINCreate.d.ts.map +1 -1
  197. package/lib/typescript/src/screens/PINEnter.d.ts +0 -7
  198. package/lib/typescript/src/screens/PINEnter.d.ts.map +1 -1
  199. package/lib/typescript/src/screens/PINVerify.d.ts +13 -0
  200. package/lib/typescript/src/screens/PINVerify.d.ts.map +1 -0
  201. package/lib/typescript/src/screens/Settings.d.ts.map +1 -1
  202. package/lib/typescript/src/screens/ToggleBiometry.d.ts.map +1 -1
  203. package/lib/typescript/src/theme.d.ts +10 -25
  204. package/lib/typescript/src/theme.d.ts.map +1 -1
  205. package/lib/typescript/src/types/navigators.d.ts +14 -1
  206. package/lib/typescript/src/types/navigators.d.ts.map +1 -1
  207. package/lib/typescript/src/utils/oca.d.ts +7 -2
  208. package/lib/typescript/src/utils/oca.d.ts.map +1 -1
  209. package/package.json +3 -3
  210. package/src/components/inputs/BiometryControl.tsx +16 -13
  211. package/src/components/misc/CredentialCard.tsx +5 -2
  212. package/src/components/misc/FauxHeader.tsx +75 -0
  213. package/src/components/misc/QRScanner.tsx +1 -1
  214. package/src/components/modals/DeveloperModal.tsx +30 -0
  215. package/src/components/views/PushNotificationsContent.tsx +15 -15
  216. package/src/components/views/PushNotificationsDisabledContent.tsx +10 -10
  217. package/src/contexts/auth.tsx +33 -1
  218. package/src/hooks/chat-messages.tsx +1 -1
  219. package/src/hooks/developer-mode.ts +25 -0
  220. package/src/hooks/lockout.ts +77 -0
  221. package/src/hooks/onboarding.ts +16 -0
  222. package/src/hooks/usePINValidation.ts +3 -3
  223. package/src/index.ts +7 -0
  224. package/src/localization/en/index.ts +1 -0
  225. package/src/localization/fr/index.ts +1 -0
  226. package/src/localization/pt-br/index.ts +1 -0
  227. package/src/modules/openid/components/OpenIDCredentialCard.tsx +3 -4
  228. package/src/modules/openid/display.tsx +3 -0
  229. package/src/modules/openid/metadata.tsx +7 -1
  230. package/src/modules/openid/screens/OpenIDProofChangeCredential.tsx +132 -0
  231. package/src/modules/openid/screens/OpenIDProofPresentation.tsx +131 -59
  232. package/src/modules/openid/types.tsx +8 -0
  233. package/src/modules/openid/utils/utils.tsx +0 -14
  234. package/src/navigators/DeliveryStack.tsx +9 -0
  235. package/src/navigators/OnboardingScreens.ts +0 -10
  236. package/src/navigators/OnboardingStack.tsx +2 -6
  237. package/src/navigators/RootStack.tsx +1 -1
  238. package/src/navigators/TabStack.tsx +3 -2
  239. package/src/navigators/defaultStackOptions.tsx +1 -0
  240. package/src/screens/Biometry.tsx +1 -4
  241. package/src/screens/NameWallet.tsx +2 -2
  242. package/src/screens/OnboardingPages.tsx +9 -61
  243. package/src/screens/PINChange.tsx +6 -9
  244. package/src/screens/PINCreate.tsx +7 -18
  245. package/src/screens/PINEnter.tsx +114 -361
  246. package/src/screens/PINVerify.tsx +193 -0
  247. package/src/screens/PushNotifications.tsx +2 -2
  248. package/src/screens/Settings.tsx +6 -21
  249. package/src/screens/ToggleBiometry.tsx +20 -34
  250. package/src/theme.ts +34 -3
  251. package/src/types/navigators.ts +18 -1
  252. package/src/utils/oca.ts +60 -19
@@ -0,0 +1,193 @@
1
+ import React, { useCallback, useEffect, useState } from 'react'
2
+ import { useTranslation } from 'react-i18next'
3
+ import { Keyboard, StyleSheet, View } from 'react-native'
4
+ import Button, { ButtonType } from '../components/buttons/Button'
5
+ import { InlineMessageProps } from '../components/inputs/InlineErrorText'
6
+ import PINInput from '../components/inputs/PINInput'
7
+ import { InfoBoxType } from '../components/misc/InfoBox'
8
+ import PopupModal from '../components/modals/PopupModal'
9
+ import { ThemedText } from '../components/texts/ThemedText'
10
+ import KeyboardView from '../components/views/KeyboardView'
11
+ import { minPINLength } from '../constants'
12
+ import { TOKENS, useServices } from '../container-api'
13
+ import { useAnimatedComponents } from '../contexts/animated-components'
14
+ import { useAuth } from '../contexts/auth'
15
+ import { useTheme } from '../contexts/theme'
16
+ import usePreventScreenCapture from '../hooks/screen-capture'
17
+ import { testIdWithKey } from '../utils/testable'
18
+
19
+ interface Props {
20
+ setAuthenticated: (status: boolean) => void
21
+ usage?: PINEntryUsage
22
+ onCancelAuth?: React.Dispatch<React.SetStateAction<boolean>>
23
+ }
24
+
25
+ export enum PINEntryUsage {
26
+ PINCheck,
27
+ ChangeBiometrics,
28
+ }
29
+
30
+ const PINVerify: React.FC<Props> = ({ setAuthenticated, usage = PINEntryUsage.PINCheck, onCancelAuth }) => {
31
+ const { t } = useTranslation()
32
+ const { verifyPIN } = useAuth()
33
+ const [PIN, setPIN] = useState<string>('')
34
+ const [continueDisabled, setContinueDisabled] = useState(false)
35
+ const [loading, setLoading] = useState(false)
36
+ const [alertModalVisible, setAlertModalVisible] = useState<boolean>(false)
37
+ const { ColorPallet } = useTheme()
38
+ const { ButtonLoading } = useAnimatedComponents()
39
+ const [inlineMessageField, setInlineMessageField] = useState<InlineMessageProps>()
40
+ // Temporary until all use cases are built with the new design
41
+ const isNewDesign = usage === PINEntryUsage.ChangeBiometrics
42
+ const [{ preventScreenCapture }] = useServices([TOKENS.CONFIG])
43
+ usePreventScreenCapture(preventScreenCapture)
44
+
45
+ useEffect(() => {
46
+ setInlineMessageField(undefined)
47
+ }, [PIN])
48
+
49
+ const clearAlertModal = useCallback(() => {
50
+ setAlertModalVisible(false)
51
+ setAuthenticated(false)
52
+ }, [setAlertModalVisible, setAuthenticated])
53
+
54
+ const onPINInputCompleted = useCallback(async () => {
55
+ Keyboard.dismiss()
56
+ setLoading(true)
57
+ setContinueDisabled(true)
58
+ const isPINVerified = await verifyPIN(PIN)
59
+ if (isPINVerified) {
60
+ setAuthenticated(true)
61
+ } else {
62
+ setAlertModalVisible(true)
63
+ }
64
+ setLoading(false)
65
+ setContinueDisabled(false)
66
+ }, [verifyPIN, setLoading, setAuthenticated, setContinueDisabled, PIN])
67
+
68
+ const inputLabelText = {
69
+ [PINEntryUsage.ChangeBiometrics]: t('PINEnter.ChangeBiometricsInputLabel'),
70
+ [PINEntryUsage.PINCheck]: t('PINEnter.AppSettingChangedEnterPIN'),
71
+ }
72
+
73
+ const inputTestId = {
74
+ [PINEntryUsage.ChangeBiometrics]: 'BiometricChangedEnterPIN',
75
+ [PINEntryUsage.PINCheck]: 'AppSettingChangedEnterPIN',
76
+ }
77
+
78
+ const primaryButtonText = {
79
+ [PINEntryUsage.ChangeBiometrics]: t('Global.Continue'),
80
+ [PINEntryUsage.PINCheck]: t('PINEnter.AppSettingSave'),
81
+ }
82
+
83
+ const primaryButtonTestId = {
84
+ [PINEntryUsage.ChangeBiometrics]: 'Continue',
85
+ [PINEntryUsage.PINCheck]: 'AppSettingSave',
86
+ }
87
+
88
+ const helpText = {
89
+ [PINEntryUsage.ChangeBiometrics]: t('PINEnter.ChangeBiometricsSubtext'),
90
+ [PINEntryUsage.PINCheck]: t('PINEnter.AppSettingChanged'),
91
+ }
92
+
93
+ const isContinueDisabled = continueDisabled || PIN.length < minPINLength
94
+
95
+ const style = StyleSheet.create({
96
+ screenContainer: {
97
+ flex: 1,
98
+ padding: 20,
99
+ backgroundColor: ColorPallet.brand.primaryBackground,
100
+ justifyContent: isNewDesign ? 'flex-start' : 'space-between',
101
+ },
102
+ buttonContainer: {
103
+ marginTop: 'auto',
104
+ width: '100%',
105
+ },
106
+ helpText: {
107
+ alignSelf: 'auto',
108
+ textAlign: 'left',
109
+ marginBottom: isNewDesign ? 40 : 20,
110
+ },
111
+ inputLabelText: {
112
+ alignSelf: 'auto',
113
+ textAlign: 'left',
114
+ marginBottom: isNewDesign ? 20 : 4,
115
+ },
116
+ modalText: {
117
+ marginVertical: 5,
118
+ },
119
+ changeBiometricsHeader: {
120
+ marginTop: 0,
121
+ marginBottom: isNewDesign ? 40 : 20,
122
+ },
123
+ })
124
+
125
+ return (
126
+ <KeyboardView>
127
+ <View style={style.screenContainer}>
128
+ {usage === PINEntryUsage.ChangeBiometrics && (
129
+ <ThemedText variant="headingTwo" style={style.changeBiometricsHeader}>
130
+ {t('PINEnter.ChangeBiometricsHeader')}
131
+ </ThemedText>
132
+ )}
133
+ <ThemedText style={style.helpText}>{helpText[usage]}</ThemedText>
134
+ <ThemedText variant="bold" style={style.inputLabelText}>
135
+ {inputLabelText[usage]}
136
+ {usage === PINEntryUsage.ChangeBiometrics && (
137
+ <ThemedText variant="caption">
138
+ {` `}
139
+ {t('PINEnter.ChangeBiometricsInputLabelParenthesis')}
140
+ </ThemedText>
141
+ )}
142
+ </ThemedText>
143
+ <PINInput
144
+ onPINChanged={(p: string) => {
145
+ setPIN(p)
146
+ if (p.length === minPINLength) {
147
+ Keyboard.dismiss()
148
+ }
149
+ }}
150
+ testID={testIdWithKey(inputTestId[usage])}
151
+ accessibilityLabel={inputLabelText[usage]}
152
+ autoFocus={true}
153
+ inlineMessage={inlineMessageField}
154
+ />
155
+ <View style={style.buttonContainer}>
156
+ <Button
157
+ title={primaryButtonText[usage]}
158
+ buttonType={ButtonType.Primary}
159
+ testID={testIdWithKey(primaryButtonTestId[usage])}
160
+ disabled={isContinueDisabled}
161
+ accessibilityLabel={primaryButtonText[usage]}
162
+ onPress={async () => {
163
+ await onPINInputCompleted()
164
+ }}
165
+ >
166
+ {loading && <ButtonLoading />}
167
+ </Button>
168
+ </View>
169
+ {usage === PINEntryUsage.PINCheck && (
170
+ <View style={[style.buttonContainer, { marginTop: 10 }]}>
171
+ <Button
172
+ title={t('PINEnter.AppSettingCancel')}
173
+ buttonType={ButtonType.Secondary}
174
+ testID={testIdWithKey('AppSettingCancel')}
175
+ accessibilityLabel={t('PINEnter.AppSettingCancel')}
176
+ onPress={() => onCancelAuth?.(false)}
177
+ />
178
+ </View>
179
+ )}
180
+ </View>
181
+ {alertModalVisible && (
182
+ <PopupModal
183
+ notificationType={InfoBoxType.Info}
184
+ title={t('PINEnter.IncorrectPIN')}
185
+ onCallToActionLabel={t('Global.Okay')}
186
+ onCallToActionPressed={clearAlertModal}
187
+ />
188
+ )}
189
+ </KeyboardView>
190
+ )
191
+ }
192
+
193
+ export default PINVerify
@@ -28,7 +28,7 @@ const PushNotifications: React.FC = () => {
28
28
  },
29
29
  controlsContainer: {
30
30
  marginTop: 'auto',
31
- }
31
+ },
32
32
  })
33
33
 
34
34
  const activatePushNotifications = async () => {
@@ -40,7 +40,7 @@ const PushNotifications: React.FC = () => {
40
40
  <SafeAreaView style={{ flex: 1 }} edges={['left', 'right', 'bottom']}>
41
41
  <ScrollView contentContainerStyle={{ flexGrow: 1 }}>
42
42
  <View style={styles.screenContainer}>
43
- <PushNotificationsContent/>
43
+ <PushNotificationsContent />
44
44
  <View style={styles.controlsContainer}>
45
45
  <Button
46
46
  buttonType={ButtonType.Primary}
@@ -1,5 +1,5 @@
1
1
  import { StackScreenProps } from '@react-navigation/stack'
2
- import React, { useRef } from 'react'
2
+ import React from 'react'
3
3
  import { useTranslation } from 'react-i18next'
4
4
  import {
5
5
  ScrollView,
@@ -18,9 +18,9 @@ import IconButton, { ButtonLocation } from '../components/buttons/IconButton'
18
18
  import { ThemedText } from '../components/texts/ThemedText'
19
19
  import { TOKENS, useServices } from '../container-api'
20
20
  import { AutoLockTime } from '../contexts/activity'
21
- import { DispatchAction } from '../contexts/reducers/store'
22
21
  import { useStore } from '../contexts/store'
23
22
  import { useTheme } from '../contexts/theme'
23
+ import { useDeveloperMode } from '../hooks/developer-mode'
24
24
  import { Locales } from '../localization'
25
25
  import { GenericFn } from '../types/fn'
26
26
  import { Screens, SettingStackParams, Stacks } from '../types/navigators'
@@ -29,12 +29,11 @@ import { testIdWithKey } from '../utils/testable'
29
29
 
30
30
  type SettingsProps = StackScreenProps<SettingStackParams>
31
31
 
32
- const touchCountToEnableBiometrics = 9
33
-
34
32
  const Settings: React.FC<SettingsProps> = ({ navigation }) => {
35
33
  const { t, i18n } = useTranslation()
36
- const [store, dispatch] = useStore()
37
- const developerOptionCount = useRef(0)
34
+ const [store] = useStore()
35
+ const onDevModeTriggered = () => navigation.navigate(Screens.Developer)
36
+ const { incrementDeveloperMenuCounter } = useDeveloperMode(onDevModeTriggered)
38
37
  const { SettingsTheme, TextTheme, ColorPallet, Assets, maxFontSizeMultiplier } = useTheme()
39
38
  const [{ settings, enableTours, enablePushNotifications, disableContactsInSettings }, historyEnabled] = useServices([
40
39
  TOKENS.CONFIG,
@@ -82,19 +81,6 @@ const Settings: React.FC<SettingsProps> = ({ navigation }) => {
82
81
  })
83
82
 
84
83
  const currentLanguage = i18n.t('Language.code', { context: i18n.language as Locales })
85
- const incrementDeveloperMenuCounter = () => {
86
- if (developerOptionCount.current >= touchCountToEnableBiometrics) {
87
- developerOptionCount.current = 0
88
- dispatch({
89
- type: DispatchAction.ENABLE_DEVELOPER_MODE,
90
- payload: [true],
91
- })
92
-
93
- return
94
- }
95
-
96
- developerOptionCount.current = developerOptionCount.current + 1
97
- }
98
84
 
99
85
  const settingsSections: SettingSection[] = [
100
86
  {
@@ -182,8 +168,7 @@ const Settings: React.FC<SettingsProps> = ({ navigation }) => {
182
168
  value: undefined,
183
169
  accessibilityLabel: t('Settings.Notifications'),
184
170
  testID: testIdWithKey('Notifications'),
185
- onPress: () =>
186
- navigation.navigate(Screens.TogglePushNotifications),
171
+ onPress: () => navigation.navigate(Screens.TogglePushNotifications),
187
172
  })
188
173
  }
189
174
 
@@ -1,8 +1,8 @@
1
- import { Header, HeaderBackButton, useHeaderHeight } from '@react-navigation/elements'
2
1
  import React, { useCallback, useState } from 'react'
3
2
  import { useTranslation } from 'react-i18next'
4
3
 
5
4
  import BiometryControl from '../components/inputs/BiometryControl'
5
+ import FauxHeader from '../components/misc/FauxHeader'
6
6
  import SafeAreaModal from '../components/modals/SafeAreaModal'
7
7
  import { TOKENS, useServices } from '../container-api'
8
8
  import { useAuth } from '../contexts/auth'
@@ -11,15 +11,9 @@ import { useStore } from '../contexts/store'
11
11
  import { useTheme } from '../contexts/theme'
12
12
  import { HistoryCardType, HistoryRecord } from '../modules/history/types'
13
13
  import { useAppAgent } from '../utils/agent'
14
- import PINEnter, { PINEntryUsage } from './PINEnter'
14
+ import PINVerify, { PINEntryUsage } from './PINVerify'
15
+ import { SafeAreaView } from 'react-native-safe-area-context'
15
16
 
16
- interface BackButtonProps {
17
- setCanSeeCheckPIN: (value: boolean) => void
18
- }
19
-
20
- const BackButton: React.FC<BackButtonProps> = ({ setCanSeeCheckPIN }) => (
21
- <HeaderBackButton onPress={() => setCanSeeCheckPIN(false)} tintColor="white" labelVisible={false} />
22
- )
23
17
 
24
18
  const ToggleBiometry: React.FC = () => {
25
19
  const [store, dispatch] = useStore()
@@ -34,8 +28,7 @@ const ToggleBiometry: React.FC = () => {
34
28
  const { commitWalletToKeychain, disableBiometrics } = useAuth()
35
29
  const [biometryEnabled, setBiometryEnabled] = useState(store.preferences.useBiometry)
36
30
  const [canSeeCheckPIN, setCanSeeCheckPIN] = useState<boolean>(false)
37
- const { TextTheme, ColorPallet } = useTheme()
38
- const headerHeight = useHeaderHeight()
31
+ const { ColorPallet, NavigationTheme } = useTheme()
39
32
 
40
33
  const logHistoryRecord = useCallback(
41
34
  (type: HistoryCardType) => {
@@ -79,11 +72,14 @@ const ToggleBiometry: React.FC = () => {
79
72
  store.onboarding.didConsiderBiometry,
80
73
  ])
81
74
 
82
- const handleBiometryToggle = useCallback((newValue: boolean) => {
83
- if (newValue === biometryEnabled) return
84
-
85
- onSwitchToggleAllowed()
86
- }, [biometryEnabled, onSwitchToggleAllowed])
75
+ const handleBiometryToggle = useCallback(
76
+ (newValue: boolean) => {
77
+ if (newValue === biometryEnabled) return
78
+
79
+ onSwitchToggleAllowed()
80
+ },
81
+ [biometryEnabled, onSwitchToggleAllowed]
82
+ )
87
83
 
88
84
  const onAuthenticationComplete = useCallback(
89
85
  (status: boolean) => {
@@ -91,7 +87,7 @@ const ToggleBiometry: React.FC = () => {
91
87
  if (status) {
92
88
  const newValue = !biometryEnabled
93
89
  setBiometryEnabled(newValue)
94
-
90
+
95
91
  if (newValue) {
96
92
  commitWalletToKeychain(newValue).then(() => {
97
93
  dispatch({
@@ -107,7 +103,7 @@ const ToggleBiometry: React.FC = () => {
107
103
  })
108
104
  })
109
105
  }
110
-
106
+
111
107
  if (
112
108
  historyEventsLogger.logToggleBiometry &&
113
109
  store.onboarding.didAgreeToTerms &&
@@ -131,30 +127,20 @@ const ToggleBiometry: React.FC = () => {
131
127
  ]
132
128
  )
133
129
 
134
- const renderHeaderLeft = useCallback(
135
- () => <BackButton setCanSeeCheckPIN={() => setCanSeeCheckPIN(false)} />,
136
- [setCanSeeCheckPIN]
137
- )
130
+ const onBackPressed = () => setCanSeeCheckPIN(false)
138
131
 
139
132
  return (
140
- <BiometryControl
141
- biometryEnabled={biometryEnabled}
142
- onBiometryToggle={handleBiometryToggle}
143
- >
133
+ <BiometryControl biometryEnabled={biometryEnabled} onBiometryToggle={handleBiometryToggle}>
144
134
  <SafeAreaModal
145
135
  style={{ backgroundColor: ColorPallet.brand.primaryBackground }}
146
136
  visible={canSeeCheckPIN}
147
137
  transparent={false}
148
138
  animationType={'slide'}
149
- presentationStyle="fullScreen"
139
+ presentationStyle={'fullScreen'}
150
140
  >
151
- <Header
152
- title={t('Screens.EnterPIN')}
153
- headerTitleStyle={TextTheme.headerTitle}
154
- headerStyle={{ height: headerHeight }}
155
- headerLeft={renderHeaderLeft}
156
- />
157
- <PINEnter
141
+ <SafeAreaView edges={['top']} style={{ backgroundColor: NavigationTheme.colors.primary }}/>
142
+ <FauxHeader title={t('Screens.EnterPIN')} onBackPressed={onBackPressed}/>
143
+ <PINVerify
158
144
  usage={PINEntryUsage.ChangeBiometrics}
159
145
  setAuthenticated={onAuthenticationComplete}
160
146
  onCancelAuth={setCanSeeCheckPIN}
package/src/theme.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { StyleSheet, ViewStyle } from 'react-native'
1
+ import { StyleSheet, TextStyle, ViewStyle } from 'react-native'
2
2
  import { SvgProps } from 'react-native-svg'
3
3
 
4
4
  import Arrow from './assets/icons/large-arrow.svg'
@@ -717,7 +717,37 @@ export const ListItems = StyleSheet.create({
717
717
  },
718
718
  })
719
719
 
720
- export const TabTheme = {
720
+ export interface ITabTheme {
721
+ tabBarStyle: ViewStyle & {
722
+ height: number
723
+ backgroundColor: string
724
+ shadowOffset: {
725
+ width: number
726
+ height: number
727
+ }
728
+ shadowRadius: number
729
+ shadowColor: string
730
+ shadowOpacity: number
731
+ borderTopWidth: number
732
+ paddingBottom: number
733
+ },
734
+ tabBarContainerStyle: ViewStyle,
735
+ tabBarActiveTintColor: string,
736
+ tabBarInactiveTintColor: string,
737
+ tabBarTextStyle: TextStyle & {
738
+ fontSize: number
739
+ },
740
+ tabBarButtonIconStyle: {
741
+ color: string
742
+ },
743
+ focusTabIconStyle: ViewStyle,
744
+ focusTabActiveTintColor: {
745
+ backgroundColor: string
746
+ },
747
+ tabBarSecondaryBackgroundColor: string,
748
+ }
749
+
750
+ export const TabTheme: ITabTheme = {
721
751
  tabBarStyle: {
722
752
  height: 60,
723
753
  backgroundColor: ColorPallet.brand.secondaryBackground,
@@ -753,6 +783,7 @@ export const TabTheme = {
753
783
  focusTabActiveTintColor: {
754
784
  backgroundColor: ColorPallet.brand.secondary,
755
785
  },
786
+ tabBarSecondaryBackgroundColor: ColorPallet.brand.secondaryBackground,
756
787
  }
757
788
 
758
789
  export const NavigationTheme = {
@@ -1098,7 +1129,7 @@ export interface ITheme {
1098
1129
  Inputs: IInputs
1099
1130
  Buttons: any
1100
1131
  ListItems: any
1101
- TabTheme: any
1132
+ TabTheme: ITabTheme
1102
1133
  NavigationTheme: any
1103
1134
  HomeTheme: any
1104
1135
  SettingsTheme: any
@@ -22,6 +22,7 @@ export enum Screens {
22
22
  OpenIDCredentialDetails = 'Open ID Credential details',
23
23
  OpenIDCredentialOffer = 'Open ID Credential offer',
24
24
  OpenIDProofPresentation = 'Open ID Proof Presentation',
25
+ OpenIDProofCredentialSelect = 'Open ID Proof Credential Select',
25
26
  ProofRequest = 'Proof Request',
26
27
  ProofRequestDetails = 'Proof Request Details',
27
28
  ProofRequestUsageHistory = 'Proof Request Usage History',
@@ -108,7 +109,6 @@ export type OnboardingStackParams = {
108
109
  [Screens.Biometry]: undefined
109
110
  [Screens.NameWallet]: undefined
110
111
  [Screens.PushNotifications]: undefined
111
- [Screens.Developer]: undefined
112
112
  }
113
113
 
114
114
  export type ContactStackParams = {
@@ -199,6 +199,23 @@ export type DeliveryStackParams = {
199
199
  credential: SdJwtVcRecord | W3cCredentialRecord | MdocRecord
200
200
  }
201
201
  [Screens.OpenIDProofPresentation]: { credential: OpenId4VPRequestRecord }
202
+ [Screens.OpenIDProofCredentialSelect]: {
203
+ inputDescriptorID: string
204
+ selectedCredID: string
205
+ altCredIDs: {
206
+ id: string
207
+ claimFormat: string
208
+ }[]
209
+ onCredChange: ({
210
+ inputDescriptorID,
211
+ id,
212
+ claimFormat,
213
+ }: {
214
+ inputDescriptorID: string
215
+ id: string
216
+ claimFormat: string
217
+ }) => void
218
+ }
202
219
  }
203
220
 
204
221
  export type HistoryStackParams = {
package/src/utils/oca.ts CHANGED
@@ -11,32 +11,73 @@ import {
11
11
  import { W3cCredentialDisplay } from '../modules/openid/types'
12
12
  import { BrandingOverlay } from '@bifold/oca'
13
13
 
14
- export const buildFieldsFromAnonCredsCredential = (credential: CredentialExchangeRecord): Array<Field> => {
15
- return credential?.credentialAttributes?.map((attr) => new Attribute(attr)) || []
14
+ export type FieldExt = {
15
+ field: Attribute
16
+ attribute_name: string
16
17
  }
17
18
 
18
- export const buildFieldsFromW3cCredsCredential = (value: W3cCredentialDisplay): Array<Field> => {
19
- return (
20
- Object.entries(value.attributes)
21
- .filter(([key]) => key !== 'id')
22
- .map(([key, value]) => {
23
- let formattedValue: string | number | null
19
+ type AttributeFieldValue = string | number | null
24
20
 
25
- if (typeof value === 'object' && value !== null) {
26
- formattedValue = JSON.stringify(value) // Convert object to string
27
- } else {
28
- formattedValue = value as string | number | null
29
- }
21
+ export const getAttributeField = (display: W3cCredentialDisplay, searchKey: string): FieldExt | undefined => {
22
+ let attributeName: string = 'Unknown'
23
+ let attributeValue: AttributeFieldValue = 'Unknown'
30
24
 
31
- return new Attribute({
32
- name: key,
33
- value: formattedValue,
34
- mimeType: typeof value === 'number' ? 'text/number' : 'text/plain',
35
- })
36
- }) || []
25
+ for (const [key, value] of Object.entries(display.attributes)) {
26
+ let formattedValue: AttributeFieldValue
27
+
28
+ if (searchKey === key) {
29
+ if (typeof value === 'object' && value !== null) {
30
+ formattedValue = JSON.stringify(value) // Convert object to string
31
+ } else {
32
+ formattedValue = value as AttributeFieldValue
33
+ }
34
+
35
+ attributeName = key
36
+ attributeValue = formattedValue
37
+ }
38
+ }
39
+
40
+ //Now check credentialSubject for attributeName mapping
41
+ const credentialSubject = display.credentialSubject
42
+
43
+ if (credentialSubject) {
44
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
45
+ for (const [key, value] of Object.entries(credentialSubject)) {
46
+ if (key !== searchKey || !value) continue
47
+ const { display } = value
48
+ const { name } = display[0]
49
+ attributeName = name
50
+ }
51
+ }
52
+
53
+ return {
54
+ field: new Attribute({
55
+ name: attributeName,
56
+ value: attributeValue,
57
+ mimeType: typeof attributeValue === 'number' ? 'text/number' : 'text/plain',
58
+ }),
59
+ attribute_name: searchKey,
60
+ }
61
+ }
62
+
63
+ export const buildFieldsFromW3cCredsCredential = (
64
+ display: W3cCredentialDisplay,
65
+ filterByAttributes?: string[]
66
+ ): Array<Field> => {
67
+ return (
68
+ Object.entries(display.attributes)
69
+ .filter(([key]) => key !== 'id')
70
+ .map(([key]) => getAttributeField(display, key))
71
+ .filter((field) => field !== undefined)
72
+ .filter((field: FieldExt) => (filterByAttributes ? filterByAttributes.includes(field.attribute_name) : true))
73
+ .map((fld) => fld.field) || []
37
74
  )
38
75
  }
39
76
 
77
+ export const buildFieldsFromAnonCredsCredential = (credential: CredentialExchangeRecord): Array<Field> => {
78
+ return credential?.credentialAttributes?.map((attr) => new Attribute(attr)) || []
79
+ }
80
+
40
81
  export const buildFieldsFromAnonCredsProofRequestTemplate = (
41
82
  data: AnonCredsProofRequestTemplatePayloadData
42
83
  ): Array<Field> => {