page.tsx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. 'use client'
  2. import cn from 'classnames'
  3. import { useRouter, useSearchParams } from 'next/navigation'
  4. import type { FC } from 'react'
  5. import React, { useEffect } from 'react'
  6. import Toast from '@/app/components/base/toast'
  7. import { fetchSystemFeatures, fetchWebOAuth2SSOUrl, fetchWebOIDCSSOUrl, fetchWebSAMLSSOUrl } from '@/service/share'
  8. import { setAccessToken } from '@/app/components/share/utils'
  9. import Loading from '@/app/components/base/loading'
  10. const WebSSOForm: FC = () => {
  11. const searchParams = useSearchParams()
  12. const router = useRouter()
  13. const redirectUrl = searchParams.get('redirect_url')
  14. const tokenFromUrl = searchParams.get('web_sso_token')
  15. const message = searchParams.get('message')
  16. const showErrorToast = (message: string) => {
  17. Toast.notify({
  18. type: 'error',
  19. message,
  20. })
  21. }
  22. const getAppCodeFromRedirectUrl = () => {
  23. const appCode = redirectUrl?.split('/').pop()
  24. if (!appCode)
  25. return null
  26. return appCode
  27. }
  28. const processTokenAndRedirect = async () => {
  29. const appCode = getAppCodeFromRedirectUrl()
  30. if (!appCode || !tokenFromUrl || !redirectUrl) {
  31. showErrorToast('redirect url or app code or token is invalid.')
  32. return
  33. }
  34. await setAccessToken(appCode, tokenFromUrl)
  35. router.push(redirectUrl)
  36. }
  37. const handleSSOLogin = async (protocol: string) => {
  38. const appCode = getAppCodeFromRedirectUrl()
  39. if (!appCode || !redirectUrl) {
  40. showErrorToast('redirect url or app code is invalid.')
  41. return
  42. }
  43. switch (protocol) {
  44. case 'saml': {
  45. const samlRes = await fetchWebSAMLSSOUrl(appCode, redirectUrl)
  46. router.push(samlRes.url)
  47. break
  48. }
  49. case 'oidc': {
  50. const oidcRes = await fetchWebOIDCSSOUrl(appCode, redirectUrl)
  51. router.push(oidcRes.url)
  52. break
  53. }
  54. case 'oauth2': {
  55. const oauth2Res = await fetchWebOAuth2SSOUrl(appCode, redirectUrl)
  56. router.push(oauth2Res.url)
  57. break
  58. }
  59. default:
  60. showErrorToast('SSO protocol is not supported.')
  61. }
  62. }
  63. useEffect(() => {
  64. const init = async () => {
  65. const res = await fetchSystemFeatures()
  66. const protocol = res.sso_enforced_for_web_protocol
  67. if (message) {
  68. showErrorToast(message)
  69. return
  70. }
  71. if (!tokenFromUrl) {
  72. await handleSSOLogin(protocol)
  73. return
  74. }
  75. await processTokenAndRedirect()
  76. }
  77. init()
  78. }, [message, tokenFromUrl]) // Added dependencies to useEffect
  79. return (
  80. <div className="flex items-center justify-center h-full">
  81. <div className={cn('flex flex-col items-center w-full grow justify-center', 'px-6', 'md:px-[108px]')}>
  82. <Loading type='area' />
  83. </div>
  84. </div>
  85. )
  86. }
  87. export default React.memo(WebSSOForm)