Skip to content

Commit

Permalink
feat: Enabled Swagger UI on OID4VP instance endpoints below /api-docs
Browse files Browse the repository at this point in the history
  • Loading branch information
nklomp committed Feb 16, 2025
1 parent fbd6e13 commit a6c9fb4
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 7 deletions.
5 changes: 3 additions & 2 deletions packages/siopv2-oid4vp-rp-rest-api/__tests__/RestAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ import agent from './agent'

const opts: ISIOPv2RPRestAPIOpts = {
endpointOpts: {
basePath: '/oid4vp',
globalAuth: {
authentication: {
enabled: true,
strategy: 'bearer',
},
},
webappCreateAuthRequest: {
webappBaseURI: 'http://192.168.2.18:5000',
siopBaseURI: 'http://192.168.2.18:5000',
webappBaseURI: 'http://localhost:5000/oid4vp',
siopBaseURI: 'http://localhost:5000',
},
},
}
Expand Down
4 changes: 1 addition & 3 deletions packages/siopv2-oid4vp-rp-rest-api/__tests__/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
ICredentialHandlerLDLocal,
LdDefaultContexts,
MethodNames,
SphereonBbsBlsSignature2020,
SphereonEd25519Signature2018,
SphereonEd25519Signature2020,
SphereonJsonWebSignature2020,
Expand All @@ -24,11 +23,11 @@ import { Resolver } from 'did-resolver'
import { DB_CONNECTION_NAME, DB_ENCRYPTION_KEY, getDbConnection } from './database'
import { ISIOPv2RP, SIOPv2RP } from '@sphereon/ssi-sdk.siopv2-oid4vp-rp-auth'
import { IPresentationExchange, PresentationExchange } from '@sphereon/ssi-sdk.presentation-exchange'
import { CheckLinkedDomain } from '@sphereon/did-auth-siop'
import { entraAndSphereonCompatibleDef, entraVerifiedIdPresentation } from './presentationDefinitions'
import Debug from 'debug'
import { createHash } from 'crypto'
import { SchemaValidation } from '@sphereon/ssi-sdk.credential-validation'
import {CheckLinkedDomain} from "@sphereon/did-auth-siop-adapter";

const debug = Debug('ssi-sdk-siopv2-oid4vp-rp-rest-api')

