Skip to content

Commit 5a2158c

Browse files
authored
Merge pull request #1561 from credebl/feat/oidc4vc-verify-authorization-response
feat:API for verify authorization response
2 parents e516d40 + cc30334 commit 5a2158c

11 files changed

Lines changed: 196 additions & 5 deletions

apps/agent-service/src/agent-service.controller.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ import {
1818
ITenantRecord,
1919
ITenantSchema,
2020
IUserRequestInterface,
21-
IWallet
21+
IWallet,
22+
VerifyAuthorizationResponse
2223
} from './interface/agent-service.interface';
2324

2425
import { AgentServiceService } from './agent-service.service';
@@ -467,4 +468,20 @@ export class AgentServiceController {
467468
);
468469
return this.agentServiceService.createOid4vpVerificationSession(payload.sessionRequest, payload.url, payload.orgId);
469470
}
471+
472+
@MessagePattern({ cmd: 'agent-verify-oid4vp-session-auth-response' })
473+
async verifyOid4vpSessionAuthResponse(payload: {
474+
verifyAuthorizationResponse: VerifyAuthorizationResponse;
475+
url: string;
476+
orgId: string;
477+
}): Promise<object> {
478+
this.logger.log(
479+
`[verifyOid4vpSessionAuthResponse] Received 'agent-verify-oid4vp-session-auth-response' request for orgId=${payload?.orgId || 'N/A'}`
480+
);
481+
return this.agentServiceService.verifyOid4vpSessionAuthResponse(
482+
payload.verifyAuthorizationResponse,
483+
payload.url,
484+
payload.orgId
485+
);
486+
}
470487
}

apps/agent-service/src/agent-service.service.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ import {
5454
IBasicMessage,
5555
WalletDetails,
5656
ILedger,
57-
IStoreOrgAgent
57+
IStoreOrgAgent,
58+
VerifyAuthorizationResponse
5859
} from './interface/agent-service.interface';
5960
import { AgentSpinUpStatus, AgentType, DidMethod, Ledgers, OrgAgentType, PromiseResult } from '@credebl/enum/enum';
6061
import { AgentServiceRepository } from './repositories/agent-service.repository';
@@ -2284,4 +2285,26 @@ export class AgentServiceService {
22842285
throw error;
22852286
}
22862287
}
2288+
2289+
async verifyOid4vpSessionAuthResponse(
2290+
verifyAuthorizationResponse: VerifyAuthorizationResponse,
2291+
url: string,
2292+
orgId: string
2293+
): Promise<object> {
2294+
this.logger.log(
2295+
`[verifyOid4vpSessionAuthResponse] Verifying OID4VP session auth response for orgId=${orgId || 'N/A'}`
2296+
);
2297+
try {
2298+
const getApiKey = await this.getOrgAgentApiKey(orgId);
2299+
const verifySession = await this.commonService
2300+
.httpPost(url, verifyAuthorizationResponse, { headers: { authorization: getApiKey } })
2301+
.then(async (response) => response);
2302+
return verifySession;
2303+
} catch (error) {
2304+
this.logger.error(
2305+
`[verifyOid4vpSessionAuthResponse] Error in verifying oid4vp session auth response in agent service : ${JSON.stringify(error)}`
2306+
);
2307+
throw error;
2308+
}
2309+
}
22872310
}

