@sphereon/ssi-sdk.siopv2-oid4vp-rp-rest-api 0.34.1-fix.182 → 0.34.1-fix.223
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 +59 -74
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -74
- package/dist/index.d.ts +6 -74
- package/dist/index.js +59 -74
- package/dist/index.js.map +1 -1
- package/package.json +21 -19
- package/src/siop-api-functions.ts +34 -16
- package/src/types/types.ts +8 -39
- package/src/universal-oid4vp-api-functions.ts +39 -27
- package/src/schemas/index.ts +0 -36
- package/src/webapp-api-functions.ts +0 -183
|
@@ -46,19 +46,30 @@ export function verifyAuthResponseSIOPv2Endpoint(router: Router, context: IRequi
|
|
|
46
46
|
console.log(`verifyAuthResponse SIOP endpoint is disabled`)
|
|
47
47
|
return
|
|
48
48
|
}
|
|
49
|
-
const path = opts?.path ?? '/siop/
|
|
49
|
+
const path = opts?.path ?? '/siop/queries/:queryId/auth-responses/:correlationId'
|
|
50
50
|
router.post(path, checkAuth(opts?.endpoint), async (request: Request, response: Response) => {
|
|
51
51
|
try {
|
|
52
52
|
const { correlationId, queryId, tenantId, version } = request.params
|
|
53
|
-
if (!correlationId
|
|
54
|
-
console.log(`No authorization request could be found for the given url. correlationId: ${correlationId}
|
|
53
|
+
if (!correlationId) {
|
|
54
|
+
console.log(`No authorization request could be found for the given url. correlationId: ${correlationId}`)
|
|
55
55
|
return sendErrorResponse(response, 404, 'No authorization request could be found')
|
|
56
56
|
}
|
|
57
|
-
console.
|
|
58
|
-
console.
|
|
59
|
-
const definitionItems = await context.agent.pdmGetDefinitions({
|
|
57
|
+
console.debug('Authorization Response (siop-sessions') // TODO use logger
|
|
58
|
+
console.debug(JSON.stringify(request.body, null, 2))
|
|
59
|
+
const definitionItems = await context.agent.pdmGetDefinitions({
|
|
60
|
+
filter: [
|
|
61
|
+
{
|
|
62
|
+
queryId,
|
|
63
|
+
...(tenantId && { tenantId }),
|
|
64
|
+
...(version && { version }),
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: queryId,
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
})
|
|
60
71
|
if (definitionItems.length === 0) {
|
|
61
|
-
console.log(`Could not get
|
|
72
|
+
console.log(`Could not get dcql query with id ${queryId} from agent. Will return 404`)
|
|
62
73
|
response.statusCode = 404
|
|
63
74
|
response.statusMessage = `No definition ${queryId}`
|
|
64
75
|
return response.send()
|
|
@@ -71,7 +82,6 @@ export function verifyAuthResponseSIOPv2Endpoint(router: Router, context: IRequi
|
|
|
71
82
|
const verifiedResponse = await context.agent.siopVerifyAuthResponse({
|
|
72
83
|
authorizationResponse,
|
|
73
84
|
correlationId,
|
|
74
|
-
queryId,
|
|
75
85
|
dcqlQuery: definitionItem.query,
|
|
76
86
|
})
|
|
77
87
|
|
|
@@ -89,7 +99,7 @@ export function verifyAuthResponseSIOPv2Endpoint(router: Router, context: IRequi
|
|
|
89
99
|
return response.send(JSON.stringify(authorizationChallengeValidationResponse))
|
|
90
100
|
}
|
|
91
101
|
|
|
92
|
-
const responseRedirectURI = await context.agent.siopGetRedirectURI({ correlationId, queryId
|
|
102
|
+
const responseRedirectURI = await context.agent.siopGetRedirectURI({ correlationId, queryId, state: verifiedResponse.state })
|
|
93
103
|
if (responseRedirectURI) {
|
|
94
104
|
response.setHeader('Content-Type', 'application/json')
|
|
95
105
|
return response.send(JSON.stringify({ redirect_uri: responseRedirectURI }))
|
|
@@ -113,26 +123,35 @@ export function getAuthRequestSIOPv2Endpoint(router: Router, context: IRequiredC
|
|
|
113
123
|
console.log(`getAuthRequest SIOP endpoint is disabled`)
|
|
114
124
|
return
|
|
115
125
|
}
|
|
116
|
-
const path = opts?.path ?? '/siop/
|
|
126
|
+
const path = opts?.path ?? '/siop/queries/:queryId/auth-requests/:correlationId'
|
|
117
127
|
router.get(path, checkAuth(opts?.endpoint), async (request: Request, response: Response) => {
|
|
118
128
|
try {
|
|
119
129
|
const correlationId = request.params.correlationId
|
|
120
|
-
const
|
|
121
|
-
if (!correlationId || !
|
|
122
|
-
console.log(`No authorization request could be found for the given url. correlationId: ${correlationId},
|
|
130
|
+
const queryId = request.params.queryId
|
|
131
|
+
if (!correlationId || !queryId) {
|
|
132
|
+
console.log(`No authorization request could be found for the given url. correlationId: ${correlationId}, queryId: ${queryId}`)
|
|
123
133
|
return sendErrorResponse(response, 404, 'No authorization request could be found')
|
|
124
134
|
}
|
|
125
135
|
const requestState = await context.agent.siopGetAuthRequestState({
|
|
126
136
|
correlationId,
|
|
127
|
-
queryId: definitionId,
|
|
128
137
|
errorOnNotFound: false,
|
|
129
138
|
})
|
|
130
139
|
if (!requestState) {
|
|
131
140
|
console.log(
|
|
132
|
-
`No authorization request could be found for the given url in the state manager. correlationId: ${correlationId}, definitionId: ${
|
|
141
|
+
`No authorization request could be found for the given url in the state manager. correlationId: ${correlationId}, definitionId: ${queryId}`,
|
|
133
142
|
)
|
|
134
143
|
return sendErrorResponse(response, 404, `No authorization request could be found`)
|
|
135
144
|
}
|
|
145
|
+
|
|
146
|
+
const definitionItems = await context.agent.pdmGetDefinitions({ filter: [{ queryId }] });
|
|
147
|
+
if (definitionItems.length === 0) {
|
|
148
|
+
console.log(`Could not get dcql query with id ${queryId} from agent. Will return 404`)
|
|
149
|
+
response.statusCode = 404
|
|
150
|
+
response.statusMessage = `No definition ${queryId}`
|
|
151
|
+
return response.send()
|
|
152
|
+
}
|
|
153
|
+
const payload = requestState.request?.requestObject?.getPayload()!
|
|
154
|
+
payload.dcql_query = definitionItems[0].query
|
|
136
155
|
const requestObject = await requestState.request?.requestObject?.toJwt()
|
|
137
156
|
console.log('JWT Request object:')
|
|
138
157
|
console.log(requestObject)
|
|
@@ -148,7 +167,6 @@ export function getAuthRequestSIOPv2Endpoint(router: Router, context: IRequiredC
|
|
|
148
167
|
} finally {
|
|
149
168
|
await context.agent.siopUpdateAuthRequestState({
|
|
150
169
|
correlationId,
|
|
151
|
-
queryId: definitionId,
|
|
152
170
|
state: 'authorization_request_created',
|
|
153
171
|
error,
|
|
154
172
|
})
|
package/src/types/types.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CreateAuthorizationRequestPayload, CreateAuthorizationResponsePayload } from '@sphereon/did-auth-siop'
|
|
2
2
|
import { GenericAuthArgs, ISingleEndpointOpts } from '@sphereon/ssi-express-support'
|
|
3
|
-
import { ISIOPv2RP } from '@sphereon/ssi-sdk.siopv2-oid4vp-rp-auth'
|
|
4
3
|
import { IPDManager } from '@sphereon/ssi-sdk.pd-manager'
|
|
5
|
-
import { AdditionalClaims } from '@sphereon/ssi-types'
|
|
6
4
|
import { AuthorizationRequestStateStatus, AuthorizationResponseStateStatus } from '@sphereon/ssi-sdk.siopv2-oid4vp-common'
|
|
5
|
+
import { ISIOPv2RP } from '@sphereon/ssi-sdk.siopv2-oid4vp-rp-auth'
|
|
6
|
+
import { IAgentContext, ICredentialVerifier } from '@veramo/core'
|
|
7
7
|
import { Request, Response } from 'express'
|
|
8
|
-
import { z } from 'zod'
|
|
9
|
-
import { CreateAuthorizationRequestBodySchema, CreateAuthorizationResponseSchema } from '../schemas'
|
|
10
8
|
import { QRCodeOpts } from './QRCode.types'
|
|
9
|
+
import { VerifiedData } from '@sphereon/did-auth-siop'
|
|
11
10
|
|
|
12
11
|
export type SiopFeatures = 'rp-status' | 'siop'
|
|
13
12
|
|
|
@@ -36,24 +35,20 @@ export interface ICreateAuthRequestWebappEndpointOpts extends ISingleEndpointOpt
|
|
|
36
35
|
export type IRequiredPlugins = ICredentialVerifier & ISIOPv2RP & IPDManager
|
|
37
36
|
export type IRequiredContext = IAgentContext<IRequiredPlugins>
|
|
38
37
|
|
|
39
|
-
export type
|
|
38
|
+
export type CreateAuthorizationRequestPayloadRequest = Request<Record<string, never>, any, CreateAuthorizationRequestPayload, Record<string, never>>
|
|
40
39
|
|
|
41
|
-
export type
|
|
42
|
-
|
|
43
|
-
export type CreateAuthorizationResponse = Response<CreateAuthorizationRequestResponse>
|
|
44
|
-
|
|
45
|
-
export type CreateAuthorizationRequestResponse = z.infer<typeof CreateAuthorizationResponseSchema>;
|
|
40
|
+
export type CreateAuthorizationResponsePayloadResponse = Response<CreateAuthorizationResponsePayload>
|
|
46
41
|
|
|
47
42
|
export type DeleteAuthorizationRequest = Request<DeleteAuthorizationRequestPathParameters, any, Record<string, any>, Record<string, any>>
|
|
48
43
|
|
|
49
44
|
export type DeleteAuthorizationRequestPathParameters = {
|
|
50
|
-
correlationId: string
|
|
45
|
+
correlationId: string
|
|
51
46
|
}
|
|
52
47
|
|
|
53
48
|
export type GetAuthorizationRequestStatus = Request<GetAuthorizationRequestStatusPathParameters, any, Record<string, any>, Record<string, any>>
|
|
54
49
|
|
|
55
50
|
export type GetAuthorizationRequestStatusPathParameters = {
|
|
56
|
-
correlationId: string
|
|
51
|
+
correlationId: string
|
|
57
52
|
}
|
|
58
53
|
|
|
59
54
|
export type RequestError = {
|
|
@@ -70,29 +65,3 @@ export interface AuthStatusResponse {
|
|
|
70
65
|
verified_data?: VerifiedData
|
|
71
66
|
error?: RequestError
|
|
72
67
|
}
|
|
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
|
|
@@ -1,19 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AuthorizationRequestStateStatus,
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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,26 +31,29 @@ export function createAuthRequestUniversalOID4VPEndpoint(router: Router, context
|
|
|
26
31
|
router.post(
|
|
27
32
|
path,
|
|
28
33
|
checkAuth(opts?.endpoint),
|
|
29
|
-
validateData(
|
|
30
|
-
async (request:
|
|
34
|
+
validateData(CreateAuthorizationRequestPayloadSchema),
|
|
35
|
+
async (request: CreateAuthorizationRequestPayloadRequest, response: CreateAuthorizationResponsePayloadResponse) => {
|
|
31
36
|
try {
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
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
|
|
41
|
+
|
|
42
|
+
const definitionItems = await context.agent.pdmGetDefinitions({
|
|
43
|
+
filter: [
|
|
44
|
+
{ id: queryId }, // Allow both PK (unique queryId + version combi) or just plain queryId which assumes the latest version
|
|
45
|
+
{ queryId },
|
|
46
|
+
],
|
|
47
|
+
})
|
|
40
48
|
if (definitionItems.length === 0) {
|
|
41
49
|
console.log(`No query could be found for the given id. Query id: ${queryId}`)
|
|
42
50
|
return sendErrorResponse(response, 404, { status: 404, message: 'No query could be found' })
|
|
43
51
|
}
|
|
44
52
|
|
|
45
|
-
const requestByReferenceURI = uriWithBase(`/siop/
|
|
46
|
-
baseURI: requestUriBase ?? opts?.siopBaseURI,
|
|
53
|
+
const requestByReferenceURI = uriWithBase(`/siop/queries/${queryId}/auth-requests/${correlationId}`, {
|
|
54
|
+
baseURI: authRequest.requestUriBase ?? opts?.siopBaseURI,
|
|
47
55
|
})
|
|
48
|
-
const responseURI = uriWithBase(`/siop/
|
|
56
|
+
const responseURI = uriWithBase(`/siop/queries/${queryId}/auth-responses/${correlationId}`, { baseURI: opts?.siopBaseURI })
|
|
49
57
|
|
|
50
58
|
const authRequestURI = await context.agent.siopCreateAuthRequestURI({
|
|
51
59
|
queryId,
|
|
@@ -54,8 +62,8 @@ export function createAuthRequestUniversalOID4VPEndpoint(router: Router, context
|
|
|
54
62
|
requestByReferenceURI,
|
|
55
63
|
responseURIType: 'response_uri',
|
|
56
64
|
responseURI,
|
|
57
|
-
...(directPostResponseRedirectUri && { responseRedirectURI: directPostResponseRedirectUri }),
|
|
58
|
-
callback,
|
|
65
|
+
...(authRequest.directPostResponseRedirectUri && { responseRedirectURI: authRequest.directPostResponseRedirectUri }),
|
|
66
|
+
...(authRequest.callback && { callback: authRequest.callback }),
|
|
59
67
|
})
|
|
60
68
|
|
|
61
69
|
let qrCodeDataUri: string | undefined
|
|
@@ -63,6 +71,8 @@ export function createAuthRequestUniversalOID4VPEndpoint(router: Router, context
|
|
|
63
71
|
const { AwesomeQR } = await import('awesome-qr')
|
|
64
72
|
const qrCode = new AwesomeQR({ ...qrCodeOpts, text: authRequestURI })
|
|
65
73
|
qrCodeDataUri = `data:image/png;base64,${(await qrCode.draw())!.toString('base64')}`
|
|
74
|
+
} else {
|
|
75
|
+
qrCodeDataUri = authRequestURI
|
|
66
76
|
}
|
|
67
77
|
|
|
68
78
|
const authRequestBody = {
|
|
@@ -71,7 +81,7 @@ export function createAuthRequestUniversalOID4VPEndpoint(router: Router, context
|
|
|
71
81
|
request_uri: authRequestURI,
|
|
72
82
|
status_uri: `${uriWithBase(opts?.webappAuthStatusPath ?? `/backend/auth/status/${correlationId}`, { baseURI: opts?.webappBaseURI })}`,
|
|
73
83
|
...(qrCodeDataUri && { qr_uri: qrCodeDataUri }),
|
|
74
|
-
} satisfies
|
|
84
|
+
} satisfies CreateAuthorizationResponsePayload
|
|
75
85
|
console.log(`Auth Request URI data to send back: ${JSON.stringify(authRequestBody)}`)
|
|
76
86
|
|
|
77
87
|
return response.status(201).json(authRequestBody)
|
|
@@ -134,8 +144,11 @@ export function authStatusUniversalOID4VPEndpoint(router: Router, context: IRequ
|
|
|
134
144
|
}
|
|
135
145
|
|
|
136
146
|
let responseState
|
|
137
|
-
if (requestState.status ===
|
|
138
|
-
responseState = await context.agent.siopGetAuthResponseState({
|
|
147
|
+
if (requestState.status === AuthorizationRequestStateStatus.RETRIEVED) {
|
|
148
|
+
responseState = await context.agent.siopGetAuthResponseState({
|
|
149
|
+
correlationId,
|
|
150
|
+
errorOnNotFound: false
|
|
151
|
+
})
|
|
139
152
|
}
|
|
140
153
|
const overallState = responseState ?? requestState
|
|
141
154
|
|
|
@@ -144,9 +157,8 @@ export function authStatusUniversalOID4VPEndpoint(router: Router, context: IRequ
|
|
|
144
157
|
correlation_id: overallState.correlationId,
|
|
145
158
|
query_id: overallState.queryId,
|
|
146
159
|
last_updated: overallState.lastUpdated,
|
|
147
|
-
...(
|
|
148
|
-
|
|
149
|
-
...(overallState.error && { message: overallState.error.message }),
|
|
160
|
+
...('verifiedData' in overallState && { verified_data: overallState.verifiedData }),
|
|
161
|
+
...(overallState.error && { message: overallState.error.message })
|
|
150
162
|
} satisfies AuthStatusResponse
|
|
151
163
|
console.debug(`Will send auth status: ${JSON.stringify(statusBody)}`)
|
|
152
164
|
|
package/src/schemas/index.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
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
|
-
})
|
|
@@ -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
|
-
}
|