@authing/react-ui-components 3.0.0-alpha → 3.0.0-rc.11

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 (235) hide show
  1. package/dist/index.min.css +2 -0
  2. package/dist/index.min.js +2 -0
  3. package/dist/index.min.js.LICENSE.txt +71 -0
  4. package/{components/ShieldSpin/loading.svg → dist/static/media/loading.4a67a5f3.svg} +0 -0
  5. package/lib/index.d.ts +2108 -118
  6. package/lib/index.min.css +2 -2
  7. package/lib/index.min.js +1 -1
  8. package/lib/index.min.js.LICENSE.txt +2 -0
  9. package/package.json +32 -10
  10. package/.eslintignore +0 -6
  11. package/.eslintrc.js +0 -7
  12. package/.prettierrc +0 -5
  13. package/.vscode/settings.json +0 -31
  14. package/build/favicon.ico +0 -0
  15. package/build/logo192.png +0 -0
  16. package/build/logo512.png +0 -0
  17. package/build/manifest.json +0 -25
  18. package/build/robots.txt +0 -3
  19. package/components/AuthingDropdown/index.tsx +0 -52
  20. package/components/AuthingDropdown/style.less +0 -43
  21. package/components/AuthingGuard/AppMFALayout/index.tsx +0 -74
  22. package/components/AuthingGuard/AppMFALayout/style.less +0 -12
  23. package/components/AuthingGuard/CompleteUserInfoLayout/index.tsx +0 -29
  24. package/components/AuthingGuard/CompleteUserInfoLayout/style.less +0 -8
  25. package/components/AuthingGuard/Forms/ADLoginForm/index.tsx +0 -117
  26. package/components/AuthingGuard/Forms/Agreements/index.tsx +0 -81
  27. package/components/AuthingGuard/Forms/Agreements/style.less +0 -44
  28. package/components/AuthingGuard/Forms/CompleteUserInfoForm/index.tsx +0 -139
  29. package/components/AuthingGuard/Forms/EmailMfaVerifyForm/CheckEmailForm.tsx +0 -84
  30. package/components/AuthingGuard/Forms/EmailMfaVerifyForm/VerifyCodeForm.tsx +0 -116
  31. package/components/AuthingGuard/Forms/EmailMfaVerifyForm/index.tsx +0 -40
  32. package/components/AuthingGuard/Forms/EmailMfaVerifyForm/style.less +0 -0
  33. package/components/AuthingGuard/Forms/EmailRegisterForm/index.tsx +0 -181
  34. package/components/AuthingGuard/Forms/EmailRegisterForm/style.less +0 -0
  35. package/components/AuthingGuard/Forms/LdapLoginForm/index.tsx +0 -166
  36. package/components/AuthingGuard/Forms/LdapLoginForm/style.less +0 -0
  37. package/components/AuthingGuard/Forms/LoginFormFooter/index.tsx +0 -76
  38. package/components/AuthingGuard/Forms/LoginFormFooter/style.less +0 -6
  39. package/components/AuthingGuard/Forms/MfaResetCodeForm/Step1.tsx +0 -86
  40. package/components/AuthingGuard/Forms/MfaResetCodeForm/Step2.tsx +0 -53
  41. package/components/AuthingGuard/Forms/MfaResetCodeForm/index.tsx +0 -65
  42. package/components/AuthingGuard/Forms/MfaResetCodeForm/style.less +0 -20
  43. package/components/AuthingGuard/Forms/MfaVerifyForm/index.tsx +0 -105
  44. package/components/AuthingGuard/Forms/MfaVerifyForm/style.less +0 -12
  45. package/components/AuthingGuard/Forms/PasswordLoginForm/index.tsx +0 -261
  46. package/components/AuthingGuard/Forms/PhoneCodeLoginForm/index.tsx +0 -133
  47. package/components/AuthingGuard/Forms/PhoneRegisterForm/index.tsx +0 -202
  48. package/components/AuthingGuard/Forms/QrCodeLoginForm/index.tsx +0 -59
  49. package/components/AuthingGuard/Forms/QrCodeLoginForm/style.less +0 -14
  50. package/components/AuthingGuard/Forms/RegisterFormFooter/index.tsx +0 -56
  51. package/components/AuthingGuard/Forms/RegisterFormFooter/style.less +0 -0
  52. package/components/AuthingGuard/Forms/ResetPwdForm/Footer.tsx +0 -21
  53. package/components/AuthingGuard/Forms/ResetPwdForm/Step1.tsx +0 -86
  54. package/components/AuthingGuard/Forms/ResetPwdForm/Step2.tsx +0 -127
  55. package/components/AuthingGuard/Forms/ResetPwdForm/Step3.tsx +0 -141
  56. package/components/AuthingGuard/Forms/ResetPwdForm/Step4.tsx +0 -51
  57. package/components/AuthingGuard/Forms/ResetPwdForm/index.tsx +0 -96
  58. package/components/AuthingGuard/Forms/ResetPwdForm/style.less +0 -3
  59. package/components/AuthingGuard/Forms/SendPhoneCode/SendCodeBtn.tsx +0 -88
  60. package/components/AuthingGuard/Forms/SendPhoneCode/index.tsx +0 -50
  61. package/components/AuthingGuard/Forms/SendPhoneCode/style.less +0 -26
  62. package/components/AuthingGuard/Forms/SmsMfaVerifyForm/CheckPhoneForm.tsx +0 -86
  63. package/components/AuthingGuard/Forms/SmsMfaVerifyForm/VerifyCodeForm.tsx +0 -113
  64. package/components/AuthingGuard/Forms/SmsMfaVerifyForm/index.tsx +0 -40
  65. package/components/AuthingGuard/Forms/SmsMfaVerifyForm/style.less +0 -3
  66. package/components/AuthingGuard/Forms/SocialAndIdpLogin/index.tsx +0 -325
  67. package/components/AuthingGuard/Forms/SocialAndIdpLogin/style.less +0 -75
  68. package/components/AuthingGuard/Forms/UploadImage/index.tsx +0 -70
  69. package/components/AuthingGuard/Forms/index.ts +0 -13
  70. package/components/AuthingGuard/GuardLayout/index.tsx +0 -474
  71. package/components/AuthingGuard/GuardLayout/style.less +0 -111
  72. package/components/AuthingGuard/Header/index.tsx +0 -25
  73. package/components/AuthingGuard/Header/style.less +0 -52
  74. package/components/AuthingGuard/IconFont/iconfont.js +0 -74
  75. package/components/AuthingGuard/IconFont/index.tsx +0 -19
  76. package/components/AuthingGuard/IconFont/style.less +0 -6
  77. package/components/AuthingGuard/IconFont/svg.js +0 -2
  78. package/components/AuthingGuard/LoginLayout/index.tsx +0 -161
  79. package/components/AuthingGuard/LoginLayout/style.less +0 -0
  80. package/components/AuthingGuard/MfaLayout/Steps.ts +0 -4
  81. package/components/AuthingGuard/MfaLayout/index.tsx +0 -49
  82. package/components/AuthingGuard/MfaLayout/style.less +0 -3
  83. package/components/AuthingGuard/RegisterLayout/index.tsx +0 -89
  84. package/components/AuthingGuard/RegisterLayout/style.less +0 -0
  85. package/components/AuthingGuard/ResetPwdLayout/index.tsx +0 -20
  86. package/components/AuthingGuard/ToggleLang/index.tsx +0 -51
  87. package/components/AuthingGuard/api/appConfig.ts +0 -146
  88. package/components/AuthingGuard/api/index.ts +0 -3
  89. package/components/AuthingGuard/api/sso.ts +0 -29
  90. package/components/AuthingGuard/api/userPoolConfig.ts +0 -111
  91. package/components/AuthingGuard/constants.ts +0 -105
  92. package/components/AuthingGuard/hooks/index.tsx +0 -70
  93. package/components/AuthingGuard/hooks/useScreenSize.tsx +0 -68
  94. package/components/AuthingGuard/index.tsx +0 -126
  95. package/components/AuthingGuard/style.less +0 -103
  96. package/components/AuthingGuard/types/Forms.ts +0 -94
  97. package/components/AuthingGuard/types/GuardConfig.ts +0 -420
  98. package/components/AuthingGuard/types/GuardState.ts +0 -7
  99. package/components/AuthingGuard/types/Locales.ts +0 -12
  100. package/components/AuthingGuard/types/index.ts +0 -4
  101. package/components/AuthingTabs/index.tsx +0 -98
  102. package/components/AuthingTabs/style.less +0 -135
  103. package/components/BindTotp/core/bindSuccess.tsx +0 -61
  104. package/components/BindTotp/core/securityCode.tsx +0 -119
  105. package/components/BindTotp/index.tsx +0 -134
  106. package/components/BindTotp/props.ts +0 -30
  107. package/components/BindTotp/styles.less +0 -56
  108. package/components/ChangeLanguage/index.tsx +0 -35
  109. package/components/ChangePassword/core/firstLoginReset.tsx +0 -104
  110. package/components/ChangePassword/core/rotateReset.tsx +0 -114
  111. package/components/ChangePassword/index.tsx +0 -59
  112. package/components/CompleteInfo/core/completeInfo.tsx +0 -155
  113. package/components/CompleteInfo/index.tsx +0 -45
  114. package/components/CompleteInfo/props.ts +0 -40
  115. package/components/CompleteInfo/styles.less +0 -7
  116. package/components/CompleteUserInfo/index.tsx +0 -49
  117. package/components/CompleteUserInfo/props.ts +0 -25
  118. package/components/ComponentsRender/index.back +0 -64
  119. package/components/CopyAbleText/index.tsx +0 -54
  120. package/components/CopyAbleText/style.less +0 -13
  121. package/components/DownloadAuthenticator/index.tsx +0 -97
  122. package/components/DownloadAuthenticator/props.ts +0 -22
  123. package/components/DownloadAuthenticator/styles.less +0 -52
  124. package/components/ForgetPassword/core/resetPassword.tsx +0 -150
  125. package/components/ForgetPassword/index.tsx +0 -51
  126. package/components/Guard/Guard.tsx +0 -226
  127. package/components/Guard/authClient.ts +0 -55
  128. package/components/Guard/config.ts +0 -19
  129. package/components/Guard/event.ts +0 -18
  130. package/components/Guard/index.tsx +0 -10
  131. package/components/Guard/module.ts +0 -19
  132. package/components/Guard/stateMachine.ts +0 -133
  133. package/components/Guard/styles.less +0 -444
  134. package/components/IconFont/iconfont.js +0 -74
  135. package/components/IconFont/index.tsx +0 -16
  136. package/components/IconFont/style.less +0 -6
  137. package/components/IconFont/svg.js +0 -2
  138. package/components/ImagePro/index.tsx +0 -52
  139. package/components/ImagePro/styles.less +0 -40
  140. package/components/Login/codemap.ts +0 -35
  141. package/components/Login/core/withAD.tsx +0 -9
  142. package/components/Login/core/withAppQrcode.tsx +0 -49
  143. package/components/Login/core/withLDAP.tsx +0 -145
  144. package/components/Login/core/withPassword.tsx +0 -176
  145. package/components/Login/core/withPhonecode.tsx +0 -135
  146. package/components/Login/core/withWechatMiniQrcode.tsx +0 -60
  147. package/components/Login/core/withWechatmpQrcode.tsx +0 -53
  148. package/components/Login/index.tsx +0 -359
  149. package/components/Login/props.ts +0 -90
  150. package/components/Login/socialLogin/index.tsx +0 -413
  151. package/components/Login/socialLogin/style.less +0 -61
  152. package/components/Login/styles.less +0 -53
  153. package/components/MFA/codemap.ts +0 -21
  154. package/components/MFA/core/email.tsx +0 -226
  155. package/components/MFA/core/face.tsx +0 -297
  156. package/components/MFA/core/face_deps.tsx +0 -37
  157. package/components/MFA/core/sms.tsx +0 -222
  158. package/components/MFA/core/totp.tsx +0 -137
  159. package/components/MFA/index.tsx +0 -135
  160. package/components/MFA/mfaMethods/index.tsx +0 -81
  161. package/components/MFA/mfaMethods/style.less +0 -39
  162. package/components/MFA/props.ts +0 -51
  163. package/components/MFA/styles.less +0 -92
  164. package/components/NeedHelpView/core/describeQuestions.tsx +0 -227
  165. package/components/NeedHelpView/index.tsx +0 -99
  166. package/components/RecoveryCode/core/useCode.tsx +0 -71
  167. package/components/RecoveryCode/index.tsx +0 -27
  168. package/components/RecoveryCode/interface.ts +0 -31
  169. package/components/RecoveryCode/style.less +0 -13
  170. package/components/Register/codemap.ts +0 -16
  171. package/components/Register/components/Agreements/index.tsx +0 -81
  172. package/components/Register/components/Agreements/style.less +0 -44
  173. package/components/Register/core/WithEmail.tsx +0 -250
  174. package/components/Register/core/WithPhone.tsx +0 -190
  175. package/components/Register/index.tsx +0 -122
  176. package/components/Register/props.ts +0 -50
  177. package/components/SendCode/SendCodeBtn.tsx +0 -96
  178. package/components/SendCode/index.tsx +0 -98
  179. package/components/SendCode/style.less +0 -31
  180. package/components/ShieldSpin/index.tsx +0 -27
  181. package/components/SubmitButton/index.tsx +0 -50
  182. package/components/Type/index.ts +0 -61
  183. package/components/VerifyCodeInput/index.tsx +0 -76
  184. package/components/VerifyCodeInput/style.less +0 -24
  185. package/components/_utils/GuardErrorCode.ts +0 -8
  186. package/components/_utils/clipboard.ts +0 -27
  187. package/components/_utils/config.ts +0 -123
  188. package/components/_utils/guradHttp.ts +0 -93
  189. package/components/_utils/hooks/index.ts +0 -56
  190. package/components/_utils/http.ts +0 -85
  191. package/components/_utils/index.ts +0 -310
  192. package/components/_utils/locales/en/common.json +0 -218
  193. package/components/_utils/locales/en/index.ts +0 -6
  194. package/components/_utils/locales/en/login.json +0 -95
  195. package/components/_utils/locales/en/map.json +0 -4
  196. package/components/_utils/locales/en/user.json +0 -82
  197. package/components/_utils/locales/index.ts +0 -45
  198. package/components/_utils/locales/zh/common.json +0 -218
  199. package/components/_utils/locales/zh/index.ts +0 -6
  200. package/components/_utils/locales/zh/login.json +0 -95
  201. package/components/_utils/locales/zh/map.json +0 -4
  202. package/components/_utils/locales/zh/user.json +0 -82
  203. package/components/_utils/popupCenter.ts +0 -48
  204. package/components/context/base.tsx +0 -28
  205. package/components/context/global/context.tsx +0 -39
  206. package/components/context/global/reducer.tsx +0 -56
  207. package/components/context/module/context.tsx +0 -23
  208. package/components/index.ts +0 -10
  209. package/config/antdReplacer.js +0 -51
  210. package/config/env.js +0 -104
  211. package/config/getHttpsConfig.js +0 -66
  212. package/config/jest/cssTransform.js +0 -14
  213. package/config/jest/fileTransform.js +0 -40
  214. package/config/modules.js +0 -134
  215. package/config/paths.js +0 -71
  216. package/config/pnpTs.js +0 -35
  217. package/config/webpack.config.js +0 -835
  218. package/config/webpackDevServer.config.js +0 -130
  219. package/examples.tsx +0 -100
  220. package/index.js +0 -1
  221. package/logo.svg +0 -7
  222. package/public/favicon.ico +0 -0
  223. package/public/index.html +0 -43
  224. package/public/logo192.png +0 -0
  225. package/public/logo512.png +0 -0
  226. package/public/manifest.json +0 -25
  227. package/public/robots.txt +0 -3
  228. package/react-app-env.d.ts +0 -71
  229. package/reportWebVitals.ts +0 -15
  230. package/scripts/build.js +0 -208
  231. package/scripts/lib.js +0 -200
  232. package/scripts/start.js +0 -162
  233. package/scripts/test.js +0 -49
  234. package/setupTests.ts +0 -5
  235. package/tsconfig.json +0 -30
