Skip to content

Commit

Permalink
POST and GET endpoints for issuer,verifier,schema,namespace,assurance…
Browse files Browse the repository at this point in the history
…-levels

Signed-off-by: Vishal Sharma <[email protected]>
  • Loading branch information
vsvishalsharma committed Jul 19, 2024
1 parent 63c96e9 commit 4eff568
Show file tree
Hide file tree
Showing 28 changed files with 941 additions and 51 deletions.
265 changes: 240 additions & 25 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,17 @@
"dependencies": {
"@nestjs/common": "^10.3.9",
"@nestjs/core": "^10.0.0",
"@nestjs/jwt": "^10.2.0",
"@nestjs/passport": "^10.0.3",
"@nestjs/platform-express": "^10.0.0",
"@prisma/client": "^5.15.1",
"@types/passport-jwt": "^4.0.1",
"axios": "^1.7.2",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"dotenv": "^16.4.5",
"passport": "^0.7.0",
"passport-jwt": "^4.0.1",
"reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
Warnings:
- You are about to drop the column `organizationId` on the `Schema` table. All the data in the column will be lost.
- Added the required column `issuerId` to the `Schema` table without a default value. This is not possible if the table is not empty.
*/
-- DropForeignKey
ALTER TABLE "Schema" DROP CONSTRAINT "Schema_organizationId_fkey";

-- AlterTable
ALTER TABLE "Schema" DROP COLUMN "organizationId",
ADD COLUMN "issuerId" TEXT NOT NULL;

-- CreateTable
CREATE TABLE "_VerifierSchemas" (
"A" TEXT NOT NULL,
"B" TEXT NOT NULL
);

-- CreateIndex
CREATE UNIQUE INDEX "_VerifierSchemas_AB_unique" ON "_VerifierSchemas"("A", "B");

-- CreateIndex
CREATE INDEX "_VerifierSchemas_B_index" ON "_VerifierSchemas"("B");

-- AddForeignKey
ALTER TABLE "Schema" ADD CONSTRAINT "Schema_issuerId_fkey" FOREIGN KEY ("issuerId") REFERENCES "Organization"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "_VerifierSchemas" ADD CONSTRAINT "_VerifierSchemas_A_fkey" FOREIGN KEY ("A") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "_VerifierSchemas" ADD CONSTRAINT "_VerifierSchemas_B_fkey" FOREIGN KEY ("B") REFERENCES "Schema"("id") ON DELETE CASCADE ON UPDATE CASCADE;
71 changes: 71 additions & 0 deletions prisma/migrations/20240705072819_/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
Warnings:
- You are about to drop the column `definition` on the `Schema` table. All the data in the column will be lost.
- You are about to drop the column `issuerId` on the `Schema` table. All the data in the column will be lost.
- You are about to drop the `Credential` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `CredentialDefinition` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `RevocationRegistry` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `_VerifierSchemas` table. If the table is not empty, all the data it contains will be lost.
- Added the required column `assuranceLevelId` to the `Organization` table without a default value. This is not possible if the table is not empty.
- Added the required column `namespaceId` to the `Organization` table without a default value. This is not possible if the table is not empty.
- Added the required column `organizationId` to the `Schema` table without a default value. This is not possible if the table is not empty.
- Added the required column `type` to the `Schema` table without a default value. This is not possible if the table is not empty.
*/
-- CreateEnum
CREATE TYPE "SchemaType" AS ENUM ('W3C', 'ANONCREDS');

-- DropForeignKey
ALTER TABLE "Credential" DROP CONSTRAINT "Credential_definitionId_fkey";

-- DropForeignKey
ALTER TABLE "Credential" DROP CONSTRAINT "Credential_revocationRegistryId_fkey";

-- DropForeignKey
ALTER TABLE "Credential" DROP CONSTRAINT "Credential_schemaId_fkey";

-- DropForeignKey
ALTER TABLE "Schema" DROP CONSTRAINT "Schema_issuerId_fkey";

-- DropForeignKey
ALTER TABLE "_VerifierSchemas" DROP CONSTRAINT "_VerifierSchemas_A_fkey";

-- DropForeignKey
ALTER TABLE "_VerifierSchemas" DROP CONSTRAINT "_VerifierSchemas_B_fkey";

-- AlterTable
ALTER TABLE "Organization" ADD COLUMN "assuranceLevelId" TEXT NOT NULL,
ADD COLUMN "namespaceId" TEXT NOT NULL;

-- AlterTable
ALTER TABLE "Schema" DROP COLUMN "definition",
DROP COLUMN "issuerId",
ADD COLUMN "anonCredsDefinitionId" TEXT,
ADD COLUMN "organizationId" TEXT NOT NULL,
ADD COLUMN "type" "SchemaType" NOT NULL,
ADD COLUMN "w3cUri" TEXT;

-- DropTable
DROP TABLE "Credential";

-- DropTable
DROP TABLE "CredentialDefinition";

-- DropTable
DROP TABLE "RevocationRegistry";

-- DropTable
DROP TABLE "_VerifierSchemas";

-- DropEnum
DROP TYPE "CredentialType";

-- AddForeignKey
ALTER TABLE "Organization" ADD CONSTRAINT "Organization_namespaceId_fkey" FOREIGN KEY ("namespaceId") REFERENCES "Namespace"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Organization" ADD CONSTRAINT "Organization_assuranceLevelId_fkey" FOREIGN KEY ("assuranceLevelId") REFERENCES "AssuranceLevel"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Schema" ADD CONSTRAINT "Schema_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
2 changes: 2 additions & 0 deletions prisma/migrations/20240718151011_add_attributes/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Organization" ADD COLUMN "attributes" TEXT[];
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
Warnings:
- You are about to drop the column `attributes` on the `Organization` table. All the data in the column will be lost.
*/
-- AlterTable
ALTER TABLE "Organization" DROP COLUMN "attributes";
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
Warnings:
- You are about to drop the column `anonCredsDefinitionId` on the `Schema` table. All the data in the column will be lost.
*/
-- AlterTable
ALTER TABLE "Schema" DROP COLUMN "anonCredsDefinitionId",
ADD COLUMN "anonCredsSchemaId" TEXT;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-- DropForeignKey
ALTER TABLE "Schema" DROP CONSTRAINT "Schema_organizationId_fkey";

-- AlterTable
ALTER TABLE "Schema" ALTER COLUMN "organizationId" DROP NOT NULL;

-- AddForeignKey
ALTER TABLE "Schema" ADD CONSTRAINT "Schema_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE SET NULL ON UPDATE CASCADE;
11 changes: 11 additions & 0 deletions prisma/migrations/20240718155719_add_govid_to_schema/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
Warnings:
- Added the required column `governanceAuthorityId` to the `Schema` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE "Schema" ADD COLUMN "governanceAuthorityId" TEXT NOT NULL;

-- AddForeignKey
ALTER TABLE "Schema" ADD CONSTRAINT "Schema_governanceAuthorityId_fkey" FOREIGN KEY ("governanceAuthorityId") REFERENCES "GovernanceAuthority"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
2 changes: 2 additions & 0 deletions prisma/migrations/20240719073117_add_attributes/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Organization" ADD COLUMN "attributes" JSONB;
19 changes: 7 additions & 12 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
Expand All @@ -20,6 +17,7 @@ model GovernanceAuthority {
organizations Organization[]
namespaces Namespace[]
assuranceLevels AssuranceLevel[]
schemas Schema[]
ownedRelationships RegistryRelationship[] @relation("OwningRegistry")
relatedToRelationships RegistryRelationship[] @relation("RelatedRegistry")
}
Expand All @@ -37,22 +35,19 @@ model Organization {
assuranceLevel AssuranceLevel @relation(fields: [assuranceLevelId], references: [id])
onboardedAt DateTime @default(now())
schemas Schema[]
attributes Json?
}

model Schema {
id String @id @default(uuid())
name String
type SchemaType
w3cUri String?
anonCredsDefinitionId String?
organizationId String
organization Organization @relation(fields: [organizationId], references: [id])
}

model RevocationRegistry {
id String @id @default(uuid())
name String
definition Json
anonCredsSchemaId String?
organizationId String?
organization Organization? @relation(fields: [organizationId], references: [id])
governanceAuthorityId String // Add this line
governanceAuthority GovernanceAuthority @relation(fields: [governanceAuthorityId], references: [id])
}

model Namespace {
Expand Down
4 changes: 2 additions & 2 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
import { Module } from '@nestjs/common';
import { GovernanceAuthorityModule } from './governance-authority/governance-authority.module';
import { PrismaModule } from './prisma/prisma.module';

import { AuthModule } from './auth/auth.module';
@Module({
imports: [PrismaModule, GovernanceAuthorityModule],
imports: [AuthModule,PrismaModule, GovernanceAuthorityModule],
})
export class AppModule {}
15 changes: 15 additions & 0 deletions src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Controller, Post, Body } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LoginDto } from './dto/login.dto';
import { Public } from './public.decorator';