apps/agent-service/src/interface/agent-service.interface.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,3 +660,9 @@ export interface WalletDetails {
660660
tenantId: string;
661661
orgId: string;
662662
}
663+
664+
export interface VerifyAuthorizationResponse {
665+
verificationSessionId: string;
666+
authorizationResponse: Record<string, unknown>;
667+
origin?: string;
668+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { ApiProperty } from '@nestjs/swagger';
2+
import { IsNotEmpty, IsObject, IsOptional, IsString } from 'class-validator';
3+
4+
export class VerifyAuthorizationResponseDto {
5+
@ApiProperty({
6+
description: 'verification session id received in the authorization response',
7+
example: '93e156ca-a6b9-46ea-913d-f499be167d02'
8+
})
9+
@IsString()
10+
@IsNotEmpty()
11+
verificationSessionId!: string;
12+
13+
@ApiProperty({
14+
description:
15+
'authorization response received from the wallet after user approves or denies the verification request',
16+
example: {
17+
// eslint-disable-next-line camelcase
18+
id_token: {
19+
Passport: [
20+
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tL2F1dGgvdjEvcmVhbG0tY3JlZGVibCIsInN1YiI6IjEyMzQ1Njc4OTAiLCJhdWQiOiJhdXRoLWNlbnRlci1pZCIsImV4cCI6MTY5ODAwMDAwMCwiaWF0IjoxNjk3OTk2NDAwfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'
21+
]
22+
}
23+
}
24+
})
25+
@IsObject()
26+
@IsNotEmpty()
27+
authorizationResponse!: Record<string, unknown>;
28+
29+
@ApiProperty({
30+
description: 'The origin of the verification session, if Digital Credentials API was used.',
31+
example: 'https://example.com'
32+
})
33+
@IsOptional()
34+
@IsString()
35+
origin?: string;
36+
}

apps/api-gateway/src/oid4vc-verification/oid4vc-verification.controller.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import { PresentationRequestDto, VerificationPresentationQueryDto } from './dtos
5050
import { Oid4vpPresentationWhDto } from '../oid4vc-issuance/dtos/oid4vp-presentation-wh.dto';
5151
import { CreateVerificationTemplateDto, UpdateVerificationTemplateDto } from './dtos/verification-template.dto';
5252
import { CreateIntentBasedVerificationDto } from './dtos/create-intent-based-verification.dto';
53+
import { VerifyAuthorizationResponseDto } from './dtos/verify-authorization-response.dto';
5354

5455
@Controller()
5556
@UseFilters(CustomExceptionFilter)
@@ -718,4 +719,45 @@ export class Oid4vcVerificationController {
718719
};
719720
return res.status(HttpStatus.OK).json(finalResponse);
720721
}
722+
723+
@Post('/orgs/:orgId/oid4vp/verify-authorization-response')
724+
@ApiOperation({
725+
summary: 'Verify authorization response',
726+
description: 'Verifies an authorization response for the specified organization.'
727+
})
728+
@ApiResponse({
729+
status: HttpStatus.OK,
730+
description: 'Authorization response verified successfully.',
731+
type: ApiResponseDto
732+
})
733+
@ApiBearerAuth()
734+
@Roles(OrgRoles.OWNER)
735+
@UseGuards(AuthGuard('jwt'), OrgRolesGuard)
736+
async verifyAuthorizationResponse(
737+
@Param(
738+
'orgId',
739+
new ParseUUIDPipe({
740+
exceptionFactory: (): Error => {
741+
throw new BadRequestException(ResponseMessages.organisation.error.invalidOrgId);
742+
}
743+
})
744+
)
745+
orgId: string,
746+
@Body() verifyAuthorizationResponseDto: VerifyAuthorizationResponseDto,
747+
@Res() res: Response
748+
): Promise<Response> {
749+
this.logger.debug(`[verifyAuthorizationResponse] Called with orgId=${orgId}`);
750+
751+
const result = await this.oid4vcVerificationService.verifyAuthorizationResponse(
752+
verifyAuthorizationResponseDto,
753+
orgId
754+
);
755+
this.logger.debug(`[verifyAuthorizationResponse] Authorization response verified successfully for orgId=${orgId}`);
756+
const finalResponse: IResponse = {
757+
statusCode: HttpStatus.CREATED,
758+
message: 'Authorization response verified successfully',
759+
data: result
760+
};
761+
return res.status(HttpStatus.CREATED).json(finalResponse);
762+
}
721763
}

apps/api-gateway/src/oid4vc-verification/oid4vc-verification.service.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { IPresentationRequest } from '@credebl/common/interfaces/oid4vp-verifica
99
import { Oid4vpPresentationWhDto } from '../oid4vc-issuance/dtos/oid4vp-presentation-wh.dto';
1010
import { CreateVerificationTemplateDto, UpdateVerificationTemplateDto } from './dtos/verification-template.dto';
1111
import { CreateIntentBasedVerificationDto } from './dtos/create-intent-based-verification.dto';
12+
import { VerifyAuthorizationResponseDto } from './dtos/verify-authorization-response.dto';
1213

1314
@Injectable()
1415
export class Oid4vcVerificationService {
@@ -173,4 +174,12 @@ export class Oid4vcVerificationService {
173174
this.logger.debug(`[deleteVerificationTemplate] Called with orgId=${orgId}, templateId=${templateId}`);
174175
return this.natsClient.sendNatsMessage(this.oid4vpProxy, 'verification-template-delete', payload);
175176
}
177+
async verifyAuthorizationResponse(
178+
verifyAuthorizationResponse: VerifyAuthorizationResponseDto,
179+
orgId: string
180+
): Promise<object> {
181+
const payload = { verifyAuthorizationResponse, orgId };
182+
this.logger.debug(`[verifyAuthorizationResponse] Called with orgId=${orgId}`);
183+
return this.natsClient.sendNatsMessage(this.oid4vpProxy, 'verify-authorization-response', payload);
184+
}
176185
}

apps/oid4vc-verification/interfaces/oid4vp-verification-sessions.interfaces.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,9 @@ export interface X5cSigner {
2323
}
2424

2525
export type RequestSigner = DidSigner | X5cSigner;
26+
27+
export interface VerifyAuthorizationResponse {
28+
verificationSessionId: string;
29+
authorizationResponse: Record<string, unknown>;
30+
origin?: string;
31+
}

apps/oid4vc-verification/src/oid4vc-verification.controller.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ import {
99
} from '@credebl/common/interfaces/oid4vp-verification';
1010
import { MessagePattern } from '@nestjs/microservices';
1111
import { VerificationSessionQuery } from '../interfaces/oid4vp-verifier.interfaces';
12-
import { Oid4vpPresentationWh } from '../interfaces/oid4vp-verification-sessions.interfaces';
12+
import {
13+
Oid4vpPresentationWh,
14+
VerifyAuthorizationResponse
15+
} from '../interfaces/oid4vp-verification-sessions.interfaces';
1316
import { CreateVerificationTemplate, UpdateVerificationTemplate } from '../interfaces/verification-template.interfaces';
1417

