@sphereon/ssi-sdk.siopv2-oid4vp-rp-rest-api 0.34.1-feature.SSISDK.50.type.refactor.176 → 0.34.1-feature.SSISDK.57.uni.client.167

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.
@@ -1,19 +1,24 @@
1
- import { AuthorizationResponseStateStatus } from '@sphereon/did-auth-siop'
1
+ import {
2
+ AuthorizationResponseStateStatus,
3
+ CreateAuthorizationRequest,
4
+ createAuthorizationRequestFromPayload,
5
+ CreateAuthorizationRequestPayloadSchema,
6
+ CreateAuthorizationResponsePayload,
7
+ } from '@sphereon/did-auth-siop'
2
8
  import { checkAuth, ISingleEndpointOpts, sendErrorResponse } from '@sphereon/ssi-express-support'
3
9
  import { uriWithBase } from '@sphereon/ssi-sdk.siopv2-oid4vp-common'
4
10
  import { Request, Response, Router } from 'express'
5
11
  import uuid from 'short-uuid'
6
12
  import { validateData } from './middleware/validationMiddleware'
7
- import { CreateAuthorizationRequestBodySchema } from './schemas'
8
13
  import {
9
- CreateAuthorizationRequest,
10
- CreateAuthorizationRequestResponse,
11
- CreateAuthorizationResponse,
14
+ AuthStatusResponse,
15
+ CreateAuthorizationRequestPayloadRequest,
16
+ CreateAuthorizationResponsePayloadResponse,
12
17
  DeleteAuthorizationRequest,
13
18
  GetAuthorizationRequestStatus,
14
- AuthStatusResponse,
15
19
  ICreateAuthRequestWebappEndpointOpts,
16
20
  IRequiredContext,
21
+ QRCodeOpts,
17
22
  } from './types'
18
23
 
