src/issuer/issuance/oid4vci/authorization/chained-as-vp/chained-as-vp.controller.ts
issuers/:tenantId/chained-as-vp
No results matching.
Methods |
|
| Async authorize | |||||||||||||||
authorize(tenantId: string, query: ChainedAsAuthorizeQueryDto, origin: string | undefined, res: Response)
|
|||||||||||||||
Decorators :
@Public()
|
|||||||||||||||
|
Parameters :
Returns :
Promise<void>
|
| Async par | ||||||||||||||||||
par(tenantId: string, body: any, dpopJwt?: string, clientAttestationJwt?: string, clientAttestationPopJwt?: string)
|
||||||||||||||||||
Decorators :
@Public()
|
||||||||||||||||||
|
Parameters :
Returns :
Promise<ChainedAsParResponseDto>
|
| Async token | ||||||||||||
token(tenantId: string, body: ChainedAsTokenRequestDto, dpopJwt?: string)
|
||||||||||||
Decorators :
@Public()
|
||||||||||||
|
Parameters :
Returns :
Promise<ChainedAsTokenResponseDto>
|
| Async vpCallback | |||||||||||||||||||||
vpCallback(tenantId: string, cas: string, responseCode?: string, error?: string, errorDescription?: string, res?: Response)
|
|||||||||||||||||||||
Decorators :
@Public()
|
|||||||||||||||||||||
|
Parameters :
Returns :
Promise<void>
|
import {
Body,
Controller,
Get,
Headers,
HttpCode,
HttpStatus,
Param,
Post,
Query,
Res,
} from "@nestjs/common";
import {
ApiConsumes,
ApiHeader,
ApiOperation,
ApiParam,
ApiResponse,
ApiTags,
} from "@nestjs/swagger";
import type { Response } from "express";
import { Public } from "../../../../../auth/public.decorator";
import {
ChainedAsAuthorizeQueryDto,
ChainedAsErrorResponseDto,
ChainedAsParResponseDto,
ChainedAsTokenRequestDto,
ChainedAsTokenResponseDto,
extractDpopJkt,
} from "../shared";
import { ChainedAsVpService } from "./chained-as-vp.service";
@ApiTags("Chained AS VP")
@Controller("issuers/:tenantId/chained-as-vp")
export class ChainedAsVpController {
constructor(private readonly chainedAsVpService: ChainedAsVpService) {}
@Public()
@Post("par")
@HttpCode(HttpStatus.CREATED)
@ApiConsumes("application/x-www-form-urlencoded")
@ApiOperation({
summary: "Pushed Authorization Request",
description:
"Submit wallet authorization request parameters for the VP-backed AS.",
})
@ApiParam({ name: "tenantId", description: "Tenant identifier" })
@ApiHeader({ name: "DPoP", required: false, description: "DPoP proof JWT" })
@ApiHeader({
name: "OAuth-Client-Attestation",
required: false,
description: "Wallet attestation JWT",
})
@ApiHeader({
name: "OAuth-Client-Attestation-PoP",
required: false,
description: "Wallet attestation proof-of-possession JWT",
})
@ApiResponse({ status: 201, type: ChainedAsParResponseDto })
@ApiResponse({ status: 400, type: ChainedAsErrorResponseDto })
async par(
@Param("tenantId") tenantId: string,
@Body() body: any,
@Headers("dpop") dpopJwt?: string,
@Headers("oauth-client-attestation") clientAttestationJwt?: string,
@Headers("oauth-client-attestation-pop")
clientAttestationPopJwt?: string,
): Promise<ChainedAsParResponseDto> {
const dpopJkt = dpopJwt ? extractDpopJkt(dpopJwt) : undefined;
const clientAttestation =
clientAttestationJwt && clientAttestationPopJwt
? { clientAttestationJwt, clientAttestationPopJwt }
: undefined;
return this.chainedAsVpService.handlePar(
tenantId,
body,
dpopJkt,
clientAttestation,
);
}
@Public()
@Get("authorize")
@ApiOperation({
summary: "Authorization endpoint",
description:
"Validates the request_uri and redirects the browser into an OID4VP wallet request.",
})
@ApiParam({ name: "tenantId", description: "Tenant identifier" })
@ApiResponse({
status: 302,
description: "Redirect to OID4VP wallet invocation",
})
@ApiResponse({ status: 400, type: ChainedAsErrorResponseDto })
async authorize(
@Param("tenantId") tenantId: string,
@Query() query: ChainedAsAuthorizeQueryDto,
@Headers("origin") origin: string | undefined,
@Res() res: Response,
): Promise<void> {
const redirectUrl = await this.chainedAsVpService.handleAuthorize(
tenantId,
query.client_id,
query.request_uri,
origin,
);
res.redirect(redirectUrl);
}
@Public()
@Get("vp-callback")
@ApiOperation({
summary: "Verifier callback",
description:
"Receives the OID4VP verifier redirect and finishes the OAuth authorization flow.",
})
@ApiParam({ name: "tenantId", description: "Tenant identifier" })
@ApiResponse({
status: 302,
description: "Redirect to wallet with authorization code",
})
@ApiResponse({ status: 400, type: ChainedAsErrorResponseDto })
async vpCallback(
@Param("tenantId") tenantId: string,
@Query("cas") cas: string,
@Query("response_code") responseCode?: string,
@Query("error") error?: string,
@Query("error_description") errorDescription?: string,
@Res() res?: Response,
): Promise<void> {
const redirectUrl =
await this.chainedAsVpService.handleVerifierCallback(
tenantId,
cas,
responseCode,
error,
errorDescription,
);
res!.redirect(redirectUrl);
}
@Public()
@Post("token")
@HttpCode(HttpStatus.OK)
@ApiOperation({
summary: "Token endpoint",
description:
"Exchanges the authorization code for an access token containing issuer_state.",
})
@ApiParam({ name: "tenantId", description: "Tenant identifier" })
@ApiHeader({ name: "DPoP", required: false, description: "DPoP proof JWT" })
@ApiResponse({ status: 200, type: ChainedAsTokenResponseDto })
@ApiResponse({ status: 400, type: ChainedAsErrorResponseDto })
async token(
@Param("tenantId") tenantId: string,
@Body() body: ChainedAsTokenRequestDto,
@Headers("dpop") dpopJwt?: string,
): Promise<ChainedAsTokenResponseDto> {
return this.chainedAsVpService.handleToken(tenantId, body, dpopJwt);
}
}