@sphereon/oid4vci-client 0.2.0 → 0.4.1-unstable.247

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.
Files changed (116) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +494 -371
  3. package/dist/AccessTokenClient.d.ts +30 -0
  4. package/dist/AccessTokenClient.d.ts.map +1 -0
  5. package/dist/AccessTokenClient.js +226 -0
  6. package/dist/AccessTokenClient.js.map +1 -0
  7. package/dist/AuthorizationDetailsBuilder.d.ts +11 -0
  8. package/dist/AuthorizationDetailsBuilder.d.ts.map +1 -0
  9. package/dist/AuthorizationDetailsBuilder.js +44 -0
  10. package/dist/AuthorizationDetailsBuilder.js.map +1 -0
  11. package/dist/CredentialOffer.d.ts +6 -0
  12. package/dist/CredentialOffer.d.ts.map +1 -0
  13. package/dist/CredentialOffer.js +49 -0
  14. package/dist/CredentialOffer.js.map +1 -0
  15. package/dist/CredentialRequestClient.d.ts +29 -0
  16. package/dist/CredentialRequestClient.d.ts.map +1 -0
  17. package/dist/CredentialRequestClient.js +63 -0
  18. package/dist/CredentialRequestClient.js.map +1 -0
  19. package/dist/CredentialRequestClientBuilderV1_0_09.d.ts +29 -0
  20. package/dist/CredentialRequestClientBuilderV1_0_09.d.ts.map +1 -0
  21. package/dist/CredentialRequestClientBuilderV1_0_09.js +63 -0
  22. package/dist/CredentialRequestClientBuilderV1_0_09.js.map +1 -0
  23. package/dist/{main/lib/MetadataClient.d.ts → MetadataClient.d.ts} +39 -38
  24. package/dist/MetadataClient.d.ts.map +1 -0
  25. package/dist/MetadataClient.js +148 -0
  26. package/dist/MetadataClient.js.map +1 -0
  27. package/dist/OpenID4VCIClient.d.ts +72 -0
  28. package/dist/OpenID4VCIClient.d.ts.map +1 -0
  29. package/dist/OpenID4VCIClient.js +361 -0
  30. package/dist/OpenID4VCIClient.js.map +1 -0
  31. package/dist/ProofOfPossessionBuilder.d.ts +35 -0
  32. package/dist/ProofOfPossessionBuilder.d.ts.map +1 -0
  33. package/dist/ProofOfPossessionBuilder.js +120 -0
  34. package/dist/ProofOfPossessionBuilder.js.map +1 -0
  35. package/dist/{main/lib/functions → functions}/Encoding.d.ts +20 -17
  36. package/dist/functions/Encoding.d.ts.map +1 -0
  37. package/dist/functions/Encoding.js +144 -0
  38. package/dist/functions/Encoding.js.map +1 -0
  39. package/dist/functions/HttpUtils.d.ts +24 -0
  40. package/dist/functions/HttpUtils.d.ts.map +1 -0
  41. package/dist/functions/HttpUtils.js +93 -0
  42. package/dist/functions/HttpUtils.js.map +1 -0
  43. package/dist/functions/ProofUtil.d.ts +29 -0
  44. package/dist/functions/ProofUtil.d.ts.map +1 -0
  45. package/dist/functions/ProofUtil.js +103 -0
  46. package/dist/functions/ProofUtil.js.map +1 -0
  47. package/dist/functions/index.d.ts +4 -0
  48. package/dist/functions/index.d.ts.map +1 -0
  49. package/dist/{main/lib/functions → functions}/index.js +20 -20
  50. package/dist/functions/index.js.map +1 -0
  51. package/dist/index.d.ts +9 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/{main/lib/index.js → index.js} +25 -24
  54. package/dist/index.js.map +1 -0
  55. package/lib/AccessTokenClient.ts +270 -0
  56. package/lib/AuthorizationDetailsBuilder.ts +46 -0
  57. package/lib/CredentialOffer.ts +55 -0
  58. package/lib/CredentialRequestClient.ts +77 -0
  59. package/lib/CredentialRequestClientBuilderV1_0_09.ts +99 -0
  60. package/lib/MetadataClient.ts +147 -0
  61. package/lib/OpenID4VCIClient.ts +477 -0
  62. package/lib/ProofOfPossessionBuilder.ts +156 -0
  63. package/lib/__tests__/AccessTokenClient.spec.ts +221 -0
  64. package/lib/__tests__/AuthorizationDetailsBuilder.spec.ts +65 -0
  65. package/lib/__tests__/AuthzFlowType.spec.ts +39 -0
  66. package/lib/__tests__/CredentialRequestClient.spec.ts +261 -0
  67. package/lib/__tests__/CredentialRequestClientBuilder.spec.ts +103 -0
  68. package/lib/__tests__/HttpUtils.spec.ts +37 -0
  69. package/lib/__tests__/IT.spec.ts +155 -0
  70. package/lib/__tests__/IssuanceInitiation.spec.ts +37 -0
  71. package/lib/__tests__/JsonURIConversions.spec.ts +86 -0
  72. package/lib/__tests__/MetadataClient.spec.ts +198 -0
  73. package/lib/__tests__/MetadataMocks.ts +428 -0
  74. package/lib/__tests__/OpenID4VCIClient.spec.ts +166 -0
  75. package/lib/__tests__/OpenID4VCIClientPAR.spec.ts +112 -0
  76. package/lib/__tests__/ProofOfPossessionBuilder.spec.ts +109 -0
  77. package/lib/__tests__/data/VciDataFixtures.ts +744 -0
  78. package/lib/functions/Encoding.ts +138 -0
  79. package/lib/functions/HttpUtils.ts +106 -0
  80. package/lib/functions/ProofUtil.ts +128 -0
  81. package/{dist/main/lib/functions/index.d.ts → lib/functions/index.ts} +3 -3
  82. package/lib/index.ts +8 -0
  83. package/package.json +68 -71
  84. package/CHANGELOG.md +0 -21
  85. package/dist/main/index.d.ts +0 -1
  86. package/dist/main/index.js +0 -18
  87. package/dist/main/lib/AccessTokenClient.d.ts +0 -20
  88. package/dist/main/lib/AccessTokenClient.js +0 -141
  89. package/dist/main/lib/CredentialRequestClient.d.ts +0 -31
  90. package/dist/main/lib/CredentialRequestClient.js +0 -66
  91. package/dist/main/lib/CredentialRequestClientBuilder.d.ts +0 -21
  92. package/dist/main/lib/CredentialRequestClientBuilder.js +0 -56
  93. package/dist/main/lib/IssuanceInitiation.d.ts +0 -5
  94. package/dist/main/lib/IssuanceInitiation.js +0 -29
  95. package/dist/main/lib/MetadataClient.js +0 -127
  96. package/dist/main/lib/functions/Encoding.js +0 -138
  97. package/dist/main/lib/functions/HttpUtils.d.ts +0 -17
  98. package/dist/main/lib/functions/HttpUtils.js +0 -133
  99. package/dist/main/lib/functions/ProofUtil.d.ts +0 -9
  100. package/dist/main/lib/functions/ProofUtil.js +0 -76
  101. package/dist/main/lib/index.d.ts +0 -7
  102. package/dist/main/lib/types/Authorization.types.d.ts +0 -66
  103. package/dist/main/lib/types/Authorization.types.js +0 -35
  104. package/dist/main/lib/types/CredentialIssuance.types.d.ts +0 -88
  105. package/dist/main/lib/types/CredentialIssuance.types.js +0 -8
  106. package/dist/main/lib/types/Generic.types.d.ts +0 -19
  107. package/dist/main/lib/types/Generic.types.js +0 -11
  108. package/dist/main/lib/types/OAuth2ASMetadata.d.ts +0 -37
  109. package/dist/main/lib/types/OAuth2ASMetadata.js +0 -3
  110. package/dist/main/lib/types/OID4VCIServerMetadata.d.ts +0 -65
  111. package/dist/main/lib/types/OID4VCIServerMetadata.js +0 -3
  112. package/dist/main/lib/types/Oidc4vciErrors.d.ts +0 -3
  113. package/dist/main/lib/types/Oidc4vciErrors.js +0 -7
  114. package/dist/main/lib/types/index.d.ts +0 -6
  115. package/dist/main/lib/types/index.js +0 -23
  116. package/dist/main/tsconfig.build.tsbuildinfo +0 -1
