Skip to content

Commit

Permalink
feat: Add support for response_uri and redirect_uri to payloads and l…
Browse files Browse the repository at this point in the history
…ogic
  • Loading branch information
nklomp committed Oct 2, 2023
1 parent cbc81ab commit 00c650b
Show file tree
Hide file tree
Showing 5 changed files with 300 additions and 15 deletions.
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
"@digitalcredentials/ed25519-signature-2020": "^3.0.2",
"@digitalcredentials/jsonld-signatures": "^9.3.2",
"@digitalcredentials/vc": "^6.0.0",
"@transmute/ed25519-key-pair": "0.7.0-unstable.81",
"@transmute/ed25519-signature-2018": "^0.7.0-unstable.81",
"@transmute/did-key-ed25519": "^0.3.0-unstable.10",
"did-resolver": "^4.1.0",
"@types/jest": "^29.5.3",
"@types/language-tags": "^1.0.1",
"@types/uuid": "^9.0.1",
Expand Down
34 changes: 27 additions & 7 deletions src/authorization-request/AuthorizationRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,21 @@ import {
PassBy,
RequestObjectJwt,
RequestObjectPayload,
RequestStateInfo,
RequestStateInfo, ResponseURIType,
RPRegistrationMetadataPayload,
Schema,
SIOPErrors,
SupportedVersion,
VerifiedAuthorizationRequest,
VerifiedJWT,
VerifiedJWT
} from '../types';

import { assertValidAuthorizationRequestOpts, assertValidVerifyAuthorizationRequestOpts } from './Opts';
import { assertValidRPRegistrationMedataPayload, checkWellknownDIDFromRequest, createAuthorizationRequestPayload } from './Payload';
import {
assertValidRPRegistrationMedataPayload,
checkWellknownDIDFromRequest,
createAuthorizationRequestPayload
} from './Payload';
import { URI } from './URI';
import { CreateAuthorizationRequestOpts, VerifyAuthorizationRequestOpts } from './types';

Expand Down Expand Up @@ -123,7 +127,7 @@ export class AuthorizationRequest {
const options: JWTVerifyOptions = {
...opts.verification?.resolveOpts?.jwtVerifyOpts,
resolver,
audience: getAudience(jwt),
audience: getAudience(jwt)
};

verifiedJwt = await verifyDidJWT(jwt, resolver, options);
Expand Down Expand Up @@ -159,9 +163,23 @@ export class AuthorizationRequest {
// TODO: We need to do something with the metadata probably
}
// When the response_uri parameter is present, the redirect_uri Authorization Request parameter MUST NOT be present. If the redirect_uri Authorization Request parameter is present when the Response Mode is direct_post, the Wallet MUST return an invalid_request Authorization Response error.
let responseURIType: ResponseURIType;
let responseURI: string;
if (mergedPayload.redirect_uri && mergedPayload.response_uri) {
throw new Error(`${SIOPErrors.INVALID_REQUEST}, redirect_uri cannot be used together with response_uri`);
} else if (mergedPayload.redirect_uri) {
responseURIType = 'redirect_uri';
responseURI = mergedPayload.redirect_uri;
} else if (mergedPayload.redirect_uri) {

Check failure on line 173 in src/authorization-request/AuthorizationRequest.ts

View workflow job for this annotation

GitHub Actions / build

This branch can never execute. Its condition is a duplicate or covered by previous conditions in the if-else-if chain
responseURIType = 'response_uri';
responseURI = mergedPayload.response_uri;
} else if (mergedPayload.client_id_scheme === 'redirect_uri' && mergedPayload.client_id) {
responseURIType = 'redirect_uri';
responseURI = mergedPayload.client_id;
} else {
throw new Error(`${SIOPErrors.INVALID_REQUEST}, redirect_uri or response_uri is needed`);
}

await checkWellknownDIDFromRequest(mergedPayload, opts);

// TODO: we need to verify somewhere that if response_mode is direct_post, that the response_uri may be present,
Expand All @@ -170,15 +188,17 @@ export class AuthorizationRequest {
const presentationDefinitions = await PresentationExchange.findValidPresentationDefinitions(mergedPayload, await this.getSupportedVersion());
return {
...verifiedJwt,
redirectURI: mergedPayload.redirect_uri,
responseURIType,
responseURI,
clientIdScheme: mergedPayload.client_id_scheme,
correlationId: opts.correlationId,
authorizationRequest: this,
verifyOpts: opts,
presentationDefinitions,
registrationMetadataPayload,
requestObject: this.requestObject,
authorizationRequestPayload: this.payload,
versions: await this.getSupportedVersionsFromPayload(),
versions: await this.getSupportedVersionsFromPayload()
};
}

Expand Down Expand Up @@ -218,7 +238,7 @@ export class AuthorizationRequest {
client_id: this.options.clientMetadata.client_id,
iat: requestObject.iat ?? this.payload.iat,
nonce: requestObject.nonce ?? this.payload.nonce,
state: this.payload.state,
state: this.payload.state
};
}

