UNPKG

@sphereon/ssi-sdk.oid4vci-issuer-rest-api

Version:

241 lines (224 loc) • 10.7 kB
import { Request, Response, Router } from 'express' import { checkAuth, sendErrorResponse } from '@sphereon/ssi-express-support' import { LOG, VcIssuer } from '@sphereon/oid4vci-issuer' import { determinePath } from '@sphereon/oid4vci-issuer-server' import { IGetIssueStatusEndpointOpts } from '@sphereon/oid4vci-issuer-server' import { IRequiredContext } from './types' import { CredentialConfigurationSupportedV1_0_15 } from '@sphereon/oid4vci-common' import { IssuerInstance } from '@sphereon/ssi-sdk.oid4vci-issuer' import { IssuerMetadataV1_0_15 } from '@sphereon/oid4vci-common' export function getCredentialConfigurationsEndpoint( router: Router, context: IRequiredContext, instance: IssuerInstance, issuer: VcIssuer, opts: IGetIssueStatusEndpointOpts, ) { const path = determinePath(opts.baseUrl, opts?.path ?? '/webapp/issuer-metadata/credential-configurations', { stripBasePath: true }) LOG.log(`[OID4VCI] getCredentialConfigurations endpoint enabled at ${path}`) if (opts?.enabled === false) { console.log(`"getCredentialConfigurations" Endpoint is disabled`) return } router.get(`${path}`, checkAuth(opts?.endpoint), async (request: Request, response: Response) => { try { const metadata = instance.issuerMetadata as IssuerMetadataV1_0_15 response.statusCode = 200 return response.json({ credential_configurations_supported: metadata?.credential_configurations_supported ?? [] }) } catch (error) { return sendErrorResponse(response, 500, error.message as string, error) } }) } export function getCredentialConfigurationByIdEndpoint( router: Router, context: IRequiredContext, instance: IssuerInstance, issuer: VcIssuer, opts: IGetIssueStatusEndpointOpts, ) { const path = determinePath(opts.baseUrl, opts?.path ?? '/webapp/issuer-metadata/credential-configurations/:configurationId', { stripBasePath: true, }) LOG.log(`[OID4VCI] getCredentialConfigurations endpoint enabled at ${path}`) if (opts?.enabled === false) { console.log(`"getCredentialConfigurations" Endpoint is disabled`) return } router.get(`${path}`, checkAuth(opts?.endpoint), async (request: Request, response: Response) => { try { const configurationId = request.params.configurationId if (!configurationId) { return sendErrorResponse(response, 400, 'Missing configurationId') } LOG.log(`[OID4VCI] getCredentialConfigurations endpoint called with configurationId: ${configurationId}`) const metadata = instance.issuerMetadata as IssuerMetadataV1_0_15 if (!metadata?.credential_configurations_supported || !metadata?.credential_configurations_supported?.[configurationId]) { return sendErrorResponse(response, 404, `Credential configuration ${configurationId} not found`) } const config = metadata.credential_configurations_supported[configurationId] return response.json({ ...config }) } catch (error) { return sendErrorResponse(response, 500, error.message as string, error) } }) } export function deleteCredentialConfigurationByIdEndpoint( router: Router, context: IRequiredContext, instance: IssuerInstance, issuer: VcIssuer, opts: IGetIssueStatusEndpointOpts, ) { const path = determinePath(opts.baseUrl, opts?.path ?? '/webapp/issuer-metadata/credential-configurations/:configurationId', { stripBasePath: true, }) LOG.log(`[OID4VCI] deleteCredentialConfigurationById endpoint enabled at ${path}`) if (opts?.enabled === false) { console.log(`"deleteCredentialConfigurationById" Endpoint is disabled`) return } router.delete(`${path}`, checkAuth(opts?.endpoint), async (request: Request, response: Response) => { try { const configurationId = request.params.configurationId if (!configurationId) { return sendErrorResponse(response, 400, 'Missing configurationId') } LOG.log(`[OID4VCI] deleteCredentialConfigurationById endpoint called with configurationId: ${configurationId}`) const storeMetadata = (await context.agent.oid4vciStoreGetMetadata({ metadataType: 'issuer', storeId: instance.metadataOptions.storeId, namespace: instance.metadataOptions.storeNamespace, correlationId: instance.metadataOptions.credentialIssuer, })) as IssuerMetadataV1_0_15 if (!storeMetadata?.credential_configurations_supported || !storeMetadata?.credential_configurations_supported?.[configurationId]) { return sendErrorResponse(response, 404, `Credential configuration ${configurationId} not found`) } const updateMetadata = JSON.parse(JSON.stringify(storeMetadata)) as IssuerMetadataV1_0_15 delete updateMetadata.credential_configurations_supported[configurationId] await context.agent.oid4vciStorePersistMetadata({ metadata: updateMetadata, metadataType: 'issuer', storeId: instance.metadataOptions.storeId, namespace: instance.metadataOptions.storeNamespace, correlationId: instance.metadataOptions.credentialIssuer, overwriteExisting: true, validation: true, }) instance.issuerMetadata = updateMetadata return response.json({}) } catch (error) { return sendErrorResponse(response, 500, error.message as string, error) } }) } export function updateCredentialConfigurationByIdEndpoint( router: Router, context: IRequiredContext, instance: IssuerInstance, issuer: VcIssuer, opts: IGetIssueStatusEndpointOpts, ) { const path = determinePath(opts.baseUrl, opts?.path ?? '/webapp/issuer-metadata/credential-configurations/:configurationId', { stripBasePath: true, }) LOG.log(`[OID4VCI] updateCredentialConfigurationById endpoint enabled at ${path}`) if (opts?.enabled === false) { console.log(`"updateCredentialConfigurationById" Endpoint is disabled`) return } router.put(`${path}`, checkAuth(opts?.endpoint), async (request: Request, response: Response) => { try { const configurationId = request.params.configurationId if (!configurationId) { return sendErrorResponse(response, 400, 'Missing configurationId') } LOG.log(`[OID4VCI] updateCredentialConfigurationById endpoint called with configurationId: ${configurationId}`) const updatedCredentialConfiguration = request.body as CredentialConfigurationSupportedV1_0_15 if (!updatedCredentialConfiguration || !updatedCredentialConfiguration.format) { return sendErrorResponse(response, 400, 'Missing credential configuration in the body, or required format missing') } const storeMetadata = (await context.agent.oid4vciStoreGetMetadata({ metadataType: 'issuer', storeId: instance.metadataOptions.storeId, namespace: instance.metadataOptions.storeNamespace, correlationId: instance.metadataOptions.credentialIssuer, })) as IssuerMetadataV1_0_15 if (!storeMetadata?.credential_configurations_supported || !storeMetadata?.credential_configurations_supported?.[configurationId]) { return sendErrorResponse(response, 404, `Credential configuration ${configurationId} not found`) } const updateMetadata = JSON.parse(JSON.stringify(storeMetadata)) as IssuerMetadataV1_0_15 updateMetadata.credential_configurations_supported[configurationId] = updatedCredentialConfiguration await context.agent.oid4vciStorePersistMetadata({ metadata: updateMetadata, metadataType: 'issuer', storeId: instance.metadataOptions.storeId, namespace: instance.metadataOptions.storeNamespace, correlationId: instance.metadataOptions.credentialIssuer, overwriteExisting: true, validation: true, }) instance.issuerMetadata = updateMetadata return response.json({ ...updatedCredentialConfiguration }) } catch (error) { return sendErrorResponse(response, 500, error.message as string, error) } }) } export function newCredentialConfigurationEndpoint( router: Router, context: IRequiredContext, instance: IssuerInstance, issuer: VcIssuer, opts: IGetIssueStatusEndpointOpts, ) { const path = determinePath(opts.baseUrl, opts?.path ?? '/webapp/issuer-metadata/credential-configurations/:configurationId', { stripBasePath: true, }) LOG.log(`[OID4VCI] newCredentialConfigurationById endpoint enabled at ${path}`) if (opts?.enabled === false) { console.log(`"newCredentialConfigurationById" Endpoint is disabled`) return } router.put(`${path}`, checkAuth(opts?.endpoint), async (request: Request, response: Response) => { try { const configurationId = request.params.configurationId if (!configurationId) { return sendErrorResponse(response, 400, 'Missing configurationId') } LOG.log(`[OID4VCI] newCredentialConfigurationById endpoint called with configurationId: ${configurationId}`) const newCredentialConfiguration = request.body as CredentialConfigurationSupportedV1_0_15 if (!newCredentialConfiguration || !newCredentialConfiguration.format) { return sendErrorResponse(response, 400, 'Missing credential configuration in the body, or required format missing') } const storeMetadata = (await context.agent.oid4vciStoreGetMetadata({ metadataType: 'issuer', storeId: instance.metadataOptions.storeId, namespace: instance.metadataOptions.storeNamespace, correlationId: instance.metadataOptions.credentialIssuer, })) as IssuerMetadataV1_0_15 if (storeMetadata?.credential_configurations_supported?.[configurationId]) { return sendErrorResponse( response, 400, `Credential configuration ${configurationId} already exists, cannot create new one. Please update instead.`, ) } const updateMetadata = JSON.parse(JSON.stringify(storeMetadata)) as IssuerMetadataV1_0_15 updateMetadata.credential_configurations_supported[configurationId] = newCredentialConfiguration await context.agent.oid4vciStorePersistMetadata({ metadata: updateMetadata, metadataType: 'issuer', storeId: instance.metadataOptions.storeId, namespace: instance.metadataOptions.storeNamespace, correlationId: instance.metadataOptions.credentialIssuer, overwriteExisting: true, validation: true, }) instance.issuerMetadata = updateMetadata return response.json({ ...newCredentialConfiguration }) } catch (error) { return sendErrorResponse(response, 500, error.message as string, error) } }) }