Refactor authWithMetamask to enhance modularity and introduce logout functionality

This commit is contained in:
Samuel Andert 2023-07-24 11:51:39 +02:00
parent 8aff269743
commit cf1a83006e
4 changed files with 205 additions and 3 deletions

View File

@ -0,0 +1,63 @@
<script>
import { onMount } from 'svelte';
import {
generateAuthSig,
getStoredAuthSig,
logout
} from '$lib/services/authWithMetamask/authWithMetamask';
let authSig = null;
let error = null;
async function handleAuth() {
try {
authSig = await generateAuthSig();
} catch (err) {
error = err.message;
}
}
function handleLogout() {
logout();
authSig = null;
}
onMount(() => {
authSig = getStoredAuthSig();
});
</script>
<!-- AuthSig Address Displayed -->
{#if authSig}
<div class="flex items-center p-4 mb-4 bg-gray-100 rounded-lg shadow-md">
<p class="font-medium text-gray-700">
Metamask Address: <span class="text-orange-500">{authSig.address}</span>
</p>
<button
class="px-4 py-2 ml-4 font-bold text-white bg-red-500 rounded-lg shadow-lg hover:bg-red-600"
on:click={handleLogout}
>
Logout
</button>
</div>
<!-- Error Message -->
{:else if error}
<div class="flex items-center p-4 mb-4 bg-red-100 rounded-lg shadow-md">
<p class="font-medium text-red-700">{error}</p>
</div>
<!-- Login Button -->
{:else}
<div class="flex justify-center">
<button
class="flex items-center px-4 py-2 m-2 font-bold text-white bg-orange-500 rounded-lg shadow-lg hover:bg-orange-600"
on:click={handleAuth}
>
<img
src="https://upload.wikimedia.org/wikipedia/commons/3/36/MetaMask_Fox.svg"
alt="MetaMask"
class="w-6 h-6 mr-2"
/>
<span class="text-lg">Login</span>
</button>
</div>
{/if}

View File

@ -0,0 +1,78 @@
# authWithMetamask.ts Documentation
This module provides utility functions for handling authentication signatures (AuthSigs) with MetaMask using the `@lit-protocol/lit-node-client`.
## Table of Contents
- [authWithMetamask.ts Documentation](#authwithmetamaskts-documentation)
- [Table of Contents](#table-of-contents)
- [Dependencies](#dependencies)
- [Functions](#functions)
- [generateAuthSig](#generateauthsig)
- [getStoredAuthSig](#getstoredauthsig)
- [logout](#logout)
- [Usage](#usage)
## Dependencies
- `@lit-protocol/lit-node-client`: Used to interact with the Lit Protocol and sign authentication messages.
- `@lit-protocol/constants`: Provides constants used in this module, specifically `LOCAL_STORAGE_KEYS.AUTH_SIGNATURE` for local storage key.
## Functions
### generateAuthSig
**Description:**
This asynchronous function initiates the signing of an authentication message using MetaMask and stores the signed message (AuthSig) in the browser's local storage.
**Returns:**
An `authSig` object containing the signed message if successful.
**Throws:**
An error with a descriptive message if the signing process fails.
### getStoredAuthSig
**Description:**
Retrieves the stored AuthSig from the browser's local storage.
**Returns:**
A parsed `authSig` object if found, or `null` if not.
### logout
**Description:**
Clears the stored AuthSig from the browser's local storage.
**Returns:**
`void`
## Usage
To use the `authWithMetamask.ts` module in a Svelte component:
```svelte
<script>
import { onMount } from 'svelte';
import {
generateAuthSig,
getStoredAuthSig,
logout
} from '$lib/services/authWithMetamask/authWithMetamask';
let authSig = null;
let error = null;
async function handleAuth() {
try {
authSig = await generateAuthSig();
} catch (err) {
error = err.message;
}
}
function handleLogout() {
logout();
authSig = null;
}
onMount(() => {
authSig = getStoredAuthSig();
});
</script>
```

View File

@ -0,0 +1,61 @@
import { checkAndSignAuthMessage } from '@lit-protocol/lit-node-client';
import { LOCAL_STORAGE_KEYS } from '@lit-protocol/constants';
function createMessage({ text, sender, type }: { text: string; sender: string; type: string }) {
console.log(`[${type}] - ${sender} - ${text}`);
}
export async function generateAuthSig(): Promise<any> {
createMessage({
text: "Attempting to generate AuthSig using MetaMask.",
sender: '$lib/services/authWithMetamask/authWithMetamask.ts',
type: 'SYSTEM'
});
try {
const authSig = await checkAndSignAuthMessage({ chain: 'xdai' });
createMessage({
text: "AuthSig generated and storing in local storage.",
sender: '$lib/services/authWithMetamask/authWithMetamask.ts',
type: 'SYSTEM'
});
localStorage.setItem(LOCAL_STORAGE_KEYS.AUTH_SIGNATURE, JSON.stringify(authSig));
return authSig;
} catch (err) {
console.error(err);
createMessage({
text: `Failed to sign auth message: ${err.message}`,
sender: '$lib/services/authWithMetamask/authWithMetamask.ts',
type: 'ERROR'
});
throw new Error(`Failed to sign auth message: ${err.message}`);
}
}
export function getStoredAuthSig(): any | null {
createMessage({
text: "Fetching stored AuthSig from local storage.",
sender: '$lib/services/authWithMetamask/authWithMetamask.ts',
type: 'SYSTEM'
});
const storedAuthSig = localStorage.getItem(LOCAL_STORAGE_KEYS.AUTH_SIGNATURE);
if (storedAuthSig) {
return JSON.parse(storedAuthSig);
}
return null;
}
export function logout(): void {
createMessage({
text: "Clearing AuthSig from local storage.",
sender: '$lib/services/authWithMetamask/authWithMetamask.ts',
type: 'SYSTEM'
});
localStorage.removeItem(LOCAL_STORAGE_KEYS.AUTH_SIGNATURE);
}

View File

@ -4,7 +4,7 @@
let componentsData = { let componentsData = {
layout: ` layout: `
grid-template-areas: grid-template-areas:
"app", "login",
"main" "main"
"footer"; "footer";
grid-template-rows: 150px 1fr auto; grid-template-rows: 150px 1fr auto;
@ -12,9 +12,9 @@
children: [ children: [
{ {
id: 1, id: 1,
componentName: 'GoogleAuth', componentName: 'Login',
props: {}, props: {},
slot: 'app' slot: 'login'
}, },
{ {
id: 2, id: 2,