-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
278 additions
and
132 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
@@ -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) { | ||
|
@@ -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; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 { } |
Oops, something went wrong.