@authing/react-ui-components 2.4.54-alpha.0 → 2.4.56

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 (69) hide show
  1. package/build/asset-manifest.json +19 -18
  2. package/build/index.html +1 -1
  3. package/build/static/css/2.51c07e65.chunk.css +3 -0
  4. package/build/static/css/2.51c07e65.chunk.css.map +1 -0
  5. package/build/static/css/main.779f221a.chunk.css +2 -0
  6. package/build/static/css/main.779f221a.chunk.css.map +1 -0
  7. package/build/static/js/2.bbae9fdb.chunk.js +3 -0
  8. package/build/static/js/2.bbae9fdb.chunk.js.LICENSE.txt +102 -0
  9. package/build/static/js/2.bbae9fdb.chunk.js.map +1 -0
  10. package/build/static/js/{3.edcab7cd.chunk.js → 3.fd17f196.chunk.js} +2 -2
  11. package/build/static/js/3.fd17f196.chunk.js.map +1 -0
  12. package/build/static/js/main.5f341531.chunk.js +2 -0
  13. package/build/static/js/main.5f341531.chunk.js.map +1 -0
  14. package/build/static/js/runtime-main.ef138021.js +2 -0
  15. package/build/static/js/runtime-main.ef138021.js.map +1 -0
  16. package/build/static/media/loading.4a67a5f3.svg +29 -0
  17. package/lib/index.d.ts +14 -159
  18. package/lib/index.min.css +1 -2
  19. package/lib/index.min.js +1 -1
  20. package/lib/index.min.js.LICENSE.txt +8 -63
  21. package/package.json +3 -4
  22. package/src/common/AuthingDropdown/index.tsx +20 -58
  23. package/src/common/AuthingDropdown/style.less +8 -33
  24. package/src/components/AuthingGuard/AppMFALayout/index.tsx +15 -30
  25. package/src/components/AuthingGuard/GuardLayout/index.tsx +10 -32
  26. package/src/components/AuthingGuard/GuardLayout/style.less +0 -4
  27. package/src/components/AuthingGuard/Header/index.tsx +5 -2
  28. package/src/components/AuthingGuard/Header/style.less +23 -11
  29. package/src/components/AuthingGuard/IconFont/iconfont.js +74 -1
  30. package/src/components/AuthingGuard/api/appConfig.ts +2 -2
  31. package/src/components/AuthingGuard/api/http.ts +32 -9
  32. package/src/components/AuthingGuard/constants.ts +2 -0
  33. package/src/components/AuthingGuard/hooks/index.tsx +0 -37
  34. package/src/components/AuthingGuard/index.tsx +8 -3
  35. package/src/components/AuthingGuard/locales/en/common.json +1 -2
  36. package/src/components/AuthingGuard/locales/en/login.json +1 -1
  37. package/src/components/AuthingGuard/locales/zh/common.json +1 -16
  38. package/src/components/AuthingGuard/style.less +1 -0
  39. package/src/components/AuthingGuard/types/Forms.ts +0 -2
  40. package/src/components/AuthingGuard/types/GuardConfig.ts +1 -1
  41. package/src/context/global/reducer.tsx +0 -4
  42. package/src/index.tsx +16 -28
  43. package/src/utils/index.ts +0 -23
  44. package/build/static/css/2.40c24d2f.chunk.css +0 -2
  45. package/build/static/css/2.40c24d2f.chunk.css.map +0 -1
  46. package/build/static/css/main.ee0e3901.chunk.css +0 -2
  47. package/build/static/css/main.ee0e3901.chunk.css.map +0 -1
  48. package/build/static/js/2.354276b9.chunk.js +0 -3
  49. package/build/static/js/2.354276b9.chunk.js.LICENSE.txt +0 -156
  50. package/build/static/js/2.354276b9.chunk.js.map +0 -1
  51. package/build/static/js/3.edcab7cd.chunk.js.map +0 -1
  52. package/build/static/js/main.6c028b56.chunk.js +0 -2
  53. package/build/static/js/main.6c028b56.chunk.js.map +0 -1
  54. package/build/static/js/runtime-main.1b4b9135.js +0 -2
  55. package/build/static/js/runtime-main.1b4b9135.js.map +0 -1
  56. package/src/components/AuthingGuard/Forms/TotpMfaVerifyForm/BindTotpForm/AppDownload.tsx +0 -198
  57. package/src/components/AuthingGuard/Forms/TotpMfaVerifyForm/BindTotpForm/BindSuccess.tsx +0 -48
  58. package/src/components/AuthingGuard/Forms/TotpMfaVerifyForm/BindTotpForm/CopyIcon.tsx +0 -52
  59. package/src/components/AuthingGuard/Forms/TotpMfaVerifyForm/BindTotpForm/InputSaftyCode.tsx +0 -25
  60. package/src/components/AuthingGuard/Forms/TotpMfaVerifyForm/BindTotpForm/SaveSecretKey.tsx +0 -34
  61. package/src/components/AuthingGuard/Forms/TotpMfaVerifyForm/BindTotpForm/ScanQrcode.tsx +0 -44
  62. package/src/components/AuthingGuard/Forms/TotpMfaVerifyForm/BindTotpForm/index.tsx +0 -40
  63. package/src/components/AuthingGuard/Forms/TotpMfaVerifyForm/BindTotpForm/styles.less +0 -454
  64. package/src/components/AuthingGuard/Forms/TotpMfaVerifyForm/MobileSteps/index.tsx +0 -49
  65. package/src/components/AuthingGuard/Forms/TotpMfaVerifyForm/MobileSteps/style.less +0 -10
  66. package/src/components/AuthingGuard/Forms/TotpMfaVerifyForm/UserMfa/index.tsx +0 -361
  67. package/src/components/AuthingGuard/Forms/TotpMfaVerifyForm/UserMfa/style.less +0 -12
  68. package/src/components/AuthingGuard/Forms/TotpMfaVerifyForm/VerifyTotpForm.tsx +0 -120
  69. package/src/components/AuthingGuard/Forms/TotpMfaVerifyForm/index.tsx +0 -35
