Last active
July 27, 2023 18:48
-
-
Save llirikkcoder/48f614766897d04c0d65d9ebfbd846eb to your computer and use it in GitHub Desktop.
sso iframe
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { FC, useEffect, useState } from 'react'; | |
interface ICallbackRes { | |
accessToken: string, | |
refreshToken: string, | |
} | |
interface IComponent { | |
parentElementId: string, | |
clientId: string, | |
redirectUri: string, | |
autoLoad?: boolean, | |
callback?: (res: ICallbackRes) => void, | |
render?: (onClick: () => string) => JSX.Element, | |
promo?: string, | |
state?: string, | |
code?: string, | |
recoveryToken?: string, | |
activateToken?: string, | |
host: string, | |
lang?: string, | |
} | |
const isBrowser = typeof window !== 'undefined'; | |
const IAuthComponent: FC<IComponent> = (props) => { | |
const { | |
clientId, | |
autoLoad, | |
callback, | |
render, // WTF? | |
redirectUri, | |
parentElementId, | |
promo, | |
recoveryToken, | |
activateToken, | |
host, | |
state, | |
code, | |
lang, | |
} = props; | |
const [enabled, setEnabled] = useState<boolean>(!!render || !!autoLoad) | |
const [authUrl] = useState(() => { | |
let page = 'login/oauth/authorize'; | |
let token; | |
if (recoveryToken) { | |
page = 'recovery'; | |
token = recoveryToken; | |
} else if (activateToken) { | |
page = 'activate'; | |
token = activateToken; | |
} else if (promo) { | |
page = 'login/oauth/registration'; | |
} | |
return `${host}/${page}?client_id=${clientId}&redirect_uri=${redirectUri}${promo ? `&promo=${promo}` : ''}${token ? `&token=${token}` : ''}${state ? `&state=${state}` : ''}${code ? `&code=${code}` : ''}&type=${render ? 'redirect' : 'message'}${lang ? `&lang=${lang}` : ''}`; | |
}); | |
useEffect(() => { | |
if (!authUrl.length || !enabled) { | |
return; | |
} | |
if (!autoLoad || !isBrowser) { | |
return; | |
} | |
const iframe = document.createElement('iframe'); | |
iframe.id = 'oauth-iframe-id'; | |
iframe.style.setProperty('width', '100%'); | |
iframe.style.setProperty('height', '100%'); | |
iframe.style.setProperty('background-color', '#fff'); | |
iframe.src = authUrl; | |
const handlerMessage = (e: MessageEvent) => { | |
const { accessToken, refreshToken, url } = e.data; | |
if (url) { | |
window.location.href = url; | |
return; | |
} | |
const origin = e.origin; | |
if (origin !== host) { | |
console.error('Origin URL doesnt equal to IFrame URL.'); | |
return; | |
} | |
iframe.remove(); | |
if (callback) { | |
callback({ accessToken, refreshToken }); | |
} | |
}; | |
const parent = document.getElementById(parentElementId); | |
const loadingEle = document.getElementById('loading'); | |
const onLoad = () => { | |
if (loadingEle) { | |
loadingEle.style.display = 'none'; | |
iframe.style.opacity = '1'; | |
} | |
} | |
if (parent) { | |
iframe.addEventListener('load', onLoad); | |
parent.appendChild(iframe); | |
if (window.addEventListener) { | |
window.addEventListener('message', handlerMessage); | |
} | |
} | |
return () => { | |
iframe.remove(); | |
window.removeEventListener('message', handlerMessage) | |
window.removeEventListener('load', onLoad) | |
} | |
}, [authUrl, enabled, autoLoad, isBrowser]); | |
if (!isBrowser) { | |
return null; | |
} | |
if (!enabled) { | |
return ( | |
<button onClick={() => setEnabled(true)}> | |
Login | |
</button> | |
) | |
} | |
if (render) { | |
return render(() => authUrl); | |
} | |
return null; | |
}; | |
export default IAuthComponent; |
import { injectable } from 'inversify';
@Injectable()
class AppConfig {
public readonly app = process.env.APP_NAME || 'fairyapp';
public readonly org = process.env.ORG_NAME || 'dao2';
public readonly imageUrlServer = process.env.NEXT_PUBLIC_API_DOMAIN_HTTP || '';
public readonly authUrlServer = 'https://grpc-auth.cryptofairies.club';
public readonly authSSOClient = 'https://sso.cryptofairies.club';
get imageStorageUrl() {
return process.env.NEXT_PUBLIC_API_DOMAIN_HTTP;
}
get defaultLang() {
return 'en';
}
get defaultTransDomain() {
return 'fairy';
}
}
export default AppConfig;
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
import React, { FC } from 'react';
import LandingLayout from '@layouts/Landng';
import stylesLayout from '../styles.module.css';
import routing from '@local/app/routing';
import dynamic from 'next/dynamic';
import SpinnerModule from '@components/Spinner';
import { useLang } from '@locus/translate-react';
interface ISignUpPageViewProps {
authSSOClient: string
parent?: string,
recoveryToken?: string,
activateToken?: string,
state?: string,
code?: string
setTokens(accessToken: string, refreshToken: string): void
}
const SignUpPageView: FC = (props) => {
console.log("🚀 ~ file: Component.tsx:20 ~ props:", props);
const { setTokens, parent, recoveryToken, activateToken, state, code, authSSOClient } = props
const { currentLanguage } = useLang();
const IAuthComponent = dynamic(() => import('@modules/sso/iframe'), { ssr: false });
return (
<IAuthComponent
host={authSSOClient}
autoLoad
state={state}
code={code}
clientId="cryptoFairyCLientId"
redirectUri={
${process.env.DOMAIN}${routing.public.signIn}
}promo={parent}
recoveryToken={recoveryToken}
activateToken={activateToken}
callback={(res) => setTokens(res.accessToken, res.refreshToken)}
parentElementId="auth-block"
lang={currentLanguage}
/>
);
};
export default SignUpPageView;