@sphereon/ssi-sdk.siopv2-oid4vp-rp-rest-api 0.34.1-feature.SSISDK.58.host.nonce.endpoint.145 → 0.34.1-feature.SSISDK.58.host.nonce.endpoint.194

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sphereon/ssi-sdk.siopv2-oid4vp-rp-rest-api",
3
- "version": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.145+5bfc0b12",
3
+ "version": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.194+287878cc",
4
4
  "source": "src/index.ts",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -23,16 +23,16 @@
23
23
  "start:dev": "ts-node __tests__/RestAPI.ts"
24
24
  },
25
25
  "dependencies": {
26
- "@sphereon/did-auth-siop": "0.19.1-feature.SSISDK.58.host.nonce.endpoint.107",
27
- "@sphereon/ssi-express-support": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.145+5bfc0b12",
28
- "@sphereon/ssi-sdk.core": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.145+5bfc0b12",
29
- "@sphereon/ssi-sdk.credential-validation": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.145+5bfc0b12",
30
- "@sphereon/ssi-sdk.kv-store-temp": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.145+5bfc0b12",
31
- "@sphereon/ssi-sdk.pd-manager": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.145+5bfc0b12",
32
- "@sphereon/ssi-sdk.presentation-exchange": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.145+5bfc0b12",
33
- "@sphereon/ssi-sdk.siopv2-oid4vp-common": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.145+5bfc0b12",
34
- "@sphereon/ssi-sdk.siopv2-oid4vp-rp-auth": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.145+5bfc0b12",
35
- "@sphereon/ssi-types": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.145+5bfc0b12",
26
+ "@sphereon/did-auth-siop": "0.19.1-feature.DIIPv4.161",
27
+ "@sphereon/ssi-express-support": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.194+287878cc",
28
+ "@sphereon/ssi-sdk.core": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.194+287878cc",
29
+ "@sphereon/ssi-sdk.credential-validation": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.194+287878cc",
30
+ "@sphereon/ssi-sdk.kv-store-temp": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.194+287878cc",
31
+ "@sphereon/ssi-sdk.pd-manager": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.194+287878cc",
32
+ "@sphereon/ssi-sdk.presentation-exchange": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.194+287878cc",
33
+ "@sphereon/ssi-sdk.siopv2-oid4vp-common": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.194+287878cc",
34
+ "@sphereon/ssi-sdk.siopv2-oid4vp-rp-auth": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.194+287878cc",
35
+ "@sphereon/ssi-types": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.194+287878cc",
36
36
  "@veramo/core": "4.2.0",
37
37
  "@veramo/credential-w3c": "4.2.0",
38
38
  "awesome-qr": "^2.1.5-rc.0",
@@ -44,18 +44,19 @@
44
44
  "express": "^4.19.2",
45
45
  "short-uuid": "^4.2.2",
46
46
  "swagger-ui-express": "^5.0.1",
47
- "uuid": "^9.0.1"
47
+ "uuid": "^9.0.1",
48
+ "zod": "^4.1.5"
48
49
  },
49
50
  "devDependencies": {
50
51
  "@decentralized-identity/ion-sdk": "^0.6.0",
51
- "@sphereon/did-auth-siop-adapter": "0.19.1-feature.SSISDK.58.host.nonce.endpoint.107",
52
+ "@sphereon/did-auth-siop-adapter": "0.19.1-feature.DIIPv4.161",
52
53
  "@sphereon/did-uni-client": "^0.6.3",
53
- "@sphereon/pex": "5.0.0-unstable.28",
54
- "@sphereon/pex-models": "^2.3.2",
55
- "@sphereon/ssi-sdk-ext.did-provider-jwk": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.145+5bfc0b12",
56
- "@sphereon/ssi-sdk.credential-vcdm": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.145+5bfc0b12",
57
- "@sphereon/ssi-sdk.credential-vcdm-jsonld-provider": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.145+5bfc0b12",
58
- "@sphereon/ssi-sdk.data-store": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.145+5bfc0b12",
54
+ "@sphereon/ssi-sdk-ext.did-provider-jwk": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.194+287878cc",
55
+ "@sphereon/ssi-sdk-ext.identifier-resolution": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.194+287878cc",
56
+ "@sphereon/ssi-sdk-ext.jwt-service": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.194+287878cc",
57
+ "@sphereon/ssi-sdk.credential-vcdm": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.194+287878cc",
58
+ "@sphereon/ssi-sdk.credential-vcdm-jsonld-provider": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.194+287878cc",
59
+ "@sphereon/ssi-sdk.data-store": "0.34.1-feature.SSISDK.58.host.nonce.endpoint.194+287878cc",
59
60
  "@types/body-parser": "^1.19.5",
60
61
  "@types/cookie-parser": "^1.4.7",
61
62
  "@types/cors": "^2.8.17",
@@ -114,5 +115,5 @@
114
115
  "OpenID Connect",
115
116
  "Authenticator"
116
117
  ],
