Skip to content

Commit

Permalink
chore: Merge latest changes
Browse files Browse the repository at this point in the history
  • Loading branch information
nklomp committed Jan 27, 2025
1 parent 9866b0a commit d1918ed
Show file tree
Hide file tree
Showing 30 changed files with 357 additions and 356 deletions.
71 changes: 30 additions & 41 deletions packages/client/lib/AuthorizationCodeClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ import {
PKCEOpts,
PushedAuthorizationResponse,
RequestObjectOpts,
ResponseType
} from '@sphereon/oid4vci-common'
ResponseType,
} from '@sphereon/oid4vci-common';
import Debug from 'debug';

import { MetadataClient } from './MetadataClient'
import { MetadataClient } from './MetadataClient';
import { ProofOfPossessionBuilder } from './ProofOfPossessionBuilder';

const debug = Debug('sphereon:oid4vci');
Expand Down Expand Up @@ -280,62 +280,51 @@ const handleLocations = (endpointMetadata: EndpointMetadataResultV1_0_13, author
return authorizationDetails;
};

export const acquireAuthorizationChallengeAuthCode = async (opts: AuthorizationChallengeRequestOpts): Promise<OpenIDResponse<AuthorizationChallengeCodeResponse>> => {
const { metadata } = opts
export const acquireAuthorizationChallengeAuthCode = async (
opts: AuthorizationChallengeRequestOpts,
): Promise<OpenIDResponse<AuthorizationChallengeCodeResponse>> => {
const { metadata } = opts;

const issuer = opts.credentialIssuer ?? opts?.metadata?.issuer as string
const issuer = opts.credentialIssuer ?? (opts?.metadata?.issuer as string);
if (!issuer) {
throw Error('Issuer required at this point');
}

const issuerOpts = {
issuer,
}
};

return await acquireAuthorizationChallengeAuthCodeUsingRequest({
authorizationChallengeRequest: await createAuthorizationChallengeRequest(opts),
metadata,
issuerOpts
issuerOpts,
});
}
};

export const acquireAuthorizationChallengeAuthCodeUsingRequest = async (
opts: {
authorizationChallengeRequest: CommonAuthorizationChallengeRequest,
metadata?: EndpointMetadata,
issuerOpts?: IssuerOpts
}
): Promise<OpenIDResponse<AuthorizationChallengeCodeResponse>> => {
const { authorizationChallengeRequest, issuerOpts } = opts
export const acquireAuthorizationChallengeAuthCodeUsingRequest = async (opts: {
authorizationChallengeRequest: CommonAuthorizationChallengeRequest;
metadata?: EndpointMetadata;
issuerOpts?: IssuerOpts;
}): Promise<OpenIDResponse<AuthorizationChallengeCodeResponse>> => {
const { authorizationChallengeRequest, issuerOpts } = opts;
const metadata = opts?.metadata
? opts?.metadata
: issuerOpts?.fetchMetadata
? await MetadataClient.retrieveAllMetadata(issuerOpts.issuer, { errorOnNotFound: false })
: undefined
const authorizationChallengeCodeUrl = metadata?.authorization_challenge_endpoint
: undefined;
const authorizationChallengeCodeUrl = metadata?.authorization_challenge_endpoint;

if (!authorizationChallengeCodeUrl) {
return Promise.reject(Error('Cannot determine authorization challenge endpoint URL'))
return Promise.reject(Error('Cannot determine authorization challenge endpoint URL'));
}

const response = await sendAuthorizationChallengeRequest(
authorizationChallengeCodeUrl,
authorizationChallengeRequest
);
const response = await sendAuthorizationChallengeRequest(authorizationChallengeCodeUrl, authorizationChallengeRequest);

return response
}
return response;
};

export const createAuthorizationChallengeRequest = async (opts: AuthorizationChallengeRequestOpts): Promise<CommonAuthorizationChallengeRequest> => {
const {
clientId,
issuerState,
authSession,
scope,
codeChallenge,
codeChallengeMethod,
presentationDuringIssuanceSession
} = opts;
const { clientId, issuerState, authSession, scope, codeChallenge, codeChallengeMethod, presentationDuringIssuanceSession } = opts;

const request: CommonAuthorizationChallengeRequest = {
client_id: clientId,
Expand All @@ -344,18 +333,18 @@ export const createAuthorizationChallengeRequest = async (opts: AuthorizationCha
scope,
code_challenge: codeChallenge,
code_challenge_method: codeChallengeMethod,
presentation_during_issuance_session: presentationDuringIssuanceSession
}
presentation_during_issuance_session: presentationDuringIssuanceSession,
};

return request
}
return request;
};

