-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CWALL-174: created branch & first v13 classes
- Loading branch information
1 parent
dc70d52
commit d0769d0
Showing
2 changed files
with
265 additions
and
0 deletions.
There are no files selected for viewing
153 changes: 153 additions & 0 deletions
153
packages/issuer/lib/builder/CredentialSupportedBuilderV1_13.ts
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 |
---|---|---|
@@ -0,0 +1,153 @@ | ||
import { | ||
CredentialsSupportedDisplay, | ||
CredentialSupported, | ||
isFormat, | ||
isNotFormat, | ||
IssuerCredentialSubject, | ||
IssuerCredentialSubjectDisplay, | ||
OID4VCICredentialFormat, | ||
TokenErrorResponse, | ||
} from '@sphereon/oid4vci-common' | ||
|
||
export class CredentialSupportedBuilderV1_13 { | ||
format?: OID4VCICredentialFormat | ||
id?: string | ||
types?: string[] | ||
cryptographicBindingMethodsSupported?: ('jwk' | 'cose_key' | 'did' | string)[] | ||
cryptographicSuitesSupported?: ('jwt_vc' | 'ldp_vc' | string)[] | ||
display?: CredentialsSupportedDisplay[] | ||
credentialSubject?: IssuerCredentialSubject | ||
|
||
withFormat(credentialFormat: OID4VCICredentialFormat): CredentialSupportedBuilderV1_13 { | ||
this.format = credentialFormat | ||
return this | ||
} | ||
|
||
withId(id: string): CredentialSupportedBuilderV1_13 { | ||
this.id = id | ||
return this | ||
} | ||
|
||
addTypes(type: string | string[]): CredentialSupportedBuilderV1_13 { | ||
if (!Array.isArray(type)) { | ||
this.types = this.types ? [...this.types, type] : [type] | ||
} else { | ||
this.cryptographicBindingMethodsSupported = this.cryptographicBindingMethodsSupported | ||
? [...this.cryptographicBindingMethodsSupported, ...type] | ||
: type | ||
} | ||
return this | ||
} | ||
|
||
withTypes(type: string | string[]): CredentialSupportedBuilderV1_13 { | ||
if (this.format === 'vc+sd-jwt' && Array.isArray(type) && type.length > 1) { | ||
throw new Error('Only one type is allowed for vc+sd-jwt') | ||
} | ||
this.types = Array.isArray(type) ? type : [type] | ||
return this | ||
} | ||
|
||
addCryptographicBindingMethod(method: string | string[]): CredentialSupportedBuilderV1_13 { | ||
if (!Array.isArray(method)) { | ||
this.cryptographicBindingMethodsSupported = this.cryptographicBindingMethodsSupported | ||
? [...this.cryptographicBindingMethodsSupported, method] | ||
: [method] | ||
} else { | ||
this.cryptographicBindingMethodsSupported = this.cryptographicBindingMethodsSupported | ||
? [...this.cryptographicBindingMethodsSupported, ...method] | ||
: method | ||
} | ||
return this | ||
} | ||
|
||
withCryptographicBindingMethod(method: string | string[]): CredentialSupportedBuilderV1_13 { | ||
this.cryptographicBindingMethodsSupported = Array.isArray(method) ? method : [method] | ||
return this | ||
} | ||
|
||
addCryptographicSuitesSupported(suit: string | string[]): CredentialSupportedBuilderV1_13 { | ||
if (!Array.isArray(suit)) { | ||
this.cryptographicSuitesSupported = this.cryptographicSuitesSupported ? [...this.cryptographicSuitesSupported, suit] : [suit] | ||
} else { | ||
this.cryptographicSuitesSupported = this.cryptographicSuitesSupported ? [...this.cryptographicSuitesSupported, ...suit] : suit | ||
} | ||
return this | ||
} | ||
|
||
withCryptographicSuitesSupported(suit: string | string[]): CredentialSupportedBuilderV1_13 { | ||
this.cryptographicSuitesSupported = Array.isArray(suit) ? suit : [suit] | ||
return this | ||
} | ||
|
||
addCredentialSupportedDisplay(credentialDisplay: CredentialsSupportedDisplay | CredentialsSupportedDisplay[]): CredentialSupportedBuilderV1_13 { | ||
if (!Array.isArray(credentialDisplay)) { | ||
this.display = this.display ? [...this.display, credentialDisplay] : [credentialDisplay] | ||
} else { | ||
this.display = this.display ? [...this.display, ...credentialDisplay] : credentialDisplay | ||
} | ||
return this | ||
} | ||
|
||
withCredentialSupportedDisplay(credentialDisplay: CredentialsSupportedDisplay | CredentialsSupportedDisplay[]): CredentialSupportedBuilderV1_13 { | ||
this.display = Array.isArray(credentialDisplay) ? credentialDisplay : [credentialDisplay] | ||
return this | ||
} | ||
|
||
withCredentialSubjectDisplay(credentialSubject: IssuerCredentialSubject) { | ||
this.credentialSubject = credentialSubject | ||
return this | ||
} | ||
|
||
addCredentialSubjectPropertyDisplay( | ||
subjectProperty: string, | ||
issuerCredentialSubjectDisplay: IssuerCredentialSubjectDisplay, | ||
): CredentialSupportedBuilderV1_13 { | ||
if (!this.credentialSubject) { | ||
this.credentialSubject = {} | ||
} | ||
this.credentialSubject[subjectProperty] = issuerCredentialSubjectDisplay | ||
return this | ||
} | ||
|
||
public build(): CredentialSupported { | ||
if (!this.format) { | ||
throw new Error(TokenErrorResponse.invalid_request) | ||
} | ||
const credentialSupported: Partial<CredentialSupported> = { | ||
format: this.format, | ||
} | ||
if (!this.types) { | ||
throw new Error('types are required') | ||
} | ||
|
||
// SdJwtVc has a different format | ||
if (isFormat(credentialSupported, 'vc+sd-jwt')) { | ||
if (this.types.length > 1) { | ||
throw new Error('Only one type is allowed for vc+sd-jwt') | ||
} | ||
credentialSupported.vct = this.types[0] | ||
} | ||
// And else would work here, but this way we get the correct typing | ||
else if (isNotFormat(credentialSupported, 'vc+sd-jwt')) { | ||
credentialSupported.types = this.types | ||
|
||
if (this.credentialSubject) { | ||
credentialSupported.credentialSubject = this.credentialSubject | ||
} | ||
} | ||
|
||
if (this.cryptographicSuitesSupported) { | ||
credentialSupported.cryptographic_suites_supported = this.cryptographicSuitesSupported | ||
} | ||
if (this.cryptographicBindingMethodsSupported) { | ||
credentialSupported.cryptographic_binding_methods_supported = this.cryptographicBindingMethodsSupported | ||
} | ||
if (this.id) { | ||
credentialSupported.id = this.id | ||
} | ||
if (this.display) { | ||
credentialSupported.display = this.display | ||
} | ||
return credentialSupported as CredentialSupported | ||
} | ||
} |
112 changes: 112 additions & 0 deletions
112
packages/issuer/lib/builder/IssuerMetadataBuilderV1_13.ts
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 |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import { CredentialIssuerMetadata, CredentialSupported, MetadataDisplay } from '@sphereon/oid4vci-common' | ||
|
||
import { CredentialSupportedBuilderV1_13 } from './CredentialSupportedBuilderV1_13' | ||
import { DisplayBuilder } from './DisplayBuilder' | ||
|
||
export class IssuerMetadataBuilderV1_13 { | ||
credentialEndpoint: string | undefined | ||
credentialIssuer: string | undefined | ||
supportedBuilders: CredentialSupportedBuilderV1_13[] = [] | ||
supportedCredentials: CredentialSupported[] = [] | ||
displayBuilders: DisplayBuilder[] = [] | ||
display: MetadataDisplay[] = [] | ||
batchCredentialEndpoint?: string | ||
authorizationServers?: string[] | ||
tokenEndpoint?: string | ||
|
||
public withBatchCredentialEndpoint(batchCredentialEndpoint: string) { | ||
this.batchCredentialEndpoint = batchCredentialEndpoint | ||
throw Error(`Not supported yet`) | ||
} | ||
|
||
public withAuthorizationServers(authorizationServers: string[]) { | ||
this.authorizationServers = authorizationServers | ||
return this | ||
} | ||
|
||
public withAuthorizationServer(authorizationServer: string) { | ||
if(this.authorizationServers === undefined) { | ||
this.authorizationServers = [] | ||
} | ||
this.authorizationServers.push(authorizationServer) | ||
return this | ||
} | ||
|
||
public withTokenEndpoint(tokenEndpoint: string) { | ||
this.tokenEndpoint = tokenEndpoint | ||
return this | ||
} | ||
|
||
public withCredentialEndpoint(credentialEndpoint: string): IssuerMetadataBuilderV1_13 { | ||
this.credentialEndpoint = credentialEndpoint | ||
return this | ||
} | ||
|
||
public withCredentialIssuer(credentialIssuer: string): IssuerMetadataBuilderV1_13 { | ||
this.credentialIssuer = credentialIssuer | ||
return this | ||
} | ||
|
||
public newSupportedCredentialBuilder(): CredentialSupportedBuilderV1_13 { | ||
const builder = new CredentialSupportedBuilderV1_13() | ||
this.addSupportedCredentialBuilder(builder) | ||
return builder | ||
} | ||
|
||
public addSupportedCredentialBuilder(supportedCredentialBuilder: CredentialSupportedBuilderV1_13) { | ||
this.supportedBuilders.push(supportedCredentialBuilder) | ||
return this | ||
} | ||
|
||
public addSupportedCredential(supportedCredential: CredentialSupported) { | ||
this.supportedCredentials.push(supportedCredential) | ||
return this | ||
} | ||
|
||
public withIssuerDisplay(issuerDisplay: MetadataDisplay[] | MetadataDisplay): IssuerMetadataBuilderV1_13 { | ||
this.display = Array.isArray(issuerDisplay) ? issuerDisplay : [issuerDisplay] | ||
return this | ||
} | ||
|
||
public addDisplay(display: MetadataDisplay) { | ||
this.display.push(display) | ||
} | ||
|
||
public addDisplayBuilder(displayBuilder: DisplayBuilder) { | ||
this.displayBuilders.push(displayBuilder) | ||
} | ||
|
||
public newDisplayBuilder(): DisplayBuilder { | ||
const builder = new DisplayBuilder() | ||
this.addDisplayBuilder(builder) | ||
return builder | ||
} | ||
|
||
public build(): CredentialIssuerMetadata { | ||
if (!this.credentialIssuer) { | ||
throw Error('No credential issuer supplied') | ||
} else if (!this.credentialEndpoint) { | ||
throw Error('No credential endpoint supplied') | ||
} | ||
const supportedCredentials: CredentialSupported[] = [] | ||
supportedCredentials.push(...this.supportedCredentials) | ||
supportedCredentials.push(...this.supportedBuilders.map((builder) => builder.build())) | ||
if (supportedCredentials.length === 0) { | ||
throw Error('No supported credentials supplied') | ||
} | ||
|
||
const display: MetadataDisplay[] = [] | ||
display.push(...this.display) | ||
display.push(...this.displayBuilders.map((builder) => builder.build())) | ||
|
||
return { | ||
credential_issuer: this.credentialIssuer, | ||
credential_endpoint: this.credentialEndpoint, | ||
credentials_supported: supportedCredentials, | ||
// batch_credential_endpoint: this.batchCredentialEndpoint; // not implemented yet | ||
...(this.authorizationServer && { authorization_server: this.authorizationServer }), | ||
...(this.tokenEndpoint && { token_endpoint: this.tokenEndpoint }), | ||
...(display.length > 0 && { display }), | ||
} | ||
} | ||
} |