wired up JWT with wundergraph auth
This commit is contained in:
parent
8a4ec6cc73
commit
53e68aa362
@ -59,7 +59,7 @@ configureWunderGraphApplication({
|
|||||||
tokenBased: {
|
tokenBased: {
|
||||||
providers: [
|
providers: [
|
||||||
{
|
{
|
||||||
userInfoEndpoint: 'http://localhost:3000/api/auth/session',
|
userInfoEndpoint: 'http://localhost:3000/api/wunderauth',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
25
src/lib/ACCs.svelte
Normal file
25
src/lib/ACCs.svelte
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<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>
|
@ -1,16 +1,17 @@
|
|||||||
<script>
|
<script>
|
||||||
import { createJwt } from "$lib/services/createJwt";
|
import { createJWT } from "$lib/services/createJWT";
|
||||||
|
import Cookies from "js-cookie";
|
||||||
|
|
||||||
let jwt = "";
|
let jwt = "";
|
||||||
|
|
||||||
async function handleClick() {
|
async function handleCreateClick() {
|
||||||
jwt = await createJwt();
|
jwt = await createJWT();
|
||||||
|
Cookies.set("token", jwt);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="p-12">
|
<div class="p-12">
|
||||||
<button on:click={handleClick} class="btn variant-filled-primary"
|
<button on:click={handleCreateClick} class="btn variant-filled-primary"
|
||||||
>Create JWT</button
|
>Create JWT</button
|
||||||
>
|
>
|
||||||
<p class="text-xs">{jwt}</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
<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} class="btn variant-filled-primary">Login</button>
|
|
@ -1,7 +1,7 @@
|
|||||||
import { LitNodeClient } from "@lit-protocol/lit-node-client";
|
import { LitNodeClient } from "@lit-protocol/lit-node-client";
|
||||||
import type { AccsEVMParams } from "@lit-protocol/types";
|
import type { AccsEVMParams } from "@lit-protocol/types";
|
||||||
|
|
||||||
export const createJwt = async () => {
|
export const createJWT = async () => {
|
||||||
|
|
||||||
const litNodeClient = new LitNodeClient({ litNetwork: "serrano" });
|
const litNodeClient = new LitNodeClient({ litNetwork: "serrano" });
|
||||||
await litNodeClient.connect();
|
await litNodeClient.connect();
|
||||||
@ -13,10 +13,10 @@ export const createJwt = async () => {
|
|||||||
|
|
||||||
const resourceId = {
|
const resourceId = {
|
||||||
baseUrl: "https://localhost:3000/",
|
baseUrl: "https://localhost:3000/",
|
||||||
path: "/wunderauth",
|
path: "wunderauth",
|
||||||
orgId: "°",
|
orgId: "°",
|
||||||
role: "admin",
|
role: "owner",
|
||||||
extraData: "{loggedIn: true}"
|
extraData: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
const sessionSigs = me.sessionSigs;
|
const sessionSigs = me.sessionSigs;
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (token) {
|
if (token) {
|
||||||
|
console.log("layout jwt token: " + token);
|
||||||
client.setAuthorizationToken(token);
|
client.setAuthorizationToken(token);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
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 });
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
// 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.');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
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 });
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
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 });
|
|
||||||
}
|
|
33
src/routes/api/wunderauth/+server.ts
Normal file
33
src/routes/api/wunderauth/+server.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
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")
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import AcCs from "$lib/ACCs.svelte";
|
||||||
import JWT from "$lib/JWT.svelte";
|
import JWT from "$lib/JWT.svelte";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<JWT />
|
<JWT />
|
||||||
|
<!-- <AcCs /> -->
|
||||||
|
@ -1,24 +1,22 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createQuery } from "../../lib/wundergraph";
|
import { createQuery } from "../../lib/wundergraph";
|
||||||
import Login from "$lib/Login.svelte";
|
import JWT from "$lib/JWT.svelte";
|
||||||
import User from "$lib/User.svelte";
|
|
||||||
|
|
||||||
const projectsQuery = createQuery({
|
const projectsQuery = createQuery({
|
||||||
operationName: "Projects",
|
operationName: "Projects",
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Login />
|
<div class="w-full h-full overflow-y-auto">
|
||||||
<User />
|
<JWT />
|
||||||
|
|
||||||
<br />
|
<div class="w-full h-full results">
|
||||||
Projects
|
{#if $projectsQuery.isLoading}
|
||||||
<div class="results">
|
<p>Loading...</p>
|
||||||
{#if $projectsQuery.isLoading}
|
{:else if $projectsQuery.error}
|
||||||
<p>Loading...</p>
|
<pre>Error: {JSON.stringify($projectsQuery.error, null, 2)}</pre>
|
||||||
{:else if $projectsQuery.error}
|
{:else}
|
||||||
<pre>Error: {JSON.stringify($projectsQuery.error, null, 2)}</pre>
|
<pre>{JSON.stringify($projectsQuery.data, null, 2)}</pre>
|
||||||
{:else}
|
{/if}
|
||||||
<pre>{JSON.stringify($projectsQuery.data, null, 2)}</pre>
|
</div>
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user