export const sendAuthorizationChallengeRequest = async (
authorizationChallengeCodeUrl: string,
authorizationChallengeRequest: CommonAuthorizationChallengeRequest,
opts?: { headers?: Record<string, string> }
opts?: { headers?: Record<string, string> },
): Promise<OpenIDResponse<AuthorizationChallengeCodeResponse>> => {
return await formPost(authorizationChallengeCodeUrl, convertJsonToURI(authorizationChallengeRequest, { mode: JsonURIMode.X_FORM_WWW_URLENCODED }), {
customHeaders: opts?.headers ? opts.headers : undefined,
});
}
};
2 changes: 1 addition & 1 deletion packages/client/lib/MetadataClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export class MetadataClient {
if (credentialIssuerMetadata.token_endpoint) {
token_endpoint = credentialIssuerMetadata.token_endpoint;
}
authorization_challenge_endpoint = credentialIssuerMetadata.authorization_challenge_endpoint
authorization_challenge_endpoint = credentialIssuerMetadata.authorization_challenge_endpoint;
if (credentialIssuerMetadata.authorization_servers) {
authorization_servers = credentialIssuerMetadata.authorization_servers as string[];
} else if (credentialIssuerMetadata.authorization_server) {
Expand Down
2 changes: 1 addition & 1 deletion packages/client/lib/MetadataClientV1_0_11.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export class MetadataClientV1_0_11 {
if (credentialIssuerMetadata.token_endpoint) {
token_endpoint = credentialIssuerMetadata.token_endpoint;
}
authorization_challenge_endpoint = credentialIssuerMetadata.authorization_challenge_endpoint
authorization_challenge_endpoint = credentialIssuerMetadata.authorization_challenge_endpoint;
if (credentialIssuerMetadata.authorization_server) {
authorization_server = credentialIssuerMetadata.authorization_server;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/client/lib/MetadataClientV1_0_13.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export class MetadataClientV1_0_13 {
if (credentialIssuerMetadata.token_endpoint) {
token_endpoint = credentialIssuerMetadata.token_endpoint;
}
authorization_challenge_endpoint = credentialIssuerMetadata.authorization_challenge_endpoint
authorization_challenge_endpoint = credentialIssuerMetadata.authorization_challenge_endpoint;
if (credentialIssuerMetadata.authorization_servers) {
authorization_servers = credentialIssuerMetadata.authorization_servers;
}
Expand Down
39 changes: 23 additions & 16 deletions packages/client/lib/OpenID4VCIClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,14 @@ import {
OpenId4VCIVersion,
PKCEOpts,
ProofOfPossessionCallbacks,
toAuthorizationResponsePayload
} from '@sphereon/oid4vci-common'
toAuthorizationResponsePayload,
} from '@sphereon/oid4vci-common';
import { CredentialFormat } from '@sphereon/ssi-types';
import Debug from 'debug';

import { AccessTokenClient } from './AccessTokenClient';
import { AccessTokenClientV1_0_11 } from './AccessTokenClientV1_0_11';
import {
acquireAuthorizationChallengeAuthCode,
createAuthorizationRequestUrl
} from './AuthorizationCodeClient'
import { acquireAuthorizationChallengeAuthCode, createAuthorizationRequestUrl } from './AuthorizationCodeClient';
import { createAuthorizationRequestUrlV1_0_11 } from './AuthorizationCodeClientV1_0_11';
import { CredentialOfferClient } from './CredentialOfferClient';
import { CredentialRequestOpts } from './CredentialRequestClient';
Expand Down Expand Up @@ -287,19 +284,23 @@ export class OpenID4VCIClient {
metadata: this.endpointMetadata,
credentialIssuer: this.getIssuer(),
clientId: this._state.clientId ?? this._state.authorizationRequestOpts?.clientId,
...opts
})
...opts,
});

if (response.errorBody) {
debug(`Authorization code error:\r\n${JSON.stringify(response.errorBody)}`);
const error = response.errorBody as AuthorizationChallengeErrorResponse
return Promise.reject(error)
const error = response.errorBody as AuthorizationChallengeErrorResponse;
return Promise.reject(error);
} else if (!response.successBody) {
debug(`Authorization code error. No success body`);
return Promise.reject(Error(`Retrieving an authorization code token from ${this._state.endpointMetadata?.authorization_challenge_endpoint} for issuer ${this.getIssuer()} failed as there was no success response body`))
return Promise.reject(
Error(
`Retrieving an authorization code token from ${this._state.endpointMetadata?.authorization_challenge_endpoint} for issuer ${this.getIssuer()} failed as there was no success response body`,
),
);
}

return { ...response.successBody }
return { ...response.successBody };
}

