Skip to content

Commit

Permalink
feat: Allow to supply data for VCI Issuer REST client and server duri…
Browse files Browse the repository at this point in the history
…ng offer
  • Loading branch information
nklomp committed Jun 16, 2023
1 parent 40abd83 commit 0878c28
Show file tree
Hide file tree
Showing 11 changed files with 82 additions and 63 deletions.
18 changes: 12 additions & 6 deletions packages/oid4vci-issuer-rest-api/__tests__/RestAPI.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { CredentialDataSupplierResult } from '@sphereon/oid4vci-issuer'
import { CredentialDataSupplier, CredentialDataSupplierResult } from '@sphereon/oid4vci-issuer'
import { CredentialDataSupplierArgs } from '@sphereon/oid4vci-issuer/lib/types'
import { TAgent } from '@veramo/core'
import { IOID4VCIRestAPIOpts, IPlugins, OID4VCIRestAPI } from '../src'
import agent from './agent'
Expand All @@ -10,23 +11,28 @@ export const opts: IOID4VCIRestAPIOpts = {
},
}

const credentialDataSupplier = () =>
Promise.resolve({
const credentialDataSupplier: CredentialDataSupplier = (args: CredentialDataSupplierArgs) => {
const firstName = args.credentialDataSupplierInput?.firstName ?? 'Hello'
const lastName = args.credentialDataSupplierInput?.lastName ?? 'DBC'
const email = args.credentialDataSupplierInput?.email ?? 'dbc@example.com'

return Promise.resolve({
format: 'jwt_vc_json',
credential: {
'@context': ['https://www.w3.org/2018/credentials/v1'],
type: ['VerifiableCredential', 'DBCConferenceAttendee'],
credentialSubject: {
firstName: 'Hello',
lastName: 'DBC',
email: 'example@sphereon.com', // based on user form input,
firstName,
lastName,
email,
event: {
name: 'DBC Conference 2023',
date: '2023-06-26',
},
},
},
} as unknown as CredentialDataSupplierResult)
}

export function start() {
OID4VCIRestAPI.init({
Expand Down
6 changes: 3 additions & 3 deletions packages/oid4vci-issuer-rest-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
"start:dev": "ts-node __tests__/RestAPI.ts"
},
"dependencies": {
"@sphereon/oid4vci-common": "0.4.1-unstable.296",
"@sphereon/oid4vci-issuer": "0.4.1-unstable.296",
"@sphereon/oid4vci-issuer-server": "0.4.1-unstable.296",
"@sphereon/oid4vci-common": "0.4.1-unstable.302",
"@sphereon/oid4vci-issuer": "0.4.1-unstable.302",
"@sphereon/oid4vci-issuer-server": "0.4.1-unstable.302",
"@sphereon/ssi-sdk.kv-store-temp": "workspace:*",
"@sphereon/ssi-sdk.oid4vci-issuer": "workspace:*",
"@sphereon/ssi-sdk.oid4vci-issuer-store": "workspace:*",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default (testContext: { getAgent: () => ConfiguredAgent; setup: () => Pro

it('should create the url Offer Url with baseUrl', async () => {
const result = await agent.oid4vciClientCreateOfferUri({
baseUrl: 'https://ssi-backend.sphereon.com',
agentBaseUrl: 'https://ssi-backend.sphereon.com',
grants: {
'urn:ietf:params:oauth:grant-type:pre-authorized_code': {
'pre-authorized_code': '1234',
Expand Down
2 changes: 1 addition & 1 deletion packages/oid4vci-issuer-rest-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"generate-plugin-schema": "ts-node ../../packages/dev/bin/sphereon.js dev generate-plugin-schema"
},
"dependencies": {
"@sphereon/oid4vci-common": "0.4.1-unstable.296",
"@sphereon/oid4vci-common": "0.4.1-unstable.302",
"@veramo/core": "4.2.0",
"cross-fetch": "^3.1.5"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ export class OID4VCIRestClient implements IAgentPlugin {
if (!args.credentials || !args.grants) {
return Promise.reject(Error("Can't generate the credential offer url without credentials and grants params present."))
}
const baseUrl = this.assertedAgentBaseUrl(args.baseUrl)
const baseUrl = this.assertedAgentBaseUrl(args.agentBaseUrl)
const request: IOID4VCIClientCreateOfferUriRequest = {
credentials: args.credentials,
grants: args.grants,
...(args.credentialDataSupplierInput && { credentialDataSupplierInput: args.credentialDataSupplierInput }),
}
const url = OID4VCIRestClient.urlWithBase(`webapp/credential-offers`, baseUrl)
debug(`OID4VCIRestClient is going to send request: ${JSON.stringify(request)} to ${url}`)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,32 @@
import { IAgentContext, IPluginMethodMap } from '@veramo/core'
import { CredentialOfferFormat, Grant, IssueStatusResponse } from '@sphereon/oid4vci-common'
import {
CredentialOfferFormat,
Grant,
IssueStatusResponse,
CredentialDataSupplierInput,
CreateCredentialOfferURIResult,
} from '@sphereon/oid4vci-common'

export interface IOID4VCIRestClient extends IPluginMethodMap {
oid4vciClientCreateOfferUri(args: IOID4VCIClientCreateOfferUriRequestArgs, context: IRequiredContext): Promise<IOID4VCIClientCreateOfferUriResponse>
oid4vciClientGetIssueStatus(args: IOID4VCIClientGetIssueStatusArgs, context: IRequiredContext): Promise<IssueStatusResponse>
}

export interface IOID4VCIClientCreateOfferUriRequestArgs {
grants: Grant
credentials: (CredentialOfferFormat | string)[]
baseUrl?: string
export interface IOID4VCIClientCreateOfferUriRequestArgs extends IOID4VCIClientCreateOfferUriRequest {
agentBaseUrl?: string
}

export interface IOID4VCIClientGetIssueStatusArgs {
id: string
baseUrl?: string
}

export interface IOID4VCIClientCreateOfferUriResponse {
uri: string
}
export type IOID4VCIClientCreateOfferUriResponse = Omit<CreateCredentialOfferURIResult, 'session'>

export interface IOID4VCIClientCreateOfferUriRequest {
credentials: (CredentialOfferFormat | string)[]
grants: Grant
credentialDataSupplierInput?: CredentialDataSupplierInput
}

export type IRequiredContext = IAgentContext<never>
2 changes: 1 addition & 1 deletion packages/oid4vci-issuer-store/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"build:clean": "tsc --build --clean && tsc --build"
},
"dependencies": {
"@sphereon/oid4vci-common": "0.4.1-unstable.296",
"@sphereon/oid4vci-common": "0.4.1-unstable.302",
"@sphereon/ssi-sdk-ext.did-utils": "^0.12.0",
"@types/uuid": "^9.0.1",
"@veramo/core": "4.2.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/oid4vci-issuer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"build:clean": "tsc --build --clean && tsc --build"
},
"dependencies": {
"@sphereon/oid4vci-common": "0.4.1-unstable.296",
"@sphereon/oid4vci-issuer": "0.4.1-unstable.296",
"@sphereon/oid4vci-common": "0.4.1-unstable.302",
"@sphereon/oid4vci-issuer": "0.4.1-unstable.302",
"@sphereon/ssi-sdk.oid4vci-issuer-store": "workspace:*",
"@sphereon/ssi-sdk.core": "workspace:*",
"@sphereon/ssi-sdk-ext.did-utils": "^0.12.0",
Expand Down
13 changes: 11 additions & 2 deletions packages/oid4vci-issuer/src/agent/OID4VCIIssuer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { IAgentPlugin } from '@veramo/core'
import { getAccessTokenSignerCallback } from '../functions'
import {
IAssertValidAccessTokenArgs,
ICreateCredentialOfferURIResult,
ICreateOfferArgs,
IIssueCredentialArgs,
IIssuerInstanceArgs,
Expand Down Expand Up @@ -35,10 +36,18 @@ export class OID4VCIIssuer implements IAgentPlugin {
this._opts = opts ?? {}
}

private async oid4vciCreateOfferURI(createArgs: ICreateOfferArgs, context: IRequiredContext): Promise<string> {
private async oid4vciCreateOfferURI(createArgs: ICreateOfferArgs, context: IRequiredContext): Promise<ICreateCredentialOfferURIResult> {
return await this.oid4vciGetInstance(createArgs, context)
.then((instance) => instance.get({ context }))
.then((issuer: VcIssuer) => issuer.createCredentialOfferURI(createArgs))
.then((issuer: VcIssuer) =>
issuer.createCredentialOfferURI(createArgs).then((response) => {
const result: ICreateCredentialOfferURIResult = response
if (this._opts.returnSessions === false) {
delete result.session
}
return result
})
)
}

private async oid4vciIssueCredential(issueArgs: IIssueCredentialArgs, context: IRequiredContext): Promise<CredentialResponse> {
Expand Down
30 changes: 15 additions & 15 deletions packages/oid4vci-issuer/src/types/IOID4VCIIssuer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AccessTokenRequest, AccessTokenResponse } from '@sphereon/oid4vci-common'
import { AccessTokenRequest, AccessTokenResponse, CredentialDataSupplierInput, CredentialOfferSession } from '@sphereon/oid4vci-common'
import {
CredentialIssuerMetadataOpts,
CredentialOfferFormat,
Expand All @@ -11,20 +11,11 @@ import { CredentialDataSupplier } from '@sphereon/oid4vci-issuer/lib/types'
import { IDIDOptions, ResolveOpts } from '@sphereon/ssi-sdk-ext.did-utils'
import { IOID4VCIStore } from '@sphereon/ssi-sdk.oid4vci-issuer-store'
import { ICredential } from '@sphereon/ssi-types/dist'
import {
IAgentContext,
ICredentialIssuer,
ICredentialVerifier,
IDataStoreORM,
IDIDManager,
IKeyManager,
IPluginMethodMap,
IResolver,
} from '@veramo/core'
import { IAgentContext, ICredentialIssuer, IDataStoreORM, IDIDManager, IKeyManager, IPluginMethodMap, IResolver } from '@veramo/core'
import { IssuerInstance } from '../IssuerInstance'

export interface IOID4VCIIssuer extends IPluginMethodMap {
oid4vciCreateOfferURI(createArgs: ICreateOfferArgs, context: IRequiredContext): Promise<string>
oid4vciCreateOfferURI(createArgs: ICreateOfferArgs, context: IRequiredContext): Promise<ICreateCredentialOfferURIResult>
oid4vciIssueCredential(issueArgs: IIssueCredentialArgs, context: IRequiredContext): Promise<CredentialResponse>
oid4vciCreateAccessTokenResponse(accessTokenArgs: IAssertValidAccessTokenArgs, context: IRequiredContext): Promise<AccessTokenResponse>
oid4vciGetInstance(args: IIssuerInstanceArgs, context: IRequiredContext): Promise<IssuerInstance>
Expand All @@ -34,6 +25,7 @@ export interface IOID4VCIIssuerOpts {
defaultStoreId?: string
defaultNamespace?: string
resolveOpts?: ResolveOpts
returnSessions?: boolean
}

export interface IIssuerDefaultOpts extends IIssuerOptions {}
Expand All @@ -43,6 +35,7 @@ export interface ICreateOfferArgs extends IIssuerInstanceArgs {
credentials?: (CredentialOfferFormat | string)[]
credentialDefinition?: IssuerCredentialDefinition
credentialOfferUri?: string
credentialDataSupplierInput?: CredentialDataSupplierInput // Optional storage that can help the credential Data Supplier. For instance to store credential input data during offer creation, if no additional data can be supplied later on
baseUri?: string
scheme?: string
pinLength?: number
Expand All @@ -52,6 +45,7 @@ export interface IIssueCredentialArgs extends IIssuerInstanceArgs {
credentialRequest: CredentialRequestV1_0_11
credential?: ICredential
credentialDataSupplier?: CredentialDataSupplier
credentialDataSupplierInput?: CredentialDataSupplierInput
newCNonce?: string
cNonceExpiresIn?: number
tokenExpiresIn?: number
Expand Down Expand Up @@ -86,6 +80,12 @@ export interface IMetadataOptions {
storeNamespace?: string
}

export type IRequiredContext = IAgentContext<
IDataStoreORM & IResolver & IDIDManager & IKeyManager & ICredentialIssuer & ICredentialVerifier & IOID4VCIStore
>
export type ICreateCredentialOfferURIResult = {
uri: string
session?: CredentialOfferSession
userPin?: string
userPinLength?: number
userPinRequired: boolean
}

export type IRequiredContext = IAgentContext<IDataStoreORM & IResolver & IDIDManager & IKeyManager & ICredentialIssuer & IOID4VCIStore>
46 changes: 23 additions & 23 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 0878c28

Please sign in to comment.