Compare commits

..

No commits in common. "35b31675091cf50b9a7d592704709ba02fdf579c" and "c13047e28134f7567bb23f09a9052f4e38d0da98" have entirely different histories.

19 changed files with 281 additions and 190 deletions

View File

@ -59,7 +59,7 @@ configureWunderGraphApplication({
tokenBased: { tokenBased: {
providers: [ providers: [
{ {
userInfoEndpoint: 'http://localhost:3000/jwt/wunderauth', userInfoEndpoint: 'http://localhost:3000/api/auth/session',
}, },
], ],
}, },

View File

@ -1,25 +0,0 @@
<script>
let accs = [
// Mock data
{ id: 1, name: "ACC 1" },
{ id: 2, name: "ACC 2" },
{ id: 3, name: "ACC 3" },
];
function createNewACC() {
// Logic for creating a new ACC goes here
console.log("Create new ACC button clicked");
}
</script>
<div class="p-12">
<h1>Access Control Conditions</h1>
{#each accs as acc (acc.id)}
<p>{acc.name}</p>
{/each}
<button on:click={createNewACC}>Create New ACC</button>
</div>
<style>
/* Add your Tailwind CSS classes here */
</style>

View File

@ -1,17 +0,0 @@
<script>
import { createJWT } from "$lib/services/createJWT";
import Cookies from "js-cookie";
let jwt = "";
async function handleCreateClick() {
jwt = await createJWT();
Cookies.set("token", jwt);
}
</script>
<div class="p-12">
<button on:click={handleCreateClick} class="btn variant-filled-primary"
>Wundergraph Login</button
>
</div>

27
src/lib/Login.svelte Normal file
View File

@ -0,0 +1,27 @@
<script>
import Cookies from "js-cookie";
async function login() {
const response = await fetch("/api/auth", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Sam",
loggedIn: true,
roles: ["admin"],
}),
});
if (!response.ok) {
alert("Login failed");
} else {
let { token } = await response.json();
Cookies.set("token", token);
alert(`Login Success: ${token}`);
console.log(token);
}
}
</script>
<button on:click={login}>Login</button>

120
src/lib/SignerOLD.svelte Normal file
View File