19
24
  export function createAuthRequestUniversalOID4VPEndpoint(router: Router, context: IRequiredContext, opts?: ICreateAuthRequestWebappEndpointOpts) {
@@ -26,15 +31,13 @@ export function createAuthRequestUniversalOID4VPEndpoint(router: Router, context
26
31
  router.post(
27
32
  path,
28
33
  checkAuth(opts?.endpoint),
29
- validateData(CreateAuthorizationRequestBodySchema),
30
- async (request: CreateAuthorizationRequest, response: CreateAuthorizationResponse) => {
34
+ validateData(CreateAuthorizationRequestPayloadSchema),
35
+ async (request: CreateAuthorizationRequestPayloadRequest, response: CreateAuthorizationResponsePayloadResponse) => {
31
36
  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
37
+ const authRequest: CreateAuthorizationRequest = createAuthorizationRequestFromPayload(request.body)
38
+ const correlationId = authRequest.correlationId ?? uuid.uuid()
39
+ const qrCodeOpts = authRequest.qrCode ? ({ ...authRequest.qrCode } satisfies QRCodeOpts) : opts?.qrCodeOpts
40
+ const queryId = authRequest.queryId
38
41
 
39
42
  const definitionItems = await context.agent.pdmGetDefinitions({ filter: [{ queryId }] })
40
43
  if (definitionItems.length === 0) {
@@ -43,7 +46,7 @@ export function createAuthRequestUniversalOID4VPEndpoint(router: Router, context
43
46
  }
44
47
 
45
48
  const requestByReferenceURI = uriWithBase(`/siop/definitions/${queryId}/auth-requests/${correlationId}`, {
46
- baseURI: requestUriBase ?? opts?.siopBaseURI,
49
+ baseURI: authRequest.requestUriBase ?? opts?.siopBaseURI,
47
50
  })
48
51
  const responseURI = uriWithBase(`/siop/definitions/${queryId}/auth-responses/${correlationId}`, { baseURI: opts?.siopBaseURI })
49
52
 
@@ -54,8 +57,8 @@ export function createAuthRequestUniversalOID4VPEndpoint(router: Router, context
54
57
  requestByReferenceURI,
55
58
  responseURIType: 'response_uri',
56
59
  responseURI,
57
- ...(directPostResponseRedirectUri && { responseRedirectURI: directPostResponseRedirectUri }),
58
- callback,
60
+ ...(authRequest.directPostResponseRedirectUri && { responseRedirectURI: authRequest.directPostResponseRedirectUri }),
61
+ ...(authRequest.callback && { callback: authRequest.callback }),
59
62
  })
60
63
 
61
64
  let qrCodeDataUri: string | undefined
@@ -71,7 +74,7 @@ export function createAuthRequestUniversalOID4VPEndpoint(router: Router, context
71
74
  request_uri: authRequestURI,
72
75
  status_uri: `${uriWithBase(opts?.webappAuthStatusPath ?? `/backend/auth/status/${correlationId}`, { baseURI: opts?.webappBaseURI })}`,
73
76
  ...(qrCodeDataUri && { qr_uri: qrCodeDataUri }),
74
- } satisfies CreateAuthorizationRequestResponse
77
+ } satisfies CreateAuthorizationResponsePayload
75
78
  console.log(`Auth Request URI data to send back: ${JSON.stringify(authRequestBody)}`)
76
79
 
77
80
  return response.status(201).json(authRequestBody)
@@ -145,7 +148,7 @@ export function authStatusUniversalOID4VPEndpoint(router: Router, context: IRequ
145
148
  query_id: overallState.queryId,
146
149
  last_updated: overallState.lastUpdated,
147
150
  ...(responseState?.status === AuthorizationResponseStateStatus.VERIFIED &&
148
- responseState.verifiedData !== undefined && { verified_data: responseState.verifiedData }),
151
+ responseState.verifiedData !== undefined && { verifiedData: responseState.verifiedData }),
149
152
  ...(overallState.error && { message: overallState.error.message }),
150
153
  } satisfies AuthStatusResponse
151
154
  console.debug(`Will send auth status: ${JSON.stringify(statusBody)}`)
@@ -1,183 +0,0 @@
1
- import { AuthorizationRequestState, AuthorizationResponseStateStatus } from '@sphereon/did-auth-siop'
2
- import { checkAuth, ISingleEndpointOpts, sendErrorResponse } from '@sphereon/ssi-express-support'
3
- import { AuthStatusResponse, GenerateAuthRequestURIResponse, uriWithBase } from '@sphereon/ssi-sdk.siopv2-oid4vp-common'
4
- import { AuthorizationResponseStateWithVerifiedData, VerifiedDataMode } from '@sphereon/ssi-sdk.siopv2-oid4vp-rp-auth'
5
- import { shaHasher as defaultHasher } from '@sphereon/ssi-sdk.core'
6
- import { Request, Response, Router } from 'express'
7
- import uuid from 'short-uuid'
8
- import { ICreateAuthRequestWebappEndpointOpts, IRequiredContext } from './types'
9
-
10
- export function createAuthRequestWebappEndpoint(router: Router, context: IRequiredContext, opts?: ICreateAuthRequestWebappEndpointOpts) {
11
- if (opts?.enabled === false) {
12
- console.log(`createAuthRequest Webapp endpoint is disabled`)
13
- return
14
- }
15
- const path = opts?.path ?? '/webapp/definitions/:definitionId/auth-requests'
16
- router.post(path, checkAuth(opts?.endpoint), async (request: Request, response: Response) => {
17
- try {
18
- // if (!request.agent) throw Error('No agent configured')
19
- const definitionId = request.params.definitionId
20
- if (!definitionId) {
21
- return sendErrorResponse(response, 400, 'No definitionId query parameter provided')
22
- }
23
- const state: string = request.body.state ?? uuid.uuid()
24
- const correlationId = request.body.correlationId ?? state
25
- const qrCodeOpts = request.body.qrCodeOpts ?? opts?.qrCodeOpts
26
-
27
- const requestByReferenceURI = uriWithBase(`/siop/definitions/${definitionId}/auth-requests/${state}`, {
28
- baseURI: opts?.siopBaseURI,
29
- })
30
- const responseURI = uriWithBase(`/siop/definitions/${definitionId}/auth-responses/${state}`, { baseURI: opts?.siopBaseURI })
31
- // first version is for backwards compat
32
- const responseRedirectURI =
33
- ('response_redirect_uri' in request.body && (request.body.response_redirect_uri as string | undefined)) ??
34
- ('responseRedirectURI' in request.body && (request.body.responseRedirectURI as string | undefined))
35
-
36
- const authRequestURI = await context.agent.siopCreateAuthRequestURI({
37
- definitionId,
38
- correlationId,
39
- state,
40
- nonce: uuid.uuid(),
41
- requestByReferenceURI,
42
- responseURIType: 'response_uri',
43
- responseURI,
44
- ...(responseRedirectURI && { responseRedirectURI }),
45
- })
46
-
47
- let qrCodeDataUri: string | undefined
48
- if (qrCodeOpts) {
49
- const { AwesomeQR } = await import('awesome-qr')
50
- const qrCode = new AwesomeQR({ ...qrCodeOpts, text: authRequestURI })
51
- qrCodeDataUri = `data:image/png;base64,${(await qrCode.draw())!.toString('base64')}`
52
- }
53
- const authRequestBody: GenerateAuthRequestURIResponse = {
54
- correlationId,
55
- state,
56
- definitionId,
57
- authRequestURI,
58
- authStatusURI: `${uriWithBase(opts?.webappAuthStatusPath ?? '/webapp/auth-status', { baseURI: opts?.webappBaseURI })}`,
59
- ...(qrCodeDataUri && { qrCodeDataUri }),
60
- }
61
- console.log(`Auth Request URI data to send back: ${JSON.stringify(authRequestBody)}`)
62
- return response.json(authRequestBody)
63
- } catch (error) {
64
- return sendErrorResponse(response, 500, 'Could not create an authorization request URI', error)
65
- }
66
- })
67
- }
68
-
69
- export function authStatusWebappEndpoint(router: Router, context: IRequiredContext, opts?: ISingleEndpointOpts) {
70
- if (opts?.enabled === false) {
71
- console.log(`authStatus Webapp endpoint is disabled`)
72
- return
73
- }
74
- const path = opts?.path ?? '/webapp/auth-status'
75
- router.post(path, checkAuth(opts?.endpoint), async (request: Request, response: Response) => {
76
- try {
77
- console.log('Received auth-status request...')
78
- const correlationId: string = request.body.correlationId as string
79
- const definitionId: string = request.body.definitionId as string
80
-
81
- const requestState =
82
- correlationId && definitionId
83
- ? await context.agent.siopGetAuthRequestState({
84
- correlationId,
85
- definitionId,
86
- errorOnNotFound: false,
87
- })
88
- : undefined
89
- if (!requestState || !definitionId || !correlationId) {
90
- console.log(
91
- `No authentication request mapping could be found for the given URL. correlation: ${correlationId}, definitionId: ${definitionId}`,
92
- )
93
- response.statusCode = 404
94
- const statusBody: AuthStatusResponse = {
95
- status: requestState ? requestState.status : 'error',
96
- error: 'No authentication request mapping could be found for the given URL.',
97
- correlationId,
98
- definitionId,
99
- lastUpdated: requestState ? requestState.lastUpdated : Date.now(),
100
- }
101
- return response.json(statusBody)
102
- }
103
-
104
- let includeVerifiedData: VerifiedDataMode = VerifiedDataMode.NONE
105
- if ('includeVerifiedData' in request.body) {
106
- includeVerifiedData = request.body.includeVerifiedData as VerifiedDataMode
107
- }
108
-
109
- let responseState
110
- if (requestState.status === 'sent') {
111
- responseState = (await context.agent.siopGetAuthResponseState({
112
- correlationId,
113
- definitionId,
114
- includeVerifiedData: includeVerifiedData,
115
- errorOnNotFound: false,
116
- })) as AuthorizationResponseStateWithVerifiedData
117
- }
118
- const overallState: AuthorizationRequestState | AuthorizationResponseStateWithVerifiedData = responseState ?? requestState
119
-
120
- const statusBody: AuthStatusResponse = {
121
- status: overallState.status,
122
- ...(overallState.error ? { error: overallState.error?.message } : {}),
123
- correlationId,
124
- definitionId,
125
- lastUpdated: overallState.lastUpdated,
126
- ...(responseState && responseState.status === AuthorizationResponseStateStatus.VERIFIED
127
- ? {
128
- payload: await responseState.response.mergedPayloads({ hasher: defaultHasher }),
129
- verifiedData: responseState.verifiedData,
130
- }
131
- : {}),
132
- }
133
- console.debug(`Will send auth status: ${JSON.stringify(statusBody)}`)
134
- if (overallState.status === 'error') {
135
- response.statusCode = 500
136
- return response.json(statusBody)
137
- }
138
- response.statusCode = 200
139
- return response.json(statusBody)
140
- } catch (error) {
141
- return sendErrorResponse(response, 500, error.message, error)
142
- }
143
- })
144
- }
145
-
146
- export function removeAuthRequestStateWebappEndpoint(router: Router, context: IRequiredContext, opts?: ISingleEndpointOpts) {
147
- if (opts?.enabled === false) {
148
- console.log(`removeAuthStatus Webapp endpoint is disabled`)
149
- return
150
- }
151
- const path = opts?.path ?? '/webapp/definitions/:definitionId/auth-requests/:correlationId'
152
- router.delete(path, checkAuth(opts?.endpoint), async (request: Request, response: Response) => {
153
- try {
154
- const correlationId: string = request.params.correlationId
155
- const definitionId: string = request.params.definitionId
156
- if (!correlationId || !definitionId) {
157
- console.log(`No authorization request could be found for the given url. correlationId: ${correlationId}, definitionId: ${definitionId}`)
158
- return sendErrorResponse(response, 404, 'No authorization request could be found')
159
- }
160
- response.statusCode = 200
161
- return response.json(await context.agent.siopDeleteAuthState({ definitionId, correlationId }))
162
- } catch (error) {
163
- return sendErrorResponse(response, 500, error.message, error)
164
- }
165
- })
166
- }
167
-
168
- export function getDefinitionsEndpoint(router: Router, context: IRequiredContext, opts?: ISingleEndpointOpts) {
169
- if (opts?.enabled === false) {
170
- console.log(`getDefinitions Webapp endpoint is disabled`)
171
- return
172
- }
173
- const path = opts?.path ?? '/webapp/definitions'
174
- router.get(path, checkAuth(opts?.endpoint), async (request: Request, response: Response) => {
175
- try {
176
- const definitions = await context.agent.pdmGetDefinitions()
177
- response.statusCode = 200
178
- return response.json(definitions)
179
- } catch (error) {
180
- return sendErrorResponse(response, 500, error.message, error)
181
- }
182
- })
183
- }