* feat(auth): init auth package & collection * feat(auth): register * feat(auth): use authenticator * feat(auth): mapRoles * feat(auth): refactor * feat(auth): base auth class * feat(auth): add plugin * chore(auth): test * chore(auth): add test cases * feat(auth): authenticators pane * chore(auth): custom hook useAuthTypes * feat(auth): authenticator pane * chore(auth): store options schema using context * feat(auth): signInPage provider * feat(auth): signUpPage provider * chore(auth): solve build errors * chore(auth): add dependency * chore(auth): remove dependency cycles * chore(auth): add plugin-auth to preset * chore(auth): fix test * feat(auth): authenticator enable status * fix(test): fix test using new authentication * feat(auth): migration, set up basic auth * chore(auth): can set options ui by component * fix(test): workflow manunal.test * fix(test): typo * feat(auth): support multi-language * chore(auth): imporve code * chore(auth): hide button if no configuration * chore(auth): readme * chore(auth): remove allowSignup prop * chore(auth): move configure pane to edit form * fix(auth): jwt options bug * feat(auth): init sms-auth * chore(auth): at least authenticator required * chore(auth): add test * feat(auth): support sms auth * fix(auth): fix test * chore(auth): move findOrCreateUser to AuthModel * chore(auth): history compatible processing * feat(auth): support SAML auth * chore(auth): saml auth list * chore(saml-auth): improve ui * Merge branch 'main' into feat/authentication * chore(auth): improve code * fix(saml-auth): fix bug * fix(saml-auth): fix saml options * chore(saml-auth): compatible processing && ut * fix(auth): signin page bug * chore(auth): saml compatible processing * feat(auth): oidc-auth * fix(oidc-auth): bug * fix(oidc-auth): bug * fix(auth): fix test * chore(auth): filter enabled authenticator * chore(oidc): add field map * chore(auth): update readme * docs(auth): create sms-auth readme * feat(auth): allow signup config * test(auth): fix test * feat(auth): allow saml and oidc use http * chore(oidc-auth): extends timeout * docs(auth): update readme * feat(auth): support sort * docs(saml): update readme * feat(auth): support sort all authenticator * Merge branch 'main' into feat/authentication * Merge branch 'main' into feat/authentication * feat: improve code * docs(auth): add doc * Merge branch 'main' into feat/authentication * chore: update yarn.lock * feat: improve code * chore(acl): write role to acl if it exists in database and not found … (#2001) * chore(acl): write role to acl if it exists in database and not found in acl * fix: test * fix: eager load with nested association (#2002) * chore: upgrade vitest * chore: edit * refactor: auth class * fix: set options * chore(acl): write role to acl if it exists in database and not found … (#2001) * chore(acl): write role to acl if it exists in database and not found in acl * fix: test * fix: eager load with nested association (#2002) * chore: upgrade vitest * chore: add migrations * test: fix api-client test * chore: add sms-auth * feat: avoid no permission after auth type disabled * fix: translation --------- Co-authored-by: chenos <chenlinxh@gmail.com>
79 lines
2.0 KiB
TypeScript
79 lines
2.0 KiB
TypeScript
import { LoginOutlined } from '@ant-design/icons';
|
|
import { css } from '@emotion/css';
|
|
import { Authenticator, useAPIClient, useRedirect } from '@nocobase/client';
|
|
import { Button, Space } from 'antd';
|
|
import React, { useEffect, useState, useCallback } from 'react';
|
|
|
|
export const SAMLButton = (props: { authenticator: Authenticator }) => {
|
|
const [windowHandler, setWindowHandler] = useState<Window | undefined>();
|
|
const api = useAPIClient();
|
|
const redirect = useRedirect();
|
|
|
|
/**
|
|
* 打开登录弹出框
|
|
*/
|
|
const handleOpen = async (name: string) => {
|
|
const response = await api.request({
|
|
method: 'post',
|
|
url: 'saml:getAuthUrl',
|
|
headers: {
|
|
'X-Authenticator': name,
|
|
},
|
|
});
|
|
|
|
const authUrl = response?.data?.data;
|
|
const { width, height } = screen;
|
|
|
|
const win = window.open(
|
|
authUrl,
|
|
'_blank',
|
|
`width=800,height=600,left=${(width - 800) / 2},top=${
|
|
(height - 600) / 2
|
|
},toolbar=no,menubar=no,location=no,status=no`,
|
|
);
|
|
|
|
setWindowHandler(win);
|
|
};
|
|
|
|
const handleSAMLLogin = useCallback(
|
|
async (event: MessageEvent) => {
|
|
try {
|
|
await api.auth.signIn(event.data, event.data?.authenticator);
|
|
redirect();
|
|
} catch (err) {
|
|
console.error(err);
|
|
} finally {
|
|
windowHandler.close();
|
|
setWindowHandler(undefined);
|
|
}
|
|
},
|
|
[api, redirect, windowHandler],
|
|
);
|
|
|
|
/**
|
|
* 监听弹出窗口的消息
|
|
*/
|
|
useEffect(() => {
|
|
if (!windowHandler) return;
|
|
|
|
window.addEventListener('message', handleSAMLLogin);
|
|
return () => {
|
|
window.removeEventListener('message', handleSAMLLogin);
|
|
};
|
|
}, [windowHandler, handleSAMLLogin]);
|
|
|
|
const authenticator = props.authenticator;
|
|
return (
|
|
<Space
|
|
direction="vertical"
|
|
className={css`
|
|
display: flex;
|
|
`}
|
|
>
|
|
<Button shape="round" block icon={<LoginOutlined />} onClick={() => handleOpen(authenticator.name)}>
|
|
{authenticator.title}
|
|
</Button>
|
|
</Space>
|
|
);
|
|
};
|