@ -0,0 +1,120 @@
<!-- SignVerifyMessage.svelte -->
<script lang="ts">
import { ethers } from "ethers";
import { onMount } from "svelte";
import { signRequest, signedMessages } from "./stores.js";
let messageToSign = {};
let currentPKP;
let sessionSigs;
let status = "";
let litNodeClient;
let messageSignature;
onMount(async () => {
litNodeClient = new LitNodeClient({ litNetwork: "serrano" });
await litNodeClient.connect();
const sessionSigsLocalStorage = localStorage.getItem("google-session");
const currentPKPLocalStorage = localStorage.getItem("current-pkp");
if (sessionSigsLocalStorage && currentPKPLocalStorage) {
sessionSigs = JSON.parse(sessionSigsLocalStorage);
currentPKP = JSON.parse(currentPKPLocalStorage);
}
});
async function signMessageWithPKP() {
const userConfirmed = window.confirm(
"Do you want to sign the following message?\n\n" +
JSON.stringify(messageToSign, null, 2)
);
if (!userConfirmed) {
status = "User did not allow to sign the message.";
dispatch("status", status);
return;
}
try {
// Create a specific JSON object
const jsonString = JSON.stringify(messageToSign);
// Convert the JSON string to an array of character codes
const toSign = ethers.getBytes(ethers.hashMessage(jsonString));
const litActionCode = `
const go = async () => {
const sigShare = await LitActions.signEcdsa({ toSign, publicKey, sigName });
};
go();
`;
// Sign message
const results = await litNodeClient.executeJs({
code: litActionCode,
sessionSigs: sessionSigs,
jsParams: {
toSign: toSign,
publicKey: currentPKP.publicKey,
sigName: "sig1",
},
});
// Get signature
const result = results.signatures["sig1"];
messageSignature = ethers.Signature.from({
r: "0x" + result.r,
s: "0x" + result.s,
v: result.recid,
});
signedMessages.update((messages) => [
...messages,
{ json: messageToSign, signature: messageSignature },
]);
// verify();
} catch (err) {
console.error(err);
}
}
async function verify() {
const response = await fetch("/api/verify", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
messageToSign,
messageSignature,
currentPKP,
}),
});
if (!response.ok) {
alert("verify failed");
} else {
let json = await response.json();
alert(json.verified ? "Signature valid" : "! Signature NOT valid !");
}
}
signRequest.subscribe(({ json }) => {
if (messageToSign && Object.keys(json).length > 0) {
signRequest.set({ json: {} });
messageToSign = json;
signMessageWithPKP(json);
}
});
</script>
{#if status}
<div class="mt-4 text-center">
<p>Status: {status}</p>
</div>
{/if}
{#if messageSignature}
<div class="mt-4 text-center">
<p>Signature</p>
<pre>{JSON.stringify(messageSignature)}</pre>
</div>
<button on:click={verify}>Verify</button><br />
{/if}

27
src/lib/User.svelte Normal file
View File

@ -0,0 +1,27 @@
<script>
import { onMount } from "svelte";
import Cookies from "js-cookie";
let user = null;
onMount(async () => {
const token = Cookies.get("token");
const response = await fetch("/api/auth/session", {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (response.ok) {
user = await response.json();
} else {
console.error("Failed to fetch user data");
}
});
</script>
{#if user}
<p>Welcome, {user.name}!</p>
<p>Your roles: {user.roles.join(", ")}</p>
{:else}
<p>Loading...</p>
{/if}

View File

@ -4,6 +4,7 @@
import { onMount } from "svelte"; import { onMount } from "svelte";
import Icon from "@iconify/svelte"; import Icon from "@iconify/svelte";
import { walletState, signRequest } from "./stores"; import { walletState, signRequest } from "./stores";
import { import {
signInWithGoogle, signInWithGoogle,
startSignIn as startSignInService, startSignIn as startSignInService,
@ -59,10 +60,10 @@
} }
</script> </script>
<!-- ... existing markup ... -->
{#if $state.matches("sessionAvailable") || $state.matches("creatingSession") || $state.matches("signIn")} {#if $state.matches("sessionAvailable") || $state.matches("creatingSession") || $state.matches("signIn")}
{#if $state.matches("signIn")} {#if $state.matches("signIn")}
<div class="flex items-center justify-center pb-4"> <div class="w-1/3">
<div class="flex flex-col items-center w-1/3">
<button <button
on:click={startSignIn} on:click={startSignIn}
class="flex items-center justify-center w-full py-2 text-white bg-blue-500 rounded hover:bg-blue-700" class="flex items-center justify-center w-full py-2 text-white bg-blue-500 rounded hover:bg-blue-700"
@ -71,10 +72,9 @@
<span>Sign in with Google</span> <span>Sign in with Google</span>
</button> </button>
</div> </div>
</div>
{:else if $state.context.pkps} {:else if $state.context.pkps}
<div <div
class="flex flex-col items-center p-3 space-y-4 bg-white bg-opacity-75 rounded-t-lg shadow-md" class="fixed bottom-0 left-0 right-0 flex flex-col items-center p-3 space-y-4 bg-white bg-opacity-75 rounded-t-lg shadow-md"
> >
<div class="flex items-center justify-between w-full space-x-4"> <div class="flex items-center justify-between w-full space-x-4">
<div class="flex items-center space-x-2"> <div class="flex items-center space-x-2">

View File

@ -11,7 +11,7 @@ export async function createLitSession(
pkpPublicKey, pkpPublicKey,
authMethod, authMethod,
sessionSigsParams: { sessionSigsParams: {
chain: 'xdai', chain: 'ethereum',
resourceAbilityRequests: [ resourceAbilityRequests: [
{ {
resource: litResource, resource: litResource,

View File

@ -2,6 +2,7 @@
import { createMachine, assign } from 'xstate'; import { createMachine, assign } from 'xstate';
import { signInWithGoogle } from '../services/signInWithGoogle'; import { signInWithGoogle } from '../services/signInWithGoogle';
import { createSession } from '../services/createSession'; import { createSession } from '../services/createSession';
import { goto } from '$app/navigation';
const walletMachine = createMachine({ const walletMachine = createMachine({
id: 'wallet', id: 'wallet',
@ -69,6 +70,7 @@ const walletMachine = createMachine({
pkps: (_, event) => event.data.pkps, pkps: (_, event) => event.data.pkps,
sessionSigs: (_, event) => event.data.sessionSigs, sessionSigs: (_, event) => event.data.sessionSigs,
}), }),
(context) => console.log('Context after creating session:', context), // Debug log
], ],
}, },
onError: { onError: {

View File

@ -1,55 +0,0 @@
import { LitNodeClient } from "@lit-protocol/lit-node-client";
import type { AccsEVMParams } from "@lit-protocol/types";
export const createJWT = async () => {
const litNodeClient = new LitNodeClient({ litNetwork: "serrano" });
await litNodeClient.connect();
const me = JSON.parse(localStorage.getItem('me'));
if (!me || !me.sessionSigs) {
throw new Error('No sessionSigs found in local storage');
}
const resourceId = {
baseUrl: "https://localhost:3000/",
path: "wunderauth",
orgId: "°",
role: "owner",
extraData: ""
}
const sessionSigs = me.sessionSigs;
const unifiedAccessControlConditions: AccsEVMParams[] = [
{
conditionType: 'evmBasic',
contractAddress: '',
standardContractType: '',
chain: 'xdai',
method: 'eth_getBalance',
parameters: [':userAddress', 'latest'],
returnValueTest: {
comparator: '>=',
value: '1000000000000',
},
},
];
await litNodeClient.saveSigningCondition({
unifiedAccessControlConditions,
sessionSigs,
resourceId,
chain: "litSessionSign",
});
const jwt = await litNodeClient.getSignedToken({
unifiedAccessControlConditions,
chain: 'xdai',
sessionSigs,
resourceId
});
return jwt;
};

View File

@ -12,14 +12,19 @@ export const createSession = async (provider, authMethod, pkps: IRelayPKP[]) =>
currentPKP = pkps[0]; currentPKP = pkps[0];
} }
console.log('Current PKP:', currentPKP); // Debug log
const sessionSigs = await createLitSession( const sessionSigs = await createLitSession(
provider, provider,
currentPKP.publicKey, currentPKP.publicKey,
authMethod, authMethod
); );
console.log('Session Signatures:', sessionSigs); // Debug log
return { pkps, sessionSigs }; return { pkps, sessionSigs };
} catch (error) { } catch (error) {
console.error('Error in createSession:', error); // Debug log
throw new Error(`Failed to create session: ${error.message}`); throw new Error(`Failed to create session: ${error.message}`);
} }
}; };

View File

@ -31,7 +31,6 @@
}); });
if (token) { if (token) {
console.log("layout jwt token: " + token);
client.setAuthorizationToken(token); client.setAuthorizationToken(token);
} }
</script> </script>
@ -45,24 +44,15 @@
> >
<div <div
class="grid h-screen bg-center bg-cover grid-rows-layout" class="flex items-center justify-center h-screen bg-center bg-cover"
style="background-image: url('lake.jpeg');" style="background-image: url('lake.jpeg');"
> >
<QueryClientProvider client={data.queryClient}> <QueryClientProvider client={data.queryClient}>
<div class="w-full h-full p-6 overflow-hidden">
<div class="w-full h-full overflow-hidden bg-white rounded-xl">
<slot />
</div>
</div>
</QueryClientProvider>
<div class="row-start-2 row-end-3">
<Wallet /> <Wallet />
</div> <!-- <GoogleSession />
<div class="text-lg bg-white">{activeSession}</div> -->
<slot />
<!-- {#if activeSession}active {:else} expired {/if}
<GooglePKP /> -->
</QueryClientProvider>
</div> </div>
<style>
.grid-rows-layout {
grid-template-rows: 1fr auto;
}
</style>

View File

@ -9,23 +9,6 @@
// export let data: PageData; // export let data: PageData;
</script> </script>
<section
class="flex flex-col items-center justify-center min-h-screen p-8 space-y-8 text-white bg-green-500"
>
<h2 class="text-4xl font-bold text-center">
Unleash Your Full Potential and Transform Your Life <br />
</h2>
<h1 class="text-6xl font-bold text-center">Become a Vision Architect</h1>
<p class="text-xl text-center">
We are committed to creating an amazing life experience for every human on
the planet. Our mission is to foster a world where everyone can thrive in
abundance, excitement, and creativity. We envision a sustainable green
planet and future cities where innovation and nature coexist harmoniously.
</p>
<h3 class="text-2xl">Stand Up NOW, Break Free And Follow Your Passions</h3>
</section>
<!-- <div class="bg-white">myPKP {data.myPKP}</div> --> <!-- <div class="bg-white">myPKP {data.myPKP}</div> -->
<!-- <button on:click={trigger}>Sign Request</button> --> <!-- <button on:click={trigger}>Sign Request</button> -->

View File

@ -0,0 +1,13 @@
import jwt from 'jsonwebtoken';
import { error } from '@sveltejs/kit';
const secretKey = process.env.JWT_KEY;
export async function POST({ request }) {
const user = await request.json();
const token = jwt.sign(user, secretKey);
if (!token) {
throw error(400, 'No token created.');
}
return new Response(JSON.stringify({ token }), { status: 200 });
}

View File

@ -0,0 +1,24 @@
// src/routes/api/session/+server.ts
import jwt from 'jsonwebtoken';
import { error } from '@sveltejs/kit';
const secretKey = process.env.JWT_KEY;
export async function GET({ request }) {
const authHeader = request.headers.get('Authorization');
if (!authHeader) {
throw error(401, 'No Authorization header provided.');
}
const token = authHeader.split(' ')[1];
if (!token) {
throw error(401, 'No token provided.');
}
try {
const user = jwt.verify(token, secretKey);
return new Response(JSON.stringify(user), { status: 200 });
} catch (err) {
throw error(401, 'Invalid token.');
}
}

View File

@ -0,0 +1,13 @@
import jwt from 'jsonwebtoken';
import { error } from '@sveltejs/kit';
const secretKey = process.env.JWT_KEY;
export async function POST({ request }) {
const user = await request.json();
const token = jwt.sign(user, secretKey);
if (!token) {
throw error(400, 'No token created.');
}
return new Response(JSON.stringify({ token }), { status: 200 });
}

View File

@ -0,0 +1,15 @@
import { json } from '@sveltejs/kit';
import { ethers } from 'ethers';
export async function POST({ request }) {
const { messageToSign, messageSignature, currentPKP } = await request.json();
// Verify the signature
const jsonString = JSON.stringify(messageToSign);
const recoveredAddr = ethers.verifyMessage(jsonString, messageSignature);
// Check if the address associated with the signature is the same as the current PKP
const verified = currentPKP.ethAddress.toLowerCase() === recoveredAddr.toLowerCase();
return json({ verified }, { status: 200 });
}

View File

@ -1,33 +0,0 @@
import { verifyJwt } from "@lit-protocol/lit-node-client";
import { error } from '@sveltejs/kit';
export async function GET({ request }) {
const authHeader = request.headers.get('Authorization');
if (!authHeader) {
throw error(401, 'No Authorization header provided.');
}
const token = authHeader.split(' ')[1];
if (!token) {
throw error(401, 'No jwt provided.');
}
try {
const { payload } = await verifyJwt({ jwt: token });
if (
payload.baseUrl !== "https://localhost:3000/" ||
payload.path !== "wunderauth" ||
payload.orgId !== "°" ||
payload.role !== "owner" ||
payload.extraData !== ""
) {
console.log("JWT payload not matching");
throw error(401, "JWT payload not macting")
}
console.log(payload);
return new Response(JSON.stringify(payload), { status: 200 });
} catch (err) {
console.log("JWT error");
throw error(401, "JWT payload not machting")
}
}

View File

@ -1,16 +1,19 @@
<script lang="ts"> <script lang="ts">
import { createQuery } from "../../lib/wundergraph"; import { createQuery } from "../../lib/wundergraph";
import JWT from "$lib/JWT.svelte"; import Login from "$lib/Login.svelte";
import User from "$lib/User.svelte";
const projectsQuery = createQuery({ const projectsQuery = createQuery({
operationName: "Projects", operationName: "Projects",
}); });
</script> </script>
<div class="w-full h-full overflow-y-auto"> <Login />
<JWT /> <User />
<div class="w-full h-full results"> <br />
Projects
<div class="results">
{#if $projectsQuery.isLoading} {#if $projectsQuery.isLoading}
<p>Loading...</p> <p>Loading...</p>
{:else if $projectsQuery.error} {:else if $projectsQuery.error}
@ -18,5 +21,4 @@
{:else} {:else}
<pre>{JSON.stringify($projectsQuery.data, null, 2)}</pre> <pre>{JSON.stringify($projectsQuery.data, null, 2)}</pre>
{/if} {/if}
</div>
</div> </div>