@@ -1,361 +0,0 @@
1
- import React, { useState, useEffect, useCallback, useMemo } from 'react'
2
- import { Steps, message, Spin, Button, Space } from 'antd'
3
- import { useMediaSize } from 'src/components/AuthingGuard/hooks'
4
- import { useTranslation } from 'react-i18next'
5
- import { requestClient } from '../../../api/http'
6
- import { MobileSteps } from '../MobileSteps'
7
- import { AppDownload } from '../BindTotpForm/AppDownload'
8
- import { ScanQrcode } from '../BindTotpForm/ScanQrcode'
9
- import { InputSaftyCode } from '../BindTotpForm/InputSaftyCode'
10
- import { User } from 'authing-js-sdk'
11
- import { SaveSecretKey } from '../BindTotpForm/SaveSecretKey'
12
- import { BindSuccess } from '../BindTotpForm/BindSuccess'
13
- import { useGuardContext } from '../../../../../context/global/context'
14
- import { GuardScenes } from '../../../../AuthingGuard/types'
15
- import { MediaAppDownload } from '../BindTotpForm/AppDownload'
16
-
17
- import './style.less'
18
-
19
- const { Step } = Steps
20
-
21
- // 临时
22
- export const ErrorCodes = {
23
- // 密码错误
24
- WRONG_PASSWORD: 2006,
25
- // 未登录
26
- LOGIN_REQUIRED: 2020,
27
- // 用户或密码错误
28
- USER_OR_PASSWORD_WRONG: 2333,
29
- // 用户不存在
30
- USER_NOT_EXISTS: 2004,
31
- // TOP MFA 的 error code
32
- OTP_MFA_CODE: 1635,
33
- // 手机和短信验证吗 MFA 的 error code
34
- MSG_MFA_CODE: 1636,
35
- // MFA Token 失效
36
- MAF_TOKEN_INVALID: 2021,
37
- // 强制修改密码
38
- FIRST_LOGIN_CODE: 1639,
39
- // 密码输入错误次数已达上限
40
- ACCOUNT_LOCK: 2057,
41
- // 账号已经锁定了
42
- ACCOUNT_LOCKED: 2005,
43
- // 密码已过期
44
- PASSWORD_EXPIRED: 2058,
45
- // 使用过的密码
46
- USED_PASSWORD: 2059,
47
- }
48
-
49
- // 估计是为了区分个人版和企业版
50
- export enum TotpSource {
51
- SELF = 'SELF',
52
- APPLICATION = 'APPLICATION',
53
- }
54
-
55
- // 组件的属性
56
- export interface UserMfaProps {
57
- // 用户池id
58
- userPoolId: string
59
- // 用户池名称
60
- userPoolName: string
61
- // 应用id
62
- appId: string
63
- // 区分个人版还是企业版
64
- totpSource?: TotpSource
65
- MFAToken?: string
66
- className?: string
67
- }
68
-
69
- // 不知道为啥叫做 UserMfa, 只知道这个组件是为了绑定 otp
70
- export const UserMfa: React.FC<any> = ({
71
- totpSource = TotpSource.SELF,
72
- MFAToken,
73
- userPoolName,
74
- userPoolId,
75
- appId,
76
- className,
77
- onSuccess,
78
- onFail,
79
- }) => {
80
- // 多语言翻译
81
- const { t } = useTranslation()
82
- // 判断是否移动端
83
- const { isPhoneMedia } = useMediaSize()
84
- // 验证码组件需要一个初始化的值
85
- const getInitSaftyCode = () => new Array(6).fill('')
86
- // 6位安全码
87
- const [saftyCode, setSaftyCode] = useState<string[]>(getInitSaftyCode())
88
- // 加载状态
89
- const [isSpinning, setIsSpinning] = useState(false)
90
- // 当前的步骤
91
- const [currentStep, setCurrentStep] = useState<number>(0)
92
- // 绑定 mfa 的密钥
93
- const [secret, setSecret] = useState('')
94
- // 绑定 mfa 的二维码
95
- const [qrcode, setQrcode] = useState('')
96
- //
97
- const [mfaSecret, setMfaSecret] = useState('')
98
- // 按钮的加载状态
99
- const [btnLoading, setBtnLoading] = useState(false)
100
- //
101
- const [isSaved, setIsSaved] = useState(false)
102
- //
103
- const [user, setUser] = useState<User>()
104
-
105
- const { setValue } = useGuardContext()
106
-
107
- // 根据配置判断 enable 字段,如果满足直接进入到最后一步 (这块不敢删也不知道有啥用。。。。)
108
- // guard 和 user-portal 网络请求还不一样
109
- const handleCheckAuthenticator = useCallback(async () => {
110
- const config: {
111
- headers?: any
112
- } = {}
113
- if (totpSource === TotpSource.APPLICATION) {
114
- config.headers = {
115
- authorization: MFAToken,
116
- 'x-authing-userpool-id': userPoolId,
117
- 'x-authing-app-id': appId,
118
- }
119
- }
120
- const query = {
121
- type: 'totp',
122
- source: totpSource,
123
- }
124
- return await requestClient.get<any>(
125
- `/api/v2/mfa/authenticator`,
126
- query,
127
- config
128
- )
129
- }, [MFAToken, totpSource, userPoolId, appId])
130
-
131
- // 绑定所需要的一些配置信息
132
- const handleFetchBindInfo = useCallback(async () => {
133
- setIsSpinning(true)
134
- try {
135
- const config: {
136
- headers?: any
137
- } = {}
138
- if (totpSource === TotpSource.APPLICATION) {
139
- config.headers = {
140
- authorization: MFAToken,
141
- 'x-authing-userpool-id': userPoolId,
142
- 'x-authing-app-id': appId,
143
- }
144
- }
145
- const data: any = await requestClient.post(
146
- '/api/v2/mfa/totp/associate',
147
- {
148
- authenticator_type: 'totp',
149
- source: totpSource,
150
- },
151
- config as any
152
- )
153
- setSecret(data.data.recovery_code)
154
- setQrcode(data.data.qrcode_data_url)
155
- setMfaSecret(data.data.secret)
156
- setIsSpinning(false)
157
- } catch (e) {
158
- message.error(t('user.bindInfoFetchFail'))
159
- setIsSpinning(false)
160
- }
161
- }, [t, totpSource, MFAToken, userPoolId, appId])
162
-
163
- // 开始绑定
164
- const handleBind = async () => {
165
- setBtnLoading(true)
166
- try {
167
- if (totpSource === TotpSource.SELF) {
168
- await bindSelfTotp()
169
- } else {
170
- await bindApplcationTotp()
171
- }
172
- } catch (e) {
173
- message.error(t('user.bindFail'))
174
- } finally {
175
- setBtnLoading(false)
176
- }
177
- }
178
-
179
- // 绑定个人
180
- const bindSelfTotp = async () => {
181
- const data: any = await requestClient.post(
182
- '/api/v2/mfa/totp/associate/confirm',
183
- {
184
- authenticator_type: 'totp',
185
- totp: saftyCode.join(''),
186
- source: totpSource,
187
- }
188
- )
189
-
190
- if (data.code !== 200) {
191
- message.error(data.message)
192
- } else {
193
- message.success(t('user.bindSuccess'))
194
- setCurrentStep((state) => state + 1)
195
- setSaftyCode(getInitSaftyCode())
196
- }
197
- setBtnLoading(false)
198
- }
199
-
200
- // 绑定企业
201
- const bindApplcationTotp = async () => {
202
- const data: any = await requestClient.post(
203
- '/api/v2/mfa/totp/associate/confirm',
204
- {
205
- authenticator_type: 'totp',
206
- totp: saftyCode.join(''),
207
- source: totpSource,
208
- },
209
- {
210
- headers: {
211
- authorization: MFAToken,
212
- 'x-authing-userpool-id': userPoolId,
213
- 'x-authing-app-id': appId,
214
- },
215
- }
216
- )
217
- // 登录失效的校验
218
- if (data.code === ErrorCodes.MAF_TOKEN_INVALID) {
219
- message.error(t('common.mfaInvalidContent'))
220
- setValue('guardScenes', GuardScenes.AppMfaVerify)
221
- } else if (data.code !== 200) {
222
- message.error(data.message)
223
- } else {
224
- const user = data?.data
225
- message.success(t('user.bindSuccess'))
226
- setCurrentStep((state) => state + 1)
227
- setSaftyCode(getInitSaftyCode())
228
- setBtnLoading(false)
229
- user && setUser(user)
230
- }
231
- }
232
-
233
- // 组件挂载时触发的方法
234
- const handleAsyncComponentDidMount = useCallback(async () => {
235
- try {
236
- const data = await handleCheckAuthenticator()
237
- if (data.data.some((item: any) => item.enable)) {
238
- setCurrentStep(4)
239
- setIsSpinning(false)
240
- return
241
- }
242
- handleFetchBindInfo()
243
- } catch (err) {
244
- setIsSpinning(false)
245
- }
246
- }, [handleCheckAuthenticator, handleFetchBindInfo])
247
-
248
- // 下一步按钮事件
249
- const handleNextStep = async () => {
250
- if (currentStep === 2) {
251
- await handleBind()
252
- } else {
253
- setCurrentStep((state) => state + 1)
254
- }
255
- }
256
-
257
- // 上一步按钮事件
258
- const handlePrevStep = () => {
259
- setCurrentStep((state) => state - 1)
260
- }
261
-
262
- // 渲染步骤条
263
- const useSteps = useMemo(
264
- () =>
265
- isPhoneMedia ? (
266
- <MobileSteps
267
- current={currentStep}
268
- data={[
269
- t('common.downloadTotpApp'),
270
- t('user.addMfa'),
271
- t('user.inputSafteyCode'),
272
- t('user.saveRecoverCode'),
273
- t('user.bindFinish'),
274
- ]}
275
- />
276
- ) : (
277
- <Steps size="small" current={currentStep}>
278
- <Step title={`${t('common.step')} 1`} />
279
- <Step title={`${t('common.step')} 2`} />
280
- <Step title={`${t('common.step')} 3`} />
281
- <Step title={`${t('common.step')} 4`} />
282
- <Step title={`${t('common.step')} 5`} />
283
- </Steps>
284
- ),
285
- [currentStep, isPhoneMedia, t]
286
- )
287
-
288
- //渲染内容
289
- const STEP_MAP = useMemo(
290
- () => [
291
- !isPhoneMedia ? <AppDownload /> : <MediaAppDownload />,
292
- <ScanQrcode
293
- isPhoneMedia={isPhoneMedia}
294
- qrcode={qrcode}
295
- secret={mfaSecret}
296
- userpoolName={userPoolName}
297
- />,
298
- <InputSaftyCode {...{ saftyCode, setSaftyCode, isPhoneMedia }} />,
299
- <SaveSecretKey {...{ secret, setIsSaved, isSaved }} />,
300
- <BindSuccess totpSource={totpSource} user={user} />,
301
- ],
302
- [
303
- isPhoneMedia,
304
- qrcode,
305
- secret,
306
- setSaftyCode,
307
- saftyCode,
308
- isSaved,
309
- user,
310
- totpSource,
311
- mfaSecret,
312
- userPoolName,
313
- ]
314
- )
315
-
316
- // 下一步是否可用
317
- const DISABLE_MAP = [
318
- false,
319
- false,
320
- saftyCode.some((item) => !item),
321
- !isSaved,
322
- false,
323
- ]
324
-
325
- // 组件挂载
326
- useEffect(() => {
327
- handleAsyncComponentDidMount()
328
- }, [handleAsyncComponentDidMount])
329
- return (
330
- <Spin spinning={isSpinning}>
331
- <div>
332
- <div>{useSteps}</div>
333
- <div className="userMfaContent">{STEP_MAP[currentStep]}</div>
334
- <div className="userMfaBtns">
335
- <Space size={16}>
336
- {(currentStep === 1 || currentStep === 2) && (
337
- <Button
338
- loading={btnLoading}
339
- size="large"
340
- onClick={handlePrevStep}
341
- >
342
- {t('user.prevStep')}
343
- </Button>
344
- )}
345
- {currentStep !== 4 && (
346
- <Button
347
- loading={btnLoading}
348
- disabled={DISABLE_MAP[currentStep]}
349
- size="large"
350
- type="primary"
351
- onClick={handleNextStep}
352
- >
353
- {t('user.nextStep')}
354
- </Button>
355
- )}
356
- </Space>
357
- </div>
358
- </div>
359
- </Spin>
360
- )
361
- }
@@ -1,12 +0,0 @@
1
- .userMfaBtns {
2
- margin-top: 20px;
3
- }
4
- .userMfaContent {
5
- min-height: 300px;
6
- display: flex;
7
- flex-direction: row;
8
- flex-wrap: nowrap;
9
- align-content: center;
10
- justify-content: center;
11
- align-items: center;
12
- }
@@ -1,120 +0,0 @@
1
- import React, { FC, useState } from 'react'
2
- import { Button, message } from 'antd'
3
- import { InputSaftyCode } from './BindTotpForm/InputSaftyCode'
4
- import { useMediaSize } from 'src/components/AuthingGuard/hooks'
5
- import { useTranslation } from 'react-i18next'
6
- import { requestClient } from '../../api/http'
7
- import { TotpSource, ErrorCodes } from './UserMfa'
8
- import { useGuardContext } from '../../../../context/global/context'
9
- import { GuardScenes } from '../../../AuthingGuard/types'
10
-
11
- export const VerifyTotpForm: FC<any> = ({
12
- totpSource = TotpSource.SELF,
13
- className,
14
- onSuccess,
15
- onFail,
16
- }) => {
17
- const [MFACode, setMFACode] = useState(new Array(6).fill(''))
18
- const { isPhoneMedia } = useMediaSize()
19
- const { t } = useTranslation()
20
- const [loading, setBtnLoading] = useState(false)
21
-
22
- const {
23
- state: {
24
- mfaData: { mfaToken: MFAToken },
25
- userPoolId,
26
- appId,
27
- },
28
- setValue,
29
- } = useGuardContext()
30
-
31
- // 开始绑定
32
- const handleBind = async () => {
33
- setBtnLoading(true)
34
- try {
35
- if (totpSource === TotpSource.SELF) {
36
- await bindSelfTotp()
37
- } else {
38
- await bindApplcationTotp()
39
- }
40
- } catch (e) {
41
- message.error(t('user.bindFail'))
42
- } finally {
43
- setBtnLoading(false)
44
- }
45
- }
46
-
47
- // 绑定个人
48
- const bindSelfTotp = async () => {
49
- const data: any = await requestClient.post(
50
- '/api/v2/mfa/totp/associate/confirm',
51
- {
52
- authenticator_type: 'totp',
53
- totp: MFACode.join(''),
54
- source: totpSource,
55
- }
56
- )
57
-
58
- if (data.code !== 200) {
59
- message.error(data.message)
60
- } else {
61
- message.success(t('user.bindSuccess'))
62
- setMFACode(new Array(6).fill(''))
63
- }
64
- setBtnLoading(false)
65
- }
66
-
67
- // 绑定企业
68
- const bindApplcationTotp = async () => {
69
- const data: any = await requestClient.post(
70
- '/api/v2/mfa/totp/associate/confirm',
71
- {
72
- authenticator_type: 'totp',
73
- totp: MFACode.join(''),
74
- source: totpSource,
75
- },
76
- {
77
- headers: {
78
- authorization: MFAToken,
79
- 'x-authing-userpool-id': userPoolId,
80
- 'x-authing-app-id': appId,
81
- },
82
- }
83
- )
84
- // 登录失效的校验
85
- if (data.code === ErrorCodes.MAF_TOKEN_INVALID) {
86
- message.error(t('common.mfaInvalidContent'))
87
- setValue('guardScenes', GuardScenes.AppMfaVerify)
88
- } else if (data.code !== 200) {
89
- message.error(data.message)
90
- } else {
91
- const user = data?.data
92
- // message.success(t('user.bindSuccess'))
93
- setMFACode(new Array(6).fill(''))
94
- setBtnLoading(false)
95
- user && onSuccess(user)
96
- // user && guardEvents.onLogin?.(user as any, authClient)
97
- }
98
- }
99
-
100
- return (
101
- <div>
102
- <InputSaftyCode
103
- {...{ saftyCode: MFACode, setSaftyCode: setMFACode, isPhoneMedia }}
104
- />
105
- <Button
106
- className="authing-guard-mfa-confirm-btn"
107
- loading={loading}
108
- block
109
- htmlType="submit"
110
- type="primary"
111
- size="large"
112
- onClick={async () => {
113
- await handleBind()
114
- }}
115
- >
116
- {t('common.sure')}
117
- </Button>
118
- </div>
119
- )
120
- }
@@ -1,35 +0,0 @@
1
- import React, { FC, useState } from 'react'
2
- import { useGuardContext } from 'src/context/global/context'
3
- import { TotpMFAFormProps } from '../../types'
4
- import { BindTotpForm } from './BindTotpForm/index'
5
- import { VerifyTotpForm } from './VerifyTotpForm'
6
- import { TotpSource } from './UserMfa'
7
- export const TotpMfaVerifyForm: FC<TotpMFAFormProps> = ({
8
- onSuccess,
9
- onFail,
10
- }) => {
11
- const {
12
- state: {
13
- mfaData: { totpMfaEnabled },
14
- },
15
- } = useGuardContext()
16
-
17
- // 判断是否绑定
18
- const [bindTotp] = useState<boolean>(totpMfaEnabled)
19
-
20
- // 如果绑定直接验证
21
- // 如果没有绑定进入绑定的页面
22
- return (
23
- <>
24
- {bindTotp ? (
25
- <VerifyTotpForm
26
- totpSource={TotpSource.APPLICATION}
27
- onSuccess={onSuccess}
28
- onFail={onFail}
29
- />
30
- ) : (
31
- <BindTotpForm onSuccess={onSuccess} onFail={onFail} />
32
- )}
33
- </>
34
- )
35
- }