Skip to content

Commit

Permalink
feat(unified-login): update unified login
Browse files Browse the repository at this point in the history
  • Loading branch information
cedricmagne authored and Vlad Lo. committed Aug 23, 2024
1 parent ed9c865 commit 4d22706
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 121 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"dotenv": "^16.4.5",
"ethers": "^6.13.2",
"js-cookie": "^3.0.5",
"jsonwebtoken": "^9.0.2",
"launchdarkly-js-client-sdk": "^3.3.0",
"lodash.debounce": "^4.0.8",
"lodash.isobject": "^3.0.2",
Expand Down
159 changes: 53 additions & 106 deletions src/components/AuthLogin/AuthModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,15 @@ import Modal from "react-modal";
import styles from "./styles.module.css";
import global from "../ParserOpenRPC/global.module.css";
import Icon from "../Icon/Icon";
import {
authenticateAndAuthorize,

This comment has been minimized.

Copy link
@Chator1

Chator1 Aug 23, 2024

0xFD689e5f2d8d9Aec0aD328225Ae62FdBDdb30328

AUTH_WALLET_PAIRING,

This comment has been minimized.

Copy link
@Chator1

Chator1 Aug 23, 2024

0x84e8277c938102f42FC2D9625Fc75049A86c99Ae

AUTH_WALLET_SESSION_NAME,
AUTH_WALLET_PROJECTS,
saveTokenString,
getUserIdFromSessionStorage,
} from "../../lib/siwsrp/auth";
import { authenticateAndAuthorize, AUTH_WALLET_PAIRING, AUTH_WALLET_SESSION_NAME, AUTH_WALLET_PROJECTS, saveTokenString, getUserIdFromJwtToken } from "../../lib/siwsrp/auth";
import { DASHBOARD_URL, REQUEST_PARAMS } from "@site/src/lib/constants";

Modal.setAppElement("#__docusaurus");
type AuthModalProps = {
open: boolean;
setOpen: (arg: boolean) => void;
setProjects: (arg: any[]) => void;
setUser?: (arg: string) => void;
setUser: (arg: string) => void;
};

enum AUTH_LOGIN_STEP {
Expand Down Expand Up @@ -58,40 +51,20 @@ const ConnectingModal = () => {
);
};