@@ -1,226 +0,0 @@
1
- import { UserOutlined } from '@ant-design/icons'
2
- import { Input, message as Message } from 'antd'
3
- import { Form } from 'antd'
4
- import { EmailScene, User } from 'authing-js-sdk'
5
- import React, { useRef, useState } from 'react'
6
- import { useTranslation } from 'react-i18next'
7
- import { VerifyCodeInput } from '../../VerifyCodeInput'
8
- import { useAuthClient } from '../../Guard/authClient'
9
- import { SendCodeBtn } from '../../SendCode/SendCodeBtn'
10
- import { VALIDATE_PATTERN } from '../../_utils'
11
- import SubmitButton from '../../SubmitButton'
12
-
13
- const CODE_LEN = 4
14
-
15
- interface BindMFAEmailProps {
16
- mfaToken: string
17
- onBind: (email: string) => void
18
- }
19
- export const BindMFAEmail: React.FC<BindMFAEmailProps> = ({
20
- mfaToken,
21
- onBind,
22
- }) => {
23
- const authClient = useAuthClient()
24
- const submitButtonRef = useRef<any>(null)
25
- const { t } = useTranslation()
26
- const [form] = Form.useForm()
27
-
28
- const onFinish = async ({ email }: any) => {
29
- submitButtonRef.current?.onSpin(true)
30
- try {
31
- const bindable = await authClient.mfa.phoneOrEmailBindable({
32
- mfaToken,
33
- email,
34
- })
35
-
36
- if (!bindable) {
37
- Message.error(
38
- t('common.unBindEmaileDoc', {
39
- email: email,
40
- })
41
- )
42
- return
43
- }
44
- onBind(email)
45
- } catch (e: any) {
46
- const error = JSON.parse(e?.message)
47
- submitButtonRef.current.onError()
48
- Message.error(error.message)
49
- } finally {
50
- submitButtonRef.current?.onSpin(false)
51
- }
52
- }
53
- return (
54
- <>
55
- <p className="authing-g2-mfa-title">{t('common.bindEmail')}</p>
56
- <p className="authing-g2-mfa-tips">{t('common.bindEmailDoc')}</p>
57
- <Form
58
- form={form}
59
- onFinish={onFinish}
60
- onFinishFailed={() => submitButtonRef.current.onError()}
61
- >
62
- <Form.Item
63
- className="authing-g2-input-form"
64
- name="email"
65
- rules={[
66
- {
67
- required: true,
68
- message: t('login.inputEmail'),
69
- },
70
- {
71
- pattern: VALIDATE_PATTERN.email,
72
- message: t('login.emailError'),
73
- },
74
- ]}
75
- >
76
- <Input
77
- className="authing-g2-input"
78
- autoComplete="email"
79
- size="large"
80
- placeholder={t('login.inputEmail')}
81
- prefix={<UserOutlined style={{ color: '#878A95' }} />}
82
- />
83
- </Form.Item>
84
-
85
- <SubmitButton text={t('common.sure')} ref={submitButtonRef} />
86
- </Form>
87
- </>
88
- )
89
- }
90
-
91
- interface VerifyMFAEmailProps {
92
- email: string
93
- mfaToken: string
94
- onVerify: (code: number, data: any) => void
95
- sendCodeRef: React.RefObject<HTMLButtonElement>
96
- }
97
-
98
- export const VerifyMFAEmail: React.FC<VerifyMFAEmailProps> = ({
99
- email,
100
- mfaToken,
101
- onVerify,
102
- sendCodeRef,
103
- }) => {
104
- const authClient = useAuthClient()
105
- const submitButtonRef = useRef<any>(null)
106
- const { t } = useTranslation()
107
- const [form] = Form.useForm()
108
- const [MfaCode, setMFACode] = useState(new Array(CODE_LEN).fill(''))
109
- const [sending, setSending] = useState(false)
110
- const [sent, setSent] = useState(false)
111
-
112
- const sendVerifyCode = async () => {
113
- try {
114
- setSending(true)
115
- await authClient.sendEmail(email!, EmailScene.MfaVerify)
116
- setSent(true)
117
- return true
118
- } catch (e) {
119
- return false
120
- } finally {
121
- setSending(false)
122
- }
123
- }
124
-
125
- const onFinish = async (values: any) => {
126
- submitButtonRef.current?.onSpin(true)
127
- try {
128
- const user: User = await authClient.mfa.verifyAppEmailMfa({
129
- mfaToken,
130
- email: email!,
131
- code: MfaCode.join(''),
132
- })
133
-
134
- onVerify(200, user)
135
- } catch (e: any) {
136
- const error = JSON.parse(e?.message)
137
- onVerify(error.code as number, error)
138
- } finally {
139
- submitButtonRef.current?.onSpin(false)
140
- }
141
- }
142
-
143
- return (
144
- <>
145
- <p className="authing-g2-mfa-title">{t('login.inputEmailCode')}</p>
146
- <p className="authing-g2-mfa-tips">
147
- {sending
148
- ? t('login.sendingVerifyCode')
149
- : sent
150
- ? `${t('login.verifyCodeSended')} ${email}`
151
- : t('login.clickSent')}
152
- </p>
153
- <Form
154
- form={form}
155
- onFinish={onFinish}
156
- onFinishFailed={() => submitButtonRef.current?.onError()}
157
- >
158
- <Form.Item
159
- name="mfaCode"
160
- rules={[
161
- {
162
- validateTrigger: [],
163
- validator() {
164
- if (MfaCode.some((item) => !item)) {
165
- return Promise.reject(t('login.inputFullMfaCode'))
166
- }
167
- return Promise.resolve()
168
- },
169
- },
170
- ]}
171
- >
172
- <VerifyCodeInput
173
- length={CODE_LEN}
174
- verifyCode={MfaCode}
175
- setVerifyCode={setMFACode}
176
- />
177
- </Form.Item>
178
-
179
- <SendCodeBtn
180
- btnRef={sendCodeRef}
181
- beforeSend={() => sendVerifyCode()}
182
- type="link"
183
- />
184
-
185
- <SubmitButton
186
- text={t('common.sure')}
187
- ref={submitButtonRef}
188
- className="g2-mfa-submit-button"
189
- />
190
- </Form>
191
- </>
192
- )
193
- }
194
-
195
- export const MFAEmail: React.FC<{
196
- mfaToken: string
197
- email?: string
198
- mfaLogin: any
199
- }> = ({ email: userEmail, mfaToken, mfaLogin }) => {
200
- const [email, setEmail] = useState(userEmail)
201
- const sendCodeRef = useRef<HTMLButtonElement>(null)
202
-
203
- return (
204
- <>
205
- {email ? (
206
- <VerifyMFAEmail
207
- mfaToken={mfaToken}
208
- email={email}
209
- onVerify={(code, data) => {
210
- mfaLogin(code, data)
211
- }}
212
- sendCodeRef={sendCodeRef}
213
- />
214
- ) : (
215
- <BindMFAEmail
216
- mfaToken={mfaToken}
217
- onBind={(email: string) => {
218
- console.log('email', email)
219
- setEmail(email)
220
- sendCodeRef.current?.click()
221
- }}
222
- />
223
- )}
224
- </>
225
- )
226
- }
@@ -1,297 +0,0 @@
1
- import React, { useCallback, useEffect, useRef, useState } from 'react'
2
- import { useTranslation } from 'react-i18next'
3
- import { detectSingleFace } from 'face-api.js'
4
- import { useGuardHttp } from '../../_utils/guradHttp'
5
- import {
6
- FACE_SCORE,
7
- devicesConstraints,
8
- dataURItoBlob,
9
- getCurrentFaceDetectionNet,
10
- getFaceDetectorOptions,
11
- isFaceDetectionModelLoaded,
12
- } from './face_deps'
13
- import { ImagePro } from '../../ImagePro'
14
- import SubmitButton from '../../SubmitButton'
15
-
16
- const useDashoffset = (percent: number) => {
17
- // 接受 0 - 1,返回 0-700 之间的偏移量
18
- let offset = percent * 7
19
-
20
- // 在识别成功的时候,返回绿色
21
- let dashStyle = {}
22
- return { offset, dashStyle }
23
- }
24
-
25
- export const MFAFace = (props: any) => {
26
- let { postForm, post } = useGuardHttp()
27
- let { t } = useTranslation()
28
- const [faceState, setFaceState] = useState('ready') // ready, identifying, retry
29
- const [percent, setPercent] = useState(0) // 识别进度(相似性)
30
-
31
- const videoRef = useRef<HTMLVideoElement>(null)
32
- const canvasRef = useRef<HTMLCanvasElement>(null)
33
- const interval = useRef<NodeJS.Timeout | undefined>()
34
- const p1 = useRef<string>() // p1 key
35
- const p2 = useRef<string>() // p2 key
36
- const cooldown = useRef<number>(6) // p2 cooldown, * 500ms
37
- const cdnBase = props.config.__publicConfig__.cdnBase
38
-
39
- let { offset, dashStyle } = useDashoffset(percent)
40
-
41
- // 预加载数据
42
- useEffect(() => {
43
- // 载入 cdn
44
- let cdnContext = getCurrentFaceDetectionNet().loadFromUri(
45
- `${cdnBase}/face-api/v1/tiny_face_detector_model-weights_manifest.json`
46
- )
47
- cdnContext.then((result) => {
48
- // setLoading(false)
49
- })
50
-
51
- if (faceState !== 'identifying') {
52
- return // 不存在 video dom,不要去尝试了
53
- }
54
- let devicesContext = navigator.mediaDevices.getUserMedia(devicesConstraints)
55
- devicesContext
56
- .then((stream) => {
57
- videoRef.current!.srcObject = stream
58
- })
59
- .catch((e) => {
60
- // 没有设备,或没有授权
61
- console.error(e)
62
- // setVideoType(VideoAction.ERROR)
63
- // setProgressStatus('exception')
64
- // setPercent(100)
65
- // setVideoError(e.message)
66
- })
67
-
68
- return () => {
69
- interval.current && clearInterval(interval.current)
70
- }
71
- }, [faceState, interval, props.config, cdnBase])
72
-
73
- // 监听 faceState
74
- useEffect(() => {
75
- if (faceState === 'identifying' || faceState === 'retry') {
76
- props.setShowMethods(false)
77
- } else {
78
- props.setShowMethods(true)
79
- }
80
- // eslint-disable-next-line react-hooks/exhaustive-deps
81
- }, [faceState])
82
-
83
- // 上传文件
84
- const uploadImage = async (blob: Blob) => {
85
- const formData = new FormData()
86
- formData.append('folder', 'photos')
87
- formData.append('file', blob, 'personal.jpeg')
88
-
89
- let url = '/api/v2/upload?folder=photos&private=true'
90
- let result = await postForm<any>(url, formData)
91
- let key = result.data?.key
92
- return key
93
- }
94
-
95
- // get base 64
96
- const getBase64 = (videoDom: any) => {
97
- const canvas = canvasRef.current!
98
- const ctx = canvas!.getContext('2d')!
99
- ctx.clearRect(0, 0, canvas.width, canvas.height)
100
- ctx.drawImage(videoDom, 0, 0, canvas.width, canvas.height)
101
- const base64Data = canvas.toDataURL('image/jpeg', 1.0)
102
- return base64Data
103
- }
104
-
105
- const faceLogin = (result: any) => {
106
- let { code, data, message } = result
107
-
108
- if (code === 1700 || code === 1701 || code === 1702) {
109
- p1.current = undefined
110
- p2.current = undefined
111
- interval.current = undefined
112
- cooldown.current = 6
113
- setFaceState('retry')
114
- }
115
- props.mfaLogin(code, data, message)
116
- }
117
-
118
- const faceBind = () => {
119
- let url = '/api/v2/mfa/face/associate'
120
- let data = {
121
- photoA: p1.current,
122
- photoB: p2.current,
123
- }
124
- let mfaToken = props.initData.mfaToken
125
- let config = {
126
- headers: {
127
- authorization: mfaToken,
128
- },
129
- }
130
- post(url, data, config).then((result) => {
131
- faceLogin(result)
132
- })
133
- }
134
-
135
- const faceCheck = () => {
136
- let url = '/api/v2/mfa/face/verify'
137
- let data = {
138
- photo: p1.current,
139
- }
140
- let mfaToken = props.initData.mfaToken
141
- let config = {
142
- headers: {
143
- authorization: mfaToken,
144
- },
145
- }
146
- post(url, data, config).then((result) => {
147
- // 如果是 1702,那么久绑定一个
148
- faceLogin(result)
149
- })
150
- }
151
-
152
- // bind 的情况
153
- const goToBindScene = (key: string) => {
154
- if (!p1.current) {
155
- p1.current = key
156
- } else {
157
- if (cooldown.current > 0) {
158
- cooldown.current -= 1
159
- }
160
- if (cooldown.current <= 0) {
161
- p2.current = key
162
- // 彻底上传完了,应该走验证了
163
- interval.current && clearInterval(interval.current)
164
- faceBind()
165
- }
166
- }
167
- }
168
-
169
- // goToCheck 的情况
170
- const goToCheckScene = (key: string) => {
171
- p1.current = key
172
- interval.current && clearInterval(interval.current)
173
- faceCheck()
174
- }
175
-
176
- // 识别成功,自动前进到下一个步骤
177
- const quitIdentifying = (blob: Blob) => {
178
- setPercent(100)
179
- uploadImage(blob).then((key) => {
180
- if (props.initData?.faceMfaEnabled === true) {
181
- goToCheckScene(key)
182
- } else {
183
- goToBindScene(key)
184
- }
185
- })
186
- }
187
-
188
- const autoShoot = useCallback(async () => {
189
- if (!interval.current) {
190
- interval.current = setInterval(() => autoShoot(), 500)
191
- }
192
- const videoDom = videoRef.current!
193
- if (videoDom.paused || videoDom.ended || !isFaceDetectionModelLoaded()) {
194
- return
195
- }
196
- const options = getFaceDetectorOptions()
197
- const result = await detectSingleFace(videoDom, options)
198
-
199
- if (result) {
200
- if (result.score > FACE_SCORE) {
201
- const base64Data = getBase64(videoDom)
202
- const blob = dataURItoBlob(base64Data)
203
- quitIdentifying(blob) // 识别成功,退出识别
204
- } else {
205
- // 识别失败,但是有结果,设置相似性
206
- setPercent(() => {
207
- return (result.score / FACE_SCORE) * 100
208
- })
209
- // console.log('识别失败,但是有结果,设置相似性', percent)
210
- }
211
- } else {
212
- setPercent(10)
213
- }
214
- // eslint-disable-next-line react-hooks/exhaustive-deps
215
- }, [])
216
-
217
- return (
218
- <div>
219
- <h3 className="authing-g2-mfa-title">{t('common.faceText1')}</h3>
220
- <p className="authing-g2-mfa-tips">{t('common.faceText2')}</p>
221
- {faceState === 'ready' && (
222
- <>
223
- <ImagePro
224
- className="g2-mfa-face-image"
225
- width={247}
226
- height={131}
227
- src={`${cdnBase}/face.png`}
228
- alt=""
229
- />
230
-
231
- <SubmitButton
232
- onClick={() => {
233
- setFaceState('identifying')
234
- autoShoot()
235
- }}
236
- text={t('common.faceText3')}
237
- className="mfa-face"
238
- />
239
- </>
240
- )}
241
- <div
242
- className="g2-mfa-face-identifying"
243
- style={{
244
- display: faceState !== 'ready' ? 'flex' : 'none',
245
- }}
246
- >
247
- <video
248
- className="video-round"
249
- ref={videoRef}
250
- // onLoadedMetadata={() => onIdentify()}
251
- id="inputVideo"
252
- autoPlay
253
- muted
254
- playsInline
255
- />
256
- <div
257
- className="video-round mesh"
258
- style={{
259
- display: faceState === 'retry' ? 'flex' : 'none',
260
- }}
261
- onClick={() => {
262
- setFaceState('identifying')
263
- setPercent(0)
264
- autoShoot()
265
- }}
266
- >
267
- {t('common.faceText4')}
268
- </div>
269
-
270
- <div className="video-round ring">
271
- <svg width={240} height={240} fill="none">
272
- <circle
273
- className="svg-circle-running"
274
- style={dashStyle}
275
- strokeDasharray={700} // 根据周长做 0-700 之间的数值表示准确率
276
- strokeDashoffset={700 - offset} // 处理这个 offset, 0-700之间的数
277
- cx={120}
278
- cy={120}
279
- r={110}
280
- />
281
- </svg>
282
- </div>
283
- </div>
284
-
285
- <canvas
286
- style={{
287
- width: 210,
288
- height: 210,
289
- opacity: 0,
290
- position: 'absolute',
291
- display: 'none',
292
- }}
293
- ref={canvasRef}
294
- />
295
- </div>
296
- )
297
- }
@@ -1,37 +0,0 @@
1
- import { nets, TinyFaceDetectorOptions } from 'face-api.js'
2
-
3
- let inputSize = 512
4
- let scoreThreshold = 0.5
5
-
6
- export const devicesConstraints = {
7
- video: {
8
- width: 210,
9
- height: 210,
10
- },
11
- }
12
- export const FACE_SCORE = 0.65
13
-
14
- export function getFaceDetectorOptions() {
15
- return new TinyFaceDetectorOptions({ inputSize, scoreThreshold })
16
- }
17
-
18
- export function getCurrentFaceDetectionNet() {
19
- return nets.tinyFaceDetector
20
- }
21
-
22
- export function isFaceDetectionModelLoaded() {
23
- return !!getCurrentFaceDetectionNet().params
24
- }
25
-
26
- export function dataURItoBlob(base64Data: any) {
27
- var byteString
28
- if (base64Data.split(',')[0].indexOf('base64') >= 0)
29
- byteString = atob(base64Data.split(',')[1])
30
- else byteString = unescape(base64Data.split(',')[1])
31
- var mimeString = base64Data.split(',')[0].split(':')[1].split(';')[0]
32
- var ia = new Uint8Array(byteString.length)
33
- for (var i = 0; i < byteString.length; i++) {
34
- ia[i] = byteString.charCodeAt(i)
35
- }
36
- return new Blob([ia], { type: mimeString })
37
- }