Skip to content

Commit

Permalink
feat: zupass feed
Browse files Browse the repository at this point in the history
Signed-off-by: Marin Petrunic <[email protected]>
  • Loading branch information
mpetrunic committed May 24, 2024
1 parent 320b9a0 commit 761c7b8
Show file tree
Hide file tree
Showing 10 changed files with 2,309 additions and 67 deletions.
4 changes: 3 additions & 1 deletion .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ enableGlobalCache: true

nmMode: hardlinks-local

nodeLinker: node-modules
nodeLinker: node-modules

nmHoistingLimits: workspaces
1 change: 1 addition & 0 deletions packages/zu-git-proofs-server/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SERVER_PRIVATE_KEY=b30fbb9af7dd8b265d00f588c42ba98d1ebcbcfdc88c1a58ba9f79b8e0aeeff0
3 changes: 2 additions & 1 deletion packages/zu-git-proofs-server/.env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
PORT=3000
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
GITHUB_CLIENT_SECRET=
SERVER_PRIVATE_KEY=""
8 changes: 7 additions & 1 deletion packages/zu-git-proofs-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
"dependencies": {
"@fastify/cors": "^9.0.1",
"@fastify/env": "^4.3.0",
"fastify": "^4.27.0"
"@pcd/eddsa-pcd": "^0.6.0",
"@pcd/email-pcd": "^0.6.0",
"@pcd/message-pcd": "^0.1.0",
"@pcd/passport-interface": "^0.11.0",
"@pcd/pcd-collection": "^0.11.0",
"fastify": "^4.27.0",
"react": "^18.3.1"
},
"devDependencies": {
"@tsconfig/node20": "^20.1.4",
Expand Down
14 changes: 12 additions & 2 deletions packages/zu-git-proofs-server/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,28 @@ import type { FastifyInstance } from "fastify";

const schema: FastifyEnvOptions["schema"] = {
type: 'object',
required: [ 'PORT' ],
required: [ 'SERVER_PRIVATE_KEY', 'GITHUB_CLIENT_ID', 'GITHUB_CLIENT_SECRET'],
properties: {
PORT: {
type: 'number',
default: 3000
},
SERVER_PRIVATE_KEY: {
type: 'string'
},
GITHUB_CLIENT_ID: {
type: 'string'
},
GITHUB_CLIENT_SECRET: {
type: 'string'
}
}
}

const envOptions: FastifyEnvOptions = {
schema,
dotenv: {
path: `${__dirname}/.env`,
path: `${__dirname}/../.env`,
debug: true
},
env: true
Expand All @@ -31,6 +40,7 @@ declare module 'fastify' {
PORT: number,
GITHUB_CLIENT_ID: string,
GITHUB_CLIENT_SECRET: string,
SERVER_PRIVATE_KEY: string
};
}
}
Expand Down
135 changes: 135 additions & 0 deletions packages/zu-git-proofs-server/src/feed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { MessagePCDPackage, type MessagePCD } from "@pcd/message-pcd";
import {
FeedHost,
PollFeedRequest,
PollFeedResponseValue,
verifyCredential,
} from "@pcd/passport-interface";
import {
DeleteFolderPermission,
PCDAction,
PCDActionType,
PCDPermissionType,
type ReplaceInFolderPermission
} from "@pcd/pcd-collection";
import { ArgumentTypeName, SerializedPCD } from "@pcd/pcd-types";
import { FastifyInstance, type FastifyPluginAsync } from "fastify";

const FOLDER = "Github Ranks"

export async function registerFeedService(server: FastifyInstance) {
const feedPlugin: FastifyPluginAsync = async (instance, opts) => {
const feedHost = new FeedHost(
[
{
feed: {
id: "999999999999",
name: "zu-git-rank",
description: "Feed containing your Git badges",
permissions: [
{
folder: FOLDER,
type: PCDPermissionType.DeleteFolder
} as DeleteFolderPermission,
{
folder: FOLDER,
type: PCDPermissionType.ReplaceInFolder
} as ReplaceInFolderPermission,
],
credentialRequest: {
signatureType: "sempahore-signature-pcd",
pcdType: "email-pcd"
}
},
handleRequest: async (
req: PollFeedRequest
): Promise<PollFeedResponseValue> => {
if (req.pcd === undefined) {
throw new Error(`Missing credential`);
}

const { emailClaim, emailSignatureClaim } = await verifyCredential(req.pcd);

if (emailClaim && emailSignatureClaim) {
// const verified =
// _.isEqual(emailSignatureClaim.publicKey, ZUPASS_PUBLIC_KEY);
return {
actions: await feedActionsForEmail(
server.config.SERVER_PRIVATE_KEY,
emailClaim.emailAddress
)
};
}
return { actions: [] };
}
}
],
"https://8c57-185-199-104-14.ngrok-free.app/feeds",
"Zu Git Proof Feed Server"
);
instance.decorate("feed", feedHost)
}
//@ts-expect-error
feedPlugin[Symbol.for('skip-override')] = true

await server.register(feedPlugin);
}

