feat: Access to `WeCome` user login

This commit is contained in:
haitaoo 2023-04-14 17:42:07 +08:00
parent 2e8e6be9af
commit f02f62112a
14 changed files with 427 additions and 220 deletions

View File

@ -1110,6 +1110,8 @@ ui:
installed_plugins: Installed Plugins
website_welcome: Welcome to {{site_name}}
plugins:
login: Login
qrcode_login_tip: Please use {{ agentName }} to scan the QR code and log in.
oauth:
connect: Connect with {{ auth_name }}
remove: Remove {{ auth_name }}

View File

@ -22,7 +22,6 @@
"copy-to-clipboard": "^3.3.2",
"dayjs": "^1.11.5",
"diff": "^5.1.0",
"emoji-regex": "^10.2.1",
"i18next": "^21.9.0",
"katex": "^0.16.2",
"lodash": "^4.17.21",
@ -30,6 +29,7 @@
"md5": "^2.3.0",
"mermaid": "^9.1.7",
"next-share": "^0.18.1",
"qrcode": "^1.5.1",
"qs": "^6.11.0",
"react": "^18.2.0",
"react-bootstrap": "^2.5.0",

View File

@ -29,7 +29,6 @@ specifiers:
customize-cra: ^1.0.0
dayjs: ^1.11.5
diff: ^5.1.0
emoji-regex: ^10.2.1
eslint: ^8.0.1
eslint-config-airbnb: ^19.0.4
eslint-config-airbnb-typescript: ^17.0.0
@ -54,6 +53,7 @@ specifiers:
postcss: ^8.0.0
prettier: ^2.7.1
purgecss-webpack-plugin: ^4.1.3
qrcode: ^1.5.1
qs: ^6.11.0
react: ^18.2.0
react-app-rewired: ^2.2.1
@ -81,7 +81,6 @@ dependencies:
copy-to-clipboard: 3.3.2
dayjs: 1.11.5
diff: 5.1.0
emoji-regex: 10.2.1
i18next: 21.9.2
katex: 0.16.2
lodash: 4.17.21
@ -89,6 +88,7 @@ dependencies:
md5: 2.3.0
mermaid: 9.1.7
next-share: 0.18.1_lbqamd2wfmenkveygahn4wdfcq
qrcode: 1.5.1
qs: 6.11.0
react: 18.2.0
react-bootstrap: 2.5.0_7ey2zzynotv32rpkwno45fsx4e
@ -109,8 +109,8 @@ devDependencies:
'@testing-library/jest-dom': 4.2.4
'@testing-library/react': 13.4.0_biqbaboplfbrettd7655fr4n2y
'@testing-library/user-event': 13.5.0_znccgeejomvff3jrsk3ljovfpu
'@types/color': registry.npmjs.org/@types/color/3.0.3
'@types/dompurify': registry.npmjs.org/@types/dompurify/2.4.0
'@types/color': 3.0.3
'@types/dompurify': 2.4.0
'@types/jest': 27.5.2
'@types/lodash': 4.14.185
'@types/marked': 4.0.7
@ -1682,7 +1682,7 @@ packages:
cosmiconfig-typescript-loader: 4.1.0_2uclxasecupgvdn72amnhmyg7y
lodash: 4.17.21
resolve-from: 5.0.0
ts-node: 10.9.1_5bkdw6noa5sa7givrguqy7ejvm
ts-node: 10.9.1_yxpazyh7n5pql7jdaglasgwqki
typescript: 4.9.5
transitivePeerDependencies:
- '@swc/core'
@ -2077,7 +2077,7 @@ packages:
collect-v8-coverage: 1.0.1
exit: 0.1.2
glob: 7.2.3
graceful-fs: 4.2.10
graceful-fs: 4.2.11
istanbul-lib-coverage: 3.2.0
istanbul-lib-instrument: 5.2.0
istanbul-lib-report: 3.0.0
@ -2106,7 +2106,7 @@ packages:
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
dependencies:
callsites: 3.1.0
graceful-fs: 4.2.10
graceful-fs: 4.2.11
source-map: 0.6.1
/@jest/test-result/27.5.1:
@ -2132,7 +2132,7 @@ packages:
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
dependencies:
'@jest/test-result': 27.5.1
graceful-fs: 4.2.10
graceful-fs: 4.2.11
jest-haste-map: 27.5.1
jest-runtime: 27.5.1
transitivePeerDependencies:
@ -2203,7 +2203,7 @@ packages:
dependencies:
'@jridgewell/set-array': 1.1.2
'@jridgewell/sourcemap-codec': 1.4.14
'@jridgewell/trace-mapping': 0.3.15
'@jridgewell/trace-mapping': 0.3.17
/@jridgewell/resolve-uri/3.1.0:
resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==}
@ -2217,7 +2217,7 @@ packages:
resolution: {integrity: sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==}
dependencies:
'@jridgewell/gen-mapping': 0.3.2
'@jridgewell/trace-mapping': 0.3.15
'@jridgewell/trace-mapping': 0.3.17
/@jridgewell/sourcemap-codec/1.4.14:
resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==}
@ -2637,6 +2637,22 @@ packages:
dependencies:
'@types/node': 16.11.59
/@types/color-convert/2.0.0:
resolution: {integrity: sha512-m7GG7IKKGuJUXvkZ1qqG3ChccdIM/qBBo913z+Xft0nKCX4hAU/IxKwZBU4cpRZ7GS5kV4vOblUkILtSShCPXQ==}
dependencies:
'@types/color-name': 1.1.1
dev: true
/@types/color-name/1.1.1:
resolution: {integrity: sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==}
dev: true
/@types/color/3.0.3:
resolution: {integrity: sha512-X//qzJ3d3Zj82J9sC/C18ZY5f43utPbAJ6PhYt/M7uG6etcF6MRpKdN880KBy43B0BMzSfeT96MzrsNjFI3GbA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.yarnpkg.com/@types/color/-/color-3.0.3.tgz}
dependencies:
'@types/color-convert': 2.0.0
dev: true
/@types/connect-history-api-fallback/1.3.5:
resolution: {integrity: sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==}
dependencies:
@ -2648,6 +2664,12 @@ packages:
dependencies:
'@types/node': 16.11.59
/@types/dompurify/2.4.0:
resolution: {integrity: sha512-IDBwO5IZhrKvHFUl+clZxgf3hn2b/lU6H1KaBShPkQyGJUQ0xwebezIPSuiyGwfz1UzJWQl4M7BDxtHtCCPlTg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.yarnpkg.com/@types/dompurify/-/dompurify-2.4.0.tgz}
dependencies:
'@types/trusted-types': 2.0.2
dev: true
/@types/eslint-scope/3.7.4:
resolution: {integrity: sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==}
dependencies:
@ -2823,6 +2845,9 @@ packages:
/@types/stack-utils/2.0.1:
resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==}
/@types/trusted-types/2.0.2:
resolution: {integrity: sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==}
/@types/warning/3.0.0:
resolution: {integrity: sha512-t/Tvs5qR47OLOr+4E9ckN8AmP2Tf16gWq+/qA4iUGS/OOyHVO8wv2vjJuX8SNOUTJyWb+2t7wJm6cXILFnOROA==}
dev: false
@ -3857,6 +3882,14 @@ packages:
string-width: 5.1.2
dev: true
/cliui/6.0.0:
resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
dependencies:
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi: 6.2.0
dev: false
/cliui/7.0.4:
resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==}
dependencies:
@ -4078,7 +4111,7 @@ packages:
dependencies:
'@types/node': 14.18.29
cosmiconfig: 7.0.1
ts-node: 10.9.1_5bkdw6noa5sa7givrguqy7ejvm
ts-node: 10.9.1_yxpazyh7n5pql7jdaglasgwqki
typescript: 4.9.5
dev: true
@ -4209,7 +4242,7 @@ packages:
dependencies:
boolbase: 1.0.0
css-what: 3.4.2
domutils: registry.npmjs.org/domutils/1.7.0
domutils: 1.7.0
nth-check: 1.0.2
/css-select/4.3.0:
@ -4217,8 +4250,8 @@ packages:
dependencies:
boolbase: 1.0.0
css-what: 6.1.0
domhandler: registry.npmjs.org/domhandler/4.3.1
domutils: registry.npmjs.org/domutils/2.8.0
domhandler: 4.3.1
domutils: 2.8.0
nth-check: 2.1.1
/css-tree/1.0.0-alpha.37:
@ -4890,7 +4923,6 @@ packages:
/decamelize/1.2.0:
resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
engines: {node: '>=0.10.0'}
dev: true
/decimal.js/10.4.1:
resolution: {integrity: sha512-F29o+vci4DodHYT9UrR5IEbfBw9pE5eSapIJdTqXK5+6hq+t8VRxwQyKlW2i+KDKFkkJQRvFyI/QXD83h8LyQw==}
@ -5004,6 +5036,10 @@ packages:
engines: {node: '>=0.3.1'}
dev: false
/dijkstrajs/1.0.2:
resolution: {integrity: sha512-QV6PMaHTCNmKSeP6QoXhVTw9snc9VD8MulTT0Bd99Pacp4SS1cjcrYPgBPmibqKVtMJJfqC6XvOXgPMEEPH/fg==}
dev: false
/dir-glob/3.0.1:
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
engines: {node: '>=8'}
@ -5050,12 +5086,54 @@ packages:
csstype: 3.1.1
dev: false
/dom-serializer/0.2.2:
resolution: {integrity: sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==, registry: https://registry.yarnpkg.com/}
dependencies:
domelementtype: 2.3.0
entities: 2.2.0
/dom-serializer/1.4.1:
resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==, registry: https://registry.yarnpkg.com/}
dependencies:
domelementtype: 2.3.0
domhandler: 4.3.1
entities: 2.2.0
/domelementtype/1.3.1:
resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==, registry: https://registry.yarnpkg.com/}
/domelementtype/2.3.0:
resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==, registry: https://registry.yarnpkg.com/}
/domexception/2.0.1:
resolution: {integrity: sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==}
engines: {node: '>=8'}
dependencies:
webidl-conversions: 5.0.0
/domhandler/4.3.1:
resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==, registry: https://registry.yarnpkg.com/}
engines: {node: '>= 4'}
dependencies:
domelementtype: 2.3.0
/dompurify/2.4.0:
resolution: {integrity: sha512-Be9tbQMZds4a3C6xTmz68NlMfeONA//4dOavl/1rNw50E+/QO0KVpbcU0PcaW0nsQxurXls9ZocqFxk8R2mWEA==, registry: https://registry.yarnpkg.com/}
dev: false
/domutils/1.7.0:
resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==, registry: https://registry.yarnpkg.com/}
dependencies:
dom-serializer: 0.2.2
domelementtype: 1.3.1
/domutils/2.8.0:
resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==, registry: https://registry.yarnpkg.com/}
dependencies:
dom-serializer: 1.4.1
domelementtype: 2.3.0
domhandler: 4.3.1
/dot-case/3.0.4:
resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
dependencies:
@ -5107,10 +5185,6 @@ packages:
resolution: {integrity: sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==}
engines: {node: '>=10'}
/emoji-regex/10.2.1:
resolution: {integrity: sha512-97g6QgOk8zlDRdgq1WxwgTMgEWGVAQvB5Fdpgc1MkNy56la5SKP9GsMXKDOdqwn90/41a8yPwIGk1Y6WVbeMQA==}
dev: false
/emoji-regex/8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
@ -5121,6 +5195,10 @@ packages:
resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==}
engines: {node: '>= 4'}
/encode-utf8/1.0.3:
resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==}
dev: false
/encodeurl/1.0.2:
resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==}
engines: {node: '>= 0.8'}
@ -5129,7 +5207,7 @@ packages:
resolution: {integrity: sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==}
engines: {node: '>=10.13.0'}
dependencies:
graceful-fs: 4.2.10
graceful-fs: 4.2.11
tapable: 2.2.1
/enhanced-resolve/5.12.0:
@ -5140,6 +5218,9 @@ packages:
tapable: 2.2.1
dev: true
/entities/2.2.0:
resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==, registry: https://registry.yarnpkg.com/}
/error-ex/1.3.2:
resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
dependencies:
@ -6014,7 +6095,7 @@ packages:
engines: {node: '>=10'}
dependencies:
at-least-node: 1.0.0
graceful-fs: 4.2.10
graceful-fs: 4.2.11
jsonfile: 6.1.0
universalify: 2.0.0
@ -6163,7 +6244,6 @@ packages:
/graceful-fs/4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
dev: true
/grapheme-splitter/1.0.4:
resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==}
@ -6294,6 +6374,14 @@ packages:
tapable: 2.2.1
webpack: 5.74.0
/htmlparser2/6.1.0:
resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==, registry: https://registry.yarnpkg.com/}
dependencies:
domelementtype: 2.3.0
domhandler: 4.3.1
domutils: 2.8.0
entities: 2.2.0
/http-deceiver/1.2.7:
resolution: {integrity: sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==}
@ -6805,7 +6893,7 @@ packages:
ci-info: 3.4.0
deepmerge: 4.2.2
glob: 7.2.3
graceful-fs: 4.2.10
graceful-fs: 4.2.11
jest-circus: 27.5.1
jest-environment-jsdom: 27.5.1
jest-environment-node: 27.5.1
@ -6977,7 +7065,7 @@ packages:
'@jest/types': 27.5.1
'@types/stack-utils': 2.0.1
chalk: 4.1.2
graceful-fs: 4.2.10
graceful-fs: 4.2.11
micromatch: 4.0.5
pretty-format: 27.5.1
slash: 3.0.0
@ -6991,7 +7079,7 @@ packages:
'@jest/types': 28.1.3
'@types/stack-utils': 2.0.1
chalk: 4.1.2
graceful-fs: 4.2.10
graceful-fs: 4.2.11
micromatch: 4.0.5
pretty-format: 28.1.3
slash: 3.0.0
@ -7060,7 +7148,7 @@ packages:
'@types/node': 16.11.59
chalk: 4.1.2
emittery: 0.8.1
graceful-fs: 4.2.10
graceful-fs: 4.2.11
jest-docblock: 27.5.1
jest-environment-jsdom: 27.5.1
jest-environment-node: 27.5.1
@ -7095,7 +7183,7 @@ packages:
collect-v8-coverage: 1.0.1
execa: 5.1.1
glob: 7.2.3
graceful-fs: 4.2.10
graceful-fs: 4.2.11
jest-haste-map: 27.5.1
jest-message-util: 27.5.1
jest-mock: 27.5.1
@ -7113,7 +7201,7 @@ packages:
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
dependencies:
'@types/node': 16.11.59
graceful-fs: 4.2.10
graceful-fs: 4.2.11
/jest-snapshot/27.5.1:
resolution: {integrity: sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==}
@ -7131,7 +7219,7 @@ packages:
babel-preset-current-node-syntax: 1.0.1_@babel+core@7.19.1
chalk: 4.1.2
expect: 27.5.1
graceful-fs: 4.2.10
graceful-fs: 4.2.11
jest-diff: 27.5.1
jest-get-type: 27.5.1
jest-haste-map: 27.5.1
@ -7163,7 +7251,7 @@ packages:
'@types/node': 16.11.59
chalk: 4.1.2
ci-info: 3.4.0
graceful-fs: 4.2.10
graceful-fs: 4.2.11
picomatch: 2.3.1
/jest-validate/27.5.1:
@ -7366,7 +7454,7 @@ packages:
dependencies:
universalify: 2.0.0
optionalDependencies:
graceful-fs: 4.2.10
graceful-fs: 4.2.11
/jsonp/0.2.1:
resolution: {integrity: sha512-pfog5gdDxPdV4eP7Kg87M8/bHgshlZ5pybl+yKxAnCZ5O7lCIn7Ixydj03wOlnDQesky2BPyA91SQ+5Y/mNwzw==}
@ -7682,7 +7770,7 @@ packages:
d3: 7.6.1
dagre: 0.8.5
dagre-d3: 0.6.4
dompurify: registry.npmjs.org/dompurify/2.4.0
dompurify: 2.4.0
graphlib: 2.1.8
khroma: 2.0.0
moment-mini: 2.24.0
@ -8178,6 +8266,11 @@ packages:
dependencies:
find-up: 3.0.0
/pngjs/5.0.0:
resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
engines: {node: '>=10.13.0'}
dev: false
/postcss-attribute-case-insensitive/5.0.2_postcss@8.4.16:
resolution: {integrity: sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==}
engines: {node: ^12 || ^14 || >=16}
@ -9008,6 +9101,17 @@ packages:
resolution: {integrity: sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==}
engines: {node: '>=0.6.0', teleport: '>=0.2.0'}
/qrcode/1.5.1:
resolution: {integrity: sha512-nS8NJ1Z3md8uTjKtP+SGGhfqmTCs5flU/xR623oI0JX+Wepz9R8UrRVCTBTJm3qGw3rH6jJ6MUHjkDx15cxSSg==}
engines: {node: '>=10.13.0'}
hasBin: true
dependencies:
dijkstrajs: 1.0.2
encode-utf8: 1.0.3
pngjs: 5.0.0
yargs: 15.4.1
dev: false
/qs/6.10.3:
resolution: {integrity: sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==}
engines: {node: '>=0.6'}
@ -9479,7 +9583,7 @@ packages:
dependencies:
css-select: 4.3.0
dom-converter: 0.2.0
htmlparser2: registry.npmjs.org/htmlparser2/6.1.0
htmlparser2: 6.1.0
lodash: 4.17.21
strip-ansi: 6.0.1
@ -9491,6 +9595,10 @@ packages:
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
engines: {node: '>=0.10.0'}
/require-main-filename/2.0.0:
resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
dev: false
/requires-port/1.0.0:
resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
@ -9807,6 +9915,10 @@ packages:
transitivePeerDependencies:
- supports-color
/set-blocking/2.0.0:
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
dev: false
/setprototypeof/1.1.0:
resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==}
@ -10487,6 +10599,37 @@ packages:
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
/ts-node/10.9.1_yxpazyh7n5pql7jdaglasgwqki:
resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
hasBin: true
peerDependencies:
'@swc/core': '>=1.2.50'
'@swc/wasm': '>=1.2.50'
'@types/node': '*'
typescript: '>=2.7'
peerDependenciesMeta:
'@swc/core':
optional: true
'@swc/wasm':
optional: true
dependencies:
'@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.9
'@tsconfig/node12': 1.0.11
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.3
'@types/node': 14.18.29
acorn: 8.8.0
acorn-walk: 8.2.0
arg: 4.1.3
create-require: 1.1.1
diff: 4.0.2
make-error: 1.3.6
typescript: 4.9.5
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
dev: true
/tsconfig-paths/3.14.1:
resolution: {integrity: sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==}
dependencies:
@ -10760,7 +10903,7 @@ packages:
engines: {node: '>=10.13.0'}
dependencies:
glob-to-regexp: 0.4.1
graceful-fs: 4.2.10
graceful-fs: 4.2.11
/wbuf/1.7.3:
resolution: {integrity: sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==}
@ -10991,6 +11134,10 @@ packages:
is-string: 1.0.7
is-symbol: 1.0.4
/which-module/2.0.0:
resolution: {integrity: sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==}
dev: false
/which/1.3.1:
resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==}
hasBin: true
@ -11151,7 +11298,7 @@ packages:
/workbox-window/6.5.4:
resolution: {integrity: sha512-HnLZJDwYBE+hpG25AQBO8RUWBJRaCsI9ksQJEp3aCOFCaG5kqaToAYXFRAHxzRluM2cQbGzdQF5rjKPWPA1fug==}
dependencies:
'@types/trusted-types': registry.npmjs.org/@types/trusted-types/2.0.2
'@types/trusted-types': 2.0.2
workbox-core: 6.5.4
/wrap-ansi/6.2.0:
@ -11161,7 +11308,6 @@ packages:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1
dev: true
/wrap-ansi/7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
@ -11216,6 +11362,10 @@ packages:
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
engines: {node: '>=0.4'}
/y18n/4.0.3:
resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
dev: false
/y18n/5.0.8:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'}
@ -11244,6 +11394,14 @@ packages:
engines: {node: '>= 14'}
dev: true
/yargs-parser/18.1.3:
resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==}
engines: {node: '>=6'}
dependencies:
camelcase: 5.3.1
decamelize: 1.2.0
dev: false
/yargs-parser/20.2.9:
resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==}
engines: {node: '>=10'}
@ -11253,6 +11411,23 @@ packages:
engines: {node: '>=12'}
dev: true
/yargs/15.4.1:
resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==}
engines: {node: '>=8'}
dependencies:
cliui: 6.0.0
decamelize: 1.2.0
find-up: 4.1.0
get-caller-file: 2.0.5
require-directory: 2.1.1
require-main-filename: 2.0.0
set-blocking: 2.0.0
string-width: 4.2.3
which-module: 2.0.0
y18n: 4.0.3
yargs-parser: 18.1.3
dev: false
/yargs/16.2.0:
resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==}
engines: {node: '>=10'}
@ -11301,111 +11476,3 @@ packages:
react: 18.2.0
use-sync-external-store: 1.2.0_react@18.2.0
dev: false
registry.npmjs.org/@types/color-convert/2.0.0:
resolution: {integrity: sha512-m7GG7IKKGuJUXvkZ1qqG3ChccdIM/qBBo913z+Xft0nKCX4hAU/IxKwZBU4cpRZ7GS5kV4vOblUkILtSShCPXQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@types/color-convert/-/color-convert-2.0.0.tgz}
name: '@types/color-convert'
version: 2.0.0
dependencies:
'@types/color-name': registry.npmjs.org/@types/color-name/1.1.1
dev: true
registry.npmjs.org/@types/color-name/1.1.1:
resolution: {integrity: sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz}
name: '@types/color-name'
version: 1.1.1
dev: true
registry.npmjs.org/@types/color/3.0.3:
resolution: {integrity: sha512-X//qzJ3d3Zj82J9sC/C18ZY5f43utPbAJ6PhYt/M7uG6etcF6MRpKdN880KBy43B0BMzSfeT96MzrsNjFI3GbA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@types/color/-/color-3.0.3.tgz}
name: '@types/color'
version: 3.0.3
dependencies:
'@types/color-convert': registry.npmjs.org/@types/color-convert/2.0.0
dev: true
registry.npmjs.org/@types/dompurify/2.4.0:
resolution: {integrity: sha512-IDBwO5IZhrKvHFUl+clZxgf3hn2b/lU6H1KaBShPkQyGJUQ0xwebezIPSuiyGwfz1UzJWQl4M7BDxtHtCCPlTg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@types/dompurify/-/dompurify-2.4.0.tgz}
name: '@types/dompurify'
version: 2.4.0
dependencies:
'@types/trusted-types': registry.npmjs.org/@types/trusted-types/2.0.2
dev: true
registry.npmjs.org/@types/trusted-types/2.0.2:
resolution: {integrity: sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz}
name: '@types/trusted-types'
version: 2.0.2
registry.npmjs.org/dom-serializer/0.2.2:
resolution: {integrity: sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz}
name: dom-serializer
version: 0.2.2
dependencies:
domelementtype: registry.npmjs.org/domelementtype/2.3.0
entities: registry.npmjs.org/entities/2.2.0
registry.npmjs.org/dom-serializer/1.4.1:
resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz}
name: dom-serializer
version: 1.4.1
dependencies:
domelementtype: registry.npmjs.org/domelementtype/2.3.0
domhandler: registry.npmjs.org/domhandler/4.3.1
entities: registry.npmjs.org/entities/2.2.0
registry.npmjs.org/domelementtype/1.3.1:
resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz}
name: domelementtype
version: 1.3.1
registry.npmjs.org/domelementtype/2.3.0:
resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz}
name: domelementtype
version: 2.3.0
registry.npmjs.org/domhandler/4.3.1:
resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz}
name: domhandler
version: 4.3.1
engines: {node: '>= 4'}
dependencies:
domelementtype: registry.npmjs.org/domelementtype/2.3.0
registry.npmjs.org/dompurify/2.4.0:
resolution: {integrity: sha512-Be9tbQMZds4a3C6xTmz68NlMfeONA//4dOavl/1rNw50E+/QO0KVpbcU0PcaW0nsQxurXls9ZocqFxk8R2mWEA==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/dompurify/-/dompurify-2.4.0.tgz}
name: dompurify
version: 2.4.0
dev: false
registry.npmjs.org/domutils/1.7.0:
resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz}
name: domutils
version: 1.7.0
dependencies:
dom-serializer: registry.npmjs.org/dom-serializer/0.2.2
domelementtype: registry.npmjs.org/domelementtype/1.3.1
registry.npmjs.org/domutils/2.8.0:
resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz}
name: domutils
version: 2.8.0
dependencies:
dom-serializer: registry.npmjs.org/dom-serializer/1.4.1
domelementtype: registry.npmjs.org/domelementtype/2.3.0
domhandler: registry.npmjs.org/domhandler/4.3.1
registry.npmjs.org/entities/2.2.0:
resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/entities/-/entities-2.2.0.tgz}
name: entities
version: 2.2.0
registry.npmjs.org/htmlparser2/6.1.0:
resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==, registry: https://registry.yarnpkg.com/, tarball: https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz}
name: htmlparser2
version: 6.1.0
dependencies:
domelementtype: registry.npmjs.org/domelementtype/2.3.0
domhandler: registry.npmjs.org/domhandler/4.3.1
domutils: registry.npmjs.org/domutils/2.8.0
entities: registry.npmjs.org/entities/2.2.0

