Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -265,11 +265,11 @@ export class DcqlQueryDto {
}

export class DcqlDto {
@ApiProperty({ type: DcqlQueryDto })
//@ApiProperty({ type: DcqlQueryDto })
@IsDefined()
@ValidateNested()
@Type(() => DcqlQueryDto)
query: DcqlQueryDto;
//@ValidateNested()
//@Type(() => DcqlQueryDto)
query: unknown;
Comment on lines +268 to +272
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, let's understand the repository structure and locate the file
echo "=== Repository structure ==="
ls -la apps/ 2>/dev/null | head -20

echo -e "\n=== File location check ==="
find . -name "*oid4vc-verifier-presentation.dto.ts" -type f 2>/dev/null

echo -e "\n=== Directory structure for api-gateway ==="
ls -la apps/api-gateway/src/oid4vc-verification/dtos/ 2>/dev/null || echo "Directory not found"

Repository: credebl/platform

Length of output: 1825


🏁 Script executed:

#!/bin/bash
# Let's read the specific file to understand the context
echo "=== Reading oid4vc-verifier-presentation.dto.ts ==="
cat -n apps/api-gateway/src/oid4vc-verification/dtos/oid4vc-verifier-presentation.dto.ts | sed -n '260,280p'

echo -e "\n=== Full file for context ==="
wc -l apps/api-gateway/src/oid4vc-verification/dtos/oid4vc-verifier-presentation.dto.ts

Repository: credebl/platform

Length of output: 796


🏁 Script executed:

#!/bin/bash
# Search for DcqlQueryDto and related types
echo "=== Search for DcqlQueryDto definition ==="
rg -n --type=ts 'export.*DcqlQueryDto|interface DcqlQueryDto|class DcqlQueryDto' 

echo -e "\n=== Search for DcqlDto usage ==="
rg -n --type=ts 'DcqlQueryDto|dcql-query.dto'

Repository: credebl/platform

Length of output: 607


🏁 Script executed:

#!/bin/bash
# Search for where the query property is accessed
echo "=== Direct query property access patterns ==="
rg -n --type=ts '\bquery\b' apps/api-gateway/src/oid4vc-verification/ | head -40

echo -e "\n=== Search for imports from the presentation DTO ==="
rg -n --type=ts 'import.*oid4vc-verifier-presentation' 

echo -e "\n=== Search for usages of the DTO ==="
rg -n --type=ts 'OidD4VcVerifierPresentationDto|OidD4VcVerifierPresentation'

Repository: credebl/platform

Length of output: 1826


🏁 Script executed:

#!/bin/bash
# Read the full file to understand context
cat -n apps/api-gateway/src/oid4vc-verification/dtos/oid4vc-verifier-presentation.dto.ts

Repository: credebl/platform

Length of output: 11588


🏁 Script executed:

#!/bin/bash
# Search for DcqlDto usage (not VerificationPresentationQueryDto)
echo "=== Direct DcqlDto usages ==="
rg -n --type=ts 'DcqlDto' 

echo -e "\n=== VerificationPresentationQueryDto context ==="
rg -n --type=ts -B3 -A5 'VerificationPresentationQueryDto' apps/api-gateway/src/oid4vc-verification/

Repository: credebl/platform

Length of output: 6613


🏁 Script executed:

#!/bin/bash
# Look at the service to see how queries are processed
echo "=== oid4vc-verification.service.ts - check for query handling ==="
cat -n apps/api-gateway/src/oid4vc-verification/oid4vc-verification.service.ts | head -150

Repository: credebl/platform

Length of output: 7643


🏁 Script executed:

#!/bin/bash
# Search for dcql processing logic
echo "=== Search for dcql handling in service ==="
rg -n --type=ts -i 'dcql' apps/api-gateway/src/oid4vc-verification/ -A3 -B1

Repository: credebl/platform

Length of output: 7550


🏁 Script executed:

#!/bin/bash
# Search for where dcql is processed after it's sent
echo "=== Search for DCQL processing in microservices or handlers ==="
find apps -type f -name "*.ts" | xargs grep -l "dcql" | grep -E "(microservice|handler|processor)" | head -10

echo -e "\n=== Look for DCQL validation in oid4vc-verification microservice ==="
ls -la apps/oid4vc-verification/src/ 2>/dev/null || echo "Not found in oid4vc-verification"

echo -e "\n=== Search across all DCQL handlers ==="
rg -n --type=ts -i 'dcql.*query|query.*dcql' apps/ --max-count=20

echo -e "\n=== Check where dcql is used in PresentationRequestDto ==="
rg -n --type=ts -B5 -A10 'dcql\?: DcqlDto' apps/

Repository: credebl/platform

Length of output: 3343


🏁 Script executed:

#!/bin/bash
# Look at the interface definition to understand how dcql is treated
echo "=== Interface definition for dcql ==="
cat -n libs/common/src/interfaces/oid4vp-verification.ts | head -60

echo -e "\n=== Search for where IPresentationRequest is used ==="
rg -n --type=ts 'IPresentationRequest' apps/api-gateway/ -B2 -A2

Repository: credebl/platform

Length of output: 3311


🏁 Script executed:

#!/bin/bash
# Check if there's any runtime validation logic in the service
echo "=== Search for custom validation in oid4vc-verification service ==="
rg -n --type=ts 'ValidateNested|Validate\(' apps/api-gateway/src/oid4vc-verification/oid4vc-verification.service.ts

echo -e "\n=== Check for any schema validation libraries ==="
rg -n --type=ts -i 'zod|joi|schema|validate' apps/api-gateway/src/oid4vc-verification/ | grep -v node_modules | head -20

Repository: credebl/platform

Length of output: 2387


🏁 Script executed:

#!/bin/bash
# Check the controller endpoint that uses PresentationRequestDto
echo "=== Controller endpoint using PresentationRequestDto ==="
rg -n --type=ts -B10 -A15 'PresentationRequestDto' apps/api-gateway/src/oid4vc-verification/oid4vc-verification.controller.ts | head -80

Repository: credebl/platform

Length of output: 2598


Remove unknown type from DcqlDto.query and restore validation decorators.

The query property lacks runtime type validation and transformation. While the parent PresentationRequestDto validates that dcql is a DcqlDto instance, the inner query field accepts any structure without schema validation. This allows malformed or unexpected query structures to propagate to downstream microservices that may not safely handle untyped inputs.

Restore the commented decorators (@ValidateNested(), @Type(() => DcqlQueryDto), @ApiProperty()) to enforce the expected query schema, or if the DCQL specification genuinely requires flexible query structures, replace unknown with a union type defining valid alternatives and add explicit schema validation at the service layer.

🤖 Prompt for AI Agents
In
apps/api-gateway/src/oid4vc-verification/dtos/oid4vc-verifier-presentation.dto.ts
around lines 268-272, the query property is typed as unknown and the
validation/transformation decorators were commented out; restore strong typing
and validation by changing the property type to DcqlQueryDto (or an explicit
union of allowed query shapes if DCQL requires flexibility) and re-enable
@ApiProperty({ type: DcqlQueryDto }), @ValidateNested(), and @Type(() =>
DcqlQueryDto) so class-transformer/class-validator will validate and transform
the nested query object at runtime; if you intentionally need flexible
structures instead, replace unknown with a documented union and add explicit
validation logic in the service layer.

}