public async acquireAccessToken(
Expand All @@ -312,7 +313,7 @@ export class OpenID4VCIClient {
const { pin, clientId = this._state.clientId ?? this._state.authorizationRequestOpts?.clientId } = opts ?? {};
let { redirectUri } = opts ?? {};

const code = this.getAuthorizationCode(opts?.authorizationResponse, opts?.code)
const code = this.getAuthorizationCode(opts?.authorizationResponse, opts?.code);

if (opts?.codeVerifier) {
this._state.pkce.codeVerifier = opts.codeVerifier;
Expand Down Expand Up @@ -765,13 +766,19 @@ export class OpenID4VCIClient {
return authorizationRequestOpts;
}

private getAuthorizationCode = (authorizationResponse?: string | AuthorizationResponse | AuthorizationChallengeCodeResponse, code?: string): string | undefined => {
private getAuthorizationCode = (
authorizationResponse?: string | AuthorizationResponse | AuthorizationChallengeCodeResponse,
code?: string,
): string | undefined => {
if (authorizationResponse) {
this._state.authorizationCodeResponse = { ...toAuthorizationResponsePayload(authorizationResponse) };
} else if (code) {
this._state.authorizationCodeResponse = { code };
}

return (this._state.authorizationCodeResponse as AuthorizationResponse)?.code ?? (this._state.authorizationCodeResponse as AuthorizationChallengeCodeResponse)?.authorization_code;
}
return (
(this._state.authorizationCodeResponse as AuthorizationResponse)?.code ??
(this._state.authorizationCodeResponse as AuthorizationChallengeCodeResponse)?.authorization_code
);
};
}
36 changes: 23 additions & 13 deletions packages/client/lib/OpenID4VCIClientV1_0_11.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ import {
OpenId4VCIVersion,
PKCEOpts,
ProofOfPossessionCallbacks,
toAuthorizationResponsePayload
} from '@sphereon/oid4vci-common'
toAuthorizationResponsePayload,
} from '@sphereon/oid4vci-common';
import { CredentialFormat } from '@sphereon/ssi-types';
import Debug from 'debug';

import { AccessTokenClientV1_0_11 } from './AccessTokenClientV1_0_11';
import { acquireAuthorizationChallengeAuthCode } from './AuthorizationCodeClient'
import { acquireAuthorizationChallengeAuthCode } from './AuthorizationCodeClient';
import { createAuthorizationRequestUrlV1_0_11 } from './AuthorizationCodeClientV1_0_11';
import { CredentialOfferClientV1_0_11 } from './CredentialOfferClientV1_0_11';
import { CredentialRequestClientBuilderV1_0_11 } from './CredentialRequestClientBuilderV1_0_11';
Expand Down Expand Up @@ -265,19 +265,23 @@ export class OpenID4VCIClientV1_0_11 {
metadata: this.endpointMetadata,
credentialIssuer: this.getIssuer(),
clientId: this._state.clientId ?? this._state.authorizationRequestOpts?.clientId,
...opts
})
...opts,
});

if (response.errorBody) {
debug(`Authorization code error:\r\n${JSON.stringify(response.errorBody)}`);
const error = response.errorBody as AuthorizationChallengeErrorResponse
return Promise.reject(error)
const error = response.errorBody as AuthorizationChallengeErrorResponse;
return Promise.reject(error);
} else if (!response.successBody) {
debug(`Authorization code error. No success body`);
return Promise.reject(Error(`Retrieving an authorization code token from ${this._state.endpointMetadata?.authorization_challenge_endpoint} for issuer ${this.getIssuer()} failed as there was no success response body`))
return Promise.reject(
Error(
`Retrieving an authorization code token from ${this._state.endpointMetadata?.authorization_challenge_endpoint} for issuer ${this.getIssuer()} failed as there was no success response body`,
),
);
}

return { ...response.successBody }
return { ...response.successBody };
}

