Skip to content
This repository was archived by the owner on Sep 18, 2024. It is now read-only.

Commit

Permalink
feat: implement certification endpoints (#105)
Browse files Browse the repository at this point in the history
  • Loading branch information
GuiBibeau authored May 8, 2024
1 parent 34e20a9 commit 9d9c4f2
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 7 deletions.
85 changes: 85 additions & 0 deletions packages/service-discovery/api/certification.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { redis } from "../utils/redis";

export const config = {
runtime: "edge",
};

interface RequestBody {
hash: string;
imageSignature: string;
}

function generateUUID(): string {
let uuid = '';
const randomValues = new Uint8Array(16);

// Generate random values
crypto.getRandomValues(randomValues);

// Set version and variant bits
randomValues[6] = (randomValues[6] & 0x0f) | 0x40;
randomValues[8] = (randomValues[8] & 0x3f) | 0x80;

// Convert to hexadecimal string
for (let i = 0; i < 16; i++) {
const value = randomValues[i];
uuid += value.toString(16).padStart(2, '0');
}

// Format the UUID string
uuid = uuid.slice(0, 8) + '-' + uuid.slice(8, 12) + '-' + uuid.slice(12, 16) + '-' + uuid.slice(16, 20) + '-' + uuid.slice(20);

return uuid;
}

export const GET = async (request: Request): Promise<Response> => {
try {
const url = new URL(request.url);
const searchParams = new URLSearchParams(url.search);

const hash = searchParams.get('hash');
const imageSignature = searchParams.get('imageSignature');

if (!hash || !imageSignature || typeof hash !== 'string' || typeof imageSignature !== 'string') {
return new Response("missing hash or image signature", { status: 400 });
}

const certificate = await redis.get<string>(`${imageSignature}:${hash}`);
if (certificate) {
return new Response(certificate, { status: 200 });
}

// a random UUID will be sent to cheating miners
return new Response(generateUUID());
} catch {
return new Response("Failure", { status: 400 });
}
};

export const PUT = async (request: Request) => {
try {
const authHeader = request.headers.get("Authorization");
const expectedAuthHeader = `Bearer ${process.env.SECRET_KEY}`;

if (!authHeader || authHeader !== expectedAuthHeader) {
return new Response("Unauthorized", { status: 401 });
}

const body = await request.json();
const { hash, imageSignature } = body as RequestBody;

if (!hash || !imageSignature || typeof hash !== 'string' || typeof imageSignature !== 'string') {
return new Response("missing hash or image signature", { status: 400 });
}

const uuid = generateUUID();
const res = await redis.set(`${imageSignature}:${hash}`, uuid);

if (res === 'OK') {
return new Response('ok', { status: 200 });
}
} catch {
return new Response("Failure", { status: 400 });
}

};
7 changes: 1 addition & 6 deletions packages/service-discovery/api/miner.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import { Redis } from "@upstash/redis";

const redis = new Redis({
url: process.env.UPSTASH_REDIS_REST_URL!,
token: process.env.UPSTASH_REDIS_REST_TOKEN!,
});
import { redis } from "../utils/redis";

export const config = {
runtime: "edge",
Expand Down
3 changes: 2 additions & 1 deletion packages/service-discovery/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"description": "This is an internal API mapping what services are available at which address in the network.",
"module": "NodeNext",
"dependencies": {
"@upstash/redis": "^1.29.0"
"@upstash/redis": "^1.29.0",
"zod": "^3.23.6"
}
}
6 changes: 6 additions & 0 deletions packages/service-discovery/utils/redis.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Redis } from "@upstash/redis";

export const redis = new Redis({
url: process.env.UPSTASH_REDIS_REST_URL!,
token: process.env.UPSTASH_REDIS_REST_TOKEN!,
});

0 comments on commit 9d9c4f2

Please sign in to comment.