117
- "gitHead": "5bfc0b1229134b5d80279a3baf1fc64c9c6e755e"
118
+ "gitHead": "287878cc3c59e1fe8f3303600e4139ef30258b17"
118
119
  }
package/src/index.ts CHANGED
@@ -2,6 +2,6 @@
2
2
  * @public
3
3
  */
4
4
  export * from './siop-api-functions'
5
- export * from './webapp-api-functions'
5
+ export * from './universal-oid4vp-api-functions'
6
6
  export * from './types'
7
7
  export * from './siopv2-rp-api-server'
@@ -0,0 +1,20 @@
1
+ import { Request, Response, NextFunction } from 'express';
2
+ import { z, ZodError } from 'zod';
3
+
4
+ export const validateData = (schema: z.ZodObject<any, any>) => {
5
+ return (req: Request, res: Response, next: NextFunction) => {
6
+ try {
7
+ schema.parse(req.body);
8
+ next();
9
+ } catch (error) {
10
+ if (error instanceof ZodError) {
11
+ const errorMessages = error.issues.map((issue: any) => ({
12
+ message: `${issue.path.join('.')} is ${issue.message}`,
13
+ }))
14
+ res.status(400).json({ status: 400, message: 'Invalid data', error_details: errorMessages[0].message });
15
+ } else {
16
+ res.status(500).json({ status: 500, message: 'Internal Server Error' });
17
+ }
18
+ }
19
+ };
20
+ }
@@ -0,0 +1,36 @@
1
+ import { CallbackOptsSchema, RequestUriMethod, ResponseMode, ResponseType } from '@sphereon/did-auth-siop'
2
+ import { z } from 'zod'
3
+
4
+ export const ResponseTypeSchema = z.enum([ResponseType.VP_TOKEN])
5
+
6
+ export const ResponseModeSchema = z.enum([ResponseMode.DIRECT_POST, ResponseMode.DIRECT_POST_JWT])
7
+
8
+ const requestUriMethods = ['get', 'post'] as const satisfies Array<RequestUriMethod>
9
+ export const RequestUriMethodSchema = z.enum(requestUriMethods)
10
+ export const QRCodeOptsSchema = z.object({
11
+ size: z.number().optional(),
12
+ color_dark: z.string().optional(),
13
+ color_light: z.string().optional(),
14
+ })
15
+
16
+ export const CreateAuthorizationRequestBodySchema = z.object({
17
+ query_id: z.string(),
18
+ client_id: z.string().optional(),
19
+ request_uri_base: z.string().optional(),
20
+ correlation_id: z.string().optional(),
21
+ request_uri_method: RequestUriMethodSchema.optional(),
22
+ response_type: ResponseTypeSchema.optional(),
23
+ response_mode: ResponseModeSchema.optional(),
24
+ transaction_data: z.array(z.string()).optional(),
25
+ qr_code: QRCodeOptsSchema.optional(),
26
+ direct_post_response_redirect_uri: z.string().optional(),
27
+ callback: CallbackOptsSchema.optional(),
28
+ })
29
+
30
+ export const CreateAuthorizationResponseSchema = z.object({
31
+ correlation_id: z.string(),
32
+ query_id: z.string(),
33
+ request_uri: z.string(),
34
+ status_uri: z.string(),
35
+ qr_uri: z.string().optional(),
36
+ })
@@ -49,18 +49,18 @@ export function verifyAuthResponseSIOPv2Endpoint(router: Router, context: IRequi
49
49
  const path = opts?.path ?? '/siop/definitions/:definitionId/auth-responses/:correlationId'
50
50
  router.post(path, checkAuth(opts?.endpoint), async (request: Request, response: Response) => {
51
51
  try {
52
- const { correlationId, definitionId, tenantId, version } = request.params
53
- if (!correlationId || !definitionId) {
54
- console.log(`No authorization request could be found for the given url. correlationId: ${correlationId}, definitionId: ${definitionId}`)
52
+ const { correlationId, queryId, tenantId, version } = request.params
53
+ if (!correlationId || !queryId) {
54
+ console.log(`No authorization request could be found for the given url. correlationId: ${correlationId}, queryId: ${queryId}`)
55
55
  return sendErrorResponse(response, 404, 'No authorization request could be found')
56
56
  }
57
57
  console.log('Authorization Response (siop-sessions')
58
58
  console.log(JSON.stringify(request.body, null, 2))
59
- const definitionItems = await context.agent.pdmGetDefinitions({ filter: [{ definitionId, tenantId, version }] })
59
+ const definitionItems = await context.agent.pdmGetDefinitions({ filter: [{ queryId, tenantId, version }] })
60
60
  if (definitionItems.length === 0) {
61
- console.log(`Could not get definition ${definitionId} from agent. Will return 404`)
61
+ console.log(`Could not get definition ${queryId} from agent. Will return 404`)
62
62
  response.statusCode = 404
63
- response.statusMessage = `No definition ${definitionId}`
63
+ response.statusMessage = `No definition ${queryId}`
64
64
  return response.send()
65
65
  }
66
66
 
@@ -71,8 +71,8 @@ export function verifyAuthResponseSIOPv2Endpoint(router: Router, context: IRequi
71
71
  const verifiedResponse = await context.agent.siopVerifyAuthResponse({
72
72
  authorizationResponse,
73
73
  correlationId,
74
- definitionId,
75
- dcqlQueryPayload: definitionItem.dcqlPayload,
74
+ queryId,
75
+ dcqlQuery: definitionItem.query,
76
76
  })
77
77
 
78
78
  // FIXME SSISDK-55 add proper support for checking for DCQL presentations
@@ -89,7 +89,7 @@ export function verifyAuthResponseSIOPv2Endpoint(router: Router, context: IRequi
89
89
  return response.send(JSON.stringify(authorizationChallengeValidationResponse))
90
90
  }
91
91
 
92
- const responseRedirectURI = await context.agent.siopGetRedirectURI({ correlationId, definitionId, state: verifiedResponse.state })
92
+ const responseRedirectURI = await context.agent.siopGetRedirectURI({ correlationId, queryId: queryId, state: verifiedResponse.state })
93
93
  if (responseRedirectURI) {
94
94
  response.setHeader('Content-Type', 'application/json')
95
95
  return response.send(JSON.stringify({ redirect_uri: responseRedirectURI }))
@@ -124,7 +124,7 @@ export function getAuthRequestSIOPv2Endpoint(router: Router, context: IRequiredC
124
124
  }
125
125
  const requestState = await context.agent.siopGetAuthRequestState({
126
126
  correlationId,
127
- definitionId,
127
+ queryId: definitionId,
128
128
  errorOnNotFound: false,
129
129
  })
130
130
  if (!requestState) {
@@ -148,8 +148,8 @@ export function getAuthRequestSIOPv2Endpoint(router: Router, context: IRequiredC
148
148
  } finally {
149
149
  await context.agent.siopUpdateAuthRequestState({
150
150
  correlationId,
151
- definitionId,
152
- state: 'sent',
151
+ queryId: definitionId,
152
+ state: 'authorization_request_created',
153
153
  error,
154
154
  })
155
155
  }
@@ -1,23 +1,22 @@
1
1
  import { agentContext } from '@sphereon/ssi-sdk.core'
2
2
  import { copyGlobalAuthToEndpoints, ExpressSupport } from '@sphereon/ssi-express-support'
3
- import { IPresentationExchange } from '@sphereon/ssi-sdk.presentation-exchange'
4
3
  import { ISIOPv2RP } from '@sphereon/ssi-sdk.siopv2-oid4vp-rp-auth'
5
4
  import { TAgent } from '@veramo/core'
6
5
  import express, { Express, Request, Response, Router } from 'express'
7
6
  import { getAuthRequestSIOPv2Endpoint, verifyAuthResponseSIOPv2Endpoint } from './siop-api-functions'
8
7
  import { IRequiredPlugins, ISIOPv2RPRestAPIOpts } from './types'
9
8
  import {
10
- authStatusWebappEndpoint,
11
- createAuthRequestWebappEndpoint,
9
+ authStatusUniversalOID4VPEndpoint,
10
+ createAuthRequestUniversalOID4VPEndpoint,
12
11
  getDefinitionsEndpoint,
13
- removeAuthRequestStateWebappEndpoint,
14
- } from './webapp-api-functions'
12
+ removeAuthRequestStateUniversalOID4VPEndpoint,
13
+ } from './universal-oid4vp-api-functions'
15
14
  import swaggerUi from 'swagger-ui-express'
16
15
 
17
16
  export class SIOPv2RPApiServer {
18
17
  private readonly _express: Express
19
18
  private readonly _router: Router
20
- private readonly _agent: TAgent<IPresentationExchange & ISIOPv2RP>
19
+ private readonly _agent: TAgent<ISIOPv2RP>
21
20
  private readonly _opts?: ISIOPv2RPRestAPIOpts
22
21
  private readonly _basePath: string
23
22
 
@@ -40,9 +39,9 @@ export class SIOPv2RPApiServer {
40
39
 
41
40
  // Webapp endpoints
42
41
  if (features.includes('rp-status')) {
43
- createAuthRequestWebappEndpoint(this._router, context, opts?.endpointOpts?.webappCreateAuthRequest)
44
- authStatusWebappEndpoint(this._router, context, opts?.endpointOpts?.webappAuthStatus)
45
- removeAuthRequestStateWebappEndpoint(this._router, context, opts?.endpointOpts?.webappDeleteAuthRequest)
42
+ createAuthRequestUniversalOID4VPEndpoint(this._router, context, opts?.endpointOpts?.webappCreateAuthRequest)
43
+ authStatusUniversalOID4VPEndpoint(this._router, context, opts?.endpointOpts?.webappAuthStatus)
44
+ removeAuthRequestStateUniversalOID4VPEndpoint(this._router, context, opts?.endpointOpts?.webappDeleteAuthRequest)
46
45
  getDefinitionsEndpoint(this._router, context, opts?.endpointOpts?.webappGetDefinitions)
47
46
  }
48
47
 
@@ -92,7 +91,7 @@ export class SIOPv2RPApiServer {
92
91
  return this._router
93
92
  }
94
93
 
95
- get agent(): TAgent<IPresentationExchange & ISIOPv2RP> {
94
+ get agent(): TAgent<ISIOPv2RP> {
96
95
  return this._agent
97
96
  }
98
97
 
@@ -1,11 +1,16 @@
1
+ import { IAgentContext, ICredentialVerifier } from '@veramo/core'
1
2
  import { GenericAuthArgs, ISingleEndpointOpts } from '@sphereon/ssi-express-support'
2
- import { IPresentationExchange } from '@sphereon/ssi-sdk.presentation-exchange'
3
3
  import { ISIOPv2RP } from '@sphereon/ssi-sdk.siopv2-oid4vp-rp-auth'
4
- import { IAgentContext, ICredentialVerifier } from '@veramo/core'
5
4
  import { IPDManager } from '@sphereon/ssi-sdk.pd-manager'
5
+ import { AdditionalClaims } from '@sphereon/ssi-types'
6
+ import { AuthorizationRequestStateStatus, AuthorizationResponseStateStatus } from '@sphereon/ssi-sdk.siopv2-oid4vp-common'
7
+ import { Request, Response } from 'express'
8
+ import { z } from 'zod'
9
+ import { CreateAuthorizationRequestBodySchema, CreateAuthorizationResponseSchema } from '../schemas'
6
10
  import { QRCodeOpts } from './QRCode.types'
7
11
 
8
12
  export type SiopFeatures = 'rp-status' | 'siop'
13
+
9
14
  export interface ISIOPv2RPRestAPIOpts {
10
15
  enableFeatures?: SiopFeatures[]
11
16
  endpointOpts?: {
@@ -28,5 +33,66 @@ export interface ICreateAuthRequestWebappEndpointOpts extends ISingleEndpointOpt
28
33
  responseRedirectURI?: string
29
34
  }
30
35
 
31
- export type IRequiredPlugins = ICredentialVerifier & ISIOPv2RP & IPresentationExchange & IPDManager
36
+ export type IRequiredPlugins = ICredentialVerifier & ISIOPv2RP & IPDManager
32
37
  export type IRequiredContext = IAgentContext<IRequiredPlugins>
38
+
39
+ export type CreateAuthorizationRequest = Request<Record<string, never>, any, CreateAuthorizationRequestBody, Record<string, never>>
40
+
41
+ export type CreateAuthorizationRequestBody = z.infer<typeof CreateAuthorizationRequestBodySchema>;
42
+
43
+ export type CreateAuthorizationResponse = Response<CreateAuthorizationRequestResponse>
44
+
45
+ export type CreateAuthorizationRequestResponse = z.infer<typeof CreateAuthorizationResponseSchema>;
46
+
47
+ export type DeleteAuthorizationRequest = Request<DeleteAuthorizationRequestPathParameters, any, Record<string, any>, Record<string, any>>
48
+
49
+ export type DeleteAuthorizationRequestPathParameters = {
50
+ correlationId: string;
51
+ }
52
+
53
+ export type GetAuthorizationRequestStatus = Request<GetAuthorizationRequestStatusPathParameters, any, Record<string, any>, Record<string, any>>
54
+
55
+ export type GetAuthorizationRequestStatusPathParameters = {
56
+ correlationId: string;
57
+ }
58
+
59
+ export type RequestError = {
60
+ status: number
61
+ message: string
62
+ error_details?: string
63
+ }
64
+
65
+ export interface AuthStatusResponse {
66
+ status: AuthorizationRequestStateStatus | AuthorizationResponseStateStatus
67
+ correlation_id: string
68
+ query_id: string
69
+ last_updated: number
70
+ verified_data?: VerifiedData
71
+ error?: RequestError
72
+ }
73
+
74
+ export type VerifiedData = {
75
+ authorization_response?: AuthorizationResponse
76
+ credential_claims?: AdditionalClaims
77
+ }
78
+
79
+ export type AuthorizationResponse = {
80
+ presentation_submission?: Record<string, any>
81
+ vp_token?: VpToken
82
+ }
83
+
84
+ export type SingleObjectVpTokenPE = Record<string, any>
85
+
86
+ export type SingleStringVpTokenPE = string
87
+
88
+ export type MultipleVpTokens = Array<SingleObjectVpTokenPE> | Array<SingleStringVpTokenPE>
89
+
90
+ export type MultipleVpTokenDCQL = {
91
+ [key: string]: MultipleVpTokens
92
+ }
93
+
94
+ export type VpToken =
95
+ | SingleObjectVpTokenPE
96
+ | SingleStringVpTokenPE
97
+ | MultipleVpTokens
98
+ | MultipleVpTokenDCQL
@@ -0,0 +1,179 @@
1
+ import { AuthorizationResponseStateStatus } from '@sphereon/did-auth-siop'
2
+ import { checkAuth, ISingleEndpointOpts, sendErrorResponse } from '@sphereon/ssi-express-support'
3
+ import { uriWithBase } from '@sphereon/ssi-sdk.siopv2-oid4vp-common'
4
+ import { Request, Response, Router } from 'express'
5
+ import uuid from 'short-uuid'
6
+ import { validateData } from './middleware/validationMiddleware'
7
+ import { CreateAuthorizationRequestBodySchema } from './schemas'
8
+ import {
9
+ CreateAuthorizationRequest,
10
+ CreateAuthorizationRequestResponse,
11
+ CreateAuthorizationResponse,
12
+ DeleteAuthorizationRequest,
13
+ GetAuthorizationRequestStatus,
14
+ AuthStatusResponse,
15
+ ICreateAuthRequestWebappEndpointOpts,
16
+ IRequiredContext,
17
+ } from './types'
18
+
19
+ export function createAuthRequestUniversalOID4VPEndpoint(router: Router, context: IRequiredContext, opts?: ICreateAuthRequestWebappEndpointOpts) {
20
+ if (opts?.enabled === false) {
21
+ console.log(`createAuthRequest universal OID4VP endpoint is disabled`)
22
+ return
23
+ }
24
+
25
+ const path = opts?.path ?? '/backend/auth/requests'
26
+ router.post(
27
+ path,
28
+ checkAuth(opts?.endpoint),
29
+ validateData(CreateAuthorizationRequestBodySchema),
30
+ async (request: CreateAuthorizationRequest, response: CreateAuthorizationResponse) => {
31
+ try {
32
+ const correlationId = request.body.correlation_id ?? uuid.uuid()
33
+ const qrCodeOpts = request.body.qr_code ?? opts?.qrCodeOpts
34
+ const queryId = request.body.query_id
35
+ const directPostResponseRedirectUri = request.body.direct_post_response_redirect_uri // TODO Uri not URI
36
+ const requestUriBase = request.body.request_uri_base
37
+ const callback = request.body.callback
38
+
39
+ const definitionItems = await context.agent.pdmGetDefinitions({ filter: [{ queryId }] })
40
+ if (definitionItems.length === 0) {
41
+ console.log(`No query could be found for the given id. Query id: ${queryId}`)
42
+ return sendErrorResponse(response, 404, { status: 404, message: 'No query could be found' })
43
+ }
44
+
45
+ const requestByReferenceURI = uriWithBase(`/siop/definitions/${queryId}/auth-requests/${correlationId}`, {
46
+ baseURI: requestUriBase ?? opts?.siopBaseURI,
47
+ })
48
+ const responseURI = uriWithBase(`/siop/definitions/${queryId}/auth-responses/${correlationId}`, { baseURI: opts?.siopBaseURI })
49
+
50
+ const authRequestURI = await context.agent.siopCreateAuthRequestURI({
51
+ queryId,
52
+ correlationId,
53
+ nonce: uuid.uuid(),
54
+ requestByReferenceURI,
55
+ responseURIType: 'response_uri',
56
+ responseURI,
57
+ ...(directPostResponseRedirectUri && { responseRedirectURI: directPostResponseRedirectUri }),
58
+ callback,
59
+ })
60
+
61
+ let qrCodeDataUri: string | undefined
62
+ if (qrCodeOpts) {
63
+ const { AwesomeQR } = await import('awesome-qr')
64
+ const qrCode = new AwesomeQR({ ...qrCodeOpts, text: authRequestURI })
65
+ qrCodeDataUri = `data:image/png;base64,${(await qrCode.draw())!.toString('base64')}`
66
+ }
67
+
68
+ const authRequestBody = {
69
+ query_id: queryId,
70
+ correlation_id: correlationId,
71
+ request_uri: authRequestURI,
72
+ status_uri: `${uriWithBase(opts?.webappAuthStatusPath ?? `/backend/auth/status/${correlationId}`, { baseURI: opts?.webappBaseURI })}`,
73
+ ...(qrCodeDataUri && { qr_uri: qrCodeDataUri }),
74
+ } satisfies CreateAuthorizationRequestResponse
75
+ console.log(`Auth Request URI data to send back: ${JSON.stringify(authRequestBody)}`)
76
+
77
+ return response.status(201).json(authRequestBody)
78
+ } catch (error) {
79
+ return sendErrorResponse(response, 500, { status: 500, message: 'Could not create an authorization request URI' }, error)
80
+ }
81
+ },
82
+ )
83
+ }
84
+
85
+ export function removeAuthRequestStateUniversalOID4VPEndpoint(router: Router, context: IRequiredContext, opts?: ISingleEndpointOpts) {
86
+ if (opts?.enabled === false) {
87
+ console.log(`removeAuthStatus universal OID4VP endpoint is disabled`)
88
+ return
89
+ }
90
+
91
+ const path = opts?.path ?? '/backend/auth/requests/:correlationId'
92
+ router.delete(path, checkAuth(opts?.endpoint), async (request: DeleteAuthorizationRequest, response: Response) => {
93
+ try {
94
+ const correlationId: string = request.params.correlationId
95
+
96
+ const authRequestState = await context.agent.siopGetAuthRequestState({
97
+ correlationId,
98
+ errorOnNotFound: false,
99
+ })
100
+ if (!authRequestState) {
101
+ console.log(`No authorization request could be found for the given correlationId. correlationId: ${correlationId}`)
102
+ return sendErrorResponse(response, 404, { status: 404, message: 'No authorization request could be found' })
103
+ }
104
+
105
+ await context.agent.siopDeleteAuthState({ correlationId })
106
+
107
+ return response.status(204).json()
108
+ } catch (error) {
109
+ return sendErrorResponse(response, 500, { status: 500, message: error.message }, error)
110
+ }
111
+ })
112
+ }
113
+
114
+ export function authStatusUniversalOID4VPEndpoint(router: Router, context: IRequiredContext, opts?: ISingleEndpointOpts) {
115
+ if (opts?.enabled === false) {
116
+ console.log(`authStatus universal OID4VP endpoint is disabled`)
117
+ return
118
+ }
119
+
120
+ const path = opts?.path ?? '/backend/auth/status/:correlationId'
121
+ router.get(path, checkAuth(opts?.endpoint), async (request: GetAuthorizationRequestStatus, response: Response) => {
122
+ try {
123
+ console.log('Received auth-status request...')
124
+ const correlationId: string = request.params.correlationId
125
+
126
+ const requestState = await context.agent.siopGetAuthRequestState({
127
+ correlationId,
128
+ errorOnNotFound: false,
129
+ })
130
+
131
+ if (!requestState) {
132
+ console.log(`No authorization request could be found for the given correlationId. correlationId: ${correlationId}`)
133
+ return sendErrorResponse(response, 404, { status: 404, message: 'No authorization request could be found' })
134
+ }
135
+
136
+ let responseState
137
+ if (requestState.status === 'authorization_request_created') {
138
+ responseState = await context.agent.siopGetAuthResponseState({ correlationId, errorOnNotFound: false })
139
+ }
140
+ const overallState = responseState ?? requestState
141
+
142
+ const statusBody = {
143
+ status: overallState.status,
144
+ correlation_id: overallState.correlationId,
145
+ query_id: overallState.queryId,
146
+ last_updated: overallState.lastUpdated,
147
+ ...(responseState?.status === AuthorizationResponseStateStatus.VERIFIED &&
148
+ responseState.verifiedData !== undefined && { verified_data: responseState.verifiedData }),
149
+ ...(overallState.error && { message: overallState.error.message }),
150
+ } satisfies AuthStatusResponse
151
+ console.debug(`Will send auth status: ${JSON.stringify(statusBody)}`)
152
+
153
+ if (overallState.status === 'error') {
154
+ return response.status(500).json(statusBody)
155
+ }
156
+ return response.status(200).json(statusBody)
157
+ } catch (error) {
158
+ return sendErrorResponse(response, 500, { status: 500, message: error.message }, error)
159
+ }
160
+ })
161
+ }
162
+
163
+ export function getDefinitionsEndpoint(router: Router, context: IRequiredContext, opts?: ISingleEndpointOpts) {
164
+ if (opts?.enabled === false) {
165
+ console.log(`getDefinitions universal OID4VP endpoint is disabled`)
166
+ return
167
+ }
168
+
169
+ const path = opts?.path ?? '/backend/definitions'
170
+ router.get(path, checkAuth(opts?.endpoint), async (request: Request, response: Response) => {
171
+ try {
172
+ const definitions = await context.agent.pdmGetDefinitions()
173
+ response.statusCode = 200
174
+ return response.json(definitions)
175
+ } catch (error) {
176
+ return sendErrorResponse(response, 500, { status: 500, message: error.message }, error)
177
+ }
178
+ })
179
+ }
@@ -2,10 +2,10 @@ import { AuthorizationRequestState, AuthorizationResponseStateStatus } from '@sp
2
2
  import { checkAuth, ISingleEndpointOpts, sendErrorResponse } from '@sphereon/ssi-express-support'
3
3
  import { AuthStatusResponse, GenerateAuthRequestURIResponse, uriWithBase } from '@sphereon/ssi-sdk.siopv2-oid4vp-common'
4
4
  import { AuthorizationResponseStateWithVerifiedData, VerifiedDataMode } from '@sphereon/ssi-sdk.siopv2-oid4vp-rp-auth'
5
+ import { shaHasher as defaultHasher } from '@sphereon/ssi-sdk.core'
5
6
  import { Request, Response, Router } from 'express'
6
7
  import uuid from 'short-uuid'
7
8
  import { ICreateAuthRequestWebappEndpointOpts, IRequiredContext } from './types'
8
- import { shaHasher as defaultHasher } from '@sphereon/ssi-sdk.core'
9
9
 
10
10
  export function createAuthRequestWebappEndpoint(router: Router, context: IRequiredContext, opts?: ICreateAuthRequestWebappEndpointOpts) {
11
11
  if (opts?.enabled === false) {