Skip to content

Commit 5b184fe

Browse files
committed
Add authorization request URI handling and update presentation options component
1 parent 527347c commit 5b184fe

7 files changed

Lines changed: 87 additions & 36 deletions

File tree

src/app/core/constants/general.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1+
import { Profile, RequestUriMethod } from "../models/TransactionInitializationRequest";
2+
13
export const ACTIVE_TRANSACTION = 'ACTIVE_TRANSACTION';
24
export const SCHEME = 'scheme';
35
export const DEFAULT_SCHEME = 'haip-vp://';
46
export const ISSUER_CHAIN = 'ISSUER_CHAIN';
7+
8+
export const DefaultRequestUriMethod: RequestUriMethod = 'get';
9+
export const DefaultProfile: Profile = 'openid4vp';

src/app/core/models/TransactionInitializationRequest.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export type TransactionInitializationRequest = {
99
dcql_query: DCQL;
1010
issuer_chain?: string;
1111
profile: Profile;
12+
authorization_request_uri: string;
1213
};
1314

1415
export type PresentationQuery = DCQL;

src/app/core/services/dcql-service.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export class DCQLService {
2323
selectedAttributes: { [id: string]: string[] },
2424
selectedRequestUriMethod: RequestUriMethod,
2525
selectedProfile: Profile,
26+
authorizationRequestUri: string,
2627
issuerChain?: string
2728
): TransactionInitializationRequest {
2829
let dcqlQueries: CredentialQuery[] = selectedAttestations.map(
@@ -45,7 +46,8 @@ export class DCQLService {
4546
nonce: uuidv4(),
4647
request_uri_method: selectedRequestUriMethod,
4748
issuer_chain: issuerChain,
48-
profile: selectedProfile
49+
profile: selectedProfile,
50+
authorization_request_uri: authorizationRequestUri
4951
};
5052
}
5153

src/app/features/presentation-request-preparation/components/presentation-options/presentation-options.component.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ <h5>Presentation Options</h5>
5959
placeholder="scheme://"
6060
[formControl]="authorizationSchemeControl"
6161
autocomplete="off"
62+
(input)="authorizationSchemeChange.emit(authorizationSchemeControl.value)"
6263
/>
6364
</mat-form-field>
6465
</div>

src/app/features/presentation-request-preparation/components/presentation-options/presentation-options.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@ export class PresentationOptionsComponent {
2525

2626
@Output() profileChange = new EventEmitter<Profile>();
2727
@Output() requestUriMethodChange = new EventEmitter<RequestUriMethod>();
28-
28+
@Output() authorizationSchemeChange = new EventEmitter<string>();
2929
}

src/app/features/presentation-request-preparation/home/home.component.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ <h4>Define your presentation request</h4>
4242
[authorizationSchemeControl]="authorizationSchemeControl"
4343
(profileChange)="handleProfileChangedEvent($event)"
4444
(requestUriMethodChange)="handleRequestUriMethodChangedEvent($event)"
45+
(authorizationSchemeChange)="handleAuthorizationSchemeChangedEvent($event)"
4546
></vc-presentation-options>
4647

4748
<mat-expansion-panel>

src/app/features/presentation-request-preparation/home/home.component.ts

Lines changed: 75 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,16 @@ import {
1717
Validators,
1818
} from '@angular/forms';
1919
import { MatButtonModule } from '@angular/material/button';
20-
import { AttestationSelection, AttributeSelectionMethod } from '@features/presentation-request-preparation/models/AttestationSelection';
20+
import {
21+
AttestationSelection,
22+
AttributeSelectionMethod,
23+
} from '@features/presentation-request-preparation/models/AttestationSelection';
2124
import { AttributeSelectionComponent } from '@features/presentation-request-preparation/components/attribute-selection/attribute-selection.component';
22-
import { Profile, RequestUriMethod, TransactionInitializationRequest } from '@core/models/TransactionInitializationRequest';
25+
import {
26+
Profile,
27+
RequestUriMethod,
28+
TransactionInitializationRequest,
29+
} from '@core/models/TransactionInitializationRequest';
2330
import { VerifierEndpointService } from '@core/services/verifier-endpoint.service';
2431
import { MatExpansionModule } from '@angular/material/expansion';
2532
import { MatButtonToggleModule } from '@angular/material/button-toggle';
@@ -30,7 +37,13 @@ import { AttributesSelectionEvent } from '../models/AttributesSelection';
3037
import { DCQLService } from '@app/core/services/dcql-service';
3138
import { Subject } from 'rxjs';
3239
import { SessionStorageService } from '@app/core/services/session-storage.service';
33-
import { DEFAULT_SCHEME, ISSUER_CHAIN, SCHEME } from '@app/core/constants/general';
40+
import {
41+
DEFAULT_SCHEME,
42+
DefaultProfile,
43+
DefaultRequestUriMethod,
44+
ISSUER_CHAIN,
45+
SCHEME,
46+
} from '@app/core/constants/general';
3447
import { SUPPORTED_ATTESTATIONS } from '@app/core/constants/attestation-definitions';
3548
import { PresentationOptionsComponent } from '../components/presentation-options/presentation-options.component';
3649

@@ -53,7 +66,7 @@ import { PresentationOptionsComponent } from '../components/presentation-options
5366
ClipboardModule,
5467
MatTooltipModule,
5568
MatButtonToggleModule,
56-
PresentationOptionsComponent
69+
PresentationOptionsComponent,
5770
],
5871
providers: [VerifierEndpointService],
5972
selector: 'vc-presentation-preparation-home',
@@ -65,23 +78,21 @@ export class HomeComponent implements OnDestroy {
6578
private readonly navigateService: NavigateService,
6679
private readonly verifierEndpointService: VerifierEndpointService,
6780
private readonly dcqlService: DCQLService,
68-
private readonly sessionStorageService: SessionStorageService,
81+
private readonly sessionStorageService: SessionStorageService
6982
) {}
7083

