mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-11-15 19:50:28 +03:00
Signed-off-by: Ajay Bura <ajbura@gmail.com>
This commit is contained in:
parent
3d885ec262
commit
a83aecaa69
13 changed files with 850 additions and 708 deletions
|
|
@ -1,107 +1,41 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import './SSOButtons.scss';
|
||||
|
||||
import { createTemporaryClient, getLoginFlows, startSsoLogin } from '../../../client/action/auth';
|
||||
import { createTemporaryClient, startSsoLogin } from '../../../client/action/auth';
|
||||
|
||||
import Text from '../../atoms/text/Text';
|
||||
|
||||
function SSOButtons({ homeserver }) {
|
||||
const [identityProviders, setIdentityProviders] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
// Reset sso proviers to avoid displaying sso icons if the homeserver is not valid
|
||||
setIdentityProviders([]);
|
||||
|
||||
// If the homeserver passed in is not a fully-qualified domain name, do not update.
|
||||
if (!homeserver.match('^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](?:\\.[a-zA-Z]{2,})+$')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO Check that there is a Matrix server at homename before making requests.
|
||||
// This will prevent the CORS errors that happen when a user changes their homeserver.
|
||||
createTemporaryClient(homeserver).then((client) => {
|
||||
const providers = [];
|
||||
getLoginFlows(client).then((flows) => {
|
||||
if (flows.flows !== undefined) {
|
||||
const ssoFlows = flows.flows.filter((flow) => flow.type === 'm.login.sso' || flow.type === 'm.login.cas');
|
||||
ssoFlows.forEach((flow) => {
|
||||
if (flow.identity_providers !== undefined) {
|
||||
const type = flow.type.substring(8);
|
||||
flow.identity_providers.forEach((idp) => {
|
||||
const imageSrc = client.mxcUrlToHttp(idp.icon);
|
||||
providers.push({
|
||||
homeserver, id: idp.id, name: idp.name, type, imageSrc,
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
setIdentityProviders(providers);
|
||||
}).catch(() => {});
|
||||
}).catch(() => {
|
||||
setIdentityProviders([]);
|
||||
});
|
||||
}, [homeserver]);
|
||||
|
||||
if (identityProviders.length === 0) return <></>;
|
||||
import Button from '../../atoms/button/Button';
|
||||
|
||||
function SSOButtons({ type, identityProviders, baseUrl }) {
|
||||
const tempClient = createTemporaryClient(baseUrl);
|
||||
function handleClick(id) {
|
||||
startSsoLogin(baseUrl, type, id);
|
||||
}
|
||||
return (
|
||||
<div className="sso-buttons">
|
||||
<div className="sso-buttons__divider">
|
||||
<Text>OR</Text>
|
||||
</div>
|
||||
<div className="sso-buttons__container">
|
||||
{identityProviders
|
||||
// Sort by alphabetical order
|
||||
.sort((idp, idp2) => {
|
||||
if (typeof idp.imageSrc !== 'string') return -1;
|
||||
return idp.name.toLowerCase() > idp2.name.toLowerCase() ? 1 : -1;
|
||||
})
|
||||
.map((idp) => (
|
||||
<SSOButton
|
||||
key={idp.id}
|
||||
homeserver={idp.homeserver}
|
||||
id={idp.id}
|
||||
name={idp.name}
|
||||
type={idp.type}
|
||||
imageSrc={idp.imageSrc}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
{identityProviders
|
||||
.sort((idp, idp2) => {
|
||||
if (typeof idp.icon !== 'string') return -1;
|
||||
return idp.name.toLowerCase() > idp2.name.toLowerCase() ? 1 : -1;
|
||||
})
|
||||
.map((idp) => (
|
||||
idp.icon
|
||||
? (
|
||||
<button key={idp.id} type="button" className="sso-btn" onClick={() => handleClick(idp.id)}>
|
||||
<img className="sso-btn__img" src={tempClient.mxcUrlToHttp(idp.icon, 36, 36, 'crop')} alt={idp.name} />
|
||||
</button>
|
||||
) : <Button key={idp.id} className="sso-btn__text-only" onClick={() => handleClick(idp.id)}>{`Login with ${idp.name}`}</Button>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function SSOButton({
|
||||
homeserver, id, name, type, imageSrc,
|
||||
}) {
|
||||
const isImageAvail = !!imageSrc;
|
||||
function handleClick() {
|
||||
startSsoLogin(homeserver, type, id);
|
||||
}
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className={`sso-btn${!isImageAvail ? ' sso-btn__text-only' : ''}`}
|
||||
onClick={handleClick}
|
||||
>
|
||||
{isImageAvail && <img className="sso-btn__img" src={imageSrc} alt={name} />}
|
||||
{!isImageAvail && <Text>{`Login with ${name}`}</Text>}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
SSOButtons.propTypes = {
|
||||
homeserver: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
SSOButton.propTypes = {
|
||||
homeserver: PropTypes.string.isRequired,
|
||||
id: PropTypes.string.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
type: PropTypes.string.isRequired,
|
||||
imageSrc: PropTypes.string.isRequired,
|
||||
identityProviders: PropTypes.arrayOf(
|
||||
PropTypes.shape({}),
|
||||
).isRequired,
|
||||
baseUrl: PropTypes.string.isRequired,
|
||||
type: PropTypes.oneOf(['sso', 'cas']).isRequired,
|
||||
};
|
||||
|
||||
export default SSOButtons;
|
||||
|
|
|
|||
|
|
@ -1,22 +1,7 @@
|
|||
.sso-buttons {
|
||||
&__divider {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
flex: 1;
|
||||
content: '';
|
||||
margin: var(--sp-tight);
|
||||
border-bottom: 1px solid var(--bg-surface-border);
|
||||
}
|
||||
}
|
||||
&__container {
|
||||
margin-bottom: var(--sp-extra-loose);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.sso-btn {
|
||||
|
|
@ -31,11 +16,8 @@
|
|||
width: var(--av-small);
|
||||
}
|
||||
&__text-only {
|
||||
margin-top: var(--sp-normal);
|
||||
flex-basis: 100%;
|
||||
text-align: center;
|
||||
|
||||
margin: var(--sp-tight) 0px;
|
||||
cursor: pointer;
|
||||
& .text {
|
||||
color: var(--tc-link);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue