@sphereon/ssi-sdk.siopv2-oid4vp-rp-rest-api 0.34.1-fix.171 → 0.34.1-fix.182
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/dist/index.cjs +16 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -3
- package/dist/index.d.ts +19 -3
- package/dist/index.js +16 -24
- package/dist/index.js.map +1 -1
- package/package.json +19 -19
- package/src/schemas/index.ts +8 -14
- package/src/siop-api-functions.ts +11 -21
- package/src/types/types.ts +26 -26
- package/src/universal-oid4vp-api-functions.ts +63 -57
- package/src/webapp-api-functions.ts +183 -0
|
@@ -0,0 +1,183 @@
|
|
|
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
|
+
}
|