7184
actions: BodyAction[] = HOME_ACTIONS;
7285

73-
requestUriMethodControl = new FormControl<RequestUriMethod>('get', {
86+
requestUriMethodControl = new FormControl<RequestUriMethod>(DefaultRequestUriMethod, {
7487
nonNullable: true,
7588
});
7689
authorizationSchemeControl = new FormControl<string>(
7790
this.getStoredAuthorizationScheme(),
7891
{ nonNullable: true }
7992
);
80-
presentationProfileControl = new FormControl<Profile>(
81-
'openid4vp',
82-
{ nonNullable: true }
83-
);
84-
93+
presentationProfileControl = new FormControl<Profile>(DefaultProfile, {
94+
nonNullable: true,
95+
});
8596

8697
private readonly _formBuilder = inject(FormBuilder);
8798
formGroup = this._formBuilder.group({
@@ -90,8 +101,9 @@ export class HomeComponent implements OnDestroy {
90101

91102
selectedAttestations: AttestationSelection[] | null = null;
92103
selectedAttributes: { [id: string]: string[] } | null = {};
93-
selectedRequestUriMethod: RequestUriMethod = 'get';
94-
selectedProfile: Profile = 'openid4vp';
104+
selectedRequestUriMethod: RequestUriMethod = DefaultRequestUriMethod;
105+
selectedProfile: Profile = DefaultProfile;
106+
authorizationRequestUri: string = DEFAULT_SCHEME;
95107

96108
initializationRequest: TransactionInitializationRequest | null = null;
97109

@@ -104,21 +116,23 @@ export class HomeComponent implements OnDestroy {
104116

105117
handleSelectionChangedEvent($event: AttestationSelection[]) {
106118
this.selectedAttestations = $event;
107-
119+
108120
if (this.selectedAttestations) {
109-
this.selectedAttestations.forEach(attestation => {
121+
this.selectedAttestations.forEach((attestation) => {
110122
const attestationDef = SUPPORTED_ATTESTATIONS[attestation.type];
111123
if (attestationDef) {
112124
const neverSelectivelyDisclosableAttributes = attestationDef.dataSet
113-
.filter(dataElement => dataElement.selectivelyDisclosable === 'never')
114-
.map(dataElement => dataElement.identifier);
125+
.filter(
126+
(dataElement) => dataElement.selectivelyDisclosable === 'never'
127+
)
128+
.map((dataElement) => dataElement.identifier);
115129
if (neverSelectivelyDisclosableAttributes.length > 0) {
116-
this.selectedAttributes![attestation.type] = neverSelectivelyDisclosableAttributes;
130+
this.selectedAttributes![attestation.type] =
131+
neverSelectivelyDisclosableAttributes;
117132
}
118133
}
119134
});
120135
}
121-
122136
}
123137

124138
handleAttributesCollectedEvent($event: AttributesSelectionEvent) {
@@ -165,21 +179,37 @@ export class HomeComponent implements OnDestroy {
165179
}
166180
}
167181

182+
handleAuthorizationSchemeChangedEvent($event: string) {
183+
this.authorizationRequestUri = $event;
184+
if (this.selectedAttestations && this.selectedAttributes) {
185+
this.initializationRequest = this.prepareInitializationRequest(
186+
this.selectedAttestations,
187+
this.selectedAttributes,
188+
this.selectedRequestUriMethod,
189+
this.selectedProfile
190+
);
191+
} else {
192+
this.initializationRequest = null;
193+
}
194+
}
195+
168196
private prepareInitializationRequest(
169197
selectedAttestations: AttestationSelection[],
170198
selectedAttributes: { [id: string]: string[] },
171199
selectedRequestUriMethod: RequestUriMethod,
172200
selectedProfile: Profile
173201
): TransactionInitializationRequest {
174-
175-
const issuerChain = this.sessionStorageService.get(ISSUER_CHAIN) ?? undefined;
202+
const issuerChain =
203+
this.sessionStorageService.get(ISSUER_CHAIN) ?? undefined;
176204

177205
return this.dcqlService.dcqlPresentationRequest(
178206
selectedAttestations,
179207
selectedAttributes,
180208
selectedRequestUriMethod,
181209
selectedProfile,
182-
issuerChain);
210+
this.authorizationRequestUri,
211+
issuerChain
212+
);
183213
}
184214

185215
proceedToInvokeWallet() {
@@ -196,21 +226,32 @@ export class HomeComponent implements OnDestroy {
196226
}
197227

198228
attestationsSelected(): boolean {
199-
return this.selectedAttestations !== null
200-
&& this.selectedAttestations
201-
.filter((attestation) =>
202-
attestation.format !== null && attestation.attributeSelectionMethod !== null
203-
).
204-
length > 0;
229+
return (
230+
this.selectedAttestations !== null &&
231+
this.selectedAttestations.filter(
232+
(attestation) =>
233+
attestation.format !== null &&
234+
attestation.attributeSelectionMethod !== null
235+
).length > 0
236+
);
205237
}
206238

207239
attributesSelected(): boolean {
208-
return this.selectedAttestations !== null
209-
&& this.selectedAttestations.filter((attestation) => {
210-
if(attestation.attributeSelectionMethod === AttributeSelectionMethod.SELECTABLE) {
211-
return this.selectedAttributes?.[attestation.type]?.length?? 0 > 0;
212-
} else return attestation.attributeSelectionMethod === AttributeSelectionMethod.ALL_ATTRIBUTES;
213-
}).length === this.selectedAttestations.length;
240+
return (
241+
this.selectedAttestations !== null &&
242+
this.selectedAttestations.filter((attestation) => {
243+
if (
244+
attestation.attributeSelectionMethod ===
245+
AttributeSelectionMethod.SELECTABLE
246+
) {
247+
return this.selectedAttributes?.[attestation.type]?.length ?? 0 > 0;
248+
} else
249+
return (
250+
attestation.attributeSelectionMethod ===
251+
AttributeSelectionMethod.ALL_ATTRIBUTES
252+
);
253+
}).length === this.selectedAttestations.length
254+
);
214255
}
215256

216257
canProceed() {

0 commit comments

Comments
 (0)