const ConnectionErrorModal = ({
onClose,
onRetry,
}: {
onClose: VoidFunction;
onRetry: VoidFunction;
}) => {
const ConnectionErrorModal = () => {
return (
<>
<div className={styles.spinnerContainer}>
<Icon name="spinner-error" classes={styles.spinner} />
<Icon name="metamask" classes={styles.metamask} />
</div>
<div className={styles.heading}>
There was an issue connecting your wallet
</div>
<div className={styles.heading}>There was an issue connecting your wallet</div>
<div className={styles.content}>
Please try again or <a href="#">contact us</a>.
</div>
<div className={styles.flexButton}>
<button
style={{ flex: "1", display: "block", margin: "0 5px" }}
className={global.secondaryBtn}
onClick={onClose}
>
Cancel
</button>
<button
style={{ flex: "1", display: "block", margin: "0 5px" }}
className={global.primaryBtn}
onClick={onRetry}
>
Retry
</button>
<button style={{ flex: "1", display: "block", margin: "0 5px" }} className={global.secondaryBtn}>Cancel</button>
<button style={{ flex: "1", display: "block", margin: "0 5px" }} className={global.primaryBtn}>Retry</button>
</div>
</>
);
Expand All @@ -118,90 +91,69 @@ const AuthModal = ({ open, setOpen, setProjects, setUser }: AuthModalProps) => {
});

const usersPairing = await pairingResponse.json();
const { data } = usersPairing;
// Saving of paired Infura accounts in local storage
localStorage.setItem(AUTH_WALLET_PAIRING, JSON.stringify({ data }));

const { data } = usersPairing
// Saving of paired Infura accounts in local storage
localStorage.setItem(AUTH_WALLET_PAIRING, JSON.stringify({ data }))
// Handling no wallet pairing or multiple pairing
if (data.length !== 1) {
const mm_auth = Buffer.from(
JSON.stringify({
token: true,
step:
data.length > 1
? AUTH_LOGIN_STEP.WALLET_LOGIN_MULTI_USER
: AUTH_LOGIN_STEP.WALLET_LOGIN_EMAIL_PASSWORD,
mmAuthSession: localStorage.getItem(AUTH_WALLET_SESSION_NAME),
walletPairing: data,
}),
).toString("base64");
window.location.href = `${DASHBOARD_URL}/login?mm_auth=${mm_auth}&token=true&redirect_to=${window.location.href}`;
return;
const mm_auth = Buffer.from(JSON.stringify({
token: true,
step: data.length > 1 ? AUTH_LOGIN_STEP.WALLET_LOGIN_MULTI_USER : AUTH_LOGIN_STEP.WALLET_LOGIN_EMAIL_PASSWORD,
mmAuthSession: localStorage.getItem(AUTH_WALLET_SESSION_NAME),
walletPairing: data
})).toString('base64')
window.location.href = `${DASHBOARD_URL}/login?mm_auth=${mm_auth}&token=true&redirect_to=${window.location.href}`
return
}

// We have one wallet paired with one Infura account
// Use this Infura email account and this ProfileId to login to Infura
// Pass token in request params to generate and recieve an Infura access Token
const email = data[0].email as string;
const userWithTokenResponse = await fetch(
`${DASHBOARD_URL}/api/wallet/login?token=true`,
{
...REQUEST_PARAMS(),
headers: {
...REQUEST_PARAMS().headers,
hydra_token: accessToken,
recaptcha_bypass: "84450394",
},
body: JSON.stringify({
email,
profileId: userProfile.profileId,
}),
const email = data[0].email as string
const userWithTokenResponse = await fetch(`${DASHBOARD_URL}/api/wallet/login?token=true`, {
...REQUEST_PARAMS(),
headers: {
...REQUEST_PARAMS().headers,
hydra_token: accessToken,
recaptcha_bypass: "84450394",
},
);
body: JSON.stringify({
email,
profileId: userProfile.profileId
})
});

const { token } = await userWithTokenResponse.json();
saveTokenString(token);
const userId = getUserIdFromSessionStorage();
saveTokenString(token)
const userId = getUserIdFromJwtToken()

// You can use Infura Access Token to fetch any Infura API endpoint
const projectsResponse = await fetch(
`${DASHBOARD_URL}/api/v1/users/${userId}/projects`,
{
...REQUEST_PARAMS("GET"),
headers: {
...REQUEST_PARAMS("GET").headers,
Authorization: `Bearer ${token}`,
},
},
);
const {
result: { projects },
} = await projectsResponse.json();
sessionStorage.setItem(AUTH_WALLET_PROJECTS, JSON.stringify(projects));
setProjects(projects);
if (setUser) {
setUser(userId);
}
setOpen(false);
const projectsResponse = await fetch(`${DASHBOARD_URL}/api/v1/users/${userId}/projects`, {
...REQUEST_PARAMS('GET'),
headers: {
...REQUEST_PARAMS('GET').headers,
Authorization: `Bearer ${token}`
}
});
const { result: { projects }} = await projectsResponse.json()
sessionStorage.setItem(AUTH_WALLET_PROJECTS, JSON.stringify(projects))
setProjects(projects)
setOpen(false)
};

useEffect(() => {
if (open) {
handleLogin();
(async () => {
try {
await login();
} catch (e: any) {
setStep(AUTH_LOGIN_STEP.CONNECTION_ERROR)
}
})();
}
}, [open]);

const handleLogin = () => {
(async () => {
try {
setStep(AUTH_LOGIN_STEP.CONNECTING);
await login();
} catch (e: any) {
setStep(AUTH_LOGIN_STEP.CONNECTION_ERROR);
}
})();
};

return (
<Modal
isOpen={open}
Expand All @@ -219,15 +171,10 @@ const AuthModal = ({ open, setOpen, setProjects, setUser }: AuthModalProps) => {
<Icon name="close" classes={styles.modalClose} />
</button>
{step === AUTH_LOGIN_STEP.CONNECTING ? <ConnectingModal /> : null}
{step === AUTH_LOGIN_STEP.CONNECTION_ERROR ? (
<ConnectionErrorModal
onClose={() => setOpen(false)}
onRetry={handleLogin}
/>
) : null}
{step === AUTH_LOGIN_STEP.CONNECTION_ERROR ? <ConnectionErrorModal /> : null}
</div>
</Modal>
);
};

export default AuthModal;
export default AuthModal;
11 changes: 4 additions & 7 deletions src/components/ParserOpenRPC/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
} from "@site/src/lib/segmentAnalytics";
import {
saveTokenString,
getUserIdFromSessionStorage,
getUserIdFromJwtToken,
AUTH_WALLET_PROJECTS,
} from "@site/src/lib/siwsrp/auth";
import {
Expand Down Expand Up @@ -130,7 +130,7 @@ export default function ParserOpenRPC({ network, method }: ParserProps) {
const token = url.searchParams.get("token");
if (token) {
saveTokenString(token);
const userId = getUserIdFromSessionStorage();
const userId = getUserIdFromJwtToken();
(async () => {
const projectsResponse = await fetch(
`${DASHBOARD_URL}/api/v1/users/${userId}/projects`,
Expand Down Expand Up @@ -222,11 +222,8 @@ export default function ParserOpenRPC({ network, method }: ParserProps) {

const metaMaskConnectHandler = async () => {
try {
if (extensionActive && location.pathname.startsWith(REF_SERVICES_PATH)) {
setOpenAuthModal(true);
} else {
await sdk?.connect();
}
await sdk?.connect();
setOpenAuthModal(true);
} catch (err) {
console.warn("failed to connect..", err);
}
Expand Down
10 changes: 7 additions & 3 deletions src/lib/siwsrp/auth.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { SDK } from '@metamask-previews/profile-sync-controller'
import jwt from 'jsonwebtoken'

type HydraEnv = {
authApiUrl: string
Expand Down Expand Up @@ -73,6 +74,9 @@ export const saveTokenString = (token: string) => {
sessionStorage.setItem(AUTH_WALLET_TOKEN, token)
}

export const getUserIdFromSessionStorage = () => {
return sessionStorage.getItem(AUTH_WALLET_TOKEN).split('=')[0].split('::')[2]
}
export const getUserIdFromJwtToken = () => {
const token = sessionStorage.getItem(AUTH_WALLET_TOKEN)
const decoded = jwt.decode(token as string, { complete: true }) as jwt.Jwt
const { id } = decoded.payload as jwt.Payload
return id
}
10 changes: 5 additions & 5 deletions src/theme/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
} from "@site/src/lib/constants";
import {
AUTH_WALLET_PROJECTS,
getUserIdFromSessionStorage,
getUserIdFromJwtToken,
saveTokenString,
} from "@site/src/lib/siwsrp/auth";
import AuthModal from "@site/src/components/AuthLogin/AuthModal";
Expand Down Expand Up @@ -70,7 +70,7 @@ export const LoginProvider = ({ children }) => {
setProjects(
JSON.parse(sessionStorage.getItem(AUTH_WALLET_PROJECTS) || "{}"),
);
setUserId(getUserIdFromSessionStorage());
setUserId(getUserIdFromJwtToken());
const accounts = await sdk.connect();
setAccount(accounts);
if (accounts && accounts.length > 0) {
Expand All @@ -96,8 +96,8 @@ export const LoginProvider = ({ children }) => {
const token = url.searchParams.get("token");
if (token) {
saveTokenString(token);
const userIdFromSession = getUserIdFromSessionStorage();
setUserId(userIdFromSession);
const userIdFromjwtToken = getUserIdFromJwtToken();
setUserId(userIdFromjwtToken);

(async () => {
const projectsResponse = await fetch(
Expand Down Expand Up @@ -136,10 +136,10 @@ export const LoginProvider = ({ children }) => {

const metaMaskConnectHandler = useCallback(async () => {
try {
const accounts = await sdk.connect();
if (sdk.isExtensionActive()) {
setOpenAuthModal(true);
}
const accounts = await sdk.connect();
setAccount(accounts);
if (accounts && accounts.length > 0) {
setAccount(accounts[0]);
Expand Down
Loading

0 comments on commit 4d22706

Please sign in to comment.