@ruzhiai/runid-react 0.1.0 → 0.1.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.
- package/dist/index.d.ts +2 -1
- package/dist/index.js +412 -60
- package/package.json +2 -2
- package/src/index.tsx +696 -138
package/dist/index.js
CHANGED
|
@@ -1,11 +1,36 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { createContext, useContext, useState, useCallback, useEffect, } from 'react';
|
|
3
|
-
import {
|
|
4
|
-
import { PhoneOutlined, MailOutlined, MessageOutlined, SafetyOutlined, WechatOutlined, UserOutlined,
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext, useState, useCallback, useEffect, useMemo, } from 'react';
|
|
3
|
+
import { Button, Flex, Input, Select, Space, Checkbox, Modal, Typography, Spin, message, Tooltip, } from 'antd';
|
|
4
|
+
import { ArrowRightOutlined, PhoneOutlined, MailOutlined, MessageOutlined, SafetyOutlined, WechatOutlined, UserOutlined, } from '@ant-design/icons';
|
|
5
5
|
import { RunIDAuth, isConsentRequiredResponse, parseAuthErrorMessage, } from '@ruzhiai/runid-sdk';
|
|
6
6
|
export { RunIDAuth };
|
|
7
7
|
export * from '@ruzhiai/runid-sdk';
|
|
8
8
|
const { Text, Title, Paragraph } = Typography;
|
|
9
|
+
function getBrowserUserAgent() {
|
|
10
|
+
if (typeof navigator === 'undefined')
|
|
11
|
+
return '';
|
|
12
|
+
return navigator.userAgent || '';
|
|
13
|
+
}
|
|
14
|
+
function isWecomEmbeddedBrowser() {
|
|
15
|
+
return /wxwork/i.test(getBrowserUserAgent());
|
|
16
|
+
}
|
|
17
|
+
function isMobileBrowser() {
|
|
18
|
+
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile/i.test(getBrowserUserAgent());
|
|
19
|
+
}
|
|
20
|
+
function pickWecomAutoRedirectURL(urls) {
|
|
21
|
+
if (!isWecomEmbeddedBrowser())
|
|
22
|
+
return undefined;
|
|
23
|
+
return urls.mobile_auth_url ?? urls.app_auth_url ?? urls.auth_url;
|
|
24
|
+
}
|
|
25
|
+
function pickWecomBrowserURL(urls) {
|
|
26
|
+
if (isWecomEmbeddedBrowser()) {
|
|
27
|
+
return urls.mobile_auth_url ?? urls.app_auth_url ?? urls.auth_url;
|
|
28
|
+
}
|
|
29
|
+
if (isMobileBrowser()) {
|
|
30
|
+
return urls.app_auth_url ?? urls.mobile_auth_url ?? urls.auth_url;
|
|
31
|
+
}
|
|
32
|
+
return urls.auth_url;
|
|
33
|
+
}
|
|
9
34
|
const RunIDAuthContext = createContext(null);
|
|
10
35
|
export function RunIDAuthProvider({ config, children, autoLoadMe = true, }) {
|
|
11
36
|
const [auth] = useState(() => new RunIDAuth(config));
|
|
@@ -109,6 +134,53 @@ export function useRunIDAuth() {
|
|
|
109
134
|
}
|
|
110
135
|
return context;
|
|
111
136
|
}
|
|
137
|
+
const THEME = {
|
|
138
|
+
light: {
|
|
139
|
+
surface: '#f5f7fa',
|
|
140
|
+
surfaceBorder: 'transparent',
|
|
141
|
+
text: '#0f1629',
|
|
142
|
+
textSecondary: '#6b7aa0',
|
|
143
|
+
inputIcon: '#94a0bf',
|
|
144
|
+
noticeBg: '#fff8e1',
|
|
145
|
+
noticeBorder: '#ffe082',
|
|
146
|
+
noticeText: '#8d6e00',
|
|
147
|
+
qrBg: '#fff',
|
|
148
|
+
activeTabColor: '#fff',
|
|
149
|
+
inactiveTabColor: '#6b7aa0',
|
|
150
|
+
activeTabShadow: '0 2px 8px rgba(15,22,41,0.08)',
|
|
151
|
+
buttonShadow: '0 8px 20px rgba(99, 102, 241, 0.2)',
|
|
152
|
+
socialBtnColor: '#6b7aa0',
|
|
153
|
+
},
|
|
154
|
+
dark: {
|
|
155
|
+
surface: 'rgba(255,255,255,0.06)',
|
|
156
|
+
surfaceBorder: 'rgba(255,255,255,0.08)',
|
|
157
|
+
text: '#f4f4f5',
|
|
158
|
+
textSecondary: '#a1a1aa',
|
|
159
|
+
inputIcon: '#71717a',
|
|
160
|
+
noticeBg: 'rgba(234,179,8,0.1)',
|
|
161
|
+
noticeBorder: 'rgba(234,179,8,0.25)',
|
|
162
|
+
noticeText: '#fbbf24',
|
|
163
|
+
qrBg: '#18181b',
|
|
164
|
+
activeTabColor: '#fff',
|
|
165
|
+
inactiveTabColor: '#a1a1aa',
|
|
166
|
+
activeTabShadow: '0 2px 8px rgba(0,0,0,0.3)',
|
|
167
|
+
buttonShadow: 'none',
|
|
168
|
+
socialBtnColor: '#a1a1aa',
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
function resolveTheme(explicit) {
|
|
172
|
+
if (explicit)
|
|
173
|
+
return explicit;
|
|
174
|
+
if (typeof document !== 'undefined') {
|
|
175
|
+
const htmlTheme = document.documentElement.getAttribute('data-rd-theme')
|
|
176
|
+
|| document.documentElement.getAttribute('data-theme');
|
|
177
|
+
if (htmlTheme === 'dark')
|
|
178
|
+
return 'dark';
|
|
179
|
+
if (window.matchMedia?.('(prefers-color-scheme: dark)').matches)
|
|
180
|
+
return 'dark';
|
|
181
|
+
}
|
|
182
|
+
return 'light';
|
|
183
|
+
}
|
|
112
184
|
const TEXT = {
|
|
113
185
|
'zh-CN': {
|
|
114
186
|
wechat: '微信登录',
|
|
@@ -134,7 +206,14 @@ const TEXT = {
|
|
|
134
206
|
emailPlaceholder: '请输入邮箱',
|
|
135
207
|
whatsappPlaceholder: '请输入 WhatsApp 号码',
|
|
136
208
|
codePlaceholder: '请输入验证码',
|
|
209
|
+
invalidPhone: '请输入正确的手机号',
|
|
210
|
+
invalidEmail: '请输入正确的邮箱地址',
|
|
211
|
+
invalidWhatsapp: '请输入正确的 WhatsApp 号码',
|
|
212
|
+
requiredCode: '请输入验证码',
|
|
213
|
+
sendCodeFailed: '发送验证码失败',
|
|
214
|
+
loginFailed: '登录失败',
|
|
137
215
|
mfaHint: '该账号已开启二次验证,请完成下一步认证。',
|
|
216
|
+
methodNotConfigured: '该登录方式未配置,暂不可用',
|
|
138
217
|
},
|
|
139
218
|
'en-US': {
|
|
140
219
|
wechat: 'WeChat',
|
|
@@ -160,7 +239,14 @@ const TEXT = {
|
|
|
160
239
|
emailPlaceholder: 'Enter email',
|
|
161
240
|
whatsappPlaceholder: 'Enter WhatsApp number',
|
|
162
241
|
codePlaceholder: 'Enter verification code',
|
|
242
|
+
invalidPhone: 'Enter a valid phone number',
|
|
243
|
+
invalidEmail: 'Enter a valid email address',
|
|
244
|
+
invalidWhatsapp: 'Enter a valid WhatsApp number',
|
|
245
|
+
requiredCode: 'Enter verification code',
|
|
246
|
+
sendCodeFailed: 'Failed to send code',
|
|
247
|
+
loginFailed: 'Sign-in failed',
|
|
163
248
|
mfaHint: 'MFA is required before login. Please complete second-factor verification.',
|
|
249
|
+
methodNotConfigured: 'This login method is not configured',
|
|
164
250
|
},
|
|
165
251
|
};
|
|
166
252
|
function isAllowedMethod(config, method) {
|
|
@@ -170,54 +256,73 @@ function resolveInitialMethod(config, requested) {
|
|
|
170
256
|
if (requested && isAllowedMethod(config, requested)) {
|
|
171
257
|
return requested;
|
|
172
258
|
}
|
|
259
|
+
if (config.client.allowed_methods.includes('wecom'))
|
|
260
|
+
return 'wecom';
|
|
173
261
|
if (config.client.allowed_methods.includes('phone'))
|
|
174
262
|
return 'phone';
|
|
175
263
|
if (config.client.allowed_methods.includes('email'))
|
|
176
264
|
return 'email';
|
|
177
|
-
if (config.client.allowed_methods.includes('
|
|
178
|
-
return '
|
|
179
|
-
|
|
180
|
-
return 'wechat';
|
|
181
|
-
return 'whatsapp';
|
|
265
|
+
if (config.client.allowed_methods.includes('whatsapp'))
|
|
266
|
+
return 'whatsapp';
|
|
267
|
+
return 'wechat';
|
|
182
268
|
}
|
|
183
269
|
function isMfaResponse(response) {
|
|
184
270
|
return !!(response &&
|
|
185
271
|
typeof response === 'object' &&
|
|
186
272
|
response.mfa_required === true);
|
|
187
273
|
}
|
|
274
|
+
function phoneDigits(value) {
|
|
275
|
+
return value.replace(/\D/g, '');
|
|
276
|
+
}
|
|
277
|
+
function normalizeCountryPhone(countryCode, value) {
|
|
278
|
+
return `${countryCode}${phoneDigits(value)}`;
|
|
279
|
+
}
|
|
280
|
+
function normalizeInternationalPhone(value) {
|
|
281
|
+
const trimmed = value.trim();
|
|
282
|
+
const digits = phoneDigits(trimmed);
|
|
283
|
+
return trimmed.startsWith('+') ? `+${digits}` : digits;
|
|
284
|
+
}
|
|
285
|
+
function isValidCountryPhone(countryCode, value) {
|
|
286
|
+
const digits = phoneDigits(value);
|
|
287
|
+
if (!digits)
|
|
288
|
+
return false;
|
|
289
|
+
if (countryCode === '+86')
|
|
290
|
+
return /^1\d{10}$/.test(digits);
|
|
291
|
+
if (countryCode === '+1')
|
|
292
|
+
return digits.length === 10;
|
|
293
|
+
if (countryCode === '+44')
|
|
294
|
+
return digits.length >= 10 && digits.length <= 11;
|
|
295
|
+
if (countryCode === '+81')
|
|
296
|
+
return digits.length >= 10 && digits.length <= 11;
|
|
297
|
+
if (countryCode === '+65')
|
|
298
|
+
return digits.length === 8;
|
|
299
|
+
return digits.length >= 6 && digits.length <= 20;
|
|
300
|
+
}
|
|
301
|
+
function isValidInternationalPhone(value) {
|
|
302
|
+
const digits = phoneDigits(value);
|
|
303
|
+
return digits.length >= 6 && digits.length <= 20;
|
|
304
|
+
}
|
|
305
|
+
function isValidEmail(value) {
|
|
306
|
+
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value.trim());
|
|
307
|
+
}
|
|
188
308
|
const initialCountdown = {
|
|
189
309
|
phone: 0,
|
|
190
310
|
email: 0,
|
|
191
311
|
whatsapp: 0,
|
|
192
312
|
};
|
|
193
|
-
export function RunIDLoginWidget({ config, returnUrl, defaultMethod, locale = 'zh-CN', onSuccess, onError, onOAuthRedirect, className, style, }) {
|
|
313
|
+
export function RunIDLoginWidget({ config, returnUrl, defaultMethod, locale = 'zh-CN', theme: themeProp, onSuccess, onError, onOAuthRedirect, className, style, }) {
|
|
194
314
|
const [messageApi, contextHolder] = message.useMessage();
|
|
195
|
-
const
|
|
315
|
+
const t = THEME[resolveTheme(themeProp)];
|
|
316
|
+
const auth = useMemo(() => new RunIDAuth({
|
|
196
317
|
...config,
|
|
197
318
|
defaultReturnURL: returnUrl,
|
|
198
319
|
onAuthSuccess: () => { },
|
|
199
320
|
onAuthError: (error) => {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
messageApi.error(msg);
|
|
321
|
+
if (error.status !== 401) {
|
|
322
|
+
onError?.(error);
|
|
203
323
|
}
|
|
204
|
-
onError?.(error);
|
|
205
324
|
},
|
|
206
|
-
}));
|
|
207
|
-
useEffect(() => {
|
|
208
|
-
setAuth(new RunIDAuth({
|
|
209
|
-
...config,
|
|
210
|
-
defaultReturnURL: returnUrl,
|
|
211
|
-
onAuthSuccess: () => { },
|
|
212
|
-
onAuthError: (error) => {
|
|
213
|
-
const msg = parseAuthErrorMessage(error.payload) || error.message;
|
|
214
|
-
if (msg) {
|
|
215
|
-
messageApi.error(msg);
|
|
216
|
-
}
|
|
217
|
-
onError?.(error);
|
|
218
|
-
},
|
|
219
|
-
}));
|
|
220
|
-
}, [config.baseURL, config.client_id, messageApi, onError, returnUrl]);
|
|
325
|
+
}), [config.issuer, config.apiBaseURL, config.baseURL, config.client_id, onError, returnUrl]);
|
|
221
326
|
const texts = TEXT[locale];
|
|
222
327
|
const [loginConfig, setLoginConfig] = useState(null);
|
|
223
328
|
const [loadingConfig, setLoadingConfig] = useState(true);
|
|
@@ -239,6 +344,10 @@ export function RunIDLoginWidget({ config, returnUrl, defaultMethod, locale = 'z
|
|
|
239
344
|
const [consentData, setConsentData] = useState(null);
|
|
240
345
|
const [agreed, setAgreed] = useState(false);
|
|
241
346
|
const [processingConsent, setProcessingConsent] = useState(false);
|
|
347
|
+
const [wecomURLs, setWecomURLs] = useState(null);
|
|
348
|
+
const [loadingWecomQR, setLoadingWecomQR] = useState(false);
|
|
349
|
+
const [showWecomQR, setShowWecomQR] = useState(false);
|
|
350
|
+
const [wecomAutoRedirecting, setWecomAutoRedirecting] = useState(false);
|
|
242
351
|
useEffect(() => {
|
|
243
352
|
let active = true;
|
|
244
353
|
const load = async () => {
|
|
@@ -271,12 +380,10 @@ export function RunIDLoginWidget({ config, returnUrl, defaultMethod, locale = 'z
|
|
|
271
380
|
active = false;
|
|
272
381
|
};
|
|
273
382
|
}, [auth, defaultMethod, onError, returnUrl, messageApi, texts.requiredMethodError]);
|
|
274
|
-
const
|
|
383
|
+
const primaryMethods = [
|
|
384
|
+
{ key: 'wecom', visible: isAllowedMethod(loginConfig, 'wecom'), icon: _jsx(UserOutlined, {}), label: texts.wecom },
|
|
275
385
|
{ key: 'phone', visible: isAllowedMethod(loginConfig, 'phone'), icon: _jsx(PhoneOutlined, {}), label: texts.phone },
|
|
276
386
|
{ key: 'email', visible: isAllowedMethod(loginConfig, 'email'), icon: _jsx(MailOutlined, {}), label: texts.email },
|
|
277
|
-
{ key: 'wechat', visible: isAllowedMethod(loginConfig, 'wechat'), icon: _jsx(WechatOutlined, {}), label: texts.wechat },
|
|
278
|
-
{ key: 'wecom', visible: isAllowedMethod(loginConfig, 'wecom'), icon: _jsx(UserOutlined, {}), label: texts.wecom },
|
|
279
|
-
{ key: 'whatsapp', visible: isAllowedMethod(loginConfig, 'whatsapp'), icon: _jsx(MessageOutlined, {}), label: texts.whatsapp },
|
|
280
387
|
].filter((item) => item.visible);
|
|
281
388
|
const setCountDown = useCallback((method, seconds) => {
|
|
282
389
|
setCountdown((prev) => ({ ...prev, [method]: seconds }));
|
|
@@ -303,18 +410,26 @@ export function RunIDLoginWidget({ config, returnUrl, defaultMethod, locale = 'z
|
|
|
303
410
|
const targetWhatsapp = whatsapp.trim();
|
|
304
411
|
setIsSending((prev) => ({ ...prev, [method]: true }));
|
|
305
412
|
if (method === 'phone') {
|
|
306
|
-
|
|
307
|
-
if (!target) {
|
|
413
|
+
if (!targetPhone) {
|
|
308
414
|
messageApi.error(texts.phonePlaceholder);
|
|
309
415
|
return;
|
|
310
416
|
}
|
|
417
|
+
if (!isValidCountryPhone(countryCode, targetPhone)) {
|
|
418
|
+
messageApi.error(texts.invalidPhone);
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
const target = normalizeCountryPhone(countryCode, targetPhone);
|
|
311
422
|
await auth.sendPhoneCode(target);
|
|
312
423
|
}
|
|
313
424
|
else if (method === 'email') {
|
|
314
|
-
if (!targetEmail
|
|
425
|
+
if (!targetEmail) {
|
|
315
426
|
messageApi.error(texts.emailPlaceholder);
|
|
316
427
|
return;
|
|
317
428
|
}
|
|
429
|
+
if (!isValidEmail(targetEmail)) {
|
|
430
|
+
messageApi.error(texts.invalidEmail);
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
318
433
|
await auth.sendEmailCode(targetEmail);
|
|
319
434
|
}
|
|
320
435
|
else {
|
|
@@ -322,14 +437,18 @@ export function RunIDLoginWidget({ config, returnUrl, defaultMethod, locale = 'z
|
|
|
322
437
|
messageApi.error(texts.whatsappPlaceholder);
|
|
323
438
|
return;
|
|
324
439
|
}
|
|
325
|
-
|
|
440
|
+
if (!isValidInternationalPhone(targetWhatsapp)) {
|
|
441
|
+
messageApi.error(texts.invalidWhatsapp);
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
await auth.sendWhatsAppCode(normalizeInternationalPhone(targetWhatsapp));
|
|
326
445
|
}
|
|
327
446
|
messageApi.success(texts.sendCode);
|
|
328
447
|
startTimer(method);
|
|
329
448
|
}
|
|
330
449
|
catch (error) {
|
|
331
450
|
const runErr = error;
|
|
332
|
-
const msg = parseAuthErrorMessage(runErr.payload) || runErr.message ||
|
|
451
|
+
const msg = parseAuthErrorMessage(runErr.payload) || runErr.message || texts.sendCodeFailed;
|
|
333
452
|
messageApi.error(msg);
|
|
334
453
|
onError?.(runErr);
|
|
335
454
|
}
|
|
@@ -339,10 +458,22 @@ export function RunIDLoginWidget({ config, returnUrl, defaultMethod, locale = 'z
|
|
|
339
458
|
}, [auth, countryCode, countdown, email, messageApi, onError, phone, startTimer, texts, whatsapp]);
|
|
340
459
|
const openOAuth = useCallback(async (method) => {
|
|
341
460
|
try {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
461
|
+
if (method === 'wechat') {
|
|
462
|
+
const urls = await auth.getWechatAuthURL(returnUrl);
|
|
463
|
+
const target = urls.auth_url;
|
|
464
|
+
if (onOAuthRedirect) {
|
|
465
|
+
onOAuthRedirect(method, target);
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
window.location.assign(target);
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
const urls = await auth.getWecomAuthURL(returnUrl);
|
|
472
|
+
const target = pickWecomBrowserURL(urls);
|
|
473
|
+
if (!target) {
|
|
474
|
+
messageApi.error(locale === 'zh-CN' ? '企业微信登录地址不可用' : 'WeCom sign-in URL is unavailable');
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
346
477
|
if (onOAuthRedirect) {
|
|
347
478
|
onOAuthRedirect(method, target);
|
|
348
479
|
return;
|
|
@@ -355,7 +486,128 @@ export function RunIDLoginWidget({ config, returnUrl, defaultMethod, locale = 'z
|
|
|
355
486
|
messageApi.error(msg);
|
|
356
487
|
onError?.(runErr);
|
|
357
488
|
}
|
|
358
|
-
}, [auth, onError, onOAuthRedirect, returnUrl
|
|
489
|
+
}, [auth, locale, messageApi, onError, onOAuthRedirect, returnUrl]);
|
|
490
|
+
const openWecomLogin = useCallback(async () => {
|
|
491
|
+
try {
|
|
492
|
+
const urls = wecomURLs ?? await auth.getWecomAuthURL(returnUrl);
|
|
493
|
+
if (!wecomURLs) {
|
|
494
|
+
setWecomURLs(urls);
|
|
495
|
+
}
|
|
496
|
+
const target = pickWecomBrowserURL(urls);
|
|
497
|
+
if (!target) {
|
|
498
|
+
messageApi.error(locale === 'zh-CN' ? '企业微信登录地址不可用' : 'WeCom sign-in URL is unavailable');
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
if (onOAuthRedirect) {
|
|
502
|
+
onOAuthRedirect('wecom', target);
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
window.location.assign(target);
|
|
506
|
+
}
|
|
507
|
+
catch (error) {
|
|
508
|
+
const runErr = error;
|
|
509
|
+
const msg = parseAuthErrorMessage(runErr.payload) || runErr.message || '获取企业微信登录地址失败';
|
|
510
|
+
messageApi.error(msg);
|
|
511
|
+
onError?.(runErr);
|
|
512
|
+
}
|
|
513
|
+
}, [auth, locale, messageApi, onError, onOAuthRedirect, returnUrl, wecomURLs]);
|
|
514
|
+
const loadWecomQR = useCallback(async () => {
|
|
515
|
+
try {
|
|
516
|
+
setLoadingWecomQR(true);
|
|
517
|
+
const urls = await auth.getWecomAuthURL(returnUrl);
|
|
518
|
+
setWecomURLs(urls);
|
|
519
|
+
}
|
|
520
|
+
catch (error) {
|
|
521
|
+
const runErr = error;
|
|
522
|
+
const msg = parseAuthErrorMessage(runErr.payload) || runErr.message || '获取企业微信二维码失败';
|
|
523
|
+
messageApi.error(msg);
|
|
524
|
+
onError?.(runErr);
|
|
525
|
+
}
|
|
526
|
+
finally {
|
|
527
|
+
setLoadingWecomQR(false);
|
|
528
|
+
}
|
|
529
|
+
}, [auth, messageApi, onError, returnUrl]);
|
|
530
|
+
useEffect(() => {
|
|
531
|
+
if (!loginConfig || activeMethod !== 'wecom' || !isAllowedMethod(loginConfig, 'wecom')) {
|
|
532
|
+
setWecomAutoRedirecting(false);
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
if (!isWecomEmbeddedBrowser()) {
|
|
536
|
+
setWecomAutoRedirecting(false);
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
let cancelled = false;
|
|
540
|
+
setWecomAutoRedirecting(true);
|
|
541
|
+
void (async () => {
|
|
542
|
+
try {
|
|
543
|
+
const urls = await auth.getWecomAuthURL(returnUrl);
|
|
544
|
+
if (cancelled)
|
|
545
|
+
return;
|
|
546
|
+
setWecomURLs(urls);
|
|
547
|
+
const redirect = pickWecomAutoRedirectURL(urls);
|
|
548
|
+
if (redirect) {
|
|
549
|
+
window.location.assign(redirect);
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
setWecomAutoRedirecting(false);
|
|
553
|
+
}
|
|
554
|
+
catch (error) {
|
|
555
|
+
if (cancelled)
|
|
556
|
+
return;
|
|
557
|
+
const runErr = error;
|
|
558
|
+
const msg = parseAuthErrorMessage(runErr.payload) || runErr.message || '获取企业微信登录地址失败';
|
|
559
|
+
messageApi.error(msg);
|
|
560
|
+
onError?.(runErr);
|
|
561
|
+
setWecomAutoRedirecting(false);
|
|
562
|
+
}
|
|
563
|
+
})();
|
|
564
|
+
return () => {
|
|
565
|
+
cancelled = true;
|
|
566
|
+
};
|
|
567
|
+
}, [activeMethod, auth, loginConfig, messageApi, onError, returnUrl]);
|
|
568
|
+
useEffect(() => {
|
|
569
|
+
if (activeMethod !== 'wecom') {
|
|
570
|
+
setShowWecomQR(false);
|
|
571
|
+
}
|
|
572
|
+
}, [activeMethod]);
|
|
573
|
+
useEffect(() => {
|
|
574
|
+
if (activeMethod !== 'wecom' || isWecomEmbeddedBrowser() || isMobileBrowser()) {
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
if (showWecomQR) {
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
setShowWecomQR(true);
|
|
581
|
+
if (!wecomURLs && !loadingWecomQR) {
|
|
582
|
+
void loadWecomQR();
|
|
583
|
+
}
|
|
584
|
+
}, [activeMethod, loadWecomQR, loadingWecomQR, showWecomQR, wecomURLs]);
|
|
585
|
+
useEffect(() => {
|
|
586
|
+
if (activeMethod !== 'wecom' || !wecomURLs) {
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
let cancelled = false;
|
|
590
|
+
const interval = window.setInterval(async () => {
|
|
591
|
+
try {
|
|
592
|
+
const status = await auth.getAuthStatus({ client_id: config.client_id });
|
|
593
|
+
if (cancelled)
|
|
594
|
+
return;
|
|
595
|
+
if (status.authenticated && status.account_id) {
|
|
596
|
+
window.clearInterval(interval);
|
|
597
|
+
if (!cancelled) {
|
|
598
|
+
await onSuccess(status);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
catch {
|
|
603
|
+
// Waiting for the OAuth callback to create the hosted RunID session.
|
|
604
|
+
}
|
|
605
|
+
}, 2000);
|
|
606
|
+
return () => {
|
|
607
|
+
cancelled = true;
|
|
608
|
+
window.clearInterval(interval);
|
|
609
|
+
};
|
|
610
|
+
}, [activeMethod, auth, config.client_id, onSuccess, wecomURLs]);
|
|
359
611
|
const handleVerify = useCallback(async () => {
|
|
360
612
|
if (!loginConfig) {
|
|
361
613
|
messageApi.error(texts.requiredMethodError);
|
|
@@ -365,25 +617,55 @@ export function RunIDLoginWidget({ config, returnUrl, defaultMethod, locale = 'z
|
|
|
365
617
|
try {
|
|
366
618
|
let response;
|
|
367
619
|
if (activeMethod === 'phone') {
|
|
368
|
-
|
|
620
|
+
const targetPhone = phone.trim();
|
|
621
|
+
const targetCode = phoneCode.trim();
|
|
622
|
+
if (!targetPhone) {
|
|
369
623
|
messageApi.error(texts.phonePlaceholder);
|
|
370
624
|
return;
|
|
371
625
|
}
|
|
372
|
-
|
|
626
|
+
if (!isValidCountryPhone(countryCode, targetPhone)) {
|
|
627
|
+
messageApi.error(texts.invalidPhone);
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
if (!targetCode) {
|
|
631
|
+
messageApi.error(texts.requiredCode);
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
response = await auth.verifyPhone(normalizeCountryPhone(countryCode, targetPhone), targetCode);
|
|
373
635
|
}
|
|
374
636
|
else if (activeMethod === 'email') {
|
|
375
|
-
|
|
637
|
+
const targetEmail = email.trim();
|
|
638
|
+
const targetCode = emailCode.trim();
|
|
639
|
+
if (!targetEmail) {
|
|
376
640
|
messageApi.error(texts.emailPlaceholder);
|
|
377
641
|
return;
|
|
378
642
|
}
|
|
379
|
-
|
|
643
|
+
if (!isValidEmail(targetEmail)) {
|
|
644
|
+
messageApi.error(texts.invalidEmail);
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
647
|
+
if (!targetCode) {
|
|
648
|
+
messageApi.error(texts.requiredCode);
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
response = await auth.verifyEmail(targetEmail, targetCode);
|
|
380
652
|
}
|
|
381
653
|
else if (activeMethod === 'whatsapp') {
|
|
382
|
-
|
|
654
|
+
const targetWhatsapp = whatsapp.trim();
|
|
655
|
+
const targetCode = whatsappCode.trim();
|
|
656
|
+
if (!targetWhatsapp) {
|
|
383
657
|
messageApi.error(texts.whatsappPlaceholder);
|
|
384
658
|
return;
|
|
385
659
|
}
|
|
386
|
-
|
|
660
|
+
if (!isValidInternationalPhone(targetWhatsapp)) {
|
|
661
|
+
messageApi.error(texts.invalidWhatsapp);
|
|
662
|
+
return;
|
|
663
|
+
}
|
|
664
|
+
if (!targetCode) {
|
|
665
|
+
messageApi.error(texts.requiredCode);
|
|
666
|
+
return;
|
|
667
|
+
}
|
|
668
|
+
response = await auth.verifyWhatsApp(normalizeInternationalPhone(targetWhatsapp), targetCode);
|
|
387
669
|
}
|
|
388
670
|
else {
|
|
389
671
|
messageApi.error(texts.requiredMethodError);
|
|
@@ -402,14 +684,14 @@ export function RunIDLoginWidget({ config, returnUrl, defaultMethod, locale = 'z
|
|
|
402
684
|
}
|
|
403
685
|
catch (error) {
|
|
404
686
|
const runErr = error;
|
|
405
|
-
const msg = parseAuthErrorMessage(runErr.payload) || runErr.message ||
|
|
687
|
+
const msg = parseAuthErrorMessage(runErr.payload) || runErr.message || texts.loginFailed;
|
|
406
688
|
messageApi.error(msg);
|
|
407
689
|
onError?.(runErr);
|
|
408
690
|
}
|
|
409
691
|
finally {
|
|
410
692
|
setIsSubmitting(false);
|
|
411
693
|
}
|
|
412
|
-
}, [activeMethod, auth, countryCode, email, emailCode, loginConfig, messageApi, onError, onSuccess, phone, phoneCode, texts.emailPlaceholder, texts.phonePlaceholder, texts.requiredMethodError, texts.whatsappPlaceholder, texts.mfaHint, whatsapp, whatsappCode]);
|
|
694
|
+
}, [activeMethod, auth, countryCode, email, emailCode, loginConfig, messageApi, onError, onSuccess, phone, phoneCode, texts.emailPlaceholder, texts.invalidEmail, texts.invalidPhone, texts.invalidWhatsapp, texts.loginFailed, texts.phonePlaceholder, texts.requiredCode, texts.requiredMethodError, texts.whatsappPlaceholder, texts.mfaHint, whatsapp, whatsappCode]);
|
|
413
695
|
const submitConsent = useCallback(async () => {
|
|
414
696
|
if (!consentData || !agreed) {
|
|
415
697
|
return;
|
|
@@ -419,7 +701,7 @@ export function RunIDLoginWidget({ config, returnUrl, defaultMethod, locale = 'z
|
|
|
419
701
|
const agreedIds = consentData.pending_agreements
|
|
420
702
|
.map((agreement) => agreement.id)
|
|
421
703
|
.filter(Boolean);
|
|
422
|
-
const response = await auth.consentAndLogin(consentData.account_id, agreedIds, consentData.login_method || activeMethod, consentData.client_id);
|
|
704
|
+
const response = await auth.consentAndLogin(consentData.account_id, agreedIds, consentData.login_method || activeMethod, consentData.client_id, consentData.consent_challenge);
|
|
423
705
|
setConsentData(null);
|
|
424
706
|
setAgreed(false);
|
|
425
707
|
await onSuccess(response);
|
|
@@ -440,13 +722,19 @@ export function RunIDLoginWidget({ config, returnUrl, defaultMethod, locale = 'z
|
|
|
440
722
|
if (!loginConfig) {
|
|
441
723
|
return (_jsxs("div", { className: className, style: style, children: [contextHolder, _jsx(Text, { children: texts.requiredMethodError })] }));
|
|
442
724
|
}
|
|
443
|
-
|
|
725
|
+
const isInternalProduct = loginConfig.is_internal_product || loginConfig.client.realm === 'internal';
|
|
726
|
+
const wechatConfigured = isAllowedMethod(loginConfig, 'wechat');
|
|
727
|
+
const whatsappConfigured = isAllowedMethod(loginConfig, 'whatsapp');
|
|
728
|
+
const hasConfiguredSocialMethods = wechatConfigured || whatsappConfigured;
|
|
729
|
+
const showSocialMethods = !isInternalProduct && hasConfiguredSocialMethods;
|
|
730
|
+
const countryCodeSelectOptions = [{ value: countryCode, label: countryCode }];
|
|
731
|
+
const wecomEmbeddedBrowser = isWecomEmbeddedBrowser();
|
|
732
|
+
const mobileBrowser = isMobileBrowser();
|
|
733
|
+
const showWecomContinueButton = wecomEmbeddedBrowser || mobileBrowser;
|
|
734
|
+
const showWecomQRCode = activeMethod === 'wecom' && (!showWecomContinueButton || showWecomQR);
|
|
735
|
+
if (!primaryMethods.length && !hasConfiguredSocialMethods) {
|
|
444
736
|
return (_jsxs("div", { className: className, style: style, children: [contextHolder, _jsx(Text, { children: texts.requiredMethodError })] }));
|
|
445
737
|
}
|
|
446
|
-
const tabItems = methods.map((method) => ({
|
|
447
|
-
key: method.key,
|
|
448
|
-
label: (_jsxs("span", { children: [method.icon, _jsx("span", { style: { marginLeft: 6 }, children: method.label })] })),
|
|
449
|
-
}));
|
|
450
738
|
const canSubmit = !isSubmitting &&
|
|
451
739
|
[
|
|
452
740
|
activeMethod === 'phone' ? phone.trim() && phoneCode.trim() :
|
|
@@ -458,10 +746,74 @@ export function RunIDLoginWidget({ config, returnUrl, defaultMethod, locale = 'z
|
|
|
458
746
|
const href = link.startsWith('http') || link.startsWith('/') ? link : `https://${link}`;
|
|
459
747
|
window.open(href, '_blank', 'noopener,noreferrer');
|
|
460
748
|
};
|
|
461
|
-
|
|
749
|
+
const rootClassName = ['runid-login-widget', className].filter(Boolean).join(' ');
|
|
750
|
+
const inputStyle = {
|
|
751
|
+
height: 52,
|
|
752
|
+
borderRadius: 8,
|
|
753
|
+
fontSize: 15,
|
|
754
|
+
};
|
|
755
|
+
const sendButtonStyle = {
|
|
756
|
+
minWidth: 120,
|
|
757
|
+
height: 52,
|
|
758
|
+
borderRadius: 8,
|
|
759
|
+
fontWeight: 500,
|
|
760
|
+
};
|
|
761
|
+
const primaryButtonStyle = {
|
|
762
|
+
height: 56,
|
|
763
|
+
borderRadius: 8,
|
|
764
|
+
fontSize: 16,
|
|
765
|
+
fontWeight: 600,
|
|
766
|
+
marginTop: 12,
|
|
767
|
+
boxShadow: t.buttonShadow,
|
|
768
|
+
};
|
|
769
|
+
const oauthButtonStyle = {
|
|
770
|
+
height: 56,
|
|
771
|
+
borderRadius: 8,
|
|
772
|
+
fontSize: 16,
|
|
773
|
+
fontWeight: 600,
|
|
774
|
+
width: '100%',
|
|
775
|
+
};
|
|
776
|
+
const methodButtonStyle = (method) => ({
|
|
777
|
+
flex: 1,
|
|
778
|
+
height: 40,
|
|
779
|
+
borderRadius: 6,
|
|
780
|
+
border: 'none',
|
|
781
|
+
boxShadow: activeMethod === method ? t.activeTabShadow : 'none',
|
|
782
|
+
background: activeMethod === method ? undefined : 'transparent',
|
|
783
|
+
color: activeMethod === method ? t.activeTabColor : t.inactiveTabColor,
|
|
784
|
+
fontWeight: activeMethod === method ? 600 : 400,
|
|
785
|
+
});
|
|
786
|
+
const socialButtonStyle = {
|
|
787
|
+
borderRadius: 8,
|
|
788
|
+
height: 44,
|
|
789
|
+
padding: '0 24px',
|
|
790
|
+
color: t.socialBtnColor,
|
|
791
|
+
};
|
|
792
|
+
const submitLabel = isSubmitting ? texts.verifying : texts.login;
|
|
793
|
+
return (_jsxs("div", { className: rootClassName, "data-active-method": activeMethod, style: style, children: [contextHolder, primaryMethods.length > 0 && (_jsx(Flex, { gap: 4, className: "login-method-tabs animate-fade-in-up delay-200", style: { width: '100%', marginBottom: 24, background: t.surface, border: `1px solid ${t.surfaceBorder}`, padding: 4, borderRadius: 8 }, children: primaryMethods.map((method) => (_jsx(Button, { type: activeMethod === method.key ? 'primary' : 'text', onClick: () => setActiveMethod(method.key), className: `login-method-tab login-method-tab-${method.key}`, style: methodButtonStyle(method.key), icon: method.icon, children: method.label }, method.key))) })), _jsxs("div", { className: "login-content-area animate-scale-in", style: { minHeight: 320 }, children: [activeMethod === 'phone' && (_jsxs(Flex, { vertical: true, gap: 24, style: { padding: '10px 0' }, children: [isInternalProduct && (_jsx("div", { style: { padding: '10px 14px', borderRadius: 6, background: t.noticeBg, border: `1px solid ${t.noticeBorder}`, fontSize: 12, color: t.noticeText, lineHeight: 1.6 }, children: locale === 'zh-CN'
|
|
794
|
+
? '仅限内部成员使用已登记的手机号登录,未登记的手机号无法登录。'
|
|
795
|
+
: 'Only registered internal phone numbers can sign in.' })), _jsxs(Flex, { vertical: true, gap: 16, children: [_jsxs(Flex, { gap: 12, children: [_jsx(Select, { value: countryCode, disabled: true, options: countryCodeSelectOptions, size: "large", style: { width: 100, height: 52, borderRadius: 8 } }), _jsx(Input, { size: "large", value: phone, onChange: (e) => setPhone(phoneDigits(e.target.value).slice(0, 20)), placeholder: texts.phonePlaceholder, style: { ...inputStyle, flex: 1 } })] }), _jsxs(Flex, { gap: 12, children: [_jsx(Input, { size: "large", value: phoneCode, onChange: (e) => setPhoneCode(e.target.value.replace(/\D/g, '').slice(0, 6)), placeholder: texts.codePlaceholder, style: { ...inputStyle, flex: 1 } }), _jsx(Button, { size: "large", onClick: () => sendCode('phone'), loading: isSending.phone, disabled: countdown.phone > 0, style: sendButtonStyle, children: countdown.phone > 0 ? `${countdown.phone}s` : texts.sendCode })] })] }), _jsxs(Button, { type: "primary", size: "large", block: true, loading: isSubmitting, disabled: !canSubmit, onClick: handleVerify, style: primaryButtonStyle, children: [_jsx("span", { children: submitLabel }), _jsx(ArrowRightOutlined, { style: { marginLeft: 8 } })] })] })), activeMethod === 'email' && (_jsxs(Flex, { vertical: true, gap: 24, style: { padding: '10px 0' }, children: [isInternalProduct && (_jsx("div", { style: { padding: '10px 14px', borderRadius: 6, background: t.noticeBg, border: `1px solid ${t.noticeBorder}`, fontSize: 12, color: t.noticeText, lineHeight: 1.6 }, children: locale === 'zh-CN'
|
|
796
|
+
? '仅限内部成员使用企业邮箱登录,非内部邮箱无法登录。'
|
|
797
|
+
: 'Only internal organization email accounts can sign in.' })), _jsxs(Flex, { vertical: true, gap: 16, children: [_jsx(Input, { size: "large", value: email, onChange: (e) => setEmail(e.target.value.slice(0, 120)), placeholder: texts.emailPlaceholder, prefix: _jsx(MailOutlined, { style: { color: t.inputIcon, marginRight: 8 } }), style: inputStyle }), _jsxs(Flex, { gap: 12, children: [_jsx(Input, { size: "large", value: emailCode, onChange: (e) => setEmailCode(e.target.value.replace(/\D/g, '').slice(0, 6)), placeholder: texts.codePlaceholder, style: { ...inputStyle, flex: 1 } }), _jsx(Button, { size: "large", onClick: () => sendCode('email'), loading: isSending.email, disabled: countdown.email > 0, style: sendButtonStyle, children: countdown.email > 0 ? `${countdown.email}s` : texts.sendCode })] })] }), _jsxs(Button, { type: "primary", size: "large", block: true, loading: isSubmitting, disabled: !canSubmit, onClick: handleVerify, style: primaryButtonStyle, children: [_jsx("span", { children: submitLabel }), _jsx(ArrowRightOutlined, { style: { marginLeft: 8 } })] })] })), activeMethod === 'whatsapp' && (_jsxs(Flex, { vertical: true, gap: 24, style: { padding: '10px 0' }, children: [_jsxs(Flex, { vertical: true, gap: 16, children: [_jsx(Input, { size: "large", value: whatsapp, onChange: (e) => setWhatsapp(phoneDigits(e.target.value).slice(0, 20)), placeholder: texts.whatsappPlaceholder, prefix: _jsx(MessageOutlined, { style: { color: t.inputIcon, marginRight: 8 } }), style: inputStyle }), _jsxs(Flex, { gap: 12, children: [_jsx(Input, { size: "large", value: whatsappCode, onChange: (e) => setWhatsappCode(e.target.value.replace(/\D/g, '').slice(0, 6)), placeholder: texts.codePlaceholder, style: { ...inputStyle, flex: 1 } }), _jsx(Button, { size: "large", onClick: () => sendCode('whatsapp'), loading: isSending.whatsapp, disabled: countdown.whatsapp > 0, style: sendButtonStyle, children: countdown.whatsapp > 0 ? `${countdown.whatsapp}s` : texts.sendCode })] })] }), _jsxs(Button, { type: "primary", size: "large", block: true, loading: isSubmitting, disabled: !canSubmit, onClick: handleVerify, style: primaryButtonStyle, children: [_jsx("span", { children: submitLabel }), _jsx(ArrowRightOutlined, { style: { marginLeft: 8 } })] })] })), activeMethod === 'wechat' && (_jsxs(Flex, { vertical: true, align: "center", justify: "center", gap: 20, style: { padding: '44px 0' }, children: [_jsx(Text, { style: { color: t.text, fontWeight: 500, textAlign: 'center' }, children: locale === 'zh-CN' ? '点击下方按钮完成微信授权' : 'Continue with WeChat authorization' }), _jsx(Button, { type: "primary", size: "large", onClick: () => openOAuth('wechat'), icon: _jsx(WechatOutlined, {}), style: { ...oauthButtonStyle, background: '#07c160', borderColor: '#07c160' }, children: texts.wechat })] })), activeMethod === 'wecom' && (_jsx(Flex, { className: "login-wecom-panel", vertical: true, align: "center", justify: "center", gap: 14, style: { padding: '28px 0 4px' }, children: wecomAutoRedirecting ? (_jsxs(Flex, { vertical: true, align: "center", justify: "center", gap: 14, style: { minHeight: 220 }, children: [_jsx(Spin, {}), _jsx(Text, { style: { color: t.textSecondary, fontSize: 13, textAlign: 'center' }, children: locale === 'zh-CN' ? '正在进入企业微信登录...' : 'Opening WeCom sign-in...' })] })) : (_jsxs(_Fragment, { children: [showWecomContinueButton && (_jsxs(_Fragment, { children: [_jsx(Button, { type: "primary", size: "large", block: true, onClick: openWecomLogin, icon: _jsx(UserOutlined, {}), style: { ...oauthButtonStyle, background: '#07c160', borderColor: '#07c160' }, children: locale === 'zh-CN' ? '继续企业微信登录' : 'Continue with WeCom' }), _jsx(Text, { style: { color: t.textSecondary, fontSize: 12, textAlign: 'center' }, children: locale === 'zh-CN' ? '将进入企业微信授权页;已登录客户端时可直接确认' : 'Continue on the WeCom authorization page.' })] })), !showWecomContinueButton && (_jsx(Text, { style: { color: t.textSecondary, fontSize: 13, textAlign: 'center' }, children: locale === 'zh-CN' ? '使用企业微信扫码完成登录' : 'Scan with WeCom to sign in' })), showWecomContinueButton && !showWecomQR && (_jsx(Button, { type: "link", onClick: () => {
|
|
798
|
+
setShowWecomQR(true);
|
|
799
|
+
void loadWecomQR();
|
|
800
|
+
}, children: locale === 'zh-CN' ? '无法打开时使用扫码登录' : 'Use QR code if the app does not open' })), showWecomQRCode && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "login-wecom-qr-frame", style: {
|
|
801
|
+
width: '100%',
|
|
802
|
+
maxWidth: 340,
|
|
803
|
+
height: 360,
|
|
804
|
+
overflow: 'hidden',
|
|
805
|
+
}, children: [(!showWecomQR || loadingWecomQR) && (_jsx(Flex, { align: "center", justify: "center", style: { height: 360 }, children: _jsx(Spin, {}) })), showWecomQR && !loadingWecomQR && wecomURLs?.auth_url && (_jsx("iframe", { className: "login-wecom-qr-iframe", title: locale === 'zh-CN' ? '企业微信扫码登录' : 'WeCom sign-in QR code', src: wecomURLs.auth_url, style: {
|
|
806
|
+
display: 'block',
|
|
807
|
+
width: 380,
|
|
808
|
+
height: 400,
|
|
809
|
+
border: 0,
|
|
810
|
+
background: t.qrBg,
|
|
811
|
+
transform: 'translateX(-20px) scale(0.9)',
|
|
812
|
+
transformOrigin: 'top center',
|
|
813
|
+
} })), showWecomQR && !loadingWecomQR && !wecomURLs?.auth_url && (_jsxs(Flex, { vertical: true, align: "center", justify: "center", gap: 12, style: { height: 360, padding: 24, textAlign: 'center' }, children: [_jsx(Text, { style: { color: t.textSecondary }, children: locale === 'zh-CN' ? '企业微信二维码加载失败' : 'Failed to load WeCom QR code' }), _jsx(Button, { onClick: loadWecomQR, children: locale === 'zh-CN' ? '重新加载' : 'Reload' })] }))] }), showWecomContinueButton && (_jsx(Text, { style: { color: t.textSecondary, fontSize: 13, textAlign: 'center' }, children: locale === 'zh-CN' ? '使用企业微信扫码完成登录' : 'Scan with WeCom to sign in' }))] }))] })) }))] }), showSocialMethods && (_jsxs(Flex, { justify: "center", gap: 16, style: { marginTop: 24 }, children: [wechatConfigured && (_jsx(Tooltip, { title: undefined, children: _jsx("span", { style: { display: 'inline-flex' }, children: _jsx(Button, { type: "text", size: "large", onClick: () => openOAuth('wechat'), className: "login-social-button login-social-button-wechat", icon: _jsx(WechatOutlined, { style: { fontSize: 18, color: '#94a0bf' } }), style: socialButtonStyle, children: texts.wechat }) }) })), whatsappConfigured && (_jsx(Tooltip, { title: undefined, children: _jsx("span", { style: { display: 'inline-flex' }, children: _jsx(Button, { type: activeMethod === 'whatsapp' ? 'primary' : 'text', size: "large", onClick: () => setActiveMethod('whatsapp'), className: "login-social-button login-social-button-whatsapp", icon: _jsx(MessageOutlined, { style: { fontSize: 18, color: activeMethod === 'whatsapp' ? '#fff' : '#94a0bf' } }), style: activeMethod === 'whatsapp' ? { ...socialButtonStyle, color: '#fff' } : socialButtonStyle, children: texts.whatsapp }) }) }))] })), _jsx(Modal, { open: Boolean(consentData), title: _jsx(Title, { level: 4, children: texts.consentTitle }), footer: null, onCancel: () => {
|
|
462
814
|
setConsentData(null);
|
|
463
815
|
setAgreed(false);
|
|
464
|
-
},
|
|
816
|
+
}, destroyOnHidden: true, children: consentData && (_jsxs(Space, { direction: "vertical", size: 12, style: { width: '100%' }, children: [_jsx(Paragraph, { children: consentData.is_new_user
|
|
465
817
|
? texts.consentHintNewUser
|
|
466
818
|
: texts.consentHintExistingUser }), _jsx(Space, { direction: "vertical", style: { width: '100%' }, children: consentData.pending_agreements.map((agreement) => (_jsx(Space, { align: "center", children: _jsx("a", { href: agreement.url, onClick: (event) => {
|
|
467
819
|
event.preventDefault();
|