@authing/react-ui-components 3.0.2-beta.9 → 3.1.1-rc.1

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 (144) hide show
  1. package/.eslintignore +6 -0
  2. package/.eslintrc.js +7 -0
  3. package/.prettierrc +5 -0
  4. package/.vscode/settings.json +31 -0
  5. package/LICENSE +21 -0
  6. package/config/antdReplacer.js +51 -0
  7. package/config/env.js +106 -0
  8. package/config/getHttpsConfig.js +66 -0
  9. package/config/jest/cssTransform.js +14 -0
  10. package/config/jest/fileTransform.js +40 -0
  11. package/config/modules.js +134 -0
  12. package/config/paths.js +71 -0
  13. package/config/pnpTs.js +35 -0
  14. package/config/webpack.config.js +857 -0
  15. package/config/webpackDevServer.config.js +130 -0
  16. package/lib/index.d.ts +211 -1669
  17. package/lib/index.min.css +1 -2
  18. package/lib/index.min.js +1 -1
  19. package/lib/index.min.js.LICENSE.txt +0 -32
  20. package/package.json +18 -42
  21. package/public/favicon.ico +0 -0
  22. package/public/index.html +43 -0
  23. package/public/logo192.png +0 -0
  24. package/public/logo512.png +0 -0
  25. package/public/manifest.json +25 -0
  26. package/public/robots.txt +3 -0
  27. package/scripts/build.js +212 -0
  28. package/scripts/lib.js +200 -0
  29. package/scripts/start.js +166 -0
  30. package/scripts/test.js +53 -0
  31. package/src/common/AuthingDropdown/index.tsx +52 -0
  32. package/src/common/AuthingDropdown/style.less +43 -0
  33. package/src/common/AuthingTabs/index.tsx +98 -0
  34. package/src/common/AuthingTabs/style.less +135 -0
  35. package/src/common/CopyAbleText/index.tsx +54 -0
  36. package/src/common/CopyAbleText/style.less +13 -0
  37. package/src/common/VerifyCodeInput/index.tsx +76 -0
  38. package/src/common/VerifyCodeInput/style.less +24 -0
  39. package/src/components/AuthingGuard/AppMFALayout/index.tsx +74 -0
  40. package/src/components/AuthingGuard/AppMFALayout/style.less +12 -0
  41. package/src/components/AuthingGuard/CompleteUserInfoLayout/index.tsx +29 -0
  42. package/src/components/AuthingGuard/CompleteUserInfoLayout/style.less +8 -0
  43. package/src/components/AuthingGuard/Forms/ADLoginForm/index.tsx +117 -0
  44. package/src/components/AuthingGuard/Forms/Agreements/index.tsx +81 -0
  45. package/src/components/AuthingGuard/Forms/Agreements/style.less +44 -0
  46. package/src/components/AuthingGuard/Forms/CompleteUserInfoForm/index.tsx +139 -0
  47. package/src/components/AuthingGuard/Forms/EmailMfaVerifyForm/CheckEmailForm.tsx +86 -0
  48. package/src/components/AuthingGuard/Forms/EmailMfaVerifyForm/VerifyCodeForm.tsx +116 -0
  49. package/src/components/AuthingGuard/Forms/EmailMfaVerifyForm/index.tsx +40 -0
  50. package/src/components/AuthingGuard/Forms/EmailMfaVerifyForm/style.less +0 -0
  51. package/src/components/AuthingGuard/Forms/EmailRegisterForm/index.tsx +181 -0
  52. package/src/components/AuthingGuard/Forms/EmailRegisterForm/style.less +0 -0
  53. package/src/components/AuthingGuard/Forms/LdapLoginForm/index.tsx +161 -0
  54. package/src/components/AuthingGuard/Forms/LdapLoginForm/style.less +0 -0
  55. package/src/components/AuthingGuard/Forms/LoginFormFooter/index.tsx +76 -0
  56. package/src/components/AuthingGuard/Forms/LoginFormFooter/style.less +6 -0
  57. package/src/components/AuthingGuard/Forms/MfaResetCodeForm/Step1.tsx +86 -0
  58. package/src/components/AuthingGuard/Forms/MfaResetCodeForm/Step2.tsx +53 -0
  59. package/src/components/AuthingGuard/Forms/MfaResetCodeForm/index.tsx +65 -0
  60. package/src/components/AuthingGuard/Forms/MfaResetCodeForm/style.less +20 -0
  61. package/src/components/AuthingGuard/Forms/MfaVerifyForm/index.tsx +105 -0
  62. package/src/components/AuthingGuard/Forms/MfaVerifyForm/style.less +12 -0
  63. package/src/components/AuthingGuard/Forms/PasswordLoginForm/index.tsx +261 -0
  64. package/src/components/AuthingGuard/Forms/PhoneCodeLoginForm/index.tsx +133 -0
  65. package/src/components/AuthingGuard/Forms/PhoneRegisterForm/index.tsx +202 -0
  66. package/src/components/AuthingGuard/Forms/QrCodeLoginForm/index.tsx +61 -0
  67. package/src/components/AuthingGuard/Forms/QrCodeLoginForm/style.less +14 -0
  68. package/src/components/AuthingGuard/Forms/RegisterFormFooter/index.tsx +56 -0
  69. package/src/components/AuthingGuard/Forms/RegisterFormFooter/style.less +0 -0
  70. package/src/components/AuthingGuard/Forms/ResetPwdForm/Footer.tsx +21 -0
  71. package/src/components/AuthingGuard/Forms/ResetPwdForm/Step1.tsx +86 -0
  72. package/src/components/AuthingGuard/Forms/ResetPwdForm/Step2.tsx +127 -0
  73. package/src/components/AuthingGuard/Forms/ResetPwdForm/Step3.tsx +141 -0
  74. package/src/components/AuthingGuard/Forms/ResetPwdForm/Step4.tsx +51 -0
  75. package/src/components/AuthingGuard/Forms/ResetPwdForm/index.tsx +96 -0
  76. package/src/components/AuthingGuard/Forms/ResetPwdForm/style.less +3 -0
  77. package/src/components/AuthingGuard/Forms/SendPhoneCode/SendCodeBtn.tsx +88 -0
  78. package/src/components/AuthingGuard/Forms/SendPhoneCode/index.tsx +50 -0
  79. package/src/components/AuthingGuard/Forms/SendPhoneCode/style.less +26 -0
  80. package/src/components/AuthingGuard/Forms/SmsMfaVerifyForm/CheckPhoneForm.tsx +86 -0
  81. package/src/components/AuthingGuard/Forms/SmsMfaVerifyForm/VerifyCodeForm.tsx +113 -0
  82. package/src/components/AuthingGuard/Forms/SmsMfaVerifyForm/index.tsx +40 -0
  83. package/src/components/AuthingGuard/Forms/SmsMfaVerifyForm/style.less +3 -0
  84. package/src/components/AuthingGuard/Forms/SocialAndIdpLogin/index.tsx +325 -0
  85. package/src/components/AuthingGuard/Forms/SocialAndIdpLogin/style.less +75 -0
  86. package/src/components/AuthingGuard/Forms/UploadImage/index.tsx +70 -0
  87. package/src/components/AuthingGuard/Forms/index.ts +13 -0
  88. package/src/components/AuthingGuard/GuardLayout/index.tsx +488 -0
  89. package/src/components/AuthingGuard/GuardLayout/style.less +111 -0
  90. package/src/components/AuthingGuard/Header/index.tsx +28 -0
  91. package/src/components/AuthingGuard/Header/style.less +64 -0
  92. package/src/components/AuthingGuard/IconFont/iconfont.js +74 -0
  93. package/src/components/AuthingGuard/IconFont/index.tsx +19 -0
  94. package/src/components/AuthingGuard/IconFont/style.less +6 -0
  95. package/src/components/AuthingGuard/IconFont/svg.js +2 -0
  96. package/src/components/AuthingGuard/LoginLayout/index.tsx +205 -0
  97. package/src/components/AuthingGuard/LoginLayout/style.less +0 -0
  98. package/src/components/AuthingGuard/MfaLayout/Steps.ts +4 -0
  99. package/src/components/AuthingGuard/MfaLayout/index.tsx +49 -0
  100. package/src/components/AuthingGuard/MfaLayout/style.less +3 -0
  101. package/src/components/AuthingGuard/RegisterLayout/index.tsx +89 -0
  102. package/src/components/AuthingGuard/RegisterLayout/style.less +0 -0
  103. package/src/components/AuthingGuard/ResetPwdLayout/index.tsx +20 -0
  104. package/src/components/AuthingGuard/ToggleLang/index.tsx +51 -0
  105. package/src/components/AuthingGuard/api/appConfig.ts +154 -0
  106. package/src/components/AuthingGuard/api/http.ts +88 -0
  107. package/src/components/AuthingGuard/api/index.ts +3 -0
  108. package/src/components/AuthingGuard/api/sso.ts +29 -0
  109. package/src/components/AuthingGuard/api/userPoolConfig.ts +112 -0
  110. package/src/components/AuthingGuard/constants.ts +107 -0
  111. package/src/components/AuthingGuard/hooks/index.tsx +70 -0
  112. package/src/components/AuthingGuard/hooks/useScreenSize.tsx +68 -0
  113. package/src/components/AuthingGuard/index.tsx +134 -0
  114. package/src/components/AuthingGuard/locales/en/common.json +185 -0
  115. package/src/components/AuthingGuard/locales/en/index.ts +6 -0
  116. package/src/components/AuthingGuard/locales/en/login.json +94 -0
  117. package/src/components/AuthingGuard/locales/en/map.json +4 -0
  118. package/src/components/AuthingGuard/locales/en/user.json +81 -0
  119. package/src/components/AuthingGuard/locales/index.ts +45 -0
  120. package/src/components/AuthingGuard/locales/zh/common.json +185 -0
  121. package/src/components/AuthingGuard/locales/zh/index.ts +6 -0
  122. package/src/components/AuthingGuard/locales/zh/login.json +94 -0
  123. package/src/components/AuthingGuard/locales/zh/map.json +4 -0
  124. package/src/components/AuthingGuard/locales/zh/user.json +81 -0
  125. package/src/components/AuthingGuard/style.less +108 -0
  126. package/src/components/AuthingGuard/types/Forms.ts +95 -0
  127. package/src/components/AuthingGuard/types/GuardConfig.ts +424 -0
  128. package/src/components/AuthingGuard/types/GuardState.ts +7 -0
  129. package/src/components/AuthingGuard/types/Locales.ts +12 -0
  130. package/src/components/AuthingGuard/types/index.ts +4 -0
  131. package/src/components/index.ts +7 -0
  132. package/src/context/base.tsx +28 -0
  133. package/src/context/global/context.tsx +39 -0
  134. package/src/context/global/reducer.tsx +56 -0
  135. package/src/index.tsx +142 -0
  136. package/src/logo.svg +7 -0
  137. package/src/react-app-env.d.ts +71 -0
  138. package/src/reportWebVitals.ts +15 -0
  139. package/src/setupTests.ts +5 -0
  140. package/src/utils/clipboard.ts +27 -0
  141. package/src/utils/index.ts +180 -0
  142. package/src/utils/popupCenter.ts +48 -0
  143. package/tsconfig.json +24 -0
  144. package/lib/static/media/loading.4a67a5f3.svg +0 -29
