Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

credential api #177

Open
wants to merge 4 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
-- CreateEnum
ALTER TYPE "AuthType" ADD VALUE 'OAUTH';

-- CreateEnum
CREATE TYPE "ValidationStatus" AS ENUM ('PENDING', 'COMPLETED', 'REJECTED', 'ABANDONED');

-- CreateEnum
CREATE TYPE "ResponseStatus" AS ENUM ('GREEN', 'YELLOW', 'GREY', 'RED');

-- AlterEnum
ALTER TYPE "AuthType" ADD VALUE 'OAUTH';

-- CreateTable
CREATE TABLE "Credential" (
"id" TEXT NOT NULL,
"context" JSONB NOT NULL,
"type" JSONB NOT NULL,
"issuer" JSONB NOT NULL,
"issuanceDate" TIMESTAMP(3) NOT NULL,
"expirationDate" TIMESTAMP(3),
"credentialSubject" JSONB NOT NULL,
"proof" JSONB NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,

CONSTRAINT "Credential_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "ClaimData" (
"id" SERIAL NOT NULL,
Expand Down Expand Up @@ -34,12 +50,15 @@ CREATE TABLE "Image" (
-- CreateTable
CREATE TABLE "CandidUserInfo" (
"id" SERIAL NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is interesting are we repurposing the candid workflow for validations? why edit this table?

"claimId" INTEGER,
"firstName" TEXT,
"lastName" TEXT,
"candid_entity_id" TEXT NOT NULL,
"email" TEXT NOT NULL,
"profileURL" TEXT NOT NULL,
"response" "ResponseStatus",

CONSTRAINT "CandidUserInfo_pkey" PRIMARY KEY ("id")
);
Expand All @@ -48,13 +67,15 @@ CREATE TABLE "CandidUserInfo" (
CREATE TABLE "ValidationRequest" (
"id" SERIAL NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"context" TEXT NOT NULL,
"validatorName" TEXT NOT NULL,
"validatorEmail" TEXT NOT NULL,
"claimId" INTEGER NOT NULL,
"validationClaimId" INTEGER,
"validationStatus" "ValidationStatus" NOT NULL DEFAULT 'PENDING',
"response" "ResponseStatus",
"response" "ResponseStatus" NOT NULL,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please do NOT do this allow null

"rating" INTEGER,
"validationDate" TIMESTAMP(3),
"statement" TEXT,

Expand All @@ -69,4 +90,3 @@ CREATE UNIQUE INDEX "CandidUserInfo_claimId_key" ON "CandidUserInfo"("claimId");

-- CreateIndex
CREATE UNIQUE INDEX "ValidationRequest_validationClaimId_key" ON "ValidationRequest"("validationClaimId");

3 changes: 3 additions & 0 deletions prisma/migrations/migration_lock.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"
14 changes: 14 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,20 @@ model Claim {
lastUpdatedAt DateTime @default(now())
}

model Credential {
id String @id @default(uuid())
context Json
type Json
issuer Json
issuanceDate DateTime
expirationDate DateTime?
credentialSubject Json
proof Json
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}


// this model is to connect between the claim and the data that supports it
// like the name of the claim, the image, the source, etc.
// maybe to add another atts in future like the urls that can be related to the claim, like the website, the social media, etc.
Expand Down
22 changes: 21 additions & 1 deletion src/controllers/api.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { ulid } from "ulid";
import { prisma } from "../db/prisma";
import { passToExpressErrorHandler, poormansNormalizer, turnFalsyPropsToUndefined } from "../utils";

import { ClaimDao, NodeDao } from "../dao/api.dao";
import { ClaimDao, NodeDao, CredentialDao } from "../dao/api.dao";
import { ProtectedMulterRequest } from "../middlewares/upload/multer.upload";
import { CreateClaimV2Dto, ImageDto } from "../middlewares/validators/claim.validator";
import { uploadImageToS3 } from "../utils/aws-s3";
Expand Down Expand Up @@ -49,6 +49,26 @@ export const claimPost = async (req: Request, res: Response, next: NextFunction)
return res.status(201).json({ claim, claimData, claimImages });
};

const credentialDao = new CredentialDao();
export const createCredential = async (req: Request, res: Response, next: NextFunction) => {
try {
const { context, id, type, issuer, issuanceDate, expirationDate, credentialSubject, proof } = req.body;
const credential = await credentialDao.createCredential({
context,
type,
issuer,
issuanceDate,
expirationDate,
credentialSubject,
proof,
});

return res.status(201).json({ message: "Credential created successfully!", credential });
} catch (err) {
passToExpressErrorHandler(err, next);
}
};

export async function createClaimV2(req: Request, res: Response, next: NextFunction) {
const _req = req as ProtectedMulterRequest;
const { userId } = _req;
Expand Down
1 change: 1 addition & 0 deletions src/controllers/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export {
claimPost,
createCredential,
claimsGet,
claimGraph,
claimsFeed,
Expand Down
14 changes: 14 additions & 0 deletions src/dao/api.dao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,20 @@ export class ClaimDao {
};
}

export class CredentialDao {
async createCredential(data: any) {
return await prisma.credential.create({
data,
});
}

async getCredentialById(id: string) {
return await prisma.credential.findUnique({
where: { id },
});
}
}

interface FeedEntry {
name: string;
thumbnail: string | null;
Expand Down
50 changes: 50 additions & 0 deletions src/middlewares/validators/claim.validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,56 @@ export const claimPostSchema = Joi.object({
}),
});

export const credentialPostSchema = Joi.object({
context: Joi.array().required(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey remove required from ALL of these please except the id

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note i think we might want to use the credential endpoint for OTHER types of credentials

Are we linking somewhere to the schema? its in the credential

"https://www.w3.org/2018/credentials/v1",
"https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json",

can we please REMOVE the Joi validation

and later we can add credential validation using the credential schema, which is the correct way to do it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we do NOT want to define the schema here in hardcode AND in the real schema itself

so lets remove here

id: Joi.string().required(),
type: Joi.array().required(),
issuer: Joi.object({
id: Joi.string().required(),
type: Joi.array().required(),
}).required(),
issuanceDate: Joi.date().required(),
expirationDate: Joi.date().optional(),
credentialSubject: Joi.object({
type: Joi.array().required(),
name: Joi.string().required(),
portfolio: Joi.array().items(
Joi.object({
"@type": Joi.string().required(),
name: Joi.string().required(),
url: Joi.string().uri().required(),
}),
),
evidenceLink: Joi.string().uri().required(),
evidenceDescription: Joi.string().required(),
duration: Joi.string().required(),
achievement: Joi.array()
.items(
Joi.object({
id: Joi.string().required(),
type: Joi.array().required(),
criteria: Joi.object({
narrative: Joi.string().required(),
}).required(),
description: Joi.string().required(),
name: Joi.string().required(),
image: Joi.object({
id: Joi.string().uri().required(),
type: Joi.string().required(),
}).required(),
}),
)
.required(),
}).required(),
proof: Joi.object({
type: Joi.string().required(),
created: Joi.date().required(),
verificationMethod: Joi.string().required(),
proofPurpose: Joi.string().required(),
proofValue: Joi.string().required(),
}).required(),
});

export type ImageDto = {
url: string;
metadata?: {
Expand Down
4 changes: 3 additions & 1 deletion src/routes/apiRoutes/api.route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { claimPostNormalizer } from "../../middlewares/normalizers";
import {
claimPost,
claimsGet,
createCredential,
claimsFeed,
getNodeById,
searchNodes,
Expand All @@ -15,12 +16,13 @@ import {
} from "../../controllers";
import { jwtVerify } from "../../middlewares";
import { claimsFeedV3, getAllClaims } from "../../controllers/api.controller";
import { claimPostSchema, joiValidator } from "../../middlewares/validators/claim.validator";
import { claimPostSchema, joiValidator, credentialPostSchema } from "../../middlewares/validators/claim.validator";
import { upload } from "../../middlewares/upload/multer.upload";

const router = Router();
console.log("setting up routes");
router.post("/claim", jwtVerify, claimPostNormalizer, joiValidator(claimPostSchema), claimPost);
router.post("/credential", joiValidator(credentialPostSchema), createCredential);
router.post("/claim/v2", upload as unknown as RequestHandler, jwtVerify, createClaimV2);
router.get("/claim/search", claimSearch);
router.get("/claim/:claimId?", claimGetById);
Expand Down
Loading