Expand Down
2 changes: 1 addition & 1 deletion src/op/OP.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ export class OP {
const correlationId = responseOpts?.correlationId || verifiedAuthorizationRequest.correlationId || uuidv4();
try {
// IF using DIRECT_POST, the response_uri takes precedence over the redirect_uri
let responseUri = verifiedAuthorizationRequest.redirectURI;
let responseUri = verifiedAuthorizationRequest.responseURI;
if (verifiedAuthorizationRequest.authorizationRequestPayload.response_mode === ResponseMode.DIRECT_POST) {
responseUri = verifiedAuthorizationRequest.authorizationRequestPayload.response_uri ?? responseUri;
}
Expand Down
9 changes: 7 additions & 2 deletions src/types/SIOP.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export interface RequestObjectPayload extends RequestCommonPayload, JWTPayload {
scope: string; // REQUIRED. As specified in Section 3.1.2 of [OpenID.Core].
response_type: ResponseType | string; // REQUIRED. Constant string value id_token.
client_id: string; // REQUIRED. RP's identifier at the Self-Issued OP.
client_id_scheme?: ClientIdScheme // The client_id_scheme enables deployments of this specification to use different mechanisms to obtain and validate metadata of the Verifier beyond the scope of [RFC6749]. The term client_id_scheme is used since the Verifier is acting as an OAuth 2.0 Client.
redirect_uri?: string; // REQUIRED before OID4VP v18, now optional because of response_uri. URI to which the Self-Issued OP Response will be sent
response_uri?: string; // New since OID4VP18 OPTIONAL. The Response URI to which the Wallet MUST send the Authorization Response using an HTTPS POST request as defined by the Response Mode direct_post. The Response URI receives all Authorization Response parameters as defined by the respective Response Type. When the response_uri parameter is present, the redirect_uri Authorization Request parameter MUST NOT be present. If the redirect_uri Authorization Request parameter is present when the Response Mode is direct_post, the Wallet MUST return an invalid_request Authorization Response error.
nonce: string;
Expand Down Expand Up @@ -110,8 +111,12 @@ export interface RequestRegistrationPayloadProperties {
registration_uri?: string; // OPTIONAL. This parameter is used by the RP to provide information about itself to a Self-Issued OP that would normally be provided to an OP during Dynamic RP Registration, as specified in 2.2.1.
}

export interface VerifiedAuthorizationRequest extends VerifiedJWT {
redirectURI: string;
export type ResponseURIType = 'response_uri' | 'redirect_uri'

export interface VerifiedAuthorizationRequest extends Partial<VerifiedJWT> {
responseURIType: ResponseURIType
responseURI?: string;
clientIdScheme?: string;
correlationId: string;
authorizationRequest: AuthorizationRequest;
authorizationRequestPayload: AuthorizationRequestPayload;
Expand Down
Loading

0 comments on commit 00c650b

Please sign in to comment.