@Controller('auth')
export class AuthController {
constructor(private authService: AuthService) {}

@Public()
@Post('login')
async login(@Body() loginDto: LoginDto) {
return this.authService.login(loginDto);
}
}
23 changes: 23 additions & 0 deletions src/auth/auth.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// src/auth/auth.module.ts
import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { JwtStrategy } from './jwt.strategy';
import { PrismaModule } from '../prisma/prisma.module';

@Module({
imports: [
PrismaModule,
PassportModule,
JwtModule.register({
secret: process.env.JWT_SECRET, // Make sure to set this in your .env file
signOptions: { expiresIn: '1h' },
}),
],
providers: [AuthService, JwtStrategy],
controllers: [AuthController],
exports: [AuthService],
})
export class AuthModule {}
28 changes: 28 additions & 0 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { PrismaService } from '../prisma/prisma.service';
import { LoginDto } from './dto/login.dto';

@Injectable()
export class AuthService {
constructor(
private prisma: PrismaService,
private jwtService: JwtService
) {}

async login(loginDto: LoginDto) {
const governanceAuthority = await this.prisma.governanceAuthority.findUnique({
where: { did: loginDto.did },
});

if (!governanceAuthority) {
throw new UnauthorizedException('Invalid credentials');
}

const payload = { did: governanceAuthority.did, sub: governanceAuthority.id };
return {
access_token: this.jwtService.sign(payload),
};
}
}
9 changes: 9 additions & 0 deletions src/auth/current-user.decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const CurrentUser = createParamDecorator(
(data: unknown, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
return request.user;
},
);
6 changes: 6 additions & 0 deletions src/auth/dto/login.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { IsString } from 'class-validator';