async function feedActionsForEmail(
privateKey: string,
emailAddress: string
): Promise<PCDAction[]> {

const actions = [];

// Clear out the folder
actions.push({
type: PCDActionType.DeleteFolder,
folder: FOLDER,
recursive: false
});

//TODO: check bacdge by email
actions.push({
type: PCDActionType.ReplaceInFolder,
folder: FOLDER,
pcds: [
await issueBadgePCD(privateKey, "Core Contributor")
]
});

return actions;
}

async function issueBadgePCD(
privateKey: string,
badge: string
): Promise<SerializedPCD<MessagePCD>> {

const pcd = await MessagePCDPackage.prove({
message: {
argumentType: ArgumentTypeName.Object,
value: {
displayName: "Github Rank",
mdBody: badge
}
},
privateKey: {
value: privateKey,
argumentType: ArgumentTypeName.String
},
id: {
value: undefined,
argumentType: ArgumentTypeName.String
}
});

return MessagePCDPackage.serialize(pcd);
}

declare module 'fastify' {
interface FastifyInstance {
feed: FeedHost
}
}

6 changes: 5 additions & 1 deletion packages/zu-git-proofs-server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ import fastify from 'fastify'
import {fastifyCors} from '@fastify/cors'
import { registerEnvPlugin } from './config'
import { registerRoutes } from './routes';
import { MessagePCDPackage } from "@pcd/message-pcd";
import { registerFeedService } from './feed';

const server = fastify();

async function init() {
await MessagePCDPackage.init?.({});
await registerEnvPlugin(server)
server.register(fastifyCors, {
await registerFeedService(server)
await server.register(fastifyCors, {
origin: true
})

Expand Down
9 changes: 7 additions & 2 deletions packages/zu-git-proofs-server/src/routes.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import type { FastifyInstance } from "fastify";
import { pingRoute } from "./routes/ping";
import { getEcdsaKey, getFeed, getFeeds, postFeeds } from "./routes/feeds";
import { authRoute } from "./routes/auth";

export async function registerRoutes(server: FastifyInstance) {
pingRoute(server);
authRoute(server);
pingRoute(server)
authRoute(server);
getFeeds(server)
getFeed(server)
postFeeds(server)
getEcdsaKey(server)
}
40 changes: 40 additions & 0 deletions packages/zu-git-proofs-server/src/routes/feeds.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { getEdDSAPublicKey } from "@pcd/eddsa-pcd";
import type { ListFeedsRequest, PollFeedRequest } from "@pcd/passport-interface";
import type { FastifyInstance } from "fastify";

export function getFeeds(server: FastifyInstance) {
server.get("/feeds", async (req, res) => {
const request = req.body as ListFeedsRequest;

return res.send(await server.feed.handleListFeedsRequest(request));
});
}

export function postFeeds(server: FastifyInstance) {
server.post("/feeds", async (req, res) => {
const request = req.body as PollFeedRequest;

return res.send(await server.feed.handleFeedRequest(request));
});
}

export function getFeed(server: FastifyInstance) {
server.get("/feeds/:feedId", async (req, res) => {
//@ts-expect-error
const feedId = req.params.feedId;
if (server.feed.hasFeedWithId(feedId)) {
const request = { feedId };
return res.send(await server.feed.handleListSingleFeedRequest(request));
} else {
return res.status(404).send("not found");
}
});
}

export function getEcdsaKey(server: FastifyInstance) {
server.get("/issue/eddsa-public-key", async (req, res) => {
return res.send(
await getEdDSAPublicKey(server.config.SERVER_PRIVATE_KEY)
);
});
}
Loading

0 comments on commit 761c7b8

Please sign in to comment.