/**
Expand Down
43 changes: 22 additions & 21 deletions apps/oid4vc-issuance/libs/helpers/credential-sessions.builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ export type CredentialOfferPayload = BuiltCredentialOfferBase &
(
| {
preAuthorizedCodeFlowConfig: {
txCode: { description?: string; length: number; input_mode: 'numeric' | 'text' | 'alphanumeric' };
authorizationServerUrl: string;
txCode: { description?: string; length: number; input_mode: 'numeric' | 'text' | 'alphanumeric' } | undefined;
authorizationServerUrl?: string;
};
authorizationCodeFlowConfig?: never;
}
Comment on lines 98 to 103
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's examine the file to see the actual type definitions
cat -n apps/oid4vc-issuance/libs/helpers/credential-sessions.builder.ts | head -120 | tail -30

Repository: credebl/platform

Length of output: 1186


🏁 Script executed:

# Search for preAuthorizedCodeFlowConfig usage
rg -n 'preAuthorizedCodeFlowConfig' --type=ts -C 2

Repository: credebl/platform

Length of output: 5938


🏁 Script executed:

# Search for authorizationServerUrl usage
rg -n 'authorizationServerUrl' --type=ts -C 2

Repository: credebl/platform

Length of output: 9362


Type definition loosens constraints from input interface, creating inconsistency between contract and implementation.

The input interface CreateOidcCredentialOfferDtoLike (lines 51-60) requires both fields:

txCode: { description?: string; length: number; input_mode: 'numeric' | 'text' | 'alphanumeric' };
authorizationServerUrl: string;

But the output type CredentialOfferPayload (lines 98-103) makes both optional:

txCode: ... | undefined;
authorizationServerUrl?: string;

This type mismatch is problematic because:

  1. Actual usage contradicts the permissive type: Line 582 uses authorizationServerUrl directly in a template string (${authorizationServerUrl}/oid4vci/${publicIssuerId}) without null checks. If undefined, this silently produces invalid URLs.

  2. Misleading comment on line 495: The comment says "Pass undefined to enable no auth implementation" but the code passes DEFAULT_TXCODE (a concrete object), not undefined. This inconsistency between comment and code suggests confusion about the intended behavior.

  3. Implementation compensates with guards: While the actual implementation uses non-null assertions (line 510) and validation checks (lines 488-491) to prevent undefined values at runtime, the type definition should accurately reflect these constraints rather than allowing a state the code doesn't actually handle.

Tighten the type definition to match actual requirements, and correct the misleading comment.

🤖 Prompt for AI Agents
In apps/oid4vc-issuance/libs/helpers/credential-sessions.builder.ts around lines
98-103, tighten the CredentialOfferPayload type to match the input DTO and
runtime checks: make preAuthorizedCodeFlowConfig.txCode required (remove the |
undefined) and make authorizationServerUrl a mandatory string (remove the ?), so
the type reflects that these values must be present; also update the misleading
comment near line 495 to state that DEFAULT_TXCODE is passed when using the
no-auth path (not undefined), and adjust any nearby type annotations or callers
that relied on optionality to accept the now-required properties.

Expand Down Expand Up @@ -225,31 +225,32 @@ export function validatePayloadAgainstTemplate(template: any, payload: any): { v

function buildDisclosureFrameFromTemplate(attributes: CredentialAttribute[]): DisclosureFrame {
const frame: DisclosureFrame = {};
const rootSd: string[] = [];
const sd: string[] = [];

for (const attr of attributes) {
if (!attr.disclose) {
continue;
}

// Case 1: attribute has children → nested disclosure
if (attr.children && 0 < attr.children.length) {
const childSd = attr.children.filter((child) => child.disclose).map((child) => child.key);

if (0 < childSd.length) {
frame[attr.key] = {
_sd: childSd
};
const childFrame =
attr.children && 0 < attr.children.length ? buildDisclosureFrameFromTemplate(attr.children) : undefined;

const hasChildDisclosure =
childFrame && (childFrame._sd?.length || Object.keys(childFrame).some((k) => '_sd' !== k));

// Case 1: this attribute itself is disclosed
if (attr.disclose) {
// If it has children, children are handled separately
if (!attr.children || 0 === attr.children.length) {
sd.push(attr.key);
continue;
}
continue;
}

// Case 2: simple attribute → root SD
rootSd.push(attr.key);
// Case 2: attribute has disclosed children
if (hasChildDisclosure) {
frame[attr.key] = childFrame!;
}
}

if (0 < rootSd.length) {
frame._sd = rootSd;
if (0 < sd.length) {
frame._sd = sd;
}

return frame;
Expand Down Expand Up @@ -491,7 +492,7 @@ export function buildCredentialOfferPayload(
return {
...baseEnvelope,
preAuthorizedCodeFlowConfig: {
txCode: DEFAULT_TXCODE,
txCode: DEFAULT_TXCODE, // Pass undefined to enable no auth implementation, TODO: Need to make it configuarble.
authorizationServerUrl: overrideAuthorizationServerUrl
}
};
Expand Down