Expand Down Expand Up @@ -157,7 +156,6 @@ const agent = createAgent<
suites: [
new SphereonEd25519Signature2018(),
new SphereonEd25519Signature2020(),
new SphereonBbsBlsSignature2020(),
new SphereonJsonWebSignature2020(),
],
bindingOverrides: new Map([
Expand Down
4 changes: 4 additions & 0 deletions packages/siopv2-oid4vp-rp-rest-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@
"dotenv-flow": "^3.3.0",
"express": "^4.19.2",
"short-uuid": "^4.2.2",
"swagger-ui-express": "^5.0.1",
"uuid": "^9.0.1"
},
"devDependencies": {
"@decentralized-identity/ion-sdk": "^0.6.0",
"@sphereon/did-uni-client": "^0.6.3",
"@sphereon/pex": "5.0.0-unstable.28",
"@sphereon/pex-models": "^2.3.2",
"@sphereon/did-auth-siop-adapter": "0.16.1-feature.MWALL.715.391",
"@sphereon/ssi-sdk-ext.did-provider-jwk": "0.27.1-next.14",
"@sphereon/ssi-sdk.data-store": "workspace:*",
"@sphereon/ssi-sdk.vc-handler-ld-local": "workspace:*",
Expand All @@ -51,6 +53,7 @@
"@types/node": "^20.17.1",
"@types/passport": "^1.0.16",
"@types/passport-http-bearer": "^1.0.41",
"@types/swagger-ui-express": "^4.1.7",
"@types/uuid": "^9.0.8",
"@veramo/data-store": "4.2.0",
"@veramo/did-manager": "4.2.0",
Expand All @@ -64,6 +67,7 @@
"@veramo/utils": "4.2.0",
"did-resolver": "^4.1.0",
"morgan": "^1.10.0",
"debug": "^4.4.0",
"nock": "^13.5.4",
"passport": "^0.6.0",
"passport-http-bearer": "^1.0.1",
Expand Down
37 changes: 35 additions & 2 deletions packages/siopv2-oid4vp-rp-rest-api/src/siopv2-rp-api-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { copyGlobalAuthToEndpoints, ExpressSupport } from '@sphereon/ssi-express
import { IPresentationExchange } from '@sphereon/ssi-sdk.presentation-exchange'
import { ISIOPv2RP } from '@sphereon/ssi-sdk.siopv2-oid4vp-rp-auth'
import { TAgent } from '@veramo/core'
import express, { Express, Router } from 'express'
import express, {Express, Request, Response, Router} from 'express'
import { getAuthRequestSIOPv2Endpoint, verifyAuthResponseSIOPv2Endpoint } from './siop-api-functions'
import { IRequiredPlugins, ISIOPv2RPRestAPIOpts } from './types'
import {
Expand All @@ -12,13 +12,16 @@ import {
getDefinitionsEndpoint,
removeAuthRequestStateWebappEndpoint,
} from './webapp-api-functions'
import swaggerUi from 'swagger-ui-express'

export class SIOPv2RPApiServer {
private readonly _express: Express
private readonly _router: Router
private readonly _agent: TAgent<IPresentationExchange & ISIOPv2RP>
private readonly _opts?: ISIOPv2RPRestAPIOpts
private readonly _basePath: string

private readonly OID4VP_SWAGGER_URL = 'https://api.swaggerhub.com/apis/SphereonInt/OID4VP/0.1.0'
constructor(args: { agent: TAgent<IRequiredPlugins>; expressSupport: ExpressSupport; opts?: ISIOPv2RPRestAPIOpts }) {
const { agent, opts } = args
this._agent = agent
Expand Down Expand Up @@ -48,9 +51,39 @@ export class SIOPv2RPApiServer {
getAuthRequestSIOPv2Endpoint(this._router, context, opts?.endpointOpts?.siopGetAuthRequest)
verifyAuthResponseSIOPv2Endpoint(this._router, context, opts?.endpointOpts?.siopVerifyAuthResponse)
}
this._express.use(opts?.endpointOpts?.basePath ?? '', this.router)
this._basePath = opts?.endpointOpts?.basePath ?? ''
this._express.use(this._basePath, this.router)
this.setupSwaggerUi()
}

private setupSwaggerUi() {

fetch(this.OID4VP_SWAGGER_URL)
.then((res) => res.json())
.then((swagger) => {
const apiDocs = `${this._basePath}/api-docs`
console.log(`[OID4P] API docs available at ${apiDocs}`)

this._router.use(
'/api-docs',
(req: Request, res: Response, next: any) => {
const regex = `${apiDocs.replace(/\//, '\/')}`.replace('/oid4vp', '').replace(/\/api-docs.*/, '')
swagger.servers = [{url: `${req.protocol}://${req.get('host')}${regex}`, description: 'This server'}]
// @ts-ignore
req.swaggerDoc = swagger
next()
},
swaggerUi.serveFiles(swagger, options),
swaggerUi.setup(),
)
})
.catch((err) => {
console.log(`[OID4VP] Unable to fetch swagger document: ${err}. Will not host api-docs on this instance`)
})
const options = {
// customCss: '.swagger-ui .topbar { display: none }',
}
}
get express(): Express {
return this._express
}
Expand Down
4 changes: 4 additions & 0 deletions packages/ssi-express-support/src/auth-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ export function copyGlobalAuthToEndpoint(args?: { opts?: HasEndpointOpts; key: s
if (!opts || !key || !hasEndpointOpts(opts)) {
return
}
if (key === 'basePath') {
// make sure to not copy base path over, as we use these at the global router, and this would repeat the path
return;
}
if (opts.endpointOpts?.globalAuth) {
if (opts.endpointOpts[key]?.disableGlobalAuth === true) {
return
Expand Down
12 changes: 12 additions & 0 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 a6c9fb4

Please sign in to comment.