export class LoginDto {
@IsString()
did: string;
}
23 changes: 23 additions & 0 deletions src/auth/jwt-auth.guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// src/auth/jwt-auth.guard.ts
import { ExecutionContext, Injectable } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { AuthGuard } from '@nestjs/passport';
import { IS_PUBLIC_KEY } from './public.decorator';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
constructor(private reflector: Reflector) {
super();
}

canActivate(context: ExecutionContext) {
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
context.getHandler(),
context.getClass(),
]);
if (isPublic) {
return true;
}
return super.canActivate(context);
}
}
23 changes: 23 additions & 0 deletions src/auth/jwt.strategy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// src/auth/jwt.strategy.ts
import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { PrismaService } from '../prisma/prisma.service';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private prisma: PrismaService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: process.env.JWT_SECRET,
});
}

async validate(payload: any) {
const governanceAuthority = await this.prisma.governanceAuthority.findUnique({
where: { did: payload.did },
});
return { id: governanceAuthority.id, did: payload.did };
}
}
5 changes: 5 additions & 0 deletions src/auth/public.decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// src/auth/public.decorator.ts
import { SetMetadata } from '@nestjs/common';

export const IS_PUBLIC_KEY = 'isPublic';
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
20 changes: 20 additions & 0 deletions src/common/decorators/schema-validator.decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { registerDecorator, ValidationOptions, ValidationArguments } from 'class-validator';

export function IsValidSchema(validationOptions?: ValidationOptions) {
return function (object: Object, propertyName: string) {
registerDecorator({
name: 'isValidSchema',
target: object.constructor,
propertyName: propertyName,
options: validationOptions,
validator: {
validate(value: any, args: ValidationArguments) {
return value.w3cUri || value.anonCredsDefinitionId;
},
defaultMessage(args: ValidationArguments) {
return 'Schema must have either w3cUri or anonCredsDefinitionId';
},
},
});
};
}
Loading

0 comments on commit 4eff568

Please sign in to comment.