@sphereon/oid4vci-client 0.10.3 → 0.10.4-next.14
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/README.md +18 -0
- package/dist/AccessTokenClient.d.ts.map +1 -1
- package/dist/AccessTokenClient.js +11 -16
- package/dist/AccessTokenClient.js.map +1 -1
- package/dist/CredentialOfferClient.d.ts.map +1 -1
- package/dist/CredentialOfferClient.js +8 -7
- package/dist/CredentialOfferClient.js.map +1 -1
- package/dist/CredentialRequestClient.d.ts +6 -1
- package/dist/CredentialRequestClient.d.ts.map +1 -1
- package/dist/CredentialRequestClient.js +42 -19
- package/dist/CredentialRequestClient.js.map +1 -1
- package/dist/MetadataClient.d.ts.map +1 -1
- package/dist/MetadataClient.js +1 -2
- package/dist/MetadataClient.js.map +1 -1
- package/dist/ProofOfPossessionBuilder.d.ts.map +1 -1
- package/dist/ProofOfPossessionBuilder.js +1 -2
- package/dist/ProofOfPossessionBuilder.js.map +1 -1
- package/dist/functions/index.d.ts +1 -3
- package/dist/functions/index.d.ts.map +1 -1
- package/dist/functions/index.js +1 -3
- package/dist/functions/index.js.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -1
- package/lib/AccessTokenClient.ts +12 -13
- package/lib/CredentialOfferClient.ts +7 -5
- package/lib/CredentialRequestClient.ts +43 -3
- package/lib/MetadataClient.ts +1 -2
- package/lib/ProofOfPossessionBuilder.ts +1 -2
- package/lib/__tests__/CredentialRequestClient.spec.ts +5 -1
- package/lib/__tests__/HttpUtils.spec.ts +1 -1
- package/lib/__tests__/IT.spec.ts +42 -3
- package/lib/__tests__/IssuanceInitiation.spec.ts +22 -0
- package/lib/__tests__/ProofOfPossessionBuilder.spec.ts +1 -1
- package/lib/__tests__/SdJwt.spec.ts +2 -1
- package/lib/__tests__/SphereonE2E.spec.test.ts +2 -1
- package/lib/functions/index.ts +1 -3
- package/lib/types/index.ts +6 -0
- package/package.json +4 -4
- package/dist/functions/ProofUtil.d.ts +0 -30
- package/dist/functions/ProofUtil.d.ts.map +0 -1
- package/dist/functions/ProofUtil.js +0 -106
- package/dist/functions/ProofUtil.js.map +0 -1
- package/lib/functions/ProofUtil.ts +0 -128
package/lib/AccessTokenClient.ts
CHANGED
|
@@ -5,7 +5,9 @@ import {
|
|
|
5
5
|
assertedUniformCredentialOffer,
|
|
6
6
|
AuthorizationServerOpts,
|
|
7
7
|
AuthzFlowType,
|
|
8
|
+
convertJsonToURI,
|
|
8
9
|
EndpointMetadata,
|
|
10
|
+
formPost,
|
|
9
11
|
getIssuerFromCredentialOfferPayload,
|
|
10
12
|
GrantTypes,
|
|
11
13
|
IssuerOpts,
|
|
@@ -17,12 +19,9 @@ import {
|
|
|
17
19
|
UniformCredentialOfferPayload,
|
|
18
20
|
} from '@sphereon/oid4vci-common';
|
|
19
21
|
import { ObjectUtils } from '@sphereon/ssi-types';
|
|
20
|
-
import Debug from 'debug';
|
|
21
22
|
|
|
22
23
|
import { MetadataClient } from './MetadataClient';
|
|
23
|
-
import {
|
|
24
|
-
|
|
25
|
-
const debug = Debug('sphereon:oid4vci:token');
|
|
24
|
+
import { LOG } from './types';
|
|
26
25
|
|
|
27
26
|
export class AccessTokenClient {
|
|
28
27
|
public async acquireAccessToken(opts: AccessTokenRequestOpts): Promise<OpenIDResponse<AccessTokenResponse>> {
|
|
@@ -117,7 +116,7 @@ export class AccessTokenClient {
|
|
|
117
116
|
return request as AccessTokenRequest;
|
|
118
117
|
}
|
|
119
118
|
|
|
120
|
-
throw new Error('Credential offer request
|
|
119
|
+
throw new Error('Credential offer request follows neither pre-authorized code nor authorization code flow requirements.');
|
|
121
120
|
}
|
|
122
121
|
|
|
123
122
|
private assertPreAuthorizedGrantType(grantType: GrantTypes): void {
|
|
@@ -141,39 +140,39 @@ export class AccessTokenClient {
|
|
|
141
140
|
if (requestPayload.grants?.['urn:ietf:params:oauth:grant-type:pre-authorized_code']) {
|
|
142
141
|
isPinRequired = requestPayload.grants['urn:ietf:params:oauth:grant-type:pre-authorized_code']?.user_pin_required ?? false;
|
|
143
142
|
}
|
|
144
|
-
|
|
143
|
+
LOG.warning(`Pin required for issuer ${issuer}: ${isPinRequired}`);
|
|
145
144
|
return isPinRequired;
|
|
146
145
|
}
|
|
147
146
|
|
|
148
147
|
private assertNumericPin(isPinRequired?: boolean, pin?: string): void {
|
|
149
148
|
if (isPinRequired) {
|
|
150
149
|
if (!pin || !/^\d{1,8}$/.test(pin)) {
|
|
151
|
-
|
|
150
|
+
LOG.warning(`Pin is not 1 to 8 digits long`);
|
|
152
151
|
throw new Error('A valid pin consisting of maximal 8 numeric characters must be present.');
|
|
153
152
|
}
|
|
154
153
|
} else if (pin) {
|
|
155
|
-
|
|
154
|
+
LOG.warning(`Pin set, whilst not required`);
|
|
156
155
|
throw new Error('Cannot set a pin, when the pin is not required.');
|
|
157
156
|
}
|
|
158
157
|
}
|
|
159
158
|
|
|
160
159
|
private assertNonEmptyPreAuthorizedCode(accessTokenRequest: AccessTokenRequest): void {
|
|
161
160
|
if (!accessTokenRequest[PRE_AUTH_CODE_LITERAL]) {
|
|
162
|
-
|
|
161
|
+
LOG.warning(`No pre-authorized code present, whilst it is required`, accessTokenRequest);
|
|
163
162
|
throw new Error('Pre-authorization must be proven by presenting the pre-authorized code. Code must be present.');
|
|
164
163
|
}
|
|
165
164
|
}
|
|
166
165
|
|
|
167
166
|
private assertNonEmptyCodeVerifier(accessTokenRequest: AccessTokenRequest): void {
|
|
168
167
|
if (!accessTokenRequest.code_verifier) {
|
|
169
|
-
|
|
168
|
+
LOG.warning('No code_verifier present, whilst it is required', accessTokenRequest);
|
|
170
169
|
throw new Error('Authorization flow requires the code_verifier to be present');
|
|
171
170
|
}
|
|
172
171
|
}
|
|
173
172
|
|
|
174
173
|
private assertNonEmptyCode(accessTokenRequest: AccessTokenRequest): void {
|
|
175
174
|
if (!accessTokenRequest.code) {
|
|
176
|
-
|
|
175
|
+
LOG.warning('No code present, whilst it is required');
|
|
177
176
|
throw new Error('Authorization flow requires the code to be present');
|
|
178
177
|
}
|
|
179
178
|
}
|
|
@@ -222,7 +221,7 @@ export class AccessTokenClient {
|
|
|
222
221
|
if (!url || !ObjectUtils.isString(url)) {
|
|
223
222
|
throw new Error('No authorization server token URL present. Cannot acquire access token');
|
|
224
223
|
}
|
|
225
|
-
debug(`Token endpoint determined to be ${url}`);
|
|
224
|
+
LOG.debug(`Token endpoint determined to be ${url}`);
|
|
226
225
|
return url;
|
|
227
226
|
}
|
|
228
227
|
|
|
@@ -239,7 +238,7 @@ export class AccessTokenClient {
|
|
|
239
238
|
}
|
|
240
239
|
|
|
241
240
|
private throwNotSupportedFlow(): void {
|
|
242
|
-
|
|
241
|
+
LOG.warning(`Only pre-authorized or authorization code flows supported.`);
|
|
243
242
|
throw new Error('Only pre-authorized-code or authorization code flows are supported');
|
|
244
243
|
}
|
|
245
244
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
+
convertJsonToURI,
|
|
3
|
+
convertURIToJsonObject,
|
|
2
4
|
CredentialOffer,
|
|
3
5
|
CredentialOfferPayload,
|
|
4
6
|
CredentialOfferPayloadV1_0_09,
|
|
@@ -11,8 +13,6 @@ import {
|
|
|
11
13
|
} from '@sphereon/oid4vci-common';
|
|
12
14
|
import Debug from 'debug';
|
|
13
15
|
|
|
14
|
-
import { convertJsonToURI, convertURIToJsonObject } from './functions';
|
|
15
|
-
|
|
16
16
|
const debug = Debug('sphereon:oid4vci:offer');
|
|
17
17
|
|
|
18
18
|
export class CredentialOfferClient {
|
|
@@ -27,18 +27,20 @@ export class CredentialOfferClient {
|
|
|
27
27
|
const version = determineSpecVersionFromURI(uri);
|
|
28
28
|
let credentialOffer: CredentialOffer;
|
|
29
29
|
let credentialOfferPayload: CredentialOfferPayload;
|
|
30
|
+
// credential offer was introduced in draft 9 and credential_offer_uri in draft 11
|
|
30
31
|
if (version < OpenId4VCIVersion.VER_1_0_11) {
|
|
31
32
|
credentialOfferPayload = convertURIToJsonObject(uri, {
|
|
32
33
|
arrayTypeProperties: ['credential_type'],
|
|
33
|
-
requiredProperties: uri.includes('
|
|
34
|
+
requiredProperties: uri.includes('credential_offer=') ? ['credential_offer'] : ['issuer', 'credential_type'],
|
|
34
35
|
}) as CredentialOfferPayloadV1_0_09;
|
|
35
36
|
credentialOffer = {
|
|
36
37
|
credential_offer: credentialOfferPayload,
|
|
37
38
|
};
|
|
38
39
|
} else {
|
|
39
40
|
credentialOffer = convertURIToJsonObject(uri, {
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
// It must have the '=' sign after credential_offer otherwise the uri will get split at openid_credential_offer
|
|
42
|
+
arrayTypeProperties: uri.includes('credential_offer_uri=') ? ['credential_offer_uri='] : ['credential_offer='],
|
|
43
|
+
requiredProperties: uri.includes('credential_offer_uri=') ? ['credential_offer_uri='] : ['credential_offer='],
|
|
42
44
|
}) as CredentialOfferV1_0_11;
|
|
43
45
|
if (credentialOffer?.credential_offer_uri === undefined && !credentialOffer?.credential_offer) {
|
|
44
46
|
throw Error('Either a credential_offer or credential_offer_uri should be present in ' + uri);
|
|
@@ -4,19 +4,25 @@ import {
|
|
|
4
4
|
getCredentialRequestForVersion,
|
|
5
5
|
getUniformFormat,
|
|
6
6
|
isDeferredCredentialResponse,
|
|
7
|
+
isValidURL,
|
|
8
|
+
NotificationErrorResponse,
|
|
9
|
+
NotificationRequest,
|
|
10
|
+
NotificationResult,
|
|
7
11
|
OID4VCICredentialFormat,
|
|
8
12
|
OpenId4VCIVersion,
|
|
9
13
|
OpenIDResponse,
|
|
14
|
+
post,
|
|
10
15
|
ProofOfPossession,
|
|
11
16
|
UniformCredentialRequest,
|
|
12
17
|
URL_NOT_VALID,
|
|
13
18
|
} from '@sphereon/oid4vci-common';
|
|
19
|
+
import { ExperimentalSubjectIssuance } from '@sphereon/oid4vci-common/dist/experimental/holder-vci';
|
|
14
20
|
import { CredentialFormat } from '@sphereon/ssi-types';
|
|
15
21
|
import Debug from 'debug';
|
|
16
22
|
|
|
17
23
|
import { CredentialRequestClientBuilder } from './CredentialRequestClientBuilder';
|
|
18
24
|
import { ProofOfPossessionBuilder } from './ProofOfPossessionBuilder';
|
|
19
|
-
import {
|
|
25
|
+
import { LOG } from './types';
|
|
20
26
|
|
|
21
27
|
const debug = Debug('sphereon:oid4vci:credential');
|
|
22
28
|
|
|
@@ -24,6 +30,7 @@ export interface CredentialRequestOpts {
|
|
|
24
30
|
deferredCredentialAwait?: boolean;
|
|
25
31
|
deferredCredentialIntervalInMS?: number;
|
|
26
32
|
credentialEndpoint: string;
|
|
33
|
+
notificationEndpoint?: string;
|
|
27
34
|
deferredCredentialEndpoint?: string;
|
|
28
35
|
credentialTypes: string[];
|
|
29
36
|
format?: CredentialFormat | OID4VCICredentialFormat;
|
|
@@ -80,10 +87,11 @@ export class CredentialRequestClient {
|
|
|
80
87
|
credentialTypes?: string | string[];
|
|
81
88
|
context?: string[];
|
|
82
89
|
format?: CredentialFormat | OID4VCICredentialFormat;
|
|
90
|
+
subjectIssuance?: ExperimentalSubjectIssuance;
|
|
83
91
|
}): Promise<OpenIDResponse<CredentialResponse>> {
|
|
84
|
-
const { credentialTypes, proofInput, format, context } = opts;
|
|
92
|
+
const { credentialTypes, proofInput, format, context, subjectIssuance } = opts;
|
|
85
93
|
|
|
86
|
-
const request = await this.createCredentialRequest({ proofInput, credentialTypes, context, format, version: this.version() });
|
|
94
|
+
const request = await this.createCredentialRequest({ proofInput, credentialTypes, context, format, version: this.version(), subjectIssuance });
|
|
87
95
|
return await this.acquireCredentialsUsingRequest(request);
|
|
88
96
|
}
|
|
89
97
|
|
|
@@ -103,6 +111,11 @@ export class CredentialRequestClient {
|
|
|
103
111
|
response = await this.acquireDeferredCredential(response.successBody, { bearerToken: this.credentialRequestOpts.token });
|
|
104
112
|
}
|
|
105
113
|
|
|
114
|
+
if ((uniformRequest.credential_subject_issuance && response.successBody) || response.successBody?.credential_subject_issuance) {
|
|
115
|
+
if (uniformRequest.credential_subject_issuance !== response.successBody?.credential_subject_issuance) {
|
|
116
|
+
throw Error('Subject signing was requested, but issuer did not provide the options in its response');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
106
119
|
debug(`Credential endpoint ${credentialEndpoint} response:\r\n${JSON.stringify(response, null, 2)}`);
|
|
107
120
|
return response;
|
|
108
121
|
}
|
|
@@ -136,6 +149,7 @@ export class CredentialRequestClient {
|
|
|
136
149
|
credentialTypes?: string | string[];
|
|
137
150
|
context?: string[];
|
|
138
151
|
format?: CredentialFormat | OID4VCICredentialFormat;
|
|
152
|
+
subjectIssuance?: ExperimentalSubjectIssuance;
|
|
139
153
|
version: OpenId4VCIVersion;
|
|
140
154
|
}): Promise<UniformCredentialRequest> {
|
|
141
155
|
const { proofInput } = opts;
|
|
@@ -165,6 +179,7 @@ export class CredentialRequestClient {
|
|
|
165
179
|
types,
|
|
166
180
|
format,
|
|
167
181
|
proof,
|
|
182
|
+
...opts.subjectIssuance,
|
|
168
183
|
};
|
|
169
184
|
} else if (format === 'jwt_vc_json-ld' || format === 'ldp_vc') {
|
|
170
185
|
if (this.version() >= OpenId4VCIVersion.VER_1_0_12 && !opts.context) {
|
|
@@ -174,6 +189,7 @@ export class CredentialRequestClient {
|
|
|
174
189
|
return {
|
|
175
190
|
format,
|
|
176
191
|
proof,
|
|
192
|
+
...opts.subjectIssuance,
|
|
177
193
|
|
|
178
194
|
// Ignored because v11 does not have the context value, but it is required in v12
|
|
179
195
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
@@ -192,12 +208,36 @@ export class CredentialRequestClient {
|
|
|
192
208
|
format,
|
|
193
209
|
proof,
|
|
194
210
|
vct: types[0],
|
|
211
|
+
...opts.subjectIssuance,
|
|
195
212
|
};
|
|
196
213
|
}
|
|
197
214
|
|
|
198
215
|
throw new Error(`Unsupported format: ${format}`);
|
|
199
216
|
}
|
|
200
217
|
|
|
218
|
+
public async sendNotification(request: NotificationRequest, accessToken: string): Promise<NotificationResult> {
|
|
219
|
+
LOG.info(`Sending status notification event '${request.event}' for id ${request.notification_id}`);
|
|
220
|
+
if (!this.credentialRequestOpts.notificationEndpoint) {
|
|
221
|
+
throw Error(`Cannot send notification when no notification endpoint is provided`);
|
|
222
|
+
}
|
|
223
|
+
const response = await post<NotificationErrorResponse>(this.credentialRequestOpts.notificationEndpoint, JSON.stringify(request), {
|
|
224
|
+
bearerToken: accessToken,
|
|
225
|
+
});
|
|
226
|
+
const error = response.errorBody?.error !== undefined;
|
|
227
|
+
const result = {
|
|
228
|
+
error,
|
|
229
|
+
response: error ? await response.errorBody?.json() : undefined,
|
|
230
|
+
};
|
|
231
|
+
if (error) {
|
|
232
|
+
LOG.warning(
|
|
233
|
+
`Notification endpoint returned an error for event '${request.event}' and id ${request.notification_id}: ${await response.errorBody?.json()}`,
|
|
234
|
+
);
|
|
235
|
+
} else {
|
|
236
|
+
LOG.debug(`Notification endpoint returned success for event '${request.event}' and id ${request.notification_id}`);
|
|
237
|
+
}
|
|
238
|
+
return result;
|
|
239
|
+
}
|
|
240
|
+
|
|
201
241
|
private version(): OpenId4VCIVersion {
|
|
202
242
|
return this.credentialRequestOpts?.version ?? OpenId4VCIVersion.VER_1_0_11;
|
|
203
243
|
}
|
package/lib/MetadataClient.ts
CHANGED
|
@@ -6,13 +6,12 @@ import {
|
|
|
6
6
|
CredentialOfferRequestWithBaseUrl,
|
|
7
7
|
EndpointMetadataResult,
|
|
8
8
|
getIssuerFromCredentialOfferPayload,
|
|
9
|
+
getJson,
|
|
9
10
|
OpenIDResponse,
|
|
10
11
|
WellKnownEndpoints,
|
|
11
12
|
} from '@sphereon/oid4vci-common';
|
|
12
13
|
import Debug from 'debug';
|
|
13
14
|
|
|
14
|
-
import { getJson } from './functions';
|
|
15
|
-
|
|
16
15
|
const debug = Debug('sphereon:oid4vci:metadata');
|
|
17
16
|
|
|
18
17
|
export class MetadataClient {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AccessTokenResponse,
|
|
3
3
|
Alg,
|
|
4
|
+
createProofOfPossession,
|
|
4
5
|
EndpointMetadata,
|
|
5
6
|
JWK,
|
|
6
7
|
Jwt,
|
|
@@ -12,8 +13,6 @@ import {
|
|
|
12
13
|
Typ,
|
|
13
14
|
} from '@sphereon/oid4vci-common';
|
|
14
15
|
|
|
15
|
-
import { createProofOfPossession } from './functions';
|
|
16
|
-
|
|
17
16
|
export class ProofOfPossessionBuilder<DIDDoc> {
|
|
18
17
|
private readonly proof?: ProofOfPossession;
|
|
19
18
|
private readonly callbacks?: ProofOfPossessionCallbacks<DIDDoc>;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// Walt uses a self signed cert
|
|
2
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
3
|
+
|
|
1
4
|
import { KeyObject } from 'crypto';
|
|
2
5
|
|
|
3
6
|
import {
|
|
@@ -164,7 +167,8 @@ describe('Credential Request Client with Walt.id ', () => {
|
|
|
164
167
|
afterEach(() => {
|
|
165
168
|
nock.cleanAll();
|
|
166
169
|
});
|
|
167
|
-
|
|
170
|
+
// Walt id has cert issue
|
|
171
|
+
it.skip('should have correct metadata endpoints', async function () {
|
|
168
172
|
nock.cleanAll();
|
|
169
173
|
const WALT_IRR_URI =
|
|
170
174
|
'openid-initiate-issuance://?issuer=https%3A%2F%2Fjff.walt.id%2Fissuer-api%2Foidc%2F&credential_type=OpenBadgeCredential&pre-authorized_code=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhOTUyZjUxNi1jYWVmLTQ4YjMtODIxYy00OTRkYzgyNjljZjAiLCJwcmUtYXV0aG9yaXplZCI6dHJ1ZX0.YE5DlalcLC2ChGEg47CQDaN1gTxbaQqSclIVqsSAUHE&user_pin_required=false';
|
package/lib/__tests__/IT.spec.ts
CHANGED
|
@@ -50,7 +50,13 @@ describe('OID4VCI-Client should', () => {
|
|
|
50
50
|
const INITIATE_QR =
|
|
51
51
|
'openid-initiate-issuance://?issuer=https%3A%2F%2Fissuer.research.identiproof.io&credential_type=OpenBadgeCredentialUrl&pre-authorized_code=4jLs9xZHEfqcoow0kHE7d1a8hUk6Sy-5bVSV2MqBUGUgiFFQi-ImL62T-FmLIo8hKA1UdMPH0lM1xAgcFkJfxIw9L-lI3mVs0hRT8YVwsEM1ma6N3wzuCdwtMU4bcwKp&user_pin_required=true';
|
|
52
52
|
const OFFER_QR =
|
|
53
|
-
'openid-credential-offer
|
|
53
|
+
'openid-credential-offer://?credential_offer=%7B%22credential_issuer%22%3A%22https%3A%2F%2Fissuer.research.identiproof.io%22%2C%22credentials%22%3A%5B%7B%22format%22%3A%22jwt_vc_json%22%2C%22types%22%3A%5B%22VerifiableCredential%22%2C%22UniversityDegreeCredential%22%5D%7D%5D%2C%22grants%22%3A%7B%22urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code%22%3A%7B%22pre-authorized_code%22%3A%22adhjhdjajkdkhjhdj%22%2C%22user_pin_required%22%3Atrue%7D%7D%7D';
|
|
54
|
+
const HTTPS_INITIATE_QR =
|
|
55
|
+
'https://issuer.research.identiproof.io?issuer=https%3A%2F%2Fissuer.research.identiproof.io&credential_type=OpenBadgeCredentialUrl&pre-authorized_code=4jLs9xZHEfqcoow0kHE7d1a8hUk6Sy-5bVSV2MqBUGUgiFFQi-ImL62T-FmLIo8hKA1UdMPH0lM1xAgcFkJfxIw9L-lI3mVs0hRT8YVwsEM1ma6N3wzuCdwtMU4bcwKp&user_pin_required=true';
|
|
56
|
+
const HTTPS_OFFER_QR_AUTHORIZATION_CODE =
|
|
57
|
+
'https://issuer.research.identiproof.io?credential_offer=%7B%22credential_issuer%22%3A%22https%3A%2F%2Fissuer.research.identiproof.io%22%2C%22credentials%22%3A%5B%7B%22format%22%3A%22jwt_vc_json%22%2C%22types%22%3A%5B%22VerifiableCredential%22%2C%22UniversityDegreeCredential%22%5D%7D%5D%2C%22grants%22%3A%7B%22authorization_code%22%3A%7B%22issuer_state%22%3A%22eyJhbGciOiJSU0Et...FYUaBy%22%7D%7D%7D';
|
|
58
|
+
const HTTPS_OFFER_QR_PRE_AUTHORIZED =
|
|
59
|
+
'https://issuer.research.identiproof.io?credential_offer=%7B%22credential_issuer%22%3A%22https%3A%2F%2Fissuer.research.identiproof.io%22%2C%22credentials%22%3A%5B%7B%22format%22%3A%22jwt_vc_json%22%2C%22types%22%3A%5B%22VerifiableCredential%22%2C%22UniversityDegreeCredential%22%5D%7D%5D%2C%22grants%22%3A%7B%22urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code%22%3A%7B%22pre-authorized_code%22%3A%22adhjhdjajkdkhjhdj%22%2C%22user_pin_required%22%3Atrue%7D%7D%7D';
|
|
54
60
|
|
|
55
61
|
function succeedWithAFullFlowWithClientSetup() {
|
|
56
62
|
nock(IDENTIPROOF_ISSUER_URL).get('/.well-known/openid-credential-issuer').reply(200, JSON.stringify(IDENTIPROOF_OID4VCI_METADATA));
|
|
@@ -78,7 +84,7 @@ describe('OID4VCI-Client should', () => {
|
|
|
78
84
|
await assertionOfsucceedWithAFullFlowWithClient(client);
|
|
79
85
|
});
|
|
80
86
|
|
|
81
|
-
|
|
87
|
+
it('succeed with a full flow with the client using OpenID4VCI version 11 and deeplink', async () => {
|
|
82
88
|
succeedWithAFullFlowWithClientSetup();
|
|
83
89
|
const client = await OpenID4VCIClient.fromURI({
|
|
84
90
|
uri: OFFER_QR,
|
|
@@ -89,6 +95,39 @@ describe('OID4VCI-Client should', () => {
|
|
|
89
95
|
await assertionOfsucceedWithAFullFlowWithClient(client);
|
|
90
96
|
});
|
|
91
97
|
|
|
98
|
+
it('succeed with a full flow with the client using OpenID4VCI draft < 9 and https', async () => {
|
|
99
|
+
succeedWithAFullFlowWithClientSetup();
|
|
100
|
+
const client = await OpenID4VCIClient.fromURI({
|
|
101
|
+
uri: HTTPS_INITIATE_QR,
|
|
102
|
+
kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1',
|
|
103
|
+
alg: Alg.ES256,
|
|
104
|
+
clientId: 'test-clientId',
|
|
105
|
+
});
|
|
106
|
+
await assertionOfsucceedWithAFullFlowWithClient(client);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('should succeed with a full flow with the client using OpenID4VCI draft > 11, https and authorization_code flow', async () => {
|
|
110
|
+
succeedWithAFullFlowWithClientSetup();
|
|
111
|
+
const client = await OpenID4VCIClient.fromURI({
|
|
112
|
+
uri: HTTPS_OFFER_QR_AUTHORIZATION_CODE,
|
|
113
|
+
kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1',
|
|
114
|
+
alg: Alg.ES256,
|
|
115
|
+
clientId: 'test-clientId',
|
|
116
|
+
});
|
|
117
|
+
await assertionOfsucceedWithAFullFlowWithClient(client);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('should succeed with a full flow with the client using OpenID4VCI draft > 11, https and preauthorized_code flow', async () => {
|
|
121
|
+
succeedWithAFullFlowWithClientSetup();
|
|
122
|
+
const client = await OpenID4VCIClient.fromURI({
|
|
123
|
+
uri: HTTPS_OFFER_QR_PRE_AUTHORIZED,
|
|
124
|
+
kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1',
|
|
125
|
+
alg: Alg.ES256,
|
|
126
|
+
clientId: 'test-clientId',
|
|
127
|
+
});
|
|
128
|
+
await assertionOfsucceedWithAFullFlowWithClient(client);
|
|
129
|
+
});
|
|
130
|
+
|
|
92
131
|
async function assertionOfsucceedWithAFullFlowWithClient(client: OpenID4VCIClient) {
|
|
93
132
|
expect(client.credentialOffer).toBeDefined();
|
|
94
133
|
expect(client.endpointMetadata).toBeDefined();
|
|
@@ -96,7 +135,7 @@ describe('OID4VCI-Client should', () => {
|
|
|
96
135
|
expect(client.getCredentialEndpoint()).toEqual('https://issuer.research.identiproof.io/credential');
|
|
97
136
|
expect(client.getAccessTokenEndpoint()).toEqual('https://auth.research.identiproof.io/oauth2/token');
|
|
98
137
|
|
|
99
|
-
const accessToken = await client.acquireAccessToken({ pin: '1234' });
|
|
138
|
+
const accessToken = await client.acquireAccessToken({ pin: '1234', code: 'ABCD' });
|
|
100
139
|
expect(accessToken).toEqual(mockedAccessTokenResponse);
|
|
101
140
|
|
|
102
141
|
const credentialResponse = await client.acquireCredentials({
|
|
@@ -58,4 +58,26 @@ describe('Issuance Initiation', () => {
|
|
|
58
58
|
expect(client.credential_offer.credential_issuer).toEqual('https://launchpad.vii.electron.mattrlabs.io');
|
|
59
59
|
expect(client.preAuthorizedCode).toEqual('UPZohaodPlLBnGsqB02n2tIupCIg8nKRRUEUHWA665X');
|
|
60
60
|
});
|
|
61
|
+
|
|
62
|
+
it('Should take an https url as input and return a Credential Offer', async () => {
|
|
63
|
+
const client = await CredentialOfferClient.fromURI(
|
|
64
|
+
'https://launchpad.vii.electron.mattrlabs.io?credential_offer=%7B%22credential_issuer%22%3A%22https%3A%2F%2Flaunchpad.vii.electron.mattrlabs.io%22%2C%22credentials%22%3A%5B%7B%22format%22%3A%22ldp_vc%22%2C%22types%22%3A%5B%22OpenBadgeCredential%22%5D%7D%5D%2C%22grants%22%3A%7B%22urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code%22%3A%7B%22pre-authorized_code%22%3A%22UPZohaodPlLBnGsqB02n2tIupCIg8nKRRUEUHWA665X%22%7D%7D%7D',
|
|
65
|
+
);
|
|
66
|
+
expect(client.version).toEqual(OpenId4VCIVersion.VER_1_0_11);
|
|
67
|
+
expect(client.baseUrl).toEqual('https://launchpad.vii.electron.mattrlabs.io');
|
|
68
|
+
expect(client.scheme).toEqual('https');
|
|
69
|
+
expect(client.credential_offer.credential_issuer).toEqual('https://launchpad.vii.electron.mattrlabs.io');
|
|
70
|
+
expect(client.preAuthorizedCode).toEqual('UPZohaodPlLBnGsqB02n2tIupCIg8nKRRUEUHWA665X');
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it('Should take an http url as input and return a Credential Offer', async () => {
|
|
74
|
+
const client = await CredentialOfferClient.fromURI(
|
|
75
|
+
'http://launchpad.vii.electron.mattrlabs.io?credential_offer=%7B%22credential_issuer%22%3A%22http%3A%2F%2Flaunchpad.vii.electron.mattrlabs.io%22%2C%22credentials%22%3A%5B%7B%22format%22%3A%22ldp_vc%22%2C%22types%22%3A%5B%22OpenBadgeCredential%22%5D%7D%5D%2C%22grants%22%3A%7B%22urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code%22%3A%7B%22pre-authorized_code%22%3A%22UPZohaodPlLBnGsqB02n2tIupCIg8nKRRUEUHWA665X%22%7D%7D%7D',
|
|
76
|
+
);
|
|
77
|
+
expect(client.version).toEqual(OpenId4VCIVersion.VER_1_0_11);
|
|
78
|
+
expect(client.baseUrl).toEqual('http://launchpad.vii.electron.mattrlabs.io');
|
|
79
|
+
expect(client.scheme).toEqual('http');
|
|
80
|
+
expect(client.credential_offer.credential_issuer).toEqual('http://launchpad.vii.electron.mattrlabs.io');
|
|
81
|
+
expect(client.preAuthorizedCode).toEqual('UPZohaodPlLBnGsqB02n2tIupCIg8nKRRUEUHWA665X');
|
|
82
|
+
})
|
|
61
83
|
});
|
|
@@ -9,7 +9,7 @@ import { IDENTIPROOF_ISSUER_URL } from './MetadataMocks';
|
|
|
9
9
|
|
|
10
10
|
const jwt: Jwt = {
|
|
11
11
|
header: { alg: Alg.ES256, kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'jwt' },
|
|
12
|
-
payload: { iss: 'sphereon:wallet', nonce: 'tZignsnFbp', jti: 'tZignsnFbp223', aud: IDENTIPROOF_ISSUER_URL, iat: Date.now()/1000 },
|
|
12
|
+
payload: { iss: 'sphereon:wallet', nonce: 'tZignsnFbp', jti: 'tZignsnFbp223', aud: IDENTIPROOF_ISSUER_URL, iat: Date.now() / 1000 },
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
const kid = 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1';
|
|
@@ -43,7 +43,7 @@ const vcIssuer = new VcIssuerBuilder()
|
|
|
43
43
|
},
|
|
44
44
|
payload: {
|
|
45
45
|
aud: issuerMetadata.credential_issuer,
|
|
46
|
-
iat: +new Date()/1000,
|
|
46
|
+
iat: +new Date() / 1000,
|
|
47
47
|
nonce: 'a-c-nonce',
|
|
48
48
|
},
|
|
49
49
|
},
|
|
@@ -152,6 +152,7 @@ describe('sd-jwt vc', () => {
|
|
|
152
152
|
});
|
|
153
153
|
|
|
154
154
|
expect(credentials).toEqual({
|
|
155
|
+
notification_id: expect.any(String),
|
|
155
156
|
c_nonce: 'new-c-nonce',
|
|
156
157
|
c_nonce_expires_in: 300,
|
|
157
158
|
credential: 'sd-jwt',
|
|
@@ -115,7 +115,8 @@ async function proofOfPossessionCallbackFunction(args: Jwt, kid?: string): Promi
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
describe('ismapolis bug report #63, https://github.com/Sphereon-Opensource/OID4VC-demo/issues/63, should', () => {
|
|
118
|
-
|
|
118
|
+
// Sphereon infra is not working currently
|
|
119
|
+
it.skip('work as expected provided a correct JWT is supplied', async () => {
|
|
119
120
|
debug.enable('*');
|
|
120
121
|
const { uri } = await getCredentialOffer('jwt_vc_json');
|
|
121
122
|
const client = await OpenID4VCIClient.fromURI({ uri: uri, clientId: 'test-clientID' });
|
package/lib/functions/index.ts
CHANGED
package/lib/types/index.ts
CHANGED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { VCI_LOGGERS } from '@sphereon/oid4vci-common';
|
|
2
|
+
import { ISimpleLogger, LogMethod } from '@sphereon/ssi-types';
|
|
3
|
+
|
|
4
|
+
export const LOG: ISimpleLogger<string> = VCI_LOGGERS.options('sphereon:oid4vci:client', { methods: [LogMethod.EVENT, LogMethod.DEBUG_PKG] }).get(
|
|
5
|
+
'sphereon:oid4vci:client',
|
|
6
|
+
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sphereon/oid4vci-client",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.4-next.14+68c89f4",
|
|
4
4
|
"description": "OpenID for Verifiable Credential Issuance (OpenID4VCI) client",
|
|
5
5
|
"source": "lib/index.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
"build": "tsc"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@sphereon/oid4vci-common": "0.10.
|
|
19
|
-
"@sphereon/ssi-types": "
|
|
18
|
+
"@sphereon/oid4vci-common": "0.10.4-next.14+68c89f4",
|
|
19
|
+
"@sphereon/ssi-types": "0.24.1-unstable.112",
|
|
20
20
|
"cross-fetch": "^3.1.8",
|
|
21
21
|
"debug": "^4.3.4"
|
|
22
22
|
},
|
|
@@ -69,5 +69,5 @@
|
|
|
69
69
|
"OIDC4VCI",
|
|
70
70
|
"OID4VCI"
|
|
71
71
|
],
|
|
72
|
-
"gitHead": "
|
|
72
|
+
"gitHead": "68c89f45e627577608d1b10ab260f6810a46fe88"
|
|
73
73
|
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { JWK, Jwt, ProofOfPossession, ProofOfPossessionCallbacks, Typ } from '@sphereon/oid4vci-common';
|
|
2
|
-
/**
|
|
3
|
-
*
|
|
4
|
-
* - proofOfPossessionCallback: JWTSignerCallback
|
|
5
|
-
* Mandatory if you want to create (sign) ProofOfPossession
|
|
6
|
-
* - proofOfPossessionVerifierCallback?: JWTVerifyCallback
|
|
7
|
-
* If exists, verifies the ProofOfPossession
|
|
8
|
-
* - proofOfPossessionCallbackArgs: ProofOfPossessionCallbackArgs
|
|
9
|
-
* arguments needed for signing ProofOfPossession
|
|
10
|
-
* @param callbacks:
|
|
11
|
-
* - proofOfPossessionCallback: JWTSignerCallback
|
|
12
|
-
* Mandatory to create (sign) ProofOfPossession
|
|
13
|
-
* - proofOfPossessionVerifierCallback?: JWTVerifyCallback
|
|
14
|
-
* If exists, verifies the ProofOfPossession
|
|
15
|
-
* @param jwtProps
|
|
16
|
-
* @param existingJwt
|
|
17
|
-
* - Optional, clientId of the party requesting the credential
|
|
18
|
-
*/
|
|
19
|
-
export declare const createProofOfPossession: <DIDDoc>(callbacks: ProofOfPossessionCallbacks<DIDDoc>, jwtProps?: JwtProps, existingJwt?: Jwt) => Promise<ProofOfPossession>;
|
|
20
|
-
export interface JwtProps {
|
|
21
|
-
typ?: Typ;
|
|
22
|
-
kid?: string;
|
|
23
|
-
jwk?: JWK;
|
|
24
|
-
issuer?: string;
|
|
25
|
-
clientId?: string;
|
|
26
|
-
alg?: string;
|
|
27
|
-
jti?: string;
|
|
28
|
-
nonce?: string;
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=ProofUtil.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ProofUtil.d.ts","sourceRoot":"","sources":["../../lib/functions/ProofUtil.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,GAAG,EAEH,GAAG,EAGH,iBAAiB,EACjB,0BAA0B,EAC1B,GAAG,EACJ,MAAM,0BAA0B,CAAC;AAKlC;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,uBAAuB,qEAEvB,QAAQ,gBACL,GAAG,KAChB,QAAQ,iBAAiB,CA0B3B,CAAC;AAQF,MAAM,WAAW,QAAQ;IACvB,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.createProofOfPossession = void 0;
|
|
16
|
-
const oid4vci_common_1 = require("@sphereon/oid4vci-common");
|
|
17
|
-
const debug_1 = __importDefault(require("debug"));
|
|
18
|
-
const debug = (0, debug_1.default)('sphereon:openid4vci:token');
|
|
19
|
-
/**
|
|
20
|
-
*
|
|
21
|
-
* - proofOfPossessionCallback: JWTSignerCallback
|
|
22
|
-
* Mandatory if you want to create (sign) ProofOfPossession
|
|
23
|
-
* - proofOfPossessionVerifierCallback?: JWTVerifyCallback
|
|
24
|
-
* If exists, verifies the ProofOfPossession
|
|
25
|
-
* - proofOfPossessionCallbackArgs: ProofOfPossessionCallbackArgs
|
|
26
|
-
* arguments needed for signing ProofOfPossession
|
|
27
|
-
* @param callbacks:
|
|
28
|
-
* - proofOfPossessionCallback: JWTSignerCallback
|
|
29
|
-
* Mandatory to create (sign) ProofOfPossession
|
|
30
|
-
* - proofOfPossessionVerifierCallback?: JWTVerifyCallback
|
|
31
|
-
* If exists, verifies the ProofOfPossession
|
|
32
|
-
* @param jwtProps
|
|
33
|
-
* @param existingJwt
|
|
34
|
-
* - Optional, clientId of the party requesting the credential
|
|
35
|
-
*/
|
|
36
|
-
const createProofOfPossession = (callbacks, jwtProps, existingJwt) => __awaiter(void 0, void 0, void 0, function* () {
|
|
37
|
-
if (!callbacks.signCallback) {
|
|
38
|
-
debug(`no jwt signer callback or arguments supplied!`);
|
|
39
|
-
throw new Error(oid4vci_common_1.BAD_PARAMS);
|
|
40
|
-
}
|
|
41
|
-
const signerArgs = createJWT(jwtProps, existingJwt);
|
|
42
|
-
const jwt = yield callbacks.signCallback(signerArgs, signerArgs.header.kid);
|
|
43
|
-
const proof = {
|
|
44
|
-
proof_type: 'jwt',
|
|
45
|
-
jwt,
|
|
46
|
-
};
|
|
47
|
-
try {
|
|
48
|
-
partiallyValidateJWS(jwt);
|
|
49
|
-
if (callbacks.verifyCallback) {
|
|
50
|
-
debug(`Calling supplied verify callback....`);
|
|
51
|
-
yield callbacks.verifyCallback({ jwt, kid: signerArgs.header.kid });
|
|
52
|
-
debug(`Supplied verify callback return success result`);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
catch (_a) {
|
|
56
|
-
debug(`JWS was not valid`);
|
|
57
|
-
throw new Error(oid4vci_common_1.JWS_NOT_VALID);
|
|
58
|
-
}
|
|
59
|
-
debug(`Proof of Possession JWT:\r\n${jwt}`);
|
|
60
|
-
return proof;
|
|
61
|
-
});
|
|
62
|
-
exports.createProofOfPossession = createProofOfPossession;
|
|
63
|
-
const partiallyValidateJWS = (jws) => {
|
|
64
|
-
if (jws.split('.').length !== 3 || !jws.startsWith('ey')) {
|
|
65
|
-
throw new Error(oid4vci_common_1.JWS_NOT_VALID);
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
const createJWT = (jwtProps, existingJwt) => {
|
|
69
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
70
|
-
const aud = getJwtProperty('aud', true, jwtProps === null || jwtProps === void 0 ? void 0 : jwtProps.issuer, (_a = existingJwt === null || existingJwt === void 0 ? void 0 : existingJwt.payload) === null || _a === void 0 ? void 0 : _a.aud);
|
|
71
|
-
const iss = getJwtProperty('iss', false, jwtProps === null || jwtProps === void 0 ? void 0 : jwtProps.clientId, (_b = existingJwt === null || existingJwt === void 0 ? void 0 : existingJwt.payload) === null || _b === void 0 ? void 0 : _b.iss);
|
|
72
|
-
const jti = getJwtProperty('jti', false, jwtProps === null || jwtProps === void 0 ? void 0 : jwtProps.jti, (_c = existingJwt === null || existingJwt === void 0 ? void 0 : existingJwt.payload) === null || _c === void 0 ? void 0 : _c.jti);
|
|
73
|
-
const typ = getJwtProperty('typ', true, jwtProps === null || jwtProps === void 0 ? void 0 : jwtProps.typ, (_d = existingJwt === null || existingJwt === void 0 ? void 0 : existingJwt.header) === null || _d === void 0 ? void 0 : _d.typ, 'jwt');
|
|
74
|
-
const nonce = getJwtProperty('nonce', false, jwtProps === null || jwtProps === void 0 ? void 0 : jwtProps.nonce, (_e = existingJwt === null || existingJwt === void 0 ? void 0 : existingJwt.payload) === null || _e === void 0 ? void 0 : _e.nonce); // Officially this is required, but some implementations don't have it
|
|
75
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
76
|
-
const alg = getJwtProperty('alg', false, jwtProps === null || jwtProps === void 0 ? void 0 : jwtProps.alg, (_f = existingJwt === null || existingJwt === void 0 ? void 0 : existingJwt.header) === null || _f === void 0 ? void 0 : _f.alg, 'ES256');
|
|
77
|
-
const kid = getJwtProperty('kid', false, jwtProps === null || jwtProps === void 0 ? void 0 : jwtProps.kid, (_g = existingJwt === null || existingJwt === void 0 ? void 0 : existingJwt.header) === null || _g === void 0 ? void 0 : _g.kid);
|
|
78
|
-
const jwk = getJwtProperty('jwk', false, jwtProps === null || jwtProps === void 0 ? void 0 : jwtProps.jwk, (_h = existingJwt === null || existingJwt === void 0 ? void 0 : existingJwt.header) === null || _h === void 0 ? void 0 : _h.jwk);
|
|
79
|
-
const jwt = existingJwt ? existingJwt : {};
|
|
80
|
-
const now = +new Date();
|
|
81
|
-
const jwtPayload = Object.assign(Object.assign({ aud, iat: (_k = (_j = jwt.payload) === null || _j === void 0 ? void 0 : _j.iat) !== null && _k !== void 0 ? _k : Math.round(now / 1000 - 60), exp: (_m = (_l = jwt.payload) === null || _l === void 0 ? void 0 : _l.exp) !== null && _m !== void 0 ? _m : Math.round(now / 1000 + 10 * 60), nonce }, (iss ? { iss } : {})), (jti ? { jti } : {}));
|
|
82
|
-
const jwtHeader = {
|
|
83
|
-
typ,
|
|
84
|
-
alg,
|
|
85
|
-
kid,
|
|
86
|
-
jwk,
|
|
87
|
-
};
|
|
88
|
-
return {
|
|
89
|
-
payload: Object.assign(Object.assign({}, jwt.payload), jwtPayload),
|
|
90
|
-
header: Object.assign(Object.assign({}, jwt.header), jwtHeader),
|
|
91
|
-
};
|
|
92
|
-
};
|
|
93
|
-
const getJwtProperty = (propertyName, required, option, jwtProperty, defaultValue) => {
|
|
94
|
-
if (typeof option === 'string' && option && jwtProperty && option !== jwtProperty) {
|
|
95
|
-
throw Error(`Cannot have a property '${propertyName}' with value '${option}' and different JWT value '${jwtProperty}' at the same time`);
|
|
96
|
-
}
|
|
97
|
-
let result = (jwtProperty ? jwtProperty : option);
|
|
98
|
-
if (!result) {
|
|
99
|
-
if (required) {
|
|
100
|
-
throw Error(`No ${propertyName} property provided either in a JWT or as option`);
|
|
101
|
-
}
|
|
102
|
-
result = defaultValue;
|
|
103
|
-
}
|
|
104
|
-
return result;
|
|
105
|
-
};
|
|
106
|
-
//# sourceMappingURL=ProofUtil.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ProofUtil.js","sourceRoot":"","sources":["../../lib/functions/ProofUtil.ts"],"names":[],"mappings":"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"}
|