@@ -0,0 +1,138 @@
1
+ import { BAD_PARAMS, DecodeURIAsJsonOpts, EncodeJsonAsURIOpts, SearchValue } from '@sphereon/oid4vci-common';
2
+
3
+ /**
4
+ * @function encodeJsonAsURI encodes a Json object into a URI
5
+ * @param json object
6
+ * @param opts:
7
+ * - urlTypeProperties: a list of properties of which the value is a URL
8
+ * - arrayTypeProperties: a list of properties which are an array
9
+ */
10
+ /* eslint-disable @typescript-eslint/no-explicit-any */
11
+ export function convertJsonToURI(json: { [s: string]: any } | ArrayLike<any> | string, opts?: EncodeJsonAsURIOpts): string {
12
+ if (typeof json === 'string') {
13
+ return convertJsonToURI(JSON.parse(json), opts);
14
+ }
15
+ const results = [];
16
+
17
+ function encodeAndStripWhitespace(key: string): string {
18
+ return encodeURIComponent(key.replace(' ', ''));
19
+ }
20
+
21
+ for (const [key, value] of Object.entries(json)) {
22
+ if (!value) {
23
+ continue;
24
+ }
25
+ //Skip properties that are not of URL type
26
+ if (!opts?.uriTypeProperties?.includes(key)) {
27
+ results.push(`${key}=${value}`);
28
+ continue;
29
+ }
30
+ if (opts?.arrayTypeProperties?.includes(key) && Array.isArray(value)) {
31
+ results.push(value.map((v) => `${encodeAndStripWhitespace(key)}=${customEncodeURIComponent(v, /\./g)}`).join('&'));
32
+ continue;
33
+ }
34
+ const isBool = typeof value == 'boolean';
35
+ const isNumber = typeof value == 'number';
36
+ const isString = typeof value == 'string';
37
+ let encoded;
38
+ if (isBool || isNumber) {
39
+ encoded = `${encodeAndStripWhitespace(key)}=${value}`;
40
+ } else if (isString) {
41
+ encoded = `${encodeAndStripWhitespace(key)}=${customEncodeURIComponent(value, /\./g)}`;
42
+ } else {
43
+ encoded = `${encodeAndStripWhitespace(key)}=${customEncodeURIComponent(JSON.stringify(value), /\./g)}`;
44
+ }
45
+ results.push(encoded);
46
+ }
47
+ const components = results.join('&');
48
+ if (opts?.baseUrl) {
49
+ return `${opts.baseUrl}?${components}`;
50
+ }
51
+ return components;
52
+ }
53
+
54
+ /**
55
+ * @function decodeUriAsJson decodes a URI into a Json object
56
+ * @param uri string
57
+ * @param opts:
58
+ * - requiredProperties: the required properties
59
+ * - arrayTypeProperties: properties that can show up more that once
60
+ */
61
+ export function convertURIToJsonObject(uri: string, opts?: DecodeURIAsJsonOpts): unknown {
62
+ if (!uri || !opts?.requiredProperties?.every((p) => uri.includes(p))) {
63
+ throw new Error(BAD_PARAMS);
64
+ }
65
+ const uriComponents = getURIComponentsAsArray(uri, opts?.arrayTypeProperties);
66
+ return decodeJsonProperties(uriComponents);
67
+ }
68
+
69
+ function decodeJsonProperties(parts: string[] | string[][]): unknown {
70
+ const json: { [s: string]: any } | ArrayLike<any> = {};
71
+ for (const key in parts) {
72
+ const value = parts[key];
73
+ if (!value) {
74
+ continue;
75
+ }
76
+ if (Array.isArray(value)) {
77
+ if (value.length > 1) {
78
+ json[decodeURIComponent(key)] = value.map((v) => decodeURIComponent(v));
79
+ } else {
80
+ json[decodeURIComponent(key)] = decodeURIComponent(value[0]);
81
+ }
82
+ }
83
+ const isBool = typeof value == 'boolean';
84
+ const isNumber = typeof value == 'number';
85
+ const isString = typeof value == 'string';
86
+ if (isBool || isNumber) {
87
+ json[decodeURIComponent(key)] = value;
88
+ } else if (isString) {
89
+ const decoded = decodeURIComponent(value);
90
+ if (decoded.startsWith('{') && decoded.endsWith('}')) {
91
+ json[decodeURIComponent(key)] = JSON.parse(decoded);
92
+ } else {
93
+ json[decodeURIComponent(key)] = decoded;
94
+ }
95
+ }
96
+ }
97
+ return json;
98
+ }
99
+
100
+ /**
101
+ * @function get URI Components as Array
102
+ * @param uri string
103
+ * @param arrayTypes array of string containing array like keys
104
+ */
105
+ function getURIComponentsAsArray(uri: string, arrayTypes?: string[]): string[] | string[][] {
106
+ const parts = uri.includes('?') ? uri.split('?')[1] : uri.includes('://') ? uri.split('://')[1] : uri;
107
+ const json: string[] | string[][] = [];
108
+ const dict: string[] = parts.split('&');
109
+ for (const entry of dict) {
110
+ const pair: string[] = entry.split('=');
111
+ const p0: any = pair[0];
112
+ const p1: any = pair[1];
113
+ if (arrayTypes?.includes(p0)) {
114
+ const key = json[p0];
115
+ if (Array.isArray(key)) {
116
+ key.push(p1);
117
+ } else {
118
+ json[p0] = [p1];
119
+ }
120
+ continue;
121
+ }
122
+ json[p0] = p1;
123
+ }
124
+ return json;
125
+ }
126
+
127
+ /* eslint-enable @typescript-eslint/no-explicit-any */
128
+
129
+ /**
130
+ * @function customEncodeURIComponent is used to encode chars that are not encoded by default
131
+ * @param searchValue The pattern/regexp to find the char(s) to be encoded
132
+ * @param uriComponent query string
133
+ */
134
+ function customEncodeURIComponent(uriComponent: string, searchValue: SearchValue): string {
135
+ // -_.!~*'() are not escaped because they are considered safe.
136
+ // Add them to the regex as you need
137
+ return encodeURIComponent(uriComponent).replace(searchValue, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);
138
+ }
@@ -0,0 +1,106 @@
1
+ import { Encoding, OpenIDResponse } from '@sphereon/oid4vci-common';
2
+ import { fetch } from 'cross-fetch';
3
+ import Debug from 'debug';
4
+
5
+ const debug = Debug('sphereon:openid4vci:http');
6
+
7
+ export const getJson = async <T>(
8
+ URL: string,
9
+ opts?: { bearerToken?: string; contentType?: string; accept?: string; customHeaders?: Record<string, string>; exceptionOnHttpErrorStatus?: boolean }
10
+ ): Promise<OpenIDResponse<T>> => {
11
+ return await openIdFetch(URL, undefined, { method: 'GET', ...opts });
12
+ };
13
+
14
+ export const formPost = async <T>(
15
+ url: string,
16
+ body: BodyInit,
17
+ opts?: { bearerToken?: string; contentType?: string; accept?: string; customHeaders?: Record<string, string>; exceptionOnHttpErrorStatus?: boolean }
18
+ ): Promise<OpenIDResponse<T>> => {
19
+ return await post(url, body, opts?.contentType ? { ...opts } : { contentType: Encoding.FORM_URL_ENCODED, ...opts });
20
+ };
21
+
22
+ export const post = async <T>(
23
+ url: string,
24
+ body?: BodyInit,
25
+ opts?: { bearerToken?: string; contentType?: string; accept?: string; customHeaders?: Record<string, string>; exceptionOnHttpErrorStatus?: boolean }
26
+ ): Promise<OpenIDResponse<T>> => {
27
+ return await openIdFetch(url, body, { method: 'POST', ...opts });
28
+ };
29
+
30
+ const openIdFetch = async <T>(
31
+ url: string,
32
+ body?: BodyInit,
33
+ opts?: {
34
+ method?: string;
35
+ bearerToken?: string;
36
+ contentType?: string;
37
+ accept?: string;
38
+ customHeaders?: Record<string, string>;
39
+ exceptionOnHttpErrorStatus?: boolean;
40
+ }
41
+ ): Promise<OpenIDResponse<T>> => {
42
+ const headers: Record<string, string> = opts?.customHeaders ?? {};
43
+ if (opts?.bearerToken) {
44
+ headers['Authorization'] = `Bearer ${opts.bearerToken}`;
45
+ }
46
+ const method = opts?.method ? opts.method : body ? 'POST' : 'GET';
47
+ const accept = opts?.accept ? opts.accept : 'application/json';
48
+ headers['Accept'] = accept;
49
+ if (headers['Content-Type']) {
50
+ if (opts?.contentType && opts.contentType !== headers['Content-Type']) {
51
+ throw Error(
52
+ `Mismatch in content-types from custom headers (${headers['Content-Type']}) and supplied content type option (${opts.contentType})`
53
+ );
54
+ }
55
+ } else {
56
+ if (opts?.contentType) {
57
+ headers['Content-Type'] = opts.contentType;
58
+ } else if (method !== 'GET') {
59
+ headers['Content-Type'] = 'application/json';
60
+ }
61
+ }
62
+
63
+ const payload: RequestInit = {
64
+ method,
65
+ headers,
66
+ body,
67
+ };
68
+
69
+ debug(`START fetching url: ${url}`);
70
+ if (body) {
71
+ debug(`Body:\r\n${JSON.stringify(body)}`);
72
+ }
73
+ debug(`Headers:\r\n${JSON.stringify(payload.headers)}`);
74
+ const origResponse = await fetch(url, payload);
75
+ const isJSONResponse = accept === 'application/json' || origResponse.headers.get('Content-Type') === 'application/json';
76
+ const success = origResponse && origResponse.status >= 200 && origResponse.status < 400;
77
+ const responseText = await origResponse.text();
78
+ const responseBody = isJSONResponse ? JSON.parse(responseText) : responseText;
79
+
80
+ debug(`${success ? 'success' : 'error'} status: ${origResponse.status}, body:\r\n${JSON.stringify(responseBody)}`);
81
+ if (!success && opts?.exceptionOnHttpErrorStatus) {
82
+ const error = JSON.stringify(responseBody);
83
+ throw new Error(error === '{}' ? '{"error": "not found"}' : error);
84
+ }
85
+ debug(`END fetching url: ${url}`);
86
+
87
+ return {
88
+ origResponse,
89
+ successBody: success ? responseBody : undefined,
90
+ errorBody: !success ? responseBody : undefined,
91
+ };
92
+ };
93
+
94
+ export const isValidURL = (url: string): boolean => {
95
+ const urlPattern = new RegExp(
96
+ '^(https?:\\/\\/)' + // validate protocol
97
+ '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // validate domain name
98
+ '((localhost))|' + // validate OR localhost
99
+ '((\\d{1,3}\\.){3}\\d{1,3}))' + // validate OR ip (v4) address
100
+ '(\\:\\d+)?(\\/[-a-z\\d%_.~+:]*)*' + // validate port and path
101
+ '(\\?[;&a-z\\d%_.~+=-]*)?' + // validate query string
102
+ '(\\#[-a-z\\d_]*)?$', // validate fragment locator
103
+ 'i'
104
+ );
105
+ return !!urlPattern.test(url);
106
+ };
@@ -0,0 +1,128 @@
1
+ import {
2
+ BAD_PARAMS,
3
+ JWS_NOT_VALID,
4
+ Jwt,
5
+ JWTHeader,
6
+ JWTPayload,
7
+ ProofOfPossession,
8
+ ProofOfPossessionCallbacks,
9
+ ProofType,
10
+ Typ,
11
+ } from '@sphereon/oid4vci-common';
12
+ import Debug from 'debug';
13
+
14
+ const debug = Debug('sphereon:openid4vci:token');
15
+
16
+ /**
17
+ *
18
+ * - proofOfPossessionCallback: JWTSignerCallback
19
+ * Mandatory if you want to create (sign) ProofOfPossession
20
+ * - proofOfPossessionVerifierCallback?: JWTVerifyCallback
21
+ * If exists, verifies the ProofOfPossession
22
+ * - proofOfPossessionCallbackArgs: ProofOfPossessionCallbackArgs
23
+ * arguments needed for signing ProofOfPossession
24
+ * @param callbacks:
25
+ * - proofOfPossessionCallback: JWTSignerCallback
26
+ * Mandatory to create (sign) ProofOfPossession
27
+ * - proofOfPossessionVerifierCallback?: JWTVerifyCallback
28
+ * If exists, verifies the ProofOfPossession
29
+ * @param jwtProps
30
+ * @param existingJwt
31
+ * - Optional, clientId of the party requesting the credential
32
+ */
33
+ export const createProofOfPossession = async (
34
+ callbacks: ProofOfPossessionCallbacks,
35
+ jwtProps?: JwtProps,
36
+ existingJwt?: Jwt
37
+ ): Promise<ProofOfPossession> => {
38
+ if (!callbacks.signCallback) {
39
+ debug(`no jwt signer callback or arguments supplied!`);
40
+ throw new Error(BAD_PARAMS);
41
+ }
42
+ const signerArgs = createJWT(jwtProps, existingJwt);
43
+ const jwt = await callbacks.signCallback(signerArgs, signerArgs.header.kid);
44
+ const proof = {
45
+ proof_type: ProofType.JWT,
46
+ jwt,
47
+ };
48
+
49
+ try {
50
+ partiallyValidateJWS(jwt);
51
+ if (callbacks.verifyCallback) {
52
+ debug(`Calling supplied verify callback....`);
53
+ await callbacks.verifyCallback({ jwt, kid: signerArgs.header.kid });
54
+ debug(`Supplied verify callback return success result`);
55
+ }
56
+ } catch {
57
+ debug(`JWS was not valid`);
58
+ throw new Error(JWS_NOT_VALID);
59
+ }
60
+ debug(`Proof of Possession JWT:\r\n${jwt}`);
61
+ return proof;
62
+ };
63
+
64
+ const partiallyValidateJWS = (jws: string): void => {
65
+ if (jws.split('.').length !== 3 || !jws.startsWith('ey')) {
66
+ throw new Error(JWS_NOT_VALID);
67
+ }
68
+ };
69
+
70
+ export interface JwtProps {
71
+ typ?: string;
72
+ kid?: string;
73
+ issuer?: string;
74
+ clientId?: string;
75
+ alg?: string;
76
+ jti?: string;
77
+ nonce?: string;
78
+ }
79
+
80
+ const createJWT = (jwtProps?: JwtProps, existingJwt?: Jwt): Jwt => {
81
+ const aud = getJwtProperty('aud', true, jwtProps?.issuer, existingJwt?.payload?.aud);
82
+ const iss = getJwtProperty('iss', false, jwtProps?.clientId, existingJwt?.payload?.iss);
83
+ const jti = getJwtProperty('jti', false, jwtProps?.jti, existingJwt?.payload?.jti);
84
+ const nonce = getJwtProperty('nonce', false, jwtProps?.nonce, existingJwt?.payload?.nonce); // Officially this is required, but some implementations don't have it
85
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
86
+ const alg = getJwtProperty('alg', false, jwtProps?.alg, existingJwt?.header?.alg, 'ES256')!;
87
+ const kid = getJwtProperty('kid', true, jwtProps?.kid, existingJwt?.header?.kid);
88
+ const jwt: Partial<Jwt> = existingJwt ? existingJwt : {};
89
+ const now = +new Date();
90
+ const jwtPayload: Partial<JWTPayload> = {
91
+ aud,
92
+ iat: jwt.payload?.iat ? jwt.payload.iat : now / 1000 - 60, // Let's ensure we subtract 60 seconds for potential time offsets
93
+ exp: jwt.payload?.exp ? jwt.payload.exp : now / 1000 + 10 * 60,
94
+ nonce,
95
+ ...(iss ? { iss } : {}),
96
+ ...(jti ? { jti } : {}),
97
+ };
98
+
99
+ const jwtHeader: JWTHeader = {
100
+ typ: Typ.JWT,
101
+ alg,
102
+ kid,
103
+ };
104
+ return {
105
+ payload: { ...jwt.payload, ...jwtPayload },
106
+ header: { ...jwt.header, ...jwtHeader },
107
+ };
108
+ };
109
+
110
+ const getJwtProperty = (
111
+ propertyName: string,
112
+ required: boolean,
113
+ option?: string,
114
+ jwtProperty?: string,
115
+ defaultValue?: string
116
+ ): string | undefined => {
117
+ if (option && jwtProperty && option !== jwtProperty) {
118
+ throw Error(`Cannot have a property '${propertyName}' with value '${option}' and different JWT value '${jwtProperty}' at the same time`);
119
+ }
120
+ let result = jwtProperty ? jwtProperty : option;
121
+ if (!result) {
122
+ if (required) {
123
+ throw Error(`No ${propertyName} property provided either in a JWT or as option`);
124
+ }
125
+ result = defaultValue;
126
+ }
127
+ return result;
128
+ };
@@ -1,3 +1,3 @@
1
- export * from './Encoding';
2
- export * from './HttpUtils';
3
- export * from './ProofUtil';
1
+ export * from './Encoding';
2
+ export * from './HttpUtils';
3
+ export * from './ProofUtil';
package/lib/index.ts ADDED
@@ -0,0 +1,8 @@
1
+ export * from './AccessTokenClient';
2
+ export * from './CredentialOffer';
3
+ export * from './CredentialRequestClient';
4
+ export * from './CredentialRequestClientBuilderV1_0_09';
5
+ export * from './functions';
6
+ export * from './MetadataClient';
7
+ export * from './OpenID4VCIClient';
8
+ export * from './ProofOfPossessionBuilder';
package/package.json CHANGED
@@ -1,71 +1,68 @@
1
- {
2
- "name": "@sphereon/oid4vci-client",
3
- "version": "0.2.0",
4
- "description": "OpenID for Verifiable Credential Issuance (OID4VCI) client",
5
- "main": "dist/main/index.js",
6
- "types": "dist/main/index.d.ts",
7
- "author": "Sphereon",
8
- "license": "Apache-2.0",
9
- "private": false,
10
- "scripts": {
11
- "build": "run-p build:*",
12
- "build:main": "tsc -p tsconfig.build.json",
13
- "clean": "rimraf dist coverage",
14
- "watch": "tsc -w",
15
- "fix": "run-s fix:*",
16
- "fix:prettier": "prettier \"{lib,tests}/**/*.ts\" --write",
17
- "fix:lint": "eslint . --ext .ts --fix",
18
- "test": "run-s build test:*",
19
- "test:lint": "eslint . --ext .ts",
20
- "test:prettier": "prettier \"{lib,tests}/**/*.ts\" --list-different",
21
- "test:cov": "jest --ci --coverage && codecov",
22
- "uninstall": "rimraf dist coverage yarn.lock package-lock.json node_modules"
23
- },
24
- "engines": {
25
- "node": ">=14"
26
- },
27
- "dependencies": {
28
- "@sphereon/ssi-types": "0.8.1-unstable.74",
29
- "debug": "^4.3.4",
30
- "bs58": "^5.0.0",
31
- "cross-fetch": "^3.1.5",
32
- "uint8arrays": "^3.1.1"
33
- },
34
- "devDependencies": {
35
- "@types/jest": "^28.1.8",
36
- "@typescript-eslint/eslint-plugin": "^5.36.1",
37
- "@typescript-eslint/parser": "^5.36.1",
38
- "codecov": "^3.8.3",
39
- "dotenv": "^16.0.2",
40
- "eslint": "^8.23.0",
41
- "eslint-config-prettier": "^8.5.0",
42
- "eslint-plugin-eslint-comments": "^3.2.0",
43
- "eslint-plugin-import": "^2.26.0",
44
- "jest": "^29.1.2",
45
- "jest-junit": "^14.0.1",
46
- "jose": "^4.10.0",
47
- "nock": "^13.2.9",
48
- "npm-run-all": "^4.1.5",
49
- "open-cli": "^7.0.1",
50
- "rimraf": "^3.0.2",
51
- "prettier": "^2.7.1",
52
- "ts-jest": "^29.0.3",
53
- "ts-node": "^10.9.1",
54
- "typescript": "4.6.4"
55
- },
56
- "files": [
57
- "dist/main"
58
- ],
59
- "prettier": {
60
- "singleQuote": true,
61
- "printWidth": 150
62
- },
63
- "keywords": [
64
- "Sphereon",
65
- "Verifiable Credentials",
66
- "OpenID",
67
- "OpenID for Verifiable Credential Issuance",
68
- "OIDC4VCI",
69
- "OID4VCI"
70
- ]
71
- }
1
+ {
2
+ "name": "@sphereon/oid4vci-client",
3
+ "version": "0.4.1-unstable.247+0bbe17c",
4
+ "description": "OpenID for Verifiable Credential Issuance (OpenID4VCI) client",
5
+ "source": "lib/index.ts",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "author": "Sphereon",
9
+ "license": "Apache-2.0",
10
+ "private": false,
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "scripts": {
15
+ "build": "tsc"
16
+ },
17
+ "dependencies": {
18
+ "@sphereon/oid4vci-common": "0.4.1-unstable.247+0bbe17c",
19
+ "@sphereon/ssi-types": "^0.9.0",
20
+ "cross-fetch": "^3.1.5",
21
+ "debug": "^4.3.4",
22
+ "uint8arrays": "^3.1.1"
23
+ },
24
+ "devDependencies": {
25
+ "@types/jest": "^29.5.0",
26
+ "@types/node": "^18.15.3",
27
+ "@typescript-eslint/eslint-plugin": "^5.36.1",
28
+ "@typescript-eslint/parser": "^5.36.1",
29
+ "codecov": "^3.8.3",
30
+ "dotenv": "^16.0.2",
31
+ "eslint": "^8.23.0",
32
+ "eslint-config-prettier": "^8.5.0",
33
+ "eslint-plugin-eslint-comments": "^3.2.0",
34
+ "eslint-plugin-import": "^2.26.0",
35
+ "jest": "^29.1.2",
36
+ "jest-junit": "^14.0.1",
37
+ "jose": "^4.10.0",
38
+ "nock": "^13.2.9",
39
+ "npm-run-all": "^4.1.5",
40
+ "open-cli": "^7.0.1",
41
+ "ts-jest": "^29.0.5",
42
+ "ts-node": "^10.9.1",
43
+ "typescript": "4.9.5"
44
+ },
45
+ "engines": {
46
+ "node": ">=16"
47
+ },
48
+ "files": [
49
+ "lib/**/*",
50
+ "dist/**/*"
51
+ ],
52
+ "prettier": {
53
+ "singleQuote": true,
54
+ "printWidth": 150
55
+ },
56
+ "keywords": [
57
+ "Sphereon",
58
+ "Verifiable Credentials",
59
+ "OpenID",
60
+ "OpenID for Verifiable Credential Issuance",
61
+ "OAuth2",
62
+ "SSI",
63
+ "OpenID4VCI",
64
+ "OIDC4VCI",
65
+ "OID4VCI"
66
+ ],
67
+ "gitHead": "0bbe17c13de4df95e2fd79b3470a746cc7a5374a"
68
+ }
package/CHANGELOG.md DELETED
@@ -1,21 +0,0 @@
1
- # Release Notes
2
-
3
- ## v0.2.0 - 2022-11-04
4
-
5
- Release with support for the pre-authorized code flow only.
6
-
7
- Expect breaking changes in the future, as this package still is undergoing heavy development.
8
-
9
- - Added:
10
- - Support for well-known OID4VCI, oAuth2 and OpenID metadata
11
-
12
- - Fixes:
13
- - Several fixes related to pincode handling
14
- - Overall fixes
15
-
16
-
17
- ## v0.1.0 - 2022-10-18
18
-
19
- Initial release with support for the pre-authorized code flow only.
20
-
21
- Expect breaking changes in the future, as this package still is undergoing heavy development.
@@ -1 +0,0 @@
1
- export * from './lib';
@@ -1,18 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./lib"), exports);
18
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsd0NBQXFCIn0=
@@ -1,20 +0,0 @@
1
- import { AccessTokenRequest, AccessTokenRequestOpts, AccessTokenResponse, AuthorizationServerOpts, EndpointMetadata, ErrorResponse, IssuanceInitiationRequestPayload, IssuanceInitiationWithBaseUrl, IssuerOpts } from './types';
2
- export declare class AccessTokenClient {
3
- acquireAccessTokenUsingIssuanceInitiation(issuanceInitiation: IssuanceInitiationWithBaseUrl, opts?: AccessTokenRequestOpts): Promise<AccessTokenResponse | ErrorResponse>;
4
- acquireAccessTokenUsingRequest(accessTokenRequest: AccessTokenRequest, opts?: {
5
- isPinRequired?: boolean;
6
- metadata?: EndpointMetadata;
7
- asOpts?: AuthorizationServerOpts;
8
- issuerOpts?: IssuerOpts;
9
- }): Promise<AccessTokenResponse | ErrorResponse>;
10
- createAccessTokenRequest(issuanceInitiationRequest: IssuanceInitiationRequestPayload, opts?: AccessTokenRequestOpts): Promise<AccessTokenRequest>;
11
- private assertPreAuthorizedGrantType;
12
- private isPinRequiredValue;
13
- private assertNumericPin;
14
- private assertNonEmptyPreAuthorizedCode;
15
- private validate;
16
- private sendAuthCode;
17
- private determineTokenURL;
18
- private creatTokenURLFromURL;
19
- private throwNotSupportedFlow;
20
- }