Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/CWALL-174 based on Sander's work #108

Merged
merged 51 commits into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
d0769d0
CWALL-174: created branch & first v13 classes
sanderPostma Apr 24, 2024
10c4ca2
CWALL-174: save before switch to other branch
sanderPostma May 1, 2024
e522a3d
fix: (WIP) fixed all the build errors
sksadjad May 8, 2024
bba1eed
Merge branch 'refs/heads/develop' into feature/CWALL-174_impl-draft1-…
sksadjad May 8, 2024
ff88a64
fix: (WIP) refactored and fixed build. still have to fix 33 test case…
sksadjad May 10, 2024
d8c2c4f
fix: (WIP) refactored and fixed build. still have to fix 8 test cases…
sksadjad May 11, 2024
06117c0
fix: (WIP) refactored and fixed parts of the logic for v1_0_13.
sksadjad May 13, 2024
dcf7439
fix: fixed sd jwt test with version 13
sksadjad May 13, 2024
e39bf71
fix: MetadataClient for version 13 and added better type distinction.…
sksadjad May 16, 2024
ccac046
fix: fixed some test cases
sksadjad May 16, 2024
d3b2f0c
fix: fixed the regex for pin
sksadjad May 16, 2024
16f1673
fix: (WIP) skipped failing tests and made comment to fix them
sksadjad May 16, 2024
a069396
chore: updated pnpm-lock.yaml
sksadjad May 16, 2024
da46f08
CWALL-174: package lock
sanderPostma May 16, 2024
2856644
fix: fixed createCredentialOfferURI signature
sksadjad May 16, 2024
34b7ae9
Merge remote-tracking branch 'origin/feature/CWALL-174_impl-draft1-sa…
sksadjad May 16, 2024
ac64053
chore: prettier
sksadjad May 16, 2024
c5be065
fix: fixed ClientIssuerIT.spec
sksadjad May 16, 2024
ca32202
fix: fixed test type mismatch
sksadjad May 16, 2024
215227e
fix: fixed test type mismatch
sksadjad May 16, 2024
a2b3c22
fix: fixed type mismatch in some files
sksadjad May 16, 2024
54df45d
chore: added getter for authorization url in OpenID4VCIClientState
sksadjad May 16, 2024
03c5d0d
chore: added getter for authorization url in OpenID4VCIClientState
sksadjad May 16, 2024
479bea7
fix: added back the isEbsi function to the new version's OpenID4VCICl…
sksadjad May 17, 2024
f10d0b2
fix: added generic union types for frequently used types
sksadjad May 17, 2024
da039f0
chore: skipping ebsi test
sksadjad May 17, 2024
72474d6
fix: added generic union types for frequently used types
sksadjad May 17, 2024
88341ef
fix: added back optional vct to CredentialConfigurationSupportedV1_0_…
sksadjad May 17, 2024
c3ab207
chore: CredentialSupported to CredentialConfigurationSupported
sksadjad May 17, 2024
d7a5030
chore: replaced the type for VcIssuer to a general type
sksadjad May 17, 2024
54daa9a
chore: added specific errors for general setter in VcIssuerBuilder
sksadjad May 17, 2024
978a92b
refactor: updated the types in IssuerMetadataUtils
sksadjad May 17, 2024
53bce06
fix: fixed the logic in creating credentialOffer uri
sksadjad May 17, 2024
a8ac2e3
fix: fixed the failing test for the credentialOfferUri
sksadjad May 17, 2024
5655859
fix: changed the if param in the assertAlphanumericPin
sksadjad May 17, 2024
b8bb359
fix: changed the logic for pin validation
sksadjad May 17, 2024
354e8ad
fix: for pin in IssuerTokenServer
sksadjad May 17, 2024
8a6c16f
fix: fixed some issue in the IssuerMetadataUtils
sksadjad May 21, 2024
d348641
fix: fixed some issue in the IssuerMetadataUtils plus added some unit…
sksadjad May 21, 2024
bd7bfa0
CWALL-174: fixed createCredentialOfferEndpoint
sanderPostma May 21, 2024
5eacd76
CWALL-174: createCredentialOfferEndpoint to 1.0.13
sanderPostma May 22, 2024
50fbf40
CWALL-174: createCredentialOfferEndpoint to 1.0.13
sanderPostma May 22, 2024
d7b283a
dummy commit
sanderPostma May 22, 2024
337775a
dummy commit
sanderPostma May 22, 2024
fc8cdf0
fix: fixed tests plus prettier
sksadjad May 22, 2024
cd8c11d
Merge remote-tracking branch 'origin/feature/CWALL-174_impl-draft1-sa…
sanderPostma May 22, 2024
526ea0b
Rollup minor version
sanderPostma May 22, 2024
e6eaf17
CWALL-174: Rollup minor version
sanderPostma May 22, 2024
25a6051
feat: created special type for CredentialRequest v1_0_13 and fixed th…
sksadjad May 23, 2024
b24d1ac
Merge remote-tracking branch 'origin/feature/CWALL-174_impl-draft1-sa…
sksadjad May 23, 2024
125cb81
fix: changed the accepting type in VcIssuer
sksadjad May 23, 2024
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
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"packages": ["packages/*"],
"version": "0.10.3",
"version": "0.11.0",
"npmClient": "pnpm",
"command": {
"publish": {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sphereon/oid4vci-workspace",
"version": "0.5.0",
"version": "0.11.0",
"description": "OpenID for Verifiable Credential Issuance workspace",
"author": "Sphereon",
"license": "Apache-2.0",
Expand Down
31 changes: 29 additions & 2 deletions packages/callback-example/lib/IssuerCallback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Ed25519Signature2020 } from '@digitalcredentials/ed25519-signature-2020
import { Ed25519VerificationKey2020 } from '@digitalcredentials/ed25519-verification-key-2020'
import { securityLoader } from '@digitalcredentials/security-document-loader'
import vc from '@digitalcredentials/vc'
import { CredentialRequestV1_0_11 } from '@sphereon/oid4vci-common'
import { CredentialRequest, CredentialRequestV1_0_11 } from '@sphereon/oid4vci-common'
import { CredentialIssuanceInput } from '@sphereon/oid4vci-issuer'
import { CompactSdJwtVc, W3CVerifiableCredential } from '@sphereon/ssi-types'

Expand All @@ -15,7 +15,7 @@ export const generateDid = async () => {
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const getIssuerCallback = (credential: CredentialIssuanceInput, keyPair: any, verificationMethod: string) => {
export const getIssuerCallbackV1_0_11 = (credential: CredentialIssuanceInput, keyPair: any, verificationMethod: string) => {
if (!credential) {
throw new Error('A credential needs to be provided')
}
Expand All @@ -33,6 +33,33 @@ export const getIssuerCallback = (credential: CredentialIssuanceInput, keyPair:
return await vc.issue({ credential, suite, documentLoader })
}
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const getIssuerCallbackV1_0_13 = (
credential: CredentialIssuanceInput,
credentialRequest: CredentialRequest,
keyPair: any,
verificationMethod: string,
) => {
if (!credential) {
throw new Error('A credential needs to be provided')
}

return async (_opts: {
credentialRequest: CredentialRequest
credential: CredentialIssuanceInput
format?: string
jwtVerifyResult: any // Adjust type if necessary
}): Promise<W3CVerifiableCredential | CompactSdJwtVc> => {
const documentLoader = securityLoader().build()
const verificationKey: any = Array.from(keyPair.values())[0]
const keys = await Ed25519VerificationKey2020.from({ ...verificationKey })
const suite = new Ed25519Signature2020({ key: keys })
suite.verificationMethod = verificationMethod
return await vc.issue({ credential, suite, documentLoader })
}
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const verifyCredential = async (credential: W3CVerifiableCredential, keyPair: any, verificationMethod: string): Promise<any> => {
const documentLoader = securityLoader().build()
Expand Down
45 changes: 27 additions & 18 deletions packages/callback-example/lib/__tests__/issuerCallback.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import { CredentialRequestClient, CredentialRequestClientBuilder, ProofOfPossess
import {
Alg,
CNonceState,
CredentialSupported,
CredentialConfigurationSupportedV1_0_13,
CredentialIssuerMetadataV1_0_13,
CredentialRequest,
IssuerCredentialSubjectDisplay,
IssueStatus,
Jwt,
Expand All @@ -13,17 +15,17 @@ import {
ProofOfPossession,
} from '@sphereon/oid4vci-common'
import { CredentialOfferSession } from '@sphereon/oid4vci-common/dist'
import { CredentialSupportedBuilderV1_11, VcIssuer, VcIssuerBuilder } from '@sphereon/oid4vci-issuer'
import { CredentialSupportedBuilderV1_13, VcIssuer, VcIssuerBuilder } from '@sphereon/oid4vci-issuer'
import { MemoryStates } from '@sphereon/oid4vci-issuer'
import { CredentialDataSupplierResult } from '@sphereon/oid4vci-issuer/dist/types'
import { ICredential, IProofPurpose, IProofType, W3CVerifiableCredential } from '@sphereon/ssi-types'
import { DIDDocument } from 'did-resolver'
import * as jose from 'jose'

import { generateDid, getIssuerCallback, verifyCredential } from '../IssuerCallback'
import { generateDid, getIssuerCallbackV1_0_11, getIssuerCallbackV1_0_13, verifyCredential } from '../IssuerCallback'

const INITIATION_TEST_URI =
'openid-initiate-issuance://?credential_type=OpenBadgeCredential&issuer=https%3A%2F%2Fjff%2Ewalt%2Eid%2Fissuer-api%2Foidc%2F&pre-authorized_code=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhOTUyZjUxNi1jYWVmLTQ4YjMtODIxYy00OTRkYzgyNjljZjAiLCJwcmUtYXV0aG9yaXplZCI6dHJ1ZX0.YE5DlalcLC2ChGEg47CQDaN1gTxbaQqSclIVqsSAUHE&user_pin_required=false'
'openid-credential-offer://?credential_offer=%7B%22credential_issuer%22:%22https://credential-issuer.example.com%22,%22credential_configuration_ids%22:%5B%22UniversityDegreeCredential%22%5D,%22grants%22:%7B%22urn:ietf:params:oauth:grant-type:pre-authorized_code%22:%7B%22pre-authorized_code%22:%22oaKazRN8I0IbtZ0C7JuMn5%22,%22tx_code%22:%7B%22input_mode%22:%22text%22,%22description%22:%22Please%20enter%20the%20serial%20number%20of%20your%20physical%20drivers%20license%22%7D%7D%7D%7D'
const IDENTIPROOF_ISSUER_URL = 'https://example.com/credential'
const kid = 'did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1'
let keypair: KeyPair // Proof of Possession JWT
Expand All @@ -37,7 +39,7 @@ async function proofOfPossessionCallbackFunction(args: Jwt, kid?: string): Promi
}
return await new jose.SignJWT({ ...args.payload })
.setProtectedHeader({ ...args.header })
.setIssuedAt(args.payload.iat ?? Math.round(+new Date()/1000))
.setIssuedAt(args.payload.iat ?? Math.round(+new Date() / 1000))
.setIssuer(kid)
.setAudience(args.payload.aud)
.setExpirationTime('2h')
Expand Down Expand Up @@ -85,12 +87,14 @@ describe('issuerCallback', () => {
const clientId = 'sphereon:wallet'

beforeAll(async () => {
const credentialsSupported: CredentialSupported = new CredentialSupportedBuilderV1_11()
.withCryptographicSuitesSupported('ES256K')
const credentialsSupported: Record<string, CredentialConfigurationSupportedV1_0_13> = new CredentialSupportedBuilderV1_13()
.withCredentialSigningAlgValuesSupported('ES256K')
.withCryptographicBindingMethod('did')
.withFormat('jwt_vc_json')
.withTypes('VerifiableCredential')
.withId('UniversityDegree_JWT')
.withCredentialName('UniversityDegree_JWT')
.withCredentialDefinition({
type: ['VerifiableCredential', 'UniversityDegree_JWT'],
})
.withCredentialSupportedDisplay({
name: 'University Credential',
locale: 'en-US',
Expand Down Expand Up @@ -141,14 +145,14 @@ describe('issuerCallback', () => {
const nonces = new MemoryStates<CNonceState>()
await nonces.set('test_value', { cNonce: 'test_value', createdAt: +new Date(), issuerState: 'existing-state' })
vcIssuer = new VcIssuerBuilder<DIDDocument>()
.withAuthorizationServer('https://authorization-server')
.withAuthorizationServers('https://authorization-server')
.withCredentialEndpoint('https://credential-endpoint')
.withCredentialIssuer(IDENTIPROOF_ISSUER_URL)
.withIssuerDisplay({
name: 'example issuer',
locale: 'en-US',
})
.withCredentialsSupported(credentialsSupported)
.withCredentialConfigurationsSupported(credentialsSupported)
.withCredentialOfferStateManager(stateManager)
.withCNonceStateManager(nonces)
.withJWTVerifyCallback(verifyCallbackFunction)
Expand Down Expand Up @@ -192,7 +196,7 @@ describe('issuerCallback', () => {
credentialSubject: {},
issuanceDate: new Date().toISOString(),
}
const vc = await getIssuerCallback(credential, didKey.keyPairs, didKey.didDocument.verificationMethod[0].id)({})
const vc = await getIssuerCallbackV1_0_11(credential, didKey.keyPairs, didKey.didDocument.verificationMethod[0].id)({})
expect(vc).toEqual({
'@context': ['https://www.w3.org/2018/credentials/v1', 'https://w3id.org/security/suites/ed25519-2020/v1'],
credentialSubject: {},
Expand All @@ -211,9 +215,13 @@ describe('issuerCallback', () => {
expect.objectContaining({ verified: true }),
)
})

it('Should pass requesting a verifiable credential using the client', async () => {
const credReqClient = (await CredentialRequestClientBuilder.fromURI({ uri: INITIATION_TEST_URI }))
.withCredentialEndpoint('https://oidc4vci.demo.spruceid.com/credential')
.withCredentialEndpointFromMetadata({
credential_configurations_supported: { VeriCred: { format: 'jwt_vc_json' } },
} as unknown as CredentialIssuerMetadataV1_0_13)
.withFormat('jwt_vc_json')
.withCredentialType('credentialType')
.withToken('token')
Expand All @@ -236,33 +244,34 @@ describe('issuerCallback', () => {
callbacks: {
signCallback: proofOfPossessionCallbackFunction,
},
version: OpenId4VCIVersion.VER_1_0_11,
version: OpenId4VCIVersion.VER_1_0_13,
})
.withClientId(clientId)
.withKid(kid)
.build()

const credentialRequestClient = new CredentialRequestClient(credReqClient)
const credentialRequest = await credentialRequestClient.createCredentialRequest({
credentialTypes: ['VerifiableCredential'],
const credentialRequest: CredentialRequest = await credentialRequestClient.createCredentialRequest({
credentialType: 'VerifiableCredential',
format: 'jwt_vc_json',
proofInput: proof,
version: OpenId4VCIVersion.VER_1_0_11,
version: OpenId4VCIVersion.VER_1_0_13,
})

expect(credentialRequest).toEqual({
format: 'jwt_vc_json',
proof: {
jwt: expect.stringContaining('eyJhbGciOiJFUzI1NiIsImtpZCI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFj'),
proof_type: 'jwt',
},
types: ['VerifiableCredential'],
credential_identifier: 'VerifiableCredential',
})

const credentialResponse = await vcIssuer.issueCredential({
credentialRequest: credentialRequest,
credential,
responseCNonce: state,
credentialSignerCallback: getIssuerCallback(credential, didKey.keyPairs, didKey.didDocument.verificationMethod[0].id),
credentialSignerCallback: getIssuerCallbackV1_0_13(credential, credentialRequest, didKey.keyPairs, didKey.didDocument.verificationMethod[0].id),
})

expect(credentialResponse).toEqual({
Expand Down
2 changes: 1 addition & 1 deletion packages/callback-example/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { getIssuerCallback, generateDid, verifyCredential } from './IssuerCallback'
export { getIssuerCallbackV1_0_11, generateDid, verifyCredential } from './IssuerCallback'
2 changes: 1 addition & 1 deletion packages/callback-example/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sphereon/oid4vci-callback-example",
"version": "0.10.3",
"version": "0.11.0",
"description": "OpenID 4 Verifiable Credential Issuance issuer callback example",
"source": "lib/index.ts",
"main": "dist/index.js",
Expand Down
76 changes: 54 additions & 22 deletions packages/client/lib/AccessTokenClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,20 @@ import {
assertedUniformCredentialOffer,
AuthorizationServerOpts,
AuthzFlowType,
CredentialOfferPayloadV1_0_13,
CredentialOfferV1_0_13,
determineSpecVersionFromOffer,
EndpointMetadata,
getIssuerFromCredentialOfferPayload,
GrantTypes,
IssuerOpts,
JsonURIMode,
OpenId4VCIVersion,
OpenIDResponse,
PRE_AUTH_CODE_LITERAL,
TokenErrorResponse,
toUniformCredentialOfferRequest,
TxCodeAndPinRequired,
UniformCredentialOfferPayload,
} from '@sphereon/oid4vci-common';
import { ObjectUtils } from '@sphereon/ssi-types';
Expand All @@ -29,7 +34,7 @@ export class AccessTokenClient {
const { asOpts, pin, codeVerifier, code, redirectUri, metadata } = opts;

const credentialOffer = opts.credentialOffer ? await assertedUniformCredentialOffer(opts.credentialOffer) : undefined;
const isPinRequired = credentialOffer && this.isPinRequiredValue(credentialOffer.credential_offer);
const pinMetadata: TxCodeAndPinRequired | undefined = credentialOffer && this.getPinMetadata(credentialOffer.credential_offer);
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we keep the isPinRequired as well?

const issuer =
opts.credentialIssuer ??
(credentialOffer ? getIssuerFromCredentialOfferPayload(credentialOffer.credential_offer) : (metadata?.issuer as string));
Expand All @@ -48,8 +53,9 @@ export class AccessTokenClient {
code,
redirectUri,
pin,
pinMetadata,
}),
isPinRequired,
pinMetadata,
metadata,
asOpts,
issuerOpts,
Expand All @@ -58,18 +64,18 @@ export class AccessTokenClient {

public async acquireAccessTokenUsingRequest({
accessTokenRequest,
isPinRequired,
pinMetadata,
metadata,
asOpts,
issuerOpts,
}: {
accessTokenRequest: AccessTokenRequest;
isPinRequired?: boolean;
pinMetadata?: TxCodeAndPinRequired;
metadata?: EndpointMetadata;
asOpts?: AuthorizationServerOpts;
issuerOpts?: IssuerOpts;
}): Promise<OpenIDResponse<AccessTokenResponse>> {
this.validate(accessTokenRequest, isPinRequired);
this.validate(accessTokenRequest, pinMetadata);

const requestTokenURL = AccessTokenClient.determineTokenURL({
asOpts,
Expand All @@ -86,15 +92,19 @@ export class AccessTokenClient {

public async createAccessTokenRequest(opts: AccessTokenRequestOpts): Promise<AccessTokenRequest> {
const { asOpts, pin, codeVerifier, code, redirectUri } = opts;
const credentialOfferRequest = opts.credentialOffer ? await toUniformCredentialOfferRequest(opts.credentialOffer) : undefined;
const credentialOfferRequest =
opts.credentialOffer &&
determineSpecVersionFromOffer(opts.credentialOffer as CredentialOfferPayloadV1_0_13).valueOf() <= OpenId4VCIVersion.VER_1_0_13.valueOf()
? await toUniformCredentialOfferRequest(opts.credentialOffer as CredentialOfferV1_0_13)
: undefined;
const request: Partial<AccessTokenRequest> = {};

if (asOpts?.clientId) {
request.client_id = asOpts.clientId;
}

if (credentialOfferRequest?.supportedFlows.includes(AuthzFlowType.PRE_AUTHORIZED_CODE_FLOW)) {
this.assertNumericPin(this.isPinRequiredValue(credentialOfferRequest.credential_offer), pin);
this.assertAlphanumericPin(opts.pinMetadata, pin);
request.user_pin = pin;

request.grant_type = GrantTypes.PRE_AUTHORIZED_CODE;
Expand Down Expand Up @@ -132,28 +142,50 @@ export class AccessTokenClient {
}
}

private isPinRequiredValue(requestPayload: UniformCredentialOfferPayload): boolean {
let isPinRequired = false;
private getPinMetadata(requestPayload: UniformCredentialOfferPayload): TxCodeAndPinRequired {
if (!requestPayload) {
throw new Error(TokenErrorResponse.invalid_request);
}
const issuer = getIssuerFromCredentialOfferPayload(requestPayload);
if (requestPayload.grants?.['urn:ietf:params:oauth:grant-type:pre-authorized_code']) {
isPinRequired = requestPayload.grants['urn:ietf:params:oauth:grant-type:pre-authorized_code']?.user_pin_required ?? false;
}

const grantDetails = requestPayload.grants?.['urn:ietf:params:oauth:grant-type:pre-authorized_code'];
const isPinRequired = !!grantDetails?.tx_code ?? false;

debug(`Pin required for issuer ${issuer}: ${isPinRequired}`);
return isPinRequired;
return {
txCode: grantDetails?.tx_code,
isPinRequired,
};
}

private assertNumericPin(isPinRequired?: boolean, pin?: string): void {
if (isPinRequired) {
if (!pin || !/^\d{1,8}$/.test(pin)) {
debug(`Pin is not 1 to 8 digits long`);
throw new Error('A valid pin consisting of maximal 8 numeric characters must be present.');
private assertAlphanumericPin(pinMeta?: TxCodeAndPinRequired, pin?: string): void {
if (pinMeta && pinMeta.isPinRequired) {
let regex;

if (pinMeta.txCode) {
const { input_mode, length } = pinMeta.txCode;

if (input_mode === 'numeric') {
// Create a regex for numeric input. If no length specified, allow any length of numeric input.
regex = length ? new RegExp(`^\\d{1,${length}}$`) : /^\d+$/;
} else if (input_mode === 'text') {
// Create a regex for text input. If no length specified, allow any length of alphanumeric input.
regex = length ? new RegExp(`^[a-zA-Z0-9]{1,${length}}$`) : /^[a-zA-Z0-9]+$/;
}
}

// Default regex for alphanumeric with no specific length limit if no input_mode is specified.
regex = regex || /^[a-zA-Z0-9]+$|^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+$/;
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably makes more sense to move this before the if statements and let these overwrite it instead of the || yo are doing now


if (!pin || !regex.test(pin)) {
debug(
`Pin is not valid. Expected format: ${pinMeta?.txCode?.input_mode || 'alphanumeric'}, Length: up to ${pinMeta?.txCode?.length || 'any number of'} characters`,
);
throw new Error('A valid pin must be present according to the specified transaction code requirements.');
}
} else if (pin) {
debug(`Pin set, whilst not required`);
throw new Error('Cannot set a pin, when the pin is not required.');
debug('Pin set, whilst not required');
throw new Error('Cannot set a pin when the pin is not required.');
}
}

Expand All @@ -177,11 +209,11 @@ export class AccessTokenClient {
throw new Error('Authorization flow requires the code to be present');
}
}
private validate(accessTokenRequest: AccessTokenRequest, isPinRequired?: boolean): void {
private validate(accessTokenRequest: AccessTokenRequest, pinMeta?: TxCodeAndPinRequired): void {
if (accessTokenRequest.grant_type === GrantTypes.PRE_AUTHORIZED_CODE) {
this.assertPreAuthorizedGrantType(accessTokenRequest.grant_type);
this.assertNonEmptyPreAuthorizedCode(accessTokenRequest);
this.assertNumericPin(isPinRequired, accessTokenRequest.user_pin);
this.assertAlphanumericPin(pinMeta, accessTokenRequest.user_pin);
} else if (accessTokenRequest.grant_type === GrantTypes.AUTHORIZATION_CODE) {
this.assertAuthorizationGrantType(accessTokenRequest.grant_type);
this.assertNonEmptyCodeVerifier(accessTokenRequest);
Expand Down
Loading