-
Notifications
You must be signed in to change notification settings - Fork 20
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
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 10c4ca2
CWALL-174: save before switch to other branch
sanderPostma e522a3d
fix: (WIP) fixed all the build errors
sksadjad bba1eed
Merge branch 'refs/heads/develop' into feature/CWALL-174_impl-draft1-…
sksadjad ff88a64
fix: (WIP) refactored and fixed build. still have to fix 33 test case…
sksadjad d8c2c4f
fix: (WIP) refactored and fixed build. still have to fix 8 test cases…
sksadjad 06117c0
fix: (WIP) refactored and fixed parts of the logic for v1_0_13.
sksadjad dcf7439
fix: fixed sd jwt test with version 13
sksadjad e39bf71
fix: MetadataClient for version 13 and added better type distinction.…
sksadjad ccac046
fix: fixed some test cases
sksadjad d3b2f0c
fix: fixed the regex for pin
sksadjad 16f1673
fix: (WIP) skipped failing tests and made comment to fix them
sksadjad a069396
chore: updated pnpm-lock.yaml
sksadjad da46f08
CWALL-174: package lock
sanderPostma 2856644
fix: fixed createCredentialOfferURI signature
sksadjad 34b7ae9
Merge remote-tracking branch 'origin/feature/CWALL-174_impl-draft1-sa…
sksadjad ac64053
chore: prettier
sksadjad c5be065
fix: fixed ClientIssuerIT.spec
sksadjad ca32202
fix: fixed test type mismatch
sksadjad 215227e
fix: fixed test type mismatch
sksadjad a2b3c22
fix: fixed type mismatch in some files
sksadjad 54df45d
chore: added getter for authorization url in OpenID4VCIClientState
sksadjad 03c5d0d
chore: added getter for authorization url in OpenID4VCIClientState
sksadjad 479bea7
fix: added back the isEbsi function to the new version's OpenID4VCICl…
sksadjad f10d0b2
fix: added generic union types for frequently used types
sksadjad da039f0
chore: skipping ebsi test
sksadjad 72474d6
fix: added generic union types for frequently used types
sksadjad 88341ef
fix: added back optional vct to CredentialConfigurationSupportedV1_0_…
sksadjad c3ab207
chore: CredentialSupported to CredentialConfigurationSupported
sksadjad d7a5030
chore: replaced the type for VcIssuer to a general type
sksadjad 54daa9a
chore: added specific errors for general setter in VcIssuerBuilder
sksadjad 978a92b
refactor: updated the types in IssuerMetadataUtils
sksadjad 53bce06
fix: fixed the logic in creating credentialOffer uri
sksadjad a8ac2e3
fix: fixed the failing test for the credentialOfferUri
sksadjad 5655859
fix: changed the if param in the assertAlphanumericPin
sksadjad b8bb359
fix: changed the logic for pin validation
sksadjad 354e8ad
fix: for pin in IssuerTokenServer
sksadjad 8a6c16f
fix: fixed some issue in the IssuerMetadataUtils
sksadjad d348641
fix: fixed some issue in the IssuerMetadataUtils plus added some unit…
sksadjad bd7bfa0
CWALL-174: fixed createCredentialOfferEndpoint
sanderPostma 5eacd76
CWALL-174: createCredentialOfferEndpoint to 1.0.13
sanderPostma 50fbf40
CWALL-174: createCredentialOfferEndpoint to 1.0.13
sanderPostma d7b283a
dummy commit
sanderPostma 337775a
dummy commit
sanderPostma fc8cdf0
fix: fixed tests plus prettier
sksadjad cd8c11d
Merge remote-tracking branch 'origin/feature/CWALL-174_impl-draft1-sa…
sanderPostma 526ea0b
Rollup minor version
sanderPostma e6eaf17
CWALL-174: Rollup minor version
sanderPostma 25a6051
feat: created special type for CredentialRequest v1_0_13 and fixed th…
sksadjad b24d1ac
Merge remote-tracking branch 'origin/feature/CWALL-174_impl-draft1-sa…
sksadjad 125cb81
fix: changed the accepting type in VcIssuer
sksadjad File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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'; | ||
|
@@ -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); | ||
const issuer = | ||
opts.credentialIssuer ?? | ||
(credentialOffer ? getIssuerFromCredentialOfferPayload(credentialOffer.credential_offer) : (metadata?.issuer as string)); | ||
|
@@ -48,8 +53,9 @@ export class AccessTokenClient { | |
code, | ||
redirectUri, | ||
pin, | ||
pinMetadata, | ||
}), | ||
isPinRequired, | ||
pinMetadata, | ||
metadata, | ||
asOpts, | ||
issuerOpts, | ||
|
@@ -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, | ||
|
@@ -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; | ||
|
@@ -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-_]+$/; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.'); | ||
} | ||
} | ||
|
||
|
@@ -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); | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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?