Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
amit-s19 committed Jun 27, 2023
1 parent 41c4f36 commit be768bd
Show file tree
Hide file tree
Showing 8 changed files with 278 additions and 132 deletions.
4 changes: 3 additions & 1 deletion apps/authentication/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import { AppService } from './app.service';
import { AuthModule } from './auth/auth.module';
import { TerminusModule } from '@nestjs/terminus';
import { HttpModule } from '@nestjs/axios';
import { UserModule } from './user/user.module';
@Module({
imports: [
AuthModule,
UserModule,
ConfigModule.forRoot({
isGlobal: true,
}),
Expand All @@ -17,4 +19,4 @@ import { HttpModule } from '@nestjs/axios';
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
export class AppModule { }
23 changes: 12 additions & 11 deletions apps/authentication/src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { HttpService } from '@nestjs/axios';
import { Body, Controller, Get, Param, Patch, Post, UseGuards } from '@nestjs/common';
import { Body, Controller, Get, Param, Patch, Post, Req, Request, UseGuards } from '@nestjs/common';
import { parseJwt } from '../helpers/decodeToken';
import { JwtAuthGuard } from './auth-jwt.guard';
import { AuthService } from './auth.service';
import { AuthDto } from './dto/auth.dto';
Expand All @@ -11,31 +12,31 @@ export class AuthController {

@Post('/verify')
@UseGuards(JwtAuthGuard)
hadleAuth(@Body() body: AuthDto) {
return this.authService.handleAuth(body);
hadleAuth(@Body() body: AuthDto, @Request() req) {
return this.authService.handleAuth(body, req?.headers?.authorization);
}

@Post('/register')
@UseGuards(JwtAuthGuard)
handleRegister(@Body() ca: CA) {
return this.authService.handleRegister(ca);
handleRegister(@Body() ca: CA, @Request() req) {
return this.authService.handleRegister(ca, req?.headers?.authorization);
}

@Patch('/:caId/accept')
@UseGuards(JwtAuthGuard)
handleAccept(@Param('caId') caId: string) {
return this.authService.handleConsent(caId, 'accept');
handleAccept(@Param('caId') caId: string, @Request() req) {
return this.authService.handleConsent(caId, 'accept', req?.headers?.authorization);
}

@Patch('/:caId/reject')
@UseGuards(JwtAuthGuard)
handleReject(@Param('caId') caId: string) {
return this.authService.handleConsent(caId, 'reject');
handleReject(@Param('caId') caId: string, @Request() req) {
return this.authService.handleConsent(caId, 'reject', req?.headers?.authorization);
}

@Patch('/:caId/revoke')
@UseGuards(JwtAuthGuard)
handleRevoke(@Param('caId') caId: string) {
return this.authService.handleConsent(caId, 'revoke');
handleRevoke(@Param('caId') caId: string, @Request() req) {
return this.authService.handleConsent(caId, 'revoke', req?.headers?.authorization);
}
}
211 changes: 93 additions & 118 deletions apps/authentication/src/auth/auth.service.ts
Original file line number Diff line number Diff line change
@@ -1,135 +1,74 @@
import { HttpService } from '@nestjs/axios';
import { Injectable, InternalServerErrorException } from '@nestjs/common';
import { HttpException, HttpStatus, Injectable, InternalServerErrorException } from '@nestjs/common';
import { lastValueFrom, map } from 'rxjs';
import { parseJwt } from '../helpers/decodeToken';
import { AuthDto } from './dto/auth.dto';
import { CA } from './dto/ca.dto';

@Injectable()
export class AuthService {
constructor(private readonly httpService: HttpService) { }

async handleAuth(authDTO: AuthDto) {
//TODO: add consent artifact processin
async handleAuth(authDTO: AuthDto, token: string) {
try {
// const myHeaders = new Headers();
// myHeaders.append('Content-Type', 'application/json');

// var raw = JSON.stringify({
// "id": "927d81cf-77ee-4528-94d1-2d98a2595740",
// "caId": "036232e5-0ac7-4863-bad2-c70e70ef2d2f",
// "consent_artifact": {
// "id": "036232e5-0ac7-4863-bad2-c70e70ef2d2f",
// "log": {
// "consent_use": {
// "url": "https://sample-log/api/v1/log"
// },
// "data_access": {
// "url": "https://sample-log/api/v1/log"
// }
// },
// "data": "<Valid superset GraphQL query of consented data>",
// "user": {
// "id": "[email protected]"
// },
// "proof": {
// "jws": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjAzNjIzMmU1LTBhYzctNDg2My1iYWQyLWM3MGU3MGVmMmQyZiIsImxvZyI6eyJjb25zZW50X3VzZSI6eyJ1cmwiOiJodHRwczovL3NhbXBsZS1sb2cvYXBpL3YxL2xvZyJ9LCJkYXRhX2FjY2VzcyI6eyJ1cmwiOiJodHRwczovL3NhbXBsZS1sb2cvYXBpL3YxL2xvZyJ9fSwiZGF0YSI6IjxWYWxpZCBzdXBlcnNldCBHcmFwaFFMIHF1ZXJ5IG9mIGNvbnNlbnRlZCBkYXRhPiIsInVzZXIiOnsiaWQiOiJmYXJtZXItMUBnbWFpbC5jb20ifSwiY3JlYXRlZCI6IllZWVktTU0tRERUaGg6bW06c3Nabi5uIiwiZXhwaXJlcyI6IllZWVktTU0tRERUaGg6bW06c3Nabi5uIiwicHVycG9zZSI6IiIsInJldm9rZXIiOnsiaWQiOiJkaWQ6dXNlcjoxMjMiLCJ1cmwiOiJodHRwczovL3NhbXBsZS1yZXZva2VyL2FwaS92MS9yZXZva2UifSwiY29uc3VtZXIiOnsiaWQiOiJkaWQ6Y29uc3VtZXI6MTIzIiwidXJsIjoiaHR0cHM6Ly9zYW1wbGUtY29uc3VtZXIvYXBpL3YxL2NvbnN1bWUifSwicHJvdmlkZXIiOnsiaWQiOiJkaWQ6cHJvaWRlcjoxMjMiLCJ1cmwiOiJodHRwczovL3NhbXBsZS1jb25zdW1lci9hcGkvdjEifSwiY29sbGVjdG9yIjp7ImlkIjoiZGlkOmNvbGxlY3RvcjoxMjMiLCJ1cmwiOiJodHRwczovL2ExMTItMTAzLTIxMi0xNDctMTMwLmluLm5ncm9rLmlvIn0sImZyZXF1ZW5jeSI6eyJ0dGwiOjUsImxpbWl0IjoyfSwicmV2b2NhYmxlIjpmYWxzZSwic2lnbmF0dXJlIjoiIiwidXNlcl9zaWduIjoiIiwiY29sbGVjdG9yX3NpZ24iOiIiLCJ0b3RhbF9xdWVyaWVzX2FsbG93ZWQiOjEwLCJpYXQiOjE2Njk5Mzk1OTYsImV4cCI6MTY3MDM3MTU5NiwiYXVkIjoiZGlkOmNvbnN1bWVyOjEyMyIsImlzcyI6ImNvbnNlbnQtbWFuYWdlciIsInN1YiI6ImZhcm1lci0xQGdtYWlsLmNvbSJ9.UNyoXDgMxbIVaBoK0J7OBX7ybUlZNx309KdbetoeJLqGaZbfFav3rZyoPnQNpQyAFHp8MaNczzlI0JlTSStqJl0E-Z1oGK6M-hREE1261zSxZMAueIgpNEVpNiUH4gRhleTBaKPH0EoZT27ORqZmULb2UMDfw1Gy9RuH7cHzJYdBDmi5fkePhsN8T3Z03OgnUWHHPTxwS4_szS3fLGMmJvUTyrK-UBwkMslajdoWN3vcp4MERv60F8yIk7GqGGkNHEiaLe_g_Zi73KOKDbdWOLapQiO8kwpAyblu6maNF8w4VdIft4zFT4SiloJWxeYNZUeT0ROHscTbdLOaTCn-Ag",
// "type": "RS256",
// "created": "12/2/2022, 12:06:36 AM",
// "proofPurpose": "jwtVerify",
// "verificationMethod": "https://auth.konnect.samagra.io/.well-known/jwks"
// },
// "created": "YYYY-MM-DDThh:mm:ssZn.n",
// "expires": "YYYY-MM-DDThh:mm:ssZn.n",
// "purpose": "",
// "revoker": {
// "id": "did:user:123",
// "url": "https://sample-revoker/api/v1/revoke"
// },
// "consumer": {
// "id": "did:consumer:123",
// "url": "https://sample-consumer/api/v1/consume"
// },
// "provider": {
// "id": "did:proider:123",
// "url": "https://sample-consumer/api/v1"
// },
// "collector": {
// "id": "did:collector:123",
// "url": "https://a112-103-212-147-130.in.ngrok.io"
// },
// "frequency": {
// "ttl": 5,
// "limit": 2
// },
// "revocable": false,
// "signature": "",
// "user_sign": "",
// "collector_sign": "",
// "total_queries_allowed": 10
// },
// "userId": "[email protected]",
// "state": "ACCEPT",
// "created_at": "2022-12-02T00:05:46.090Z",
// "created_by": "API",
// "updated_at": "2022-12-02T00:05:46.090Z",
// "updated_by": null,
// "webhook_url": "https://sample-consumer/api/v1/consume",
// "total_attempts": 0
// });
// const reqOptions = {
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json',
// },
// redirect: 'follow',
// };
// fetch('https://api.consent-manager.konnect.samagra.io/verify', reqOptions)
// .then((response) => response.text())
// .then((result) => console.log(result))
// .catch((error) => {
// console.log('error', error);
// throw new InternalServerErrorException(error);
// });

// this.httpService.post(
// 'https://api.consent-manager.konnect.samagra.io/verify',
// raw,
// reqOptions,
// );
const tokenPayload = parseJwt(token?.split(" ")?.[1]);
const userEmail = tokenPayload.email;

const caRes = await lastValueFrom(
const permissionRes = await lastValueFrom(
this.httpService
.get(
`${process.env.CONSENT_MANAGER_URI}/${authDTO.caId}/verify`
.post(
`http://localhost:6000/user/checkPermission`,
{
caId: authDTO.caId,
userEmail
}, { headers: { Authorization: token } }
)
.pipe(map((response) => response.data)),
);
if (!caRes.caId) {
return "An error occured while verifying Consent Artifact";
}

console.log("CA RES---->", caRes)
if (permissionRes) {
const caRes = await lastValueFrom(
this.httpService
.get(
`${process.env.CONSENT_MANAGER_URI}/${authDTO.caId}/verify`
)
.pipe(map((response) => response.data)),
);
if (!caRes.caId) {
return "An error occured while verifying Consent Artifact";
}

const responseData = await lastValueFrom(
this.httpService
.post(
process.env.LINK_TO_AUTHORIZATION_SERVICE,
{ consentArtifact: caRes, gql: authDTO.gql }
)
.pipe(map((response) => response.data)),
);
console.log("CA RES---->", caRes)

return responseData;
const responseData = await lastValueFrom(
this.httpService
.post(
process.env.LINK_TO_AUTHORIZATION_SERVICE,
{ consentArtifact: caRes, gql: authDTO.gql }
)
.pipe(map((response) => response.data)),
);

return responseData;

} else {
throw new HttpException({
status: HttpStatus.FORBIDDEN,
error: `You can only access or modify Consents which are associated with you.`,
}, HttpStatus.FORBIDDEN);
}
} catch (err) {
console.log('err: ', err);
if (err?.response?.data)
return err?.response?.data;
if (err?.response?.data || err?.response)
return err?.response?.data || err?.response;
throw new InternalServerErrorException();
}
}

handleRegister = async (data: CA) => {
handleRegister = async (data: CA, token: string) => {
try {
const tokenPayload = parseJwt(token?.split(" ")?.[1]);
const userEmail = tokenPayload.email;
let ca = data.consentArtifact
const caRes = await lastValueFrom(
this.httpService
Expand All @@ -143,6 +82,19 @@ export class AuthService {
return "An error occured while creating Consent Artifact";
}

// Adding registered CA to user's data on FA.
const userRes = await lastValueFrom(
this.httpService
.patch(
`http://localhost:6000/user/updateUserCaIds`,
{
caId: caRes.caId,
userEmail
}, { headers: { Authorization: token } }
)
.pipe(map((response) => response.data)),
);

return caRes;

} catch (err) {
Expand All @@ -153,27 +105,50 @@ export class AuthService {
}
}

handleConsent = async (caId: string, type: string) => {
handleConsent = async (caId: string, type: string, token: string) => {
try {
const caRes = await lastValueFrom(
const tokenPayload = parseJwt(token?.split(" ")?.[1]);
const userEmail = tokenPayload.email;

const permissionRes = await lastValueFrom(
this.httpService
.patch(
`${process.env.CONSENT_MANAGER_URI}/${caId}/${type}`
.post(
`http://localhost:6000/user/checkPermission`,
{
caId,
userEmail
}, { headers: { Authorization: token } }
)
.pipe(map((response) => response.data)),
);

if (!caRes.caId) {
return "An error occured while performing the requested action";
}
if (permissionRes) {
const caRes = await lastValueFrom(
this.httpService
.patch(
`${process.env.CONSENT_MANAGER_URI}/${caId}/${type}`
)
.pipe(map((response) => response.data)),
);

return caRes;
if (!caRes.caId) {
return "An error occured while performing the requested action";
}

return caRes;

} else {
throw new HttpException({
status: HttpStatus.FORBIDDEN,
error: `You can only access or modify Consents which are associated with you.`,
}, HttpStatus.FORBIDDEN);
}

} catch (err) {
console.log('err: ', err);
if (err?.response?.data)
return err?.response?.data;
throw new InternalServerErrorException();
if (err?.response)
return err?.response;
throw new InternalServerErrorException;
}
}
}
3 changes: 1 addition & 2 deletions apps/authentication/src/auth/dto/auth.dto.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export class AuthDto {
caId: string
gql: string;
token: string;
gql: string
}
10 changes: 10 additions & 0 deletions apps/authentication/src/helpers/decodeToken.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { JwtPayload } from "jsonwebtoken";

export function parseJwt(signedJwtAccessToken: string) {
if (!signedJwtAccessToken) return null;
const base64Payload = signedJwtAccessToken.split('.')[1];
const payloadBuffer = Buffer.from(base64Payload, 'base64');
const updatedJwtPayload: JwtPayload = JSON.parse(payloadBuffer.toString()) as JwtPayload;
const expires = updatedJwtPayload.exp;
return updatedJwtPayload
}
27 changes: 27 additions & 0 deletions apps/authentication/src/user/user.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Body, Controller, Get, Param, Patch, Post, Request } from '@nestjs/common';
import { UserService } from './user.service';
import { ConfigService } from '@nestjs/config';
import { ApiOperation, ApiResponse } from '@nestjs/swagger';

@Controller('user')
export class UserController {
constructor(
private readonly userService: UserService,
private configService: ConfigService,
) { }

@Get('/:email')
getUserDetails(@Param('email') email: string) {
return this.userService.getUserDetails(email);
}

@Patch('/updateUserCaIds')
updateUserCaIds(@Body() data, @Request() req) {
return this.userService.updateUserCaIds(data, req?.headers?.authorization)
}

@Post('/checkPermission')
checkPermission(@Body() data, @Request() req) {
return this.userService.checkPermission(data, req?.headers?.authorization)
}
}
18 changes: 18 additions & 0 deletions apps/authentication/src/user/user.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { UserController } from './user.controller';
import { UserService } from './user.service';
import { TerminusModule } from '@nestjs/terminus';
import { HttpModule } from '@nestjs/axios';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
TerminusModule,
HttpModule,
],
controllers: [UserController],
providers: [UserService],
})
export class UserModule { }
Loading

0 comments on commit be768bd

Please sign in to comment.