@@ -0,0 +1,488 @@
1
+ import { message, Spin } from 'antd'
2
+ import React, { FC, useCallback, useEffect, useMemo, useState } from 'react'
3
+
4
+ import {
5
+ getClassnames,
6
+ insertStyles,
7
+ deepMerge,
8
+ removeStyles,
9
+ } from '../../../utils'
10
+ import { useGuardContext } from '../../../context/global/context'
11
+ import { GuardHeader } from '../../../components/AuthingGuard/Header'
12
+ import { MfaLayout } from '../../../components/AuthingGuard/MfaLayout'
13
+ import { LoginLayout } from '../../../components/AuthingGuard/LoginLayout'
14
+ import {
15
+ defaultGuardConfig,
16
+ HIDE_SOCIALS,
17
+ } from '../../../components/AuthingGuard/constants'
18
+ import { RegisterLayout } from '../../../components/AuthingGuard/RegisterLayout'
19
+ import { ResetPwdLayout } from '../../../components/AuthingGuard/ResetPwdLayout'
20
+ import {
21
+ SessionData,
22
+ trackSession,
23
+ fetchAppConfig,
24
+ ApplicationConfig,
25
+ SocialConnectionItem,
26
+ } from '../../../components/AuthingGuard/api'
27
+ import {
28
+ GuardMode,
29
+ GuardScenes,
30
+ GuardConfig,
31
+ UserConfig,
32
+ Lang,
33
+ } from '../../../components/AuthingGuard/types'
34
+
35
+ import './style.less'
36
+ import { CompleteUserInfoLayout } from '../CompleteUserInfoLayout'
37
+ import { AppMfaLayout } from '../AppMFALayout'
38
+ import { IconFont } from '../IconFont'
39
+ import { ToggleLang } from '../ToggleLang'
40
+ import { useTranslation } from 'react-i18next'
41
+ import i18n from 'i18next'
42
+ import { changeLang } from '../locales'
43
+
44
+ const checkConfig = (appId: string) => {
45
+ // 不要去掉 console.warn,不然 vue 版打包出来每次都会 throw error,估计是 rollup 打包有问题
46
+ if (!appId) {
47
+ console.warn('APP ID: ', appId)
48
+ throw new Error(i18n.t('common.unAppId'))
49
+ }
50
+ }
51
+
52
+ const useGuardConfig = () => {
53
+ const {
54
+ state: { appId, userConfig },
55
+ setValue,
56
+ } = useGuardContext()
57
+
58
+ const { t } = useTranslation()
59
+
60
+ const [loading, setLoading] = useState(true)
61
+
62
+ const [appConfig, setAppConfig] = useState<Partial<ApplicationConfig>>({})
63
+ const [errorMsg, setErrorMsg] = useState('')
64
+ const [errorDetail, setErrorDetail] = useState<any>()
65
+
66
+ useEffect(() => {
67
+ try {
68
+ checkConfig(appId)
69
+
70
+ setErrorDetail(null)
71
+ setErrorMsg('')
72
+ } catch (e: any) {
73
+ setErrorDetail(e)
74
+ setErrorMsg(e.message)
75
+ console.error(e)
76
+ }
77
+ }, [appId])
78
+
79
+ // 获取应用配置
80
+ useEffect(() => {
81
+ setLoading(true)
82
+
83
+ if (!appId) {
84
+ setLoading(false)
85
+ return
86
+ }
87
+ fetchAppConfig(appId)
88
+ .then((res) => {
89
+ if (res.code !== 200) {
90
+ setErrorMsg(res.message!)
91
+ setErrorDetail(res)
92
+ return
93
+ }
94
+
95
+ setAppConfig(res.data!)
96
+ setValue('userPoolId', res.data?.userPoolId)
97
+ })
98
+ .catch((e: any) => {
99
+ setErrorDetail(e)
100
+ setErrorMsg(t('common.networkError'))
101
+ })
102
+ .finally(() => {
103
+ setLoading(false)
104
+ })
105
+
106
+ // eslint-disable-next-line react-hooks/exhaustive-deps
107
+ }, [appId])
108
+
109
+ useEffect(() => {
110
+ // 先移除之前的
111
+ removeStyles('appConfig')
112
+ removeStyles('userConfig')
113
+
114
+ insertStyles(appConfig?.css, 'appConfig')
115
+ insertStyles(userConfig.contentCss, 'userConfig')
116
+ }, [appConfig, userConfig.contentCss])
117
+
118
+ const guardConfig = useMemo<GuardConfig>(() => {
119
+ /**
120
+ * 将用应用配置与用户手动传入的配置合并
121
+ * 优先级:用户传入 > 应用 > 用户池
122
+ */
123
+
124
+ // 社会化登录
125
+ let socialConnectionObjs: SocialConnectionItem[] | undefined
126
+ // 默认展示所有社会化登录
127
+ if (!userConfig.socialConnections) {
128
+ socialConnectionObjs = [...(appConfig.socialConnections || [])]
129
+ } else {
130
+ const socials = userConfig.socialConnections
131
+ socialConnectionObjs = appConfig.socialConnections?.filter?.((item) =>
132
+ socials.includes(item.provider)
133
+ )
134
+ }
135
+
136
+ // 某些社会化登录会在 tabs 中显示,或者无法在 Guard 中使用,所以底部不显示了
137
+ socialConnectionObjs = socialConnectionObjs?.filter(
138
+ (item) => !HIDE_SOCIALS.includes(item.provider)
139
+ )
140
+
141
+ // 企业身份源
142
+ let enterpriseConnectionObjs: ApplicationConfig['identityProviders']
143
+
144
+ if (userConfig.enterpriseConnections) {
145
+ enterpriseConnectionObjs =
146
+ appConfig.identityProviders?.filter?.((item) =>
147
+ userConfig.enterpriseConnections!.includes(item.identifier)
148
+ ) || []
149
+ } else {
150
+ enterpriseConnectionObjs = appConfig.identityProviders || []
151
+ }
152
+
153
+ // 登录方式
154
+ const loginMethods =
155
+ userConfig.loginMethods ||
156
+ appConfig.loginTabs?.list ||
157
+ defaultGuardConfig.loginMethods
158
+
159
+ // 扫码多源配置
160
+ const qrcodeTabsSettings = appConfig.qrcodeTabsSettings ?? {}
161
+
162
+ // 账密登录的登录拆分
163
+ const passwordLoginMethods =
164
+ userConfig.passwordLoginMethods ||
165
+ appConfig.passwordTabConfig?.enabledLoginMethods ||
166
+ defaultGuardConfig.loginMethods
167
+
168
+ // 默认登录方式
169
+ const defaultLoginMethod =
170
+ userConfig.defaultLoginMethod ||
171
+ appConfig.loginTabs?.default ||
172
+ defaultGuardConfig.defaultLoginMethod
173
+
174
+ const loginMethodTitleMapping = appConfig.loginTabs?.title
175
+
176
+ // 注册方式
177
+ const registerMethods =
178
+ userConfig.registerMethods ||
179
+ appConfig.registerTabs?.list ||
180
+ defaultGuardConfig.registerMethods
181
+ // 默认注册方式
182
+ const defaultRegisterMethod =
183
+ userConfig.defaultRegisterMethod ||
184
+ appConfig.registerTabs?.default ||
185
+ defaultGuardConfig.defaultRegisterMethod
186
+
187
+ // 应用名
188
+ const title = loading
189
+ ? ''
190
+ : userConfig.title ?? appConfig.name ?? defaultGuardConfig.title
191
+
192
+ const description = loading ? '' : appConfig.description ?? ''
193
+
194
+ // 应用 logo
195
+ const logo = loading
196
+ ? ''
197
+ : userConfig.logo ?? appConfig.logo ?? defaultGuardConfig.logo
198
+
199
+ // 是否自动注册
200
+ const autoRegister =
201
+ userConfig.autoRegister ??
202
+ appConfig.ssoPageComponentDisplay?.autoRegisterThenLoginHintInfo ??
203
+ defaultGuardConfig.autoRegister
204
+
205
+ // 禁止注册
206
+ const disableRegister =
207
+ userConfig.disableRegister ??
208
+ !(
209
+ appConfig.ssoPageComponentDisplay?.registerBtn ??
210
+ !defaultGuardConfig.disableRegister
211
+ )
212
+
213
+ // 禁止重置密码
214
+ const disableResetPwd =
215
+ userConfig.disableResetPwd ??
216
+ !(
217
+ appConfig.ssoPageComponentDisplay?.registerBtn ??
218
+ !defaultGuardConfig.disableResetPwd
219
+ )
220
+
221
+ return deepMerge<GuardConfig>(
222
+ {} as GuardConfig,
223
+ defaultGuardConfig,
224
+ userConfig,
225
+ {
226
+ logo,
227
+ title,
228
+ description,
229
+ autoRegister,
230
+ loginMethods,
231
+ passwordLoginMethods,
232
+ extendsFields: appConfig.extendsFields,
233
+ disableRegister,
234
+ disableResetPwd,
235
+ registerMethods,
236
+ defaultLoginMethod,
237
+ socialConnectionObjs,
238
+ defaultRegisterMethod,
239
+ enterpriseConnectionObjs,
240
+ publicKey: appConfig.publicKey,
241
+ qrcodeTabsSettings,
242
+ agreementEnabled: appConfig.agreementEnabled,
243
+ agreements: appConfig.agreements,
244
+ loginMethodTitleMapping: loginMethodTitleMapping,
245
+ }
246
+ )
247
+ }, [
248
+ userConfig,
249
+ appConfig.loginTabs?.list,
250
+ appConfig.loginTabs?.defaultV2,
251
+ appConfig.loginTabs?.default,
252
+ appConfig.loginTabs?.title,
253
+ appConfig.qrcodeTabsSettings,
254
+ appConfig.passwordTabConfig?.enabledLoginMethods,
255
+ appConfig.registerTabs?.list,
256
+ appConfig.registerTabs?.default,
257
+ appConfig.name,
258
+ appConfig.description,
259
+ appConfig.logo,
260
+ appConfig.ssoPageComponentDisplay?.autoRegisterThenLoginHintInfo,
261
+ appConfig.ssoPageComponentDisplay?.registerBtn,
262
+ appConfig.extendsFields,
263
+ appConfig.publicKey,
264
+ appConfig.agreementEnabled,
265
+ appConfig.agreements,
266
+ appConfig.socialConnections,
267
+ appConfig.identityProviders,
268
+ loading,
269
+ ])
270
+
271
+ return {
272
+ loading,
273
+ errorMsg,
274
+ guardConfig,
275
+ errorDetail,
276
+ }
277
+ }
278
+
279
+ const useModal = (visible?: boolean) => {
280
+ const {
281
+ state: { userConfig },
282
+ } = useGuardContext()
283
+
284
+ const isModal = userConfig.mode === GuardMode.Modal
285
+ // 传入了 visible 则为受控组件
286
+ const isControlled = typeof visible !== 'undefined'
287
+
288
+ // modal 模式,没传 visible,默认为 true
289
+ const [localVisible, setLocalVisible] = useState(
290
+ isModal && isControlled ? visible : true
291
+ )
292
+
293
+ const toggleLocalVisible = () => {
294
+ setLocalVisible((v) => !v)
295
+ }
296
+
297
+ const realVisible = useMemo(() => {
298
+ return isControlled ? visible : localVisible
299
+ }, [isControlled, localVisible, visible])
300
+
301
+ return {
302
+ isModal,
303
+ realVisible,
304
+ isControlled,
305
+ toggleLocalVisible,
306
+ }
307
+ }
308
+
309
+ export const GuardLayout: FC<{
310
+ visible?: boolean
311
+ className?: string
312
+ id?: string
313
+ style?: React.CSSProperties
314
+ lang?: Lang
315
+ // 这个传下是为了响应 config 变化,好蠢,以后优化
316
+ userConfig: UserConfig
317
+ }> = ({
318
+ visible,
319
+ id,
320
+ className,
321
+ style,
322
+ lang,
323
+ userConfig: reactiveUserConfig,
324
+ }) => {
325
+ const { t } = useTranslation()
326
+ const {
327
+ state: { guardScenes, authClient, guardEvents, activeTabs, localesConfig },
328
+ setValue,
329
+ } = useGuardContext()
330
+
331
+ const { realVisible, isControlled, toggleLocalVisible } = useModal(visible)
332
+
333
+ const { loading, errorMsg, guardConfig, errorDetail } = useGuardConfig()
334
+
335
+ useEffect(() => {
336
+ if (lang) {
337
+ authClient.setLang(lang)
338
+ changeLang(lang)
339
+ }
340
+ }, [authClient, lang])
341
+
342
+ useEffect(() => {
343
+ if (!loading) {
344
+ guardEvents.onLoginTabChange?.(activeTabs.login)
345
+ }
346
+ }, [activeTabs.login, loading, guardEvents])
347
+
348
+ useEffect(() => {
349
+ if (!loading) {
350
+ guardEvents.onRegisterTabChange?.(activeTabs.register)
351
+ }
352
+ }, [activeTabs.register, loading, guardEvents])
353
+
354
+ useEffect(() => {
355
+ setValue('userConfig', reactiveUserConfig)
356
+ }, [reactiveUserConfig, setValue])
357
+
358
+ // 动画完成后完全隐藏 dom
359
+ const [hidden, setHidden] = useState(false)
360
+ useEffect(() => {
361
+ setHidden(false)
362
+ }, [realVisible])
363
+
364
+ const closeHandler = useCallback(() => {
365
+ if (!isControlled && realVisible) {
366
+ toggleLocalVisible()
367
+ }
368
+ guardEvents.onClose?.()
369
+ }, [isControlled, guardEvents, toggleLocalVisible, realVisible])
370
+
371
+ useEffect(() => {
372
+ if (loading) {
373
+ return
374
+ }
375
+ if (errorDetail) {
376
+ guardEvents.onLoadError?.(errorDetail)
377
+ return
378
+ }
379
+
380
+ guardEvents.onLoad?.(authClient)
381
+ }, [authClient, errorDetail, guardEvents, loading, t])
382
+
383
+ useEffect(() => {
384
+ if (guardConfig.isSSO) {
385
+ trackSession().then((sessionData) => {
386
+ // 这个接口没有 code, data, 直接返回了数据
387
+ let typedData = (sessionData as unknown) as SessionData
388
+ if (typedData.userInfo) {
389
+ message.success(t('common.LoginSuccess'))
390
+ guardEvents.onLogin?.(typedData.userInfo, authClient)
391
+ }
392
+ })
393
+ }
394
+ }, [guardConfig.isSSO, guardEvents, authClient, t])
395
+
396
+ useEffect(() => {
397
+ setValue('config', guardConfig)
398
+ setValue('activeTabs', {
399
+ [GuardScenes.Login]: guardConfig.defaultLoginMethod,
400
+ [GuardScenes.Register]: guardConfig.defaultRegisterMethod,
401
+ })
402
+ // eslint-disable-next-line react-hooks/exhaustive-deps
403
+ }, [guardConfig])
404
+
405
+ const isModal = useMemo(() => guardConfig.mode === GuardMode.Modal, [
406
+ guardConfig,
407
+ ])
408
+
409
+ // 监听 esc 关闭 modal
410
+ useEffect(() => {
411
+ const handler = (evt: KeyboardEvent) => {
412
+ if (evt.keyCode === 27 && isModal && guardConfig.escCloseable) {
413
+ closeHandler()
414
+ }
415
+ }
416
+
417
+ window.addEventListener('keydown', handler)
418
+ return () => window.removeEventListener('keydown', handler)
419
+ }, [closeHandler, guardConfig, isModal])
420
+
421
+ const layoutMap = {
422
+ [GuardScenes.Login]: <LoginLayout />,
423
+ [GuardScenes.Register]: <RegisterLayout />,
424
+ [GuardScenes.RestPassword]: <ResetPwdLayout />,
425
+ [GuardScenes.MfaVerify]: <MfaLayout />,
426
+ [GuardScenes.CompleteUserInfo]: <CompleteUserInfoLayout />,
427
+ [GuardScenes.AppMfaVerify]: <AppMfaLayout />,
428
+ }
429
+
430
+ return (
431
+ <div
432
+ id={id}
433
+ style={{
434
+ ...style,
435
+ zIndex: guardConfig.zIndex || 100,
436
+ }}
437
+ className={getClassnames([
438
+ 'authing-guard-layout',
439
+ !realVisible && 'authing-guard-layout__hidden',
440
+ isModal && 'authing-guard-layout__modal',
441
+ hidden && 'authing-guard-layout__dis-none',
442
+ className,
443
+ ])}
444
+ onTransitionEnd={() => {
445
+ if (!realVisible) {
446
+ setHidden(true)
447
+ }
448
+ }}
449
+ >
450
+ <>
451
+ {isModal && (
452
+ <div
453
+ className={getClassnames([
454
+ 'authing-guard-mask',
455
+ !realVisible && 'authing-guard-mask__hidden',
456
+ ])}
457
+ ></div>
458
+ )}
459
+ <div
460
+ className={getClassnames([
461
+ 'authing-guard-container',
462
+ !realVisible && 'authing-guard-container__hidden',
463
+ ])}
464
+ >
465
+ {isModal && guardConfig.clickCloseable && (
466
+ <button onClick={closeHandler} className="authing-guard-close-btn">
467
+ <IconFont type="authing-guanbi" />
468
+ </button>
469
+ )}
470
+
471
+ <GuardHeader />
472
+
473
+ {loading ? (
474
+ <Spin size="large" className="authing-guard-loading" />
475
+ ) : errorMsg ? (
476
+ <div className="authing-guard-load-error">{errorMsg}</div>
477
+ ) : (
478
+ layoutMap[guardScenes]
479
+ )}
480
+ {/* <div>{localesConfig?.isShowChange && <ToggleLang />}</div> */}
481
+ <div>
482
+ {localesConfig?.isShowChange === false ? null : <ToggleLang />}
483
+ </div>
484
+ </div>
485
+ </>
486
+ </div>
487
+ )
488
+ }
@@ -0,0 +1,111 @@
1
+ .authing-guard-layout {
2
+ display: flex;
3
+ justify-content: center;
4
+ align-items: center;
5
+ width: 100%;
6
+ padding: 24px 0;
7
+ height: 100%;
8
+ }
9
+
10
+ .authing-guard-layout__hidden {
11
+ pointer-events: none;
12
+ }
13
+
14
+ .authing-guard-layout__dis-none {
15
+ z-index: -1;
16
+ opacity: 0;
17
+ }
18
+
19
+ .authing-guard-layout__modal {
20
+ position: fixed;
21
+ left: 0;
22
+ top: 0;
23
+ }
24
+
25
+ .authing-guard-mask {
26
+ position: absolute;
27
+ left: 0;
28
+ right: 0;
29
+ top: 0;
30
+ bottom: 0;
31
+ background-color: rgba(0, 0, 0, 0.45);
32
+ opacity: 1;
33
+ transition: all 0.3s;
34
+ }
35
+
36
+ .authing-guard-mask__hidden {
37
+ opacity: 0;
38
+ }
39
+
40
+ .authing-guard-container {
41
+ width: 440px;
42
+ min-height: 610px;
43
+ max-height: 100%;
44
+ box-sizing: border-box;
45
+ background-color: #fff;
46
+ padding: 39px 38px 31px;
47
+ border-radius: 10px;
48
+ display: flex;
49
+ flex-direction: column;
50
+ box-shadow: 0 2px 10px 0 rgba(57, 106, 255, 0.2);
51
+ margin-left: auto;
52
+ margin-right: auto;
53
+ overflow: auto;
54
+ position: relative;
55
+ transform: translateY(0);
56
+ transition: all 0.3s;
57
+ }
58
+
59
+ .authing-guard-container__hidden {
60
+ transform: translateY(2000px);
61
+ }
62
+
63
+ .authing-guard-loading,
64
+ .authing-guard-load-error {
65
+ flex: 1;
66
+ display: flex;
67
+ align-items: center;
68
+ justify-content: center;
69
+ }
70
+
71
+ .authing-guard-close-btn {
72
+ position: absolute;
73
+ right: 12px;
74
+ top: 12px;
75
+ border: none;
76
+ outline: none;
77
+ box-shadow: none;
78
+ background-color: #fff;
79
+ border-radius: 50%;
80
+ width: 30px;
81
+ height: 30px;
82
+ text-align: center;
83
+ line-height: 20px;
84
+ cursor: pointer;
85
+ &:focus {
86
+ outline: none;
87
+ border: none;
88
+ box-shadow: none;
89
+ }
90
+ &:hover {
91
+ color: #396aff;
92
+ }
93
+ }
94
+
95
+ @media only screen and (max-width: 719px) {
96
+ .authing-guard-layout {
97
+ padding: 0;
98
+ }
99
+ .authing-guard-container {
100
+ width: 100%;
101
+ min-height: 100%;
102
+ border: none;
103
+ border-radius: initial;
104
+ box-shadow: initial;
105
+ padding-left: 24px;
106
+ padding-right: 24px;
107
+ }
108
+ .authing-ant-input {
109
+ font-size: 14px;
110
+ }
111
+ }
@@ -0,0 +1,28 @@
1
+ import React, { FC } from 'react'
2
+ import { Avatar } from 'antd'
3
+
4
+ import { useGuardContext } from '../../../context/global/context'
5
+
6
+ import './style.less'
7
+
8
+ export interface HeaderProps extends React.HTMLAttributes<HTMLDivElement> {}
9
+
10
+ export const GuardHeader: FC<HeaderProps> = (props) => {
11
+ const {
12
+ state: {
13
+ config: { logo, title, description },
14
+ },
15
+ } = useGuardContext()
16
+
17
+ return (
18
+ <div className="authing-guard-header">
19
+ {Boolean(logo) && (
20
+ <Avatar className="authing-guard-logo" src={logo} size={50}></Avatar>
21
+ )}
22
+ <div className="authing-guard-title-container">
23
+ <div className="authing-guard-title">{title}</div>
24
+ <div className="authing-guard-description">{description}</div>
25
+ </div>
26
+ </div>
27
+ )
28
+ }
@@ -0,0 +1,64 @@
1
+ .authing-guard-header {
2
+ display: flex;
3
+ flex-direction: column;
4
+ justify-content: center;
5
+ align-items: center;
6
+ }
7
+
8
+ .authing-guard-logo {
9
+ margin-bottom: 8px;
10
+ }
11
+
12
+ .authing-guard-logo img {
13
+ object-fit: contain;
14
+ }
15
+
16
+ .authing-guard-title-container {
17
+ display: flex;
18
+ justify-content: center;
19
+ flex-direction: column;
20
+ align-items: center;
21
+ }
22
+
23
+ .authing-guard-title {
24
+ color: #282d3c;
25
+ font-size: 24px;
26
+ margin-bottom: 4px;
27
+ width: 100%;
28
+ word-break: break-all;
29
+ text-align: center;
30
+ }
31
+ .authing-guard-description {
32
+ font-size: 16px;
33
+ color: #878a95;
34
+ margin-bottom: 23px;
35
+ }
36
+
37
+ @media only screen and (max-width: 719px) {
38
+ .authing-guard-header {
39
+ align-items: flex-start;
40
+ flex-direction: row;
41
+ align-items: center;
42
+ justify-content: flex-start;
43
+ padding-top: 40px;
44
+ padding-bottom: 48px;
45
+ }
46
+ .authing-guard-title {
47
+ margin-bottom: 0;
48
+ padding-left: 8px;
49
+ color: #333333;
50
+ font-weight: 500;
51
+ text-align: unset;
52
+ }
53
+ .authing-guard-logo {
54
+ margin: 0;
55
+ }
56
+ .authing-guard-title-container {
57
+ flex-direction: column;
58
+ align-items: flex-start;
59
+ }
60
+ .authing-guard-description {
61
+ margin-bottom: 0px;
62
+ padding-left: 8px;
63
+ }
64
+ }