public async acquireAccessToken(
Expand All @@ -290,7 +294,7 @@ export class OpenID4VCIClientV1_0_11 {
const { pin, clientId = this._state.clientId ?? this._state.authorizationRequestOpts?.clientId } = opts ?? {};
let { redirectUri } = opts ?? {};

const code = this.getAuthorizationCode(opts?.authorizationResponse, opts?.code)
const code = this.getAuthorizationCode(opts?.authorizationResponse, opts?.code);

if (opts?.codeVerifier) {
this._state.pkce.codeVerifier = opts.codeVerifier;
Expand Down Expand Up @@ -693,13 +697,19 @@ export class OpenID4VCIClientV1_0_11 {
return authorizationRequestOpts;
}

private getAuthorizationCode = (authorizationResponse?: string | AuthorizationResponse | AuthorizationChallengeCodeResponse, code?: string): string | undefined => {
private getAuthorizationCode = (
authorizationResponse?: string | AuthorizationResponse | AuthorizationChallengeCodeResponse,
code?: string,
): string | undefined => {
if (authorizationResponse) {
this._state.authorizationCodeResponse = { ...toAuthorizationResponsePayload(authorizationResponse) };
} else if (code) {
this._state.authorizationCodeResponse = { code };
}

return (this._state.authorizationCodeResponse as AuthorizationResponse)?.code ?? (this._state.authorizationCodeResponse as AuthorizationChallengeCodeResponse)?.authorization_code;
}
return (
(this._state.authorizationCodeResponse as AuthorizationResponse)?.code ??
(this._state.authorizationCodeResponse as AuthorizationChallengeCodeResponse)?.authorization_code
);
};
}
39 changes: 23 additions & 16 deletions packages/client/lib/OpenID4VCIClientV1_0_13.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,13 @@ import {
OpenId4VCIVersion,
PKCEOpts,
ProofOfPossessionCallbacks,
toAuthorizationResponsePayload
} from '@sphereon/oid4vci-common'
toAuthorizationResponsePayload,
} from '@sphereon/oid4vci-common';
import { CredentialFormat } from '@sphereon/ssi-types';
import Debug from 'debug';

import { AccessTokenClient } from './AccessTokenClient';
import {
acquireAuthorizationChallengeAuthCode,
createAuthorizationRequestUrl
} from './AuthorizationCodeClient'
import { acquireAuthorizationChallengeAuthCode, createAuthorizationRequestUrl } from './AuthorizationCodeClient';
import { CredentialOfferClient } from './CredentialOfferClient';
import { CredentialRequestOpts } from './CredentialRequestClient';
import { CredentialRequestClientBuilderV1_0_13 } from './CredentialRequestClientBuilderV1_0_13';
Expand Down Expand Up @@ -272,19 +269,23 @@ export class OpenID4VCIClientV1_0_13 {
metadata: this.endpointMetadata,
credentialIssuer: this.getIssuer(),
clientId: this._state.clientId ?? this._state.authorizationRequestOpts?.clientId,
...opts
})
...opts,
});

if (response.errorBody) {
debug(`Authorization code error:\r\n${JSON.stringify(response.errorBody)}`);
const error = response.errorBody as AuthorizationChallengeErrorResponse
return Promise.reject(error)
const error = response.errorBody as AuthorizationChallengeErrorResponse;
return Promise.reject(error);
} else if (!response.successBody) {
debug(`Authorization code error. No success body`);
return Promise.reject(Error(`Retrieving an authorization code token from ${this._state.endpointMetadata?.authorization_challenge_endpoint} for issuer ${this.getIssuer()} failed as there was no success response body`))
return Promise.reject(
Error(
`Retrieving an authorization code token from ${this._state.endpointMetadata?.authorization_challenge_endpoint} for issuer ${this.getIssuer()} failed as there was no success response body`,
),
);
}

return { ...response.successBody }
return { ...response.successBody };
}

public async acquireAccessToken(
Expand All @@ -297,7 +298,7 @@ export class OpenID4VCIClientV1_0_13 {
const { pin, clientId = this._state.clientId ?? this._state.authorizationRequestOpts?.clientId } = opts ?? {};
let { redirectUri } = opts ?? {};

const code = this.getAuthorizationCode(opts?.authorizationResponse, opts?.code)
const code = this.getAuthorizationCode(opts?.authorizationResponse, opts?.code);

if (opts?.codeVerifier) {
this._state.pkce.codeVerifier = opts.codeVerifier;
Expand Down Expand Up @@ -796,13 +797,19 @@ export class OpenID4VCIClientV1_0_13 {
return authorizationRequestOpts;
}

private getAuthorizationCode = (authorizationResponse?: string | AuthorizationResponse | AuthorizationChallengeCodeResponse, code?: string): string | undefined => {
private getAuthorizationCode = (
authorizationResponse?: string | AuthorizationResponse | AuthorizationChallengeCodeResponse,
code?: string,
): string | undefined => {
if (authorizationResponse) {
this._state.authorizationCodeResponse = { ...toAuthorizationResponsePayload(authorizationResponse) };
} else if (code) {
this._state.authorizationCodeResponse = { code };
}

return (this._state.authorizationCodeResponse as AuthorizationResponse)?.code ?? (this._state.authorizationCodeResponse as AuthorizationChallengeCodeResponse)?.authorization_code;
}
return (
(this._state.authorizationCodeResponse as AuthorizationResponse)?.code ??
(this._state.authorizationCodeResponse as AuthorizationChallengeCodeResponse)?.authorization_code
);
};
}
Loading

0 comments on commit d1918ed

Please sign in to comment.