Skip to content

Commit

Permalink
feat: added endpoint to aggregate the total number of verifications (…
Browse files Browse the repository at this point in the history
…distinct nullifier_hashes) (#58)

Co-authored-by: Paolo D'Amico <[email protected]>
  • Loading branch information
maxpetretta and paolodamico authored Feb 1, 2023
1 parent a6edaed commit ae525a0
Show file tree
Hide file tree
Showing 9 changed files with 52 additions and 8 deletions.
1 change: 1 addition & 0 deletions hasura/metadata/backend_configs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ insert_permissions:
- nullifier_type
backend_only: false
select_permissions:
- role: analytics
permission:
columns:
- created_at
- nullifier_hash
filter: {}
allow_aggregations: true
- role: api_key
permission:
columns:
Expand All @@ -41,6 +48,7 @@ select_permissions:
- created_at
- nullifier_hash
filter: {}
allow_aggregations: true
- role: user
permission:
columns:
Expand Down
1 change: 1 addition & 0 deletions hasura/metadata/metrics_config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
1 change: 1 addition & 0 deletions hasura/metadata/opentelemetry.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
4 changes: 4 additions & 0 deletions infrastructure/src/web/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ export class Web extends MultiEnvRootStack {
props.secretsSecret,
'GENERAL_SECRET_KEY'
),
ANALYTICS_API_KEY: cdk.aws_ecs.Secret.fromSecretsManager(
props.secretsSecret,
'ANALYTICS_API_KEY'
),
},
logDriver: cdk.aws_ecs.LogDrivers.firelens({
options: {
Expand Down
5 changes: 4 additions & 1 deletion web/.env.test
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ NEXT_PUBLIC_POSTHOG_ENABLE_ON_DEV=0
CONSUMER_BACKEND_JWT=consumer_backend_jwt_test_key
CONSTUMER_BACKEND_JWT_STAGING=staging_consumer_backend_jwt_test_key

# Analytics service
ANALYTICS_API_KEY=analytics_1234

# Alchemy
ALCHEMY_API_KEY=alchemy_test_key

Expand All @@ -23,7 +26,7 @@ TWILIO_ACCOUNT_SID=twilio_test_account_sid
TWILIO_AUTH_TOKEN=twilio_test_auth_token
TWILIO_VERIFY_SERVICE=twilio_test_verify_service

# Phone singal v1 (alpha)
# Phone signal v1 (alpha)
PHONE_NULLIFIER_KEY=unsafe_secret_test
PHONE_NULLIFIER_SIGNING_KEY=0x949012a42abaa28ab54d7d4a98444d3eb9c58e6e40bf339602b4b4069f8b003d

Expand Down
2 changes: 1 addition & 1 deletion web/api-graphql.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
ApolloClient,
InMemoryCache,
createHttpLink,
InMemoryCache,
NormalizedCacheObject,
} from "@apollo/client";
import { setContext } from "@apollo/client/link/context";
Expand Down
26 changes: 21 additions & 5 deletions web/api-utils.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/**
* Contains shared utilities that are reused for the Next.js API (backend)
*/
import { JwtConfig } from "./types";
import * as jose from "jose";
import crypto, { randomUUID } from "crypto";
import { NextApiRequest, NextApiResponse } from "next";
import { errorValidation } from "errors";
import { defaultAbiCoder as abi } from "@ethersproject/abi";
import { utils as widgetUtils } from "@worldcoin/id";
import crypto, { randomUUID } from "crypto";
import { errorValidation } from "errors";
import * as jose from "jose";
import { NextApiRequest, NextApiResponse } from "next";
import { JwtConfig } from "./types";

export const STAGING_RPC = "https://polygon-mumbai.g.alchemy.com";
export const PRODUCTION_RPC = "https://polygon-mainnet.g.alchemy.com";
Expand Down Expand Up @@ -128,6 +128,22 @@ export const generateAPIKeyJWT = async (team_id: string): Promise<string> => {
return await _generateJWT(payload);
};

/**
* Generates a JWT for the analytics service.
* @returns
*/
export const generateAnalyticsJWT = async (): Promise<string> => {
const payload = {
sub: "analytics_service",
"https://hasura.io/jwt/claims": {
"x-hasura-allowed-roles": ["analytics"],
"x-hasura-default-role": "analytics",
},
};

return await _generateJWT(payload);
};

/**
* Generates a secure password hash to store in the DB
* @param rawPassword
Expand Down
12 changes: 11 additions & 1 deletion web/pages/api/v1/graphql.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { gql } from "@apollo/client";
import { getAPIServiceClient } from "api-graphql";
import { generateAPIKeyJWT } from "api-utils";
import { generateAnalyticsJWT, generateAPIKeyJWT } from "api-utils";
import { errorUnauthenticated } from "errors";
import { NextApiRequest, NextApiResponse } from "next";
import getConfig from "next/config";
Expand Down Expand Up @@ -55,6 +55,16 @@ export default async function handleGraphQL(
);
}

// Check if request is from the analytics service
if (authorization?.startsWith("analytics_")) {
if (authorization !== process.env.ANALYTICS_API_KEY) {
return errorUnauthenticated("Invalid analytics API key", res);
}

headers.delete("Authorization");
headers.append("Authorization", `Bearer ${await generateAnalyticsJWT()}`);
}

let body: string | undefined = undefined;
try {
body = JSON.stringify(req.body);
Expand Down

0 comments on commit ae525a0

Please sign in to comment.