1518
@Controller()
@@ -181,4 +184,16 @@ export class Oid4vpVerificationController {
181184
);
182185
return this.oid4vpVerificationService.deleteVerificationTemplate(orgId, templateId);
183186
}
187+
188+
@MessagePattern({ cmd: 'verify-authorization-response' })
189+
async verifyAuthorizationResponse(payload: {
190+
verifyAuthorizationResponse: VerifyAuthorizationResponse;
191+
orgId: string;
192+
}): Promise<object> {
193+
const { verifyAuthorizationResponse, orgId } = payload;
194+
this.logger.debug(
195+
`[verifyAuthorizationResponse] Received 'verify-authorization-response' request for orgId=${orgId}`
196+
);
197+
return this.oid4vpVerificationService.verifyAuthorizationResponse(verifyAuthorizationResponse, orgId);
198+
}
184199
}

apps/oid4vc-verification/src/oid4vc-verification.service.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ import { VerificationSessionQuery } from '../interfaces/oid4vp-verifier.interfac
3232
import { BaseService } from 'libs/service/base.service';
3333
import { NATSClient } from '@credebl/common/NATSClient';
3434

35-
import { Oid4vpPresentationWh, RequestSigner } from '../interfaces/oid4vp-verification-sessions.interfaces';
35+
import {
36+
Oid4vpPresentationWh,
37+
RequestSigner,
38+
VerifyAuthorizationResponse
39+
} from '../interfaces/oid4vp-verification-sessions.interfaces';
3640
import { X509CertificateRecord } from '@credebl/common/interfaces/x509.interface';
3741
import { SignerMethodOption, x5cKeyType } from '@credebl/enum/enum';
3842
import { CreateVerificationTemplate, UpdateVerificationTemplate } from '../interfaces/verification-template.interfaces';
@@ -694,4 +698,31 @@ export class Oid4vpVerificationService extends BaseService {
694698
throw new RpcException(error?.response ?? error.error ?? error);
695699
}
696700
}
701+
702+
async verifyAuthorizationResponse(
703+
verifyAuthorizationResponse: VerifyAuthorizationResponse,
704+
orgId: string
705+
): Promise<object> {
706+
this.logger.debug(
707+
`[verifyAuthorizationResponse] called for orgId=${orgId}, verificationSessionId=${JSON.stringify(verifyAuthorizationResponse.verificationSessionId)}`
708+
);
709+
try {
710+
const agentDetails = await this.oid4vpRepository.getAgentEndPoint(orgId);
711+
if (!agentDetails) {
712+
throw new NotFoundException(ResponseMessages.issuance.error.agentEndPointNotFound);
713+
}
714+
const { agentEndPoint, id } = agentDetails;
715+
const url = getAgentUrl(agentEndPoint, CommonConstants.OIDC_VERIFIER_SESSION_AUTH_RESPONSE_VERIFY);
716+
const verificationResult = await this.natsClient.sendNatsMessage(
717+
this.oid4vpVerificationServiceProxy,
718+
'agent-verify-oid4vp-session-auth-response',
719+
{ url, orgId, verifyAuthorizationResponse }
720+
);
721+
this.logger.debug(`[verifyAuthorizationResponse] verification result received successfully for orgId=${orgId}`);
722+
return verificationResult;
723+
} catch (error) {
724+
this.logger.error(`[verifyAuthorizationResponse] - error: ${JSON.stringify(error)}`);
725+
throw new RpcException(error?.response ?? error);
726+
}
727+
}
697728
}

libs/common/src/common.constant.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ export enum CommonConstants {
135135
URL_OIDC_VERIFIER_SESSION_GET_BY_QUERY = '/openid4vc/verification-sessions',
136136
URL_OIDC_VERIFIER_SESSION_RESPONSE_GET_BY_ID = '/openid4vc/verification-sessions/response/#',
137137
URL_OID4VP_VERIFICATION_SESSION = '/openid4vc/verification-sessions/create-presentation-request',
138+
URL_OIDC_VERIFIER_SESSION_AUTH_RESPONSE_VERIFY = '/openid4vc/verification-sessions/verify-authorization-response',
138139

139140
//X509 agent API URLs
140141
URL_CREATE_X509_CERTIFICATE = '/x509',
@@ -439,6 +440,7 @@ export enum CommonConstants {
439440
OIDC_VERIFIER_SESSION_GET_BY_ID = 'get-oid4vp-verifier-session-id',
440441
OIDC_VERIFIER_SESSION_GET_BY_QUERY = 'get-oid4vp-verifier-session-query',
441442
OIDC_VERIFIER_SESSION_RESPONSE_GET_BY_ID = 'get-oid4vp-verifier-session-response-id',
443+
OIDC_VERIFIER_SESSION_AUTH_RESPONSE_VERIFY = 'verify-oid4vp-verifier-session-auth-response',
442444

443445
//X509
444446
X509_CREATE_CERTIFICATE = 'create-x509-certificate',

0 commit comments

Comments
 (0)