@springmicro/auth 0.7.5 → 0.7.7
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/README.md +60 -60
- package/package.json +2 -2
- package/src/components/forms/AgreementModal.tsx +88 -88
- package/src/components/forms/CaptchaController.tsx +94 -94
- package/src/components/forms/CaptchaModal.jsx +171 -171
- package/src/components/forms/CaptchaWidget.jsx +146 -146
- package/src/components/forms/PasswordChecker.ts +88 -88
- package/src/components/forms/util/auth-api.ts +198 -198
- package/src/components/forms/util/auth-util.tsx +346 -346
- package/src/components/forms/util/core.ts +493 -493
- package/src/components/forms/util/invitation-api.ts +132 -132
- package/src/components/forms/util/provider.tsx +603 -603
- package/src/components/provider/AdfsLoginButton.jsx +38 -38
- package/src/components/provider/AlipayLoginButton.jsx +38 -38
- package/src/components/provider/AppleLoginButton.jsx +38 -38
- package/src/components/provider/AzureADB2CLoginButton.jsx +38 -38
- package/src/components/provider/AzureADLoginButton.jsx +38 -38
- package/src/components/provider/BaiduLoginButton.jsx +38 -38
- package/src/components/provider/BilibiliLoginButton.jsx +37 -37
- package/src/components/provider/CasdoorLoginButton.jsx +38 -38
- package/src/components/provider/DingTalkLoginButton.jsx +37 -37
- package/src/components/provider/DouyinLoginButton.jsx +38 -38
- package/src/components/provider/FacebookLoginButton.jsx +37 -37
- package/src/components/provider/GitHubLoginButton.jsx +37 -37
- package/src/components/provider/GitLabLoginButton.jsx +38 -38
- package/src/components/provider/GiteeLoginButton.jsx +34 -34
- package/src/components/provider/GoogleLoginButton.jsx +68 -68
- package/src/components/provider/InfoflowLoginButton.jsx +38 -38
- package/src/components/provider/LarkLoginButton.jsx +38 -38
- package/src/components/provider/LinkedInLoginButton.jsx +37 -37
- package/src/components/provider/LoginButton.jsx +33 -33
- package/src/components/provider/OktaLoginButton.jsx +38 -38
- package/src/components/provider/Provider.jsx +3 -3
- package/src/components/provider/ProviderButton.jsx +327 -327
- package/src/components/provider/QqLoginButton.jsx +31 -31
- package/src/components/provider/SelfLoginButton.jsx +47 -47
- package/src/components/provider/SlackLoginButton.jsx +38 -38
- package/src/components/provider/SteamLoginButton.jsx +38 -38
- package/src/components/provider/WeComLoginButton.jsx +34 -34
- package/src/components/provider/Web3Auth.jsx +365 -365
- package/src/components/provider/WechatLoginButton.jsx +37 -37
- package/src/components/provider/WeiboLoginButton.jsx +34 -34
- package/src/i18n/en/signup.json +48 -48
- package/src/i18n/index.ts +17 -17
- package/vite.config.ts +33 -33
package/README.md
CHANGED
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
# @springmicro/auth
|
|
2
|
-
|
|
3
|
-
Auth config supplied for connecting with a Casdoor instance. Uses [auth-astro](https://github.com/nowaythatworked/auth-astro).
|
|
4
|
-
|
|
5
|
-
## Usage
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm i -g @springmicro/cli
|
|
9
|
-
springmicro add auth
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
```ts
|
|
13
|
-
// auth.config.ts
|
|
14
|
-
|
|
15
|
-
import { getAuthConfig } from "@springmicro/auth";
|
|
16
|
-
|
|
17
|
-
export default getAuthConfig({
|
|
18
|
-
casdoorEndpoint: import.meta.env.PUBLIC_CASDOOR_ENDPOINT,
|
|
19
|
-
clientId: import.meta.env.PUBLIC_CASDOOR_CLIENT_ID,
|
|
20
|
-
clientSecret: import.meta.env.CASDOOR_CLIENT_SECRET,
|
|
21
|
-
});
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
`auth-astro` requires building your site in `server` mode with a platform adapter like `@astrojs/node`.
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
pnpm run astro add node
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
```js
|
|
31
|
-
// astro.config.mjs
|
|
32
|
-
export default defineConfig({
|
|
33
|
-
output: "server",
|
|
34
|
-
adapter: node({
|
|
35
|
-
mode: "standalone",
|
|
36
|
-
}),
|
|
37
|
-
});
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### Casdoor
|
|
41
|
-
|
|
42
|
-
In the `application` settings, add the callback URL of `http://yourhost/callback`. Enable auto signin (optional).
|
|
43
|
-
|
|
44
|
-
## Development
|
|
45
|
-
|
|
46
|
-
### Build
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
pnpm run build
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### Install in repo (locally)
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
# testing it out in a demo project
|
|
56
|
-
cd astro-demo-project
|
|
57
|
-
pnpm run astro add react
|
|
58
|
-
pnpm run astro add auth-astro
|
|
59
|
-
pnpm add --workspace @springmicro/auth
|
|
60
|
-
```
|
|
1
|
+
# @springmicro/auth
|
|
2
|
+
|
|
3
|
+
Auth config supplied for connecting with a Casdoor instance. Uses [auth-astro](https://github.com/nowaythatworked/auth-astro).
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm i -g @springmicro/cli
|
|
9
|
+
springmicro add auth
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
// auth.config.ts
|
|
14
|
+
|
|
15
|
+
import { getAuthConfig } from "@springmicro/auth";
|
|
16
|
+
|
|
17
|
+
export default getAuthConfig({
|
|
18
|
+
casdoorEndpoint: import.meta.env.PUBLIC_CASDOOR_ENDPOINT,
|
|
19
|
+
clientId: import.meta.env.PUBLIC_CASDOOR_CLIENT_ID,
|
|
20
|
+
clientSecret: import.meta.env.CASDOOR_CLIENT_SECRET,
|
|
21
|
+
});
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`auth-astro` requires building your site in `server` mode with a platform adapter like `@astrojs/node`.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pnpm run astro add node
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
// astro.config.mjs
|
|
32
|
+
export default defineConfig({
|
|
33
|
+
output: "server",
|
|
34
|
+
adapter: node({
|
|
35
|
+
mode: "standalone",
|
|
36
|
+
}),
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Casdoor
|
|
41
|
+
|
|
42
|
+
In the `application` settings, add the callback URL of `http://yourhost/callback`. Enable auto signin (optional).
|
|
43
|
+
|
|
44
|
+
## Development
|
|
45
|
+
|
|
46
|
+
### Build
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pnpm run build
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Install in repo (locally)
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# testing it out in a demo project
|
|
56
|
+
cd astro-demo-project
|
|
57
|
+
pnpm run astro add react
|
|
58
|
+
pnpm run astro add auth-astro
|
|
59
|
+
pnpm add --workspace @springmicro/auth
|
|
60
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@springmicro/auth",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -53,5 +53,5 @@
|
|
|
53
53
|
"react-social-login-buttons": "^4.1.0",
|
|
54
54
|
"uuid": "^9.0.1"
|
|
55
55
|
},
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "42d5a9c07e4d99417d811f3537fde9a85815588c"
|
|
57
57
|
}
|
|
@@ -1,88 +1,88 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import type { SignUpFormState } from "../SignUp";
|
|
3
|
-
import type { Application } from "./util/provider";
|
|
4
|
-
|
|
5
|
-
export type AgreementModalProps = {
|
|
6
|
-
application: Application;
|
|
7
|
-
state: SignUpFormState;
|
|
8
|
-
setState: React.Dispatch<React.SetStateAction<SignUpFormState>>;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export function AgreementModal({
|
|
12
|
-
application,
|
|
13
|
-
state,
|
|
14
|
-
setState,
|
|
15
|
-
}: AgreementModalProps) {
|
|
16
|
-
const [visible, setVisible] = React.useState(false);
|
|
17
|
-
const dialogRef = React.useRef<HTMLDialogElement | null>(null);
|
|
18
|
-
|
|
19
|
-
React.useEffect(() => {
|
|
20
|
-
if (!dialogRef.current) {
|
|
21
|
-
dialogRef.current = document.getElementById(
|
|
22
|
-
"agreementDialog"
|
|
23
|
-
) as HTMLDialogElement | null;
|
|
24
|
-
}
|
|
25
|
-
}, []);
|
|
26
|
-
|
|
27
|
-
React.useEffect(() => {
|
|
28
|
-
if (dialogRef.current) {
|
|
29
|
-
if (visible) {
|
|
30
|
-
dialogRef.current.showModal();
|
|
31
|
-
} else {
|
|
32
|
-
dialogRef.current.close();
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}, [visible]);
|
|
36
|
-
|
|
37
|
-
const handleCancel = () => {
|
|
38
|
-
setState({ ...state, agreement: false });
|
|
39
|
-
setVisible(false);
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
const handleOk = () => {
|
|
43
|
-
setState({ ...state, agreement: true });
|
|
44
|
-
setVisible(false);
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
const handleOpen = () => {
|
|
48
|
-
setVisible(true);
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
return (
|
|
52
|
-
<>
|
|
53
|
-
<dialog id="agreementDialog" className="modal">
|
|
54
|
-
<div className="modal-box">
|
|
55
|
-
<div className="mt-4 mb-8">
|
|
56
|
-
<iframe
|
|
57
|
-
src={application.termsOfUse}
|
|
58
|
-
width="100%"
|
|
59
|
-
height="300px"
|
|
60
|
-
sandbox="allow-scripts"
|
|
61
|
-
/>
|
|
62
|
-
</div>
|
|
63
|
-
<div className="modal-action">
|
|
64
|
-
<form method="dialog" className="modal-backdrop">
|
|
65
|
-
{/* if there is a button in form, it will close the modal */}
|
|
66
|
-
<button>Close</button>
|
|
67
|
-
</form>
|
|
68
|
-
<form method="dialog" className="flex gap-3">
|
|
69
|
-
<button className="btn" onClick={handleCancel} key="closebtn">
|
|
70
|
-
Cancel
|
|
71
|
-
</button>
|
|
72
|
-
<button
|
|
73
|
-
className="btn btn-primary"
|
|
74
|
-
// disabled={isOkDisabled}
|
|
75
|
-
onClick={handleOk}
|
|
76
|
-
key="okbtn"
|
|
77
|
-
>
|
|
78
|
-
OK
|
|
79
|
-
</button>
|
|
80
|
-
</form>
|
|
81
|
-
</div>
|
|
82
|
-
</div>
|
|
83
|
-
</dialog>
|
|
84
|
-
<input checked={!!state.agreement} type="checkbox" readOnly />
|
|
85
|
-
<button onClick={handleOpen}>Open Terms</button>
|
|
86
|
-
</>
|
|
87
|
-
);
|
|
88
|
-
}
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { SignUpFormState } from "../SignUp";
|
|
3
|
+
import type { Application } from "./util/provider";
|
|
4
|
+
|
|
5
|
+
export type AgreementModalProps = {
|
|
6
|
+
application: Application;
|
|
7
|
+
state: SignUpFormState;
|
|
8
|
+
setState: React.Dispatch<React.SetStateAction<SignUpFormState>>;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export function AgreementModal({
|
|
12
|
+
application,
|
|
13
|
+
state,
|
|
14
|
+
setState,
|
|
15
|
+
}: AgreementModalProps) {
|
|
16
|
+
const [visible, setVisible] = React.useState(false);
|
|
17
|
+
const dialogRef = React.useRef<HTMLDialogElement | null>(null);
|
|
18
|
+
|
|
19
|
+
React.useEffect(() => {
|
|
20
|
+
if (!dialogRef.current) {
|
|
21
|
+
dialogRef.current = document.getElementById(
|
|
22
|
+
"agreementDialog"
|
|
23
|
+
) as HTMLDialogElement | null;
|
|
24
|
+
}
|
|
25
|
+
}, []);
|
|
26
|
+
|
|
27
|
+
React.useEffect(() => {
|
|
28
|
+
if (dialogRef.current) {
|
|
29
|
+
if (visible) {
|
|
30
|
+
dialogRef.current.showModal();
|
|
31
|
+
} else {
|
|
32
|
+
dialogRef.current.close();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}, [visible]);
|
|
36
|
+
|
|
37
|
+
const handleCancel = () => {
|
|
38
|
+
setState({ ...state, agreement: false });
|
|
39
|
+
setVisible(false);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const handleOk = () => {
|
|
43
|
+
setState({ ...state, agreement: true });
|
|
44
|
+
setVisible(false);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const handleOpen = () => {
|
|
48
|
+
setVisible(true);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<>
|
|
53
|
+
<dialog id="agreementDialog" className="modal">
|
|
54
|
+
<div className="modal-box">
|
|
55
|
+
<div className="mt-4 mb-8">
|
|
56
|
+
<iframe
|
|
57
|
+
src={application.termsOfUse}
|
|
58
|
+
width="100%"
|
|
59
|
+
height="300px"
|
|
60
|
+
sandbox="allow-scripts"
|
|
61
|
+
/>
|
|
62
|
+
</div>
|
|
63
|
+
<div className="modal-action">
|
|
64
|
+
<form method="dialog" className="modal-backdrop">
|
|
65
|
+
{/* if there is a button in form, it will close the modal */}
|
|
66
|
+
<button>Close</button>
|
|
67
|
+
</form>
|
|
68
|
+
<form method="dialog" className="flex gap-3">
|
|
69
|
+
<button className="btn" onClick={handleCancel} key="closebtn">
|
|
70
|
+
Cancel
|
|
71
|
+
</button>
|
|
72
|
+
<button
|
|
73
|
+
className="btn btn-primary"
|
|
74
|
+
// disabled={isOkDisabled}
|
|
75
|
+
onClick={handleOk}
|
|
76
|
+
key="okbtn"
|
|
77
|
+
>
|
|
78
|
+
OK
|
|
79
|
+
</button>
|
|
80
|
+
</form>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
</dialog>
|
|
84
|
+
<input checked={!!state.agreement} type="checkbox" readOnly />
|
|
85
|
+
<button onClick={handleOpen}>Open Terms</button>
|
|
86
|
+
</>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
@@ -1,94 +1,94 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { CaptchaModal } from "./CaptchaModal";
|
|
3
|
-
import * as AuthBackend from "./util/auth-api";
|
|
4
|
-
|
|
5
|
-
type CaptchaState = {
|
|
6
|
-
values: any;
|
|
7
|
-
openCaptchaModal: boolean;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export default function CaptchaController() {
|
|
11
|
-
const [state, setState] = React.useState<CaptchaState>({
|
|
12
|
-
values: {},
|
|
13
|
-
openCaptchaModal: false,
|
|
14
|
-
});
|
|
15
|
-
const dialogRef = React.useRef<HTMLElement | null>(null);
|
|
16
|
-
|
|
17
|
-
const handleClick = () => {
|
|
18
|
-
if (dialogRef.current) {
|
|
19
|
-
if (!state.openCaptchaModal) {
|
|
20
|
-
// @ts-ignore
|
|
21
|
-
dialogRef.current.showModal();
|
|
22
|
-
} else {
|
|
23
|
-
// @ts-ignore
|
|
24
|
-
dialogRef.current.close();
|
|
25
|
-
}
|
|
26
|
-
setState({ ...state, openCaptchaModal: !state.openCaptchaModal });
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const captchaCallback = (v: any) => {
|
|
31
|
-
console.log(v);
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
const onOk = (
|
|
35
|
-
captchaType: string,
|
|
36
|
-
captchaToken: string,
|
|
37
|
-
clientSecret: string
|
|
38
|
-
) => {
|
|
39
|
-
if (dialogRef.current) {
|
|
40
|
-
// @ts-ignore
|
|
41
|
-
dialogRef.current.close();
|
|
42
|
-
const values = state.values;
|
|
43
|
-
values["captchaType"] = captchaType;
|
|
44
|
-
values["captchaToken"] = captchaToken;
|
|
45
|
-
values["clientSecret"] = clientSecret;
|
|
46
|
-
AuthBackend.getCaptchaStatus(values).then((res) => {
|
|
47
|
-
if (res.status === "ok") {
|
|
48
|
-
// errors
|
|
49
|
-
if (res.data) {
|
|
50
|
-
setState({
|
|
51
|
-
openCaptchaModal: true,
|
|
52
|
-
values: values,
|
|
53
|
-
});
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
captchaCallback(values);
|
|
58
|
-
});
|
|
59
|
-
setState({ ...state, openCaptchaModal: false });
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const onCancel = () => {
|
|
64
|
-
if (dialogRef.current) {
|
|
65
|
-
// @ts-ignore
|
|
66
|
-
dialogRef.current.close();
|
|
67
|
-
setState({ ...state, openCaptchaModal: false });
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
React.useEffect(() => {
|
|
72
|
-
dialogRef.current = document.getElementById("captcha-modal");
|
|
73
|
-
}, []);
|
|
74
|
-
|
|
75
|
-
return (
|
|
76
|
-
<>
|
|
77
|
-
<CaptchaModal
|
|
78
|
-
visible={state.openCaptchaModal}
|
|
79
|
-
owner="admin"
|
|
80
|
-
name="provider_captcha_default"
|
|
81
|
-
isCurrentProvider={true}
|
|
82
|
-
onCancel={onCancel}
|
|
83
|
-
onOk={onOk}
|
|
84
|
-
/>
|
|
85
|
-
<button
|
|
86
|
-
className="btn btn-primary"
|
|
87
|
-
// @ts-ignore
|
|
88
|
-
onClick={handleClick}
|
|
89
|
-
>
|
|
90
|
-
Captcha
|
|
91
|
-
</button>
|
|
92
|
-
</>
|
|
93
|
-
);
|
|
94
|
-
}
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { CaptchaModal } from "./CaptchaModal";
|
|
3
|
+
import * as AuthBackend from "./util/auth-api";
|
|
4
|
+
|
|
5
|
+
type CaptchaState = {
|
|
6
|
+
values: any;
|
|
7
|
+
openCaptchaModal: boolean;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export default function CaptchaController() {
|
|
11
|
+
const [state, setState] = React.useState<CaptchaState>({
|
|
12
|
+
values: {},
|
|
13
|
+
openCaptchaModal: false,
|
|
14
|
+
});
|
|
15
|
+
const dialogRef = React.useRef<HTMLElement | null>(null);
|
|
16
|
+
|
|
17
|
+
const handleClick = () => {
|
|
18
|
+
if (dialogRef.current) {
|
|
19
|
+
if (!state.openCaptchaModal) {
|
|
20
|
+
// @ts-ignore
|
|
21
|
+
dialogRef.current.showModal();
|
|
22
|
+
} else {
|
|
23
|
+
// @ts-ignore
|
|
24
|
+
dialogRef.current.close();
|
|
25
|
+
}
|
|
26
|
+
setState({ ...state, openCaptchaModal: !state.openCaptchaModal });
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const captchaCallback = (v: any) => {
|
|
31
|
+
console.log(v);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const onOk = (
|
|
35
|
+
captchaType: string,
|
|
36
|
+
captchaToken: string,
|
|
37
|
+
clientSecret: string
|
|
38
|
+
) => {
|
|
39
|
+
if (dialogRef.current) {
|
|
40
|
+
// @ts-ignore
|
|
41
|
+
dialogRef.current.close();
|
|
42
|
+
const values = state.values;
|
|
43
|
+
values["captchaType"] = captchaType;
|
|
44
|
+
values["captchaToken"] = captchaToken;
|
|
45
|
+
values["clientSecret"] = clientSecret;
|
|
46
|
+
AuthBackend.getCaptchaStatus(values).then((res) => {
|
|
47
|
+
if (res.status === "ok") {
|
|
48
|
+
// errors
|
|
49
|
+
if (res.data) {
|
|
50
|
+
setState({
|
|
51
|
+
openCaptchaModal: true,
|
|
52
|
+
values: values,
|
|
53
|
+
});
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
captchaCallback(values);
|
|
58
|
+
});
|
|
59
|
+
setState({ ...state, openCaptchaModal: false });
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const onCancel = () => {
|
|
64
|
+
if (dialogRef.current) {
|
|
65
|
+
// @ts-ignore
|
|
66
|
+
dialogRef.current.close();
|
|
67
|
+
setState({ ...state, openCaptchaModal: false });
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
React.useEffect(() => {
|
|
72
|
+
dialogRef.current = document.getElementById("captcha-modal");
|
|
73
|
+
}, []);
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<>
|
|
77
|
+
<CaptchaModal
|
|
78
|
+
visible={state.openCaptchaModal}
|
|
79
|
+
owner="admin"
|
|
80
|
+
name="provider_captcha_default"
|
|
81
|
+
isCurrentProvider={true}
|
|
82
|
+
onCancel={onCancel}
|
|
83
|
+
onOk={onOk}
|
|
84
|
+
/>
|
|
85
|
+
<button
|
|
86
|
+
className="btn btn-primary"
|
|
87
|
+
// @ts-ignore
|
|
88
|
+
onClick={handleClick}
|
|
89
|
+
>
|
|
90
|
+
Captcha
|
|
91
|
+
</button>
|
|
92
|
+
</>
|
|
93
|
+
);
|
|
94
|
+
}
|