View File

@ -1,7 +1,4 @@
import emojiRegex from 'emoji-regex';
const pattern = {
emoji: emojiRegex(),
email:
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+\.)+[a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{2,}))$/,
};

View File

@ -93,7 +93,9 @@ const Index: FC<Props> = ({ redDot, userInfo, logOut }) => {
</Dropdown.Menu>
</Dropdown>
{/* Dropdown for user center agent info */}
{ucAgent?.enabled && ucAgent?.agent_info ? (
{ucAgent?.enabled &&
(ucAgent?.agent_info?.url ||
ucAgent?.agent_info?.control_center?.length) ? (
<Dropdown align="end">
<Dropdown.Toggle
variant="success"
@ -104,10 +106,15 @@ const Index: FC<Props> = ({ redDot, userInfo, logOut }) => {
</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item href={ucAgent.agent_info.url}>
{ucAgent.agent_info.name}
</Dropdown.Item>
<Dropdown.Divider />
{ucAgent.agent_info.url ? (
<Dropdown.Item href={ucAgent.agent_info.url}>
{ucAgent.agent_info.name}
</Dropdown.Item>
) : null}
{ucAgent.agent_info.url &&
ucAgent.agent_info.control_center?.length ? (
<Dropdown.Divider />
) : null}
{ucAgent.agent_info.control_center?.map((ctrl) => {
return (
<Dropdown.Item key={ctrl.name} href={ctrl.url}>

View File

@ -3,7 +3,7 @@ import { FC } from 'react';
import { base64ToSvg } from '@/utils';
interface IProps {
base64: string;
base64: string | undefined;
}
const Icon: FC<IProps> = ({ base64 = '' }) => {
return base64 ? (

View File

@ -3,25 +3,22 @@ import { Container, Form, Button, Col } from 'react-bootstrap';
import { Link, useNavigate, useSearchParams } from 'react-router-dom';
import { Trans, useTranslation } from 'react-i18next';
import { RouteAlias } from '@/router/alias';
import { REDIRECT_PATH_STORAGE_KEY } from '@/common/constants';
import { usePageTags } from '@/hooks';
import type {
LoginReqParams,
ImgCodeRes,
FormDataType,
} from '@/common/interface';
import { SvgIcon, Unactivate, WelcomeTitle } from '@/components';
import { PluginOauth } from '@/plugins';
import { Unactivate, WelcomeTitle } from '@/components';
import { PluginOauth, PluginUcLogin } from '@/plugins';
import {
loggedUserInfoStore,
loginSettingStore,
userCenterStore,
} from '@/stores';
import { guard, floppyNavigation, handleFormError } from '@/utils';
import { guard, handleFormError } from '@/utils';
import { login, checkImgCode } from '@/services';
import { PicAuthCodeModal } from '@/components/Modal';
import Storage from '@/utils/storage';
const Index: React.FC = () => {
const { t } = useTranslation('translation', { keyPrefix: 'login' });
@ -102,15 +99,6 @@ const Index: React.FC = () => {
return bol;
};
const handleLoginRedirect = () => {
const redirect = Storage.get(REDIRECT_PATH_STORAGE_KEY) || RouteAlias.home;
Storage.remove(REDIRECT_PATH_STORAGE_KEY);
floppyNavigation.navigate(redirect, {
handler: navigate,
options: { replace: true },
});
};
const handleLogin = (event?: any) => {
if (event) {
event.preventDefault();
@ -133,7 +121,7 @@ const Index: React.FC = () => {
setStep(2);
setRefresh((pre) => pre + 1);
} else {
handleLoginRedirect();
guard.handleLoginRedirect(navigate);
}
setModalState(false);
@ -184,19 +172,8 @@ const Index: React.FC = () => {
<Container style={{ paddingTop: '4rem', paddingBottom: '5rem' }}>
<WelcomeTitle />
{ucLoginRedirect && step === 1 && (
<Col className="mx-auto" md={3}>
<Button
className="w-100"
variant="outline-secondary"
href={ucAgent?.agent_info.login_redirect_url}>
<SvgIcon base64={ucAgent?.agent_info.icon} />
<span>
{t('connect', {
auth_name: ucAgent?.agent_info.name,
keyPrefix: 'plugins.oauth',
})}
</span>
</Button>
<Col className="mx-auto" md={4}>
<PluginUcLogin />
</Col>
)}
{step === 1 && !ucLoginRedirect && (

View File

@ -2,40 +2,16 @@ import { FC, memo, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { useSearchParams, useNavigate } from 'react-router-dom';
import { usePageTags, useLoginRedirect } from '@/hooks';
import { loggedUserInfoStore } from '@/stores';
import { getLoggedUserInfo } from '@/services';
import Storage from '@/utils/storage';
import { LOGGED_TOKEN_STORAGE_KEY } from '@/common/constants';
import { usePageTags } from '@/hooks';
import { guard } from '@/utils';
const Index: FC = () => {
const { t } = useTranslation('translation', { keyPrefix: 'page_title' });
const [searchParams] = useSearchParams();
const { loginRedirect } = useLoginRedirect();
const updateUser = loggedUserInfoStore((state) => state.update);
const navigate = useNavigate();
useEffect(() => {
const token = searchParams.get('access_token');
if (token) {
Storage.set(LOGGED_TOKEN_STORAGE_KEY, token);
getLoggedUserInfo().then((res) => {
updateUser(res);
const userStat = guard.deriveLoginState();
if (userStat.isNotActivated) {
// inactive
navigate('/users/login?status=inactive', { replace: true });
} else {
setTimeout(() => {
loginRedirect();
}, 0);
}
});
} else {
navigate('/', { replace: true });
}
guard.handleLoginWithToken(token, navigate);
}, []);
usePageTags({
title: t('oauth_callback'),

View File

@ -0,0 +1,81 @@
import React, { memo, FC, useState, useEffect } from 'react';
import { Card } from 'react-bootstrap';
import { useTranslation } from 'react-i18next';
import QrCode from 'qrcode';
import { userCenterStore } from '@/stores';
import { guard } from '@/utils';
import { getLoginConf, checkLoginResult } from './wecom.service';
let checkTimer: NodeJS.Timeout;
const Index: FC = () => {
const { t } = useTranslation('translation', { keyPrefix: 'plugins' });
const ucAgent = userCenterStore().agent;
const agentName = ucAgent?.agent_info?.name || '';
const [qrcodeDataUrl, setQrCodeDataUrl] = useState('');
const handleLoginResult = (key: string) => {
if (!key) {
return;
}
checkLoginResult(key).then((res) => {
if (res.is_login) {
guard.handleLoginWithToken(res.token);
return;
}
clearTimeout(checkTimer);
checkTimer = setTimeout(() => {
handleLoginResult(key);
}, 2000);
});
};
const handleQrCode = (targetUrl: string) => {
if (!targetUrl) {
return;
}
QrCode.toDataURL(targetUrl, { width: 240 }, (err, url) => {
if (err) {
return;
}
setQrCodeDataUrl(url);
});
};
useEffect(() => {
if (!agentName) {
return;
}
getLoginConf().then((res) => {
handleQrCode(res?.redirect_url);
handleLoginResult(res?.key);
});
}, [agentName]);
useEffect(() => {
return () => {
clearTimeout(checkTimer);
};
}, []);
if (/WeCom/i.test(agentName)) {
return (
<Card className="text-center">
<Card.Body>
<Card.Title as="h3">
{agentName} {t('login')}
</Card.Title>
{qrcodeDataUrl ? (
<>
<img width={240} height={240} src={qrcodeDataUrl} alt="" />
<div className="text-secondary">
{t('qrcode_login_tip', { agentName })}
</div>
</>
) : null}
</Card.Body>
</Card>
);
}
return null;
};
export default memo(Index);

View File

@ -0,0 +1,33 @@
import React, { memo, FC } from 'react';
import { Button } from 'react-bootstrap';
import { useTranslation } from 'react-i18next';
import { SvgIcon } from '@/components';
import { userCenterStore } from '@/stores';
import WeComLogin from './WeCom';
const Index: FC = () => {
const { t } = useTranslation('translation', { keyPrefix: 'plugins.oauth' });
const ucAgent = userCenterStore().agent;
const agentName = ucAgent?.agent_info?.name || '';
const ucLoginRedirect =
ucAgent?.enabled && ucAgent?.agent_info?.login_redirect_url;
if (/WeCom/i.test(agentName)) {
return <WeComLogin />;
}
if (ucLoginRedirect) {
return (
<Button
className="w-100"
variant="outline-secondary"
href={ucAgent?.agent_info.login_redirect_url}>
<SvgIcon base64={ucAgent?.agent_info.icon} />
<span>{t('connect', { auth_name: ucAgent?.agent_info.name })}</span>
</Button>
);
}
return null;
};
export default memo(Index);

View File

@ -0,0 +1,21 @@
import request from '@/utils/request';
type loginConf = {
key: string;
redirect_url: string;
};
type loginResult = {
is_login: boolean;
token: string;
};
export const getLoginConf = () => {
const apiUrl = `/answer/api/v1/wecom/login/url`;
return request.get<loginConf>(apiUrl);
};
export const checkLoginResult = (key: loginConf['key']) => {
const apiUrl = `/answer/api/v1/wecom/login/check?key=${key}`;
return request.get<loginResult>(apiUrl);
};

View File

@ -1,3 +1,4 @@
import PluginOauth from './PluginOauth';
import PluginUcLogin from './PluginUcLogin';
export { PluginOauth };
export { PluginOauth, PluginUcLogin };

View File

@ -47,15 +47,12 @@ const isRoutableLink = (url = '') => {
* only navigate if not same as current url
*/
type NavigateHandler = 'href' | 'replace' | NavigateFunction;
interface NavigateConfig {
handler: NavigateHandler;
export interface NavigateConfig {
handler?: NavigateHandler;
options?: any;
}
const navigate = (
to: string | number,
config: NavigateConfig = { handler: 'href' },
) => {
let { handler } = config;
const navigate = (to: string | number, config: NavigateConfig = {}) => {
let { handler = 'href' } = config;
if (to && typeof to === 'string') {
if (!differentCurrent(to)) {
return;
@ -130,7 +127,6 @@ const handleRouteLinkClick = (evt) => {
};
export const floppyNavigation = {
differentCurrent,
navigate,
navigateToLogin,
shouldProcessLinkClick,

View File

@ -11,9 +11,14 @@ import {
loginToContinueStore,
} from '@/stores';
import { RouteAlias } from '@/router/alias';
import {
LOGGED_TOKEN_STORAGE_KEY,
REDIRECT_PATH_STORAGE_KEY,
} from '@/common/constants';
import Storage from '@/utils/storage';
import { setupAppLanguage, setupAppTimeZone } from './localize';
import { floppyNavigation } from './floppyNavigation';
import { floppyNavigation, NavigateConfig } from './floppyNavigation';
import { pullUcAgent, getLoginUrl, getSignUpUrl } from './userCenter';
type TLoginState = {
@ -310,6 +315,51 @@ export const tryLoggedAndActivated = () => {
return gr;
};
/**
* Auto handling of page redirect logic after a successful login
*/
export const handleLoginRedirect = (handler?: NavigateConfig['handler']) => {
const redirectUrl = Storage.get(REDIRECT_PATH_STORAGE_KEY) || RouteAlias.home;
Storage.remove(REDIRECT_PATH_STORAGE_KEY);
floppyNavigation.navigate(redirectUrl, {
handler,
options: { replace: true },
});
};
/**
* Unified processing of login logic after getting `access_token`
*/
export const handleLoginWithToken = (
token: string | null,
handler?: NavigateConfig['handler'],
) => {
if (token) {
Storage.set(LOGGED_TOKEN_STORAGE_KEY, token);
getLoggedUserInfo().then((res) => {
loggedUserInfoStore.getState().update(res);
const userStat = deriveLoginState();
if (userStat.isNotActivated) {
floppyNavigation.navigate(RouteAlias.activation, {
handler,
options: {
replace: true,
},
});
} else {
handleLoginRedirect(handler);
}
});
} else {
floppyNavigation.navigate(RouteAlias.home, {
handler,
options: {
replace: true,
},
});
}
};
/**
* Initialize app configuration
*/
@ -339,7 +389,6 @@ export const setupApp = async () => {
* 1. must pre init logged user info for router guard
* 2. must pre init app settings for app render
*/
// TODO: optimize `initAppSettingsStore` by server render
await Promise.allSettled([
pullLoggedUser(),
pullUcAgent(),