@sphereon/jarm 0.16.1-unstable.68 → 0.17.0
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/jarm-auth-response/jarm-auth-response.d.ts +1 -1
- package/dist/jarm-auth-response/v-jarm-direct-post-jwt-auth-response-params.d.ts +1 -1
- package/dist/jarm-auth-response/v-jarm-direct-post-jwt-auth-response-params.js +1 -1
- package/dist/jarm-auth-response/v-jarm-direct-post-jwt-auth-response-params.js.map +1 -1
- package/dist/jarm-auth-response-send/jarm-auth-response-send.d.ts +1 -0
- package/dist/jarm-auth-response-send/jarm-auth-response-send.d.ts.map +1 -1
- package/dist/jarm-auth-response-send/jarm-auth-response-send.js +10 -10
- package/dist/jarm-auth-response-send/jarm-auth-response-send.js.map +1 -1
- package/lib/jarm-auth-response/v-jarm-direct-post-jwt-auth-response-params.ts +1 -1
- package/lib/jarm-auth-response-send/jarm-auth-response-send.ts +11 -11
- package/package.json +3 -3
|
@@ -33,7 +33,7 @@ export declare const jarmAuthResponseDirectPostJwtValidate: (input: JarmDirectPo
|
|
|
33
33
|
[key: string]: unknown;
|
|
34
34
|
};
|
|
35
35
|
authResponseParams: {
|
|
36
|
-
vp_token: string;
|
|
36
|
+
vp_token: string | string[];
|
|
37
37
|
presentation_submission: unknown;
|
|
38
38
|
state?: string | undefined;
|
|
39
39
|
iss?: string | undefined;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as v from 'valibot';
|
|
2
2
|
export declare const vJarmDirectPostJwtParams: v.LooseObjectSchema<{
|
|
3
|
-
readonly vp_token: v.StringSchema<undefined>;
|
|
3
|
+
readonly vp_token: v.UnionSchema<[v.StringSchema<undefined>, v.ArraySchema<v.SchemaWithPipe<[v.StringSchema<undefined>, v.NonEmptyAction<string, undefined>]>, undefined>], undefined>;
|
|
4
4
|
readonly presentation_submission: v.UnknownSchema;
|
|
5
5
|
readonly nonce: v.OptionalSchema<v.StringSchema<undefined>, never>;
|
|
6
6
|
readonly iss: v.OptionalSchema<v.StringSchema<undefined>, never>;
|
|
@@ -26,7 +26,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
26
26
|
exports.jarmAuthResponseDirectPostValidateParams = exports.vJarmDirectPostJwtParams = void 0;
|
|
27
27
|
const v = __importStar(require("valibot"));
|
|
28
28
|
const v_jarm_auth_response_params_js_1 = require("./v-jarm-auth-response-params.js");
|
|
29
|
-
exports.vJarmDirectPostJwtParams = v.looseObject(Object.assign(Object.assign(Object.assign({}, v.omit(v_jarm_auth_response_params_js_1.vJarmAuthResponseParams, ['iss', 'aud', 'exp']).entries), v.partial(v.pick(v_jarm_auth_response_params_js_1.vJarmAuthResponseParams, ['iss', 'aud', 'exp'])).entries), { vp_token: v.string(), presentation_submission: v.unknown(), nonce: v.optional(v.string()) }));
|
|
29
|
+
exports.vJarmDirectPostJwtParams = v.looseObject(Object.assign(Object.assign(Object.assign({}, v.omit(v_jarm_auth_response_params_js_1.vJarmAuthResponseParams, ['iss', 'aud', 'exp']).entries), v.partial(v.pick(v_jarm_auth_response_params_js_1.vJarmAuthResponseParams, ['iss', 'aud', 'exp'])).entries), { vp_token: v.union([v.string(), v.array(v.pipe(v.string(), v.nonEmpty()))]), presentation_submission: v.unknown(), nonce: v.optional(v.string()) }));
|
|
30
30
|
const jarmAuthResponseDirectPostValidateParams = (input) => {
|
|
31
31
|
const { authRequestParams, authResponseParams } = input;
|
|
32
32
|
// 2. The client obtains the state parameter from the JWT and checks its binding to the user agent. If the check fails, the client MUST abort processing and refuse the response.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"v-jarm-direct-post-jwt-auth-response-params.js","sourceRoot":"","sources":["../../lib/jarm-auth-response/v-jarm-direct-post-jwt-auth-response-params.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA6B;AAE7B,qFAA2E;AAE9D,QAAA,wBAAwB,GAAG,CAAC,CAAC,WAAW,+CAChD,CAAC,CAAC,IAAI,CAAC,wDAAuB,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,GAC9D,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,wDAAuB,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,KAE5E,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"v-jarm-direct-post-jwt-auth-response-params.js","sourceRoot":"","sources":["../../lib/jarm-auth-response/v-jarm-direct-post-jwt-auth-response-params.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA6B;AAE7B,qFAA2E;AAE9D,QAAA,wBAAwB,GAAG,CAAC,CAAC,WAAW,+CAChD,CAAC,CAAC,IAAI,CAAC,wDAAuB,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,GAC9D,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,wDAAuB,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,KAE5E,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,EAC1E,uBAAuB,EAAE,CAAC,CAAC,OAAO,EAAE,EACpC,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAC7B,CAAC;AAII,MAAM,wCAAwC,GAAG,CAAC,KAGxD,EAAE,EAAE;IACH,MAAM,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,GAAG,KAAK,CAAC;IAExD,iLAAiL;IACjL,IAAI,iBAAiB,CAAC,KAAK,KAAK,kBAAkB,CAAC,KAAK,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CAAC,yCAAyC,iBAAiB,CAAC,KAAK,+BAA+B,CAAC,CAAC;IACnH,CAAC;AACH,CAAC,CAAC;AAVW,QAAA,wCAAwC,4CAUnD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jarm-auth-response-send.d.ts","sourceRoot":"","sources":["../../lib/jarm-auth-response-send/jarm-auth-response-send.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAElG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAEtE,UAAU,yBAAyB;IACjC,iBAAiB,EAAE;QACjB,aAAa,CAAC,EAAE,gBAAgB,GAAG,yBAAyB,CAAC;QAC7D,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,CACA;QACE,YAAY,EAAE,MAAM,CAAC;KACtB,GACD;QACE,YAAY,EAAE,MAAM,CAAC;KACtB,CACJ,CAAC;IAEF,YAAY,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"jarm-auth-response-send.d.ts","sourceRoot":"","sources":["../../lib/jarm-auth-response-send/jarm-auth-response-send.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAElG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAEtE,UAAU,yBAAyB;IACjC,iBAAiB,EAAE;QACjB,aAAa,CAAC,EAAE,gBAAgB,GAAG,yBAAyB,CAAC;QAC7D,aAAa,EAAE,eAAe,CAAC;KAChC,GAAG,CACA;QACE,YAAY,EAAE,MAAM,CAAC;KACtB,GACD;QACE,YAAY,EAAE,MAAM,CAAC;KACtB,CACJ,CAAC;IAEF,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,oBAAoB,UAAiB,yBAAyB,KAAG,OAAO,CAAC,QAAQ,CAyB7F,CAAC"}
|
|
@@ -13,7 +13,7 @@ exports.jarmAuthResponseSend = void 0;
|
|
|
13
13
|
const utils_js_1 = require("../utils.js");
|
|
14
14
|
const v_response_mode_registry_js_1 = require("../v-response-mode-registry.js");
|
|
15
15
|
const jarmAuthResponseSend = (input) => __awaiter(void 0, void 0, void 0, function* () {
|
|
16
|
-
const { authRequestParams, authResponse } = input;
|
|
16
|
+
const { authRequestParams, authResponse, state } = input;
|
|
17
17
|
const responseEndpoint = 'response_uri' in authRequestParams ? new URL(authRequestParams.response_uri) : new URL(authRequestParams.redirect_uri);
|
|
18
18
|
const responseMode = authRequestParams.response_mode && authRequestParams.response_mode !== 'jwt'
|
|
19
19
|
? authRequestParams.response_mode
|
|
@@ -24,41 +24,41 @@ const jarmAuthResponseSend = (input) => __awaiter(void 0, void 0, void 0, functi
|
|
|
24
24
|
});
|
|
25
25
|
switch (responseMode) {
|
|
26
26
|
case 'direct_post.jwt':
|
|
27
|
-
return handleDirectPostJwt(responseEndpoint, authResponse);
|
|
27
|
+
return handleDirectPostJwt(responseEndpoint, authResponse, state);
|
|
28
28
|
case 'query.jwt':
|
|
29
|
-
return handleQueryJwt(responseEndpoint, authResponse);
|
|
29
|
+
return handleQueryJwt(responseEndpoint, authResponse, state);
|
|
30
30
|
case 'fragment.jwt':
|
|
31
|
-
return handleFragmentJwt(responseEndpoint, authResponse);
|
|
31
|
+
return handleFragmentJwt(responseEndpoint, authResponse, state);
|
|
32
32
|
case 'form_post.jwt':
|
|
33
33
|
throw new Error('Not implemented. form_post.jwt is not yet supported.');
|
|
34
34
|
}
|
|
35
35
|
});
|
|
36
36
|
exports.jarmAuthResponseSend = jarmAuthResponseSend;
|
|
37
|
-
function handleDirectPostJwt(responseEndpoint, responseJwt) {
|
|
37
|
+
function handleDirectPostJwt(responseEndpoint, responseJwt, state) {
|
|
38
38
|
return __awaiter(this, void 0, void 0, function* () {
|
|
39
39
|
const response = yield fetch(responseEndpoint, {
|
|
40
40
|
method: 'POST',
|
|
41
41
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
42
|
-
body: `response=${responseJwt}`,
|
|
42
|
+
body: `response=${responseJwt}&state=${state}`,
|
|
43
43
|
});
|
|
44
44
|
return response;
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
|
-
function handleQueryJwt(responseEndpoint, responseJwt) {
|
|
47
|
+
function handleQueryJwt(responseEndpoint, responseJwt, state) {
|
|
48
48
|
return __awaiter(this, void 0, void 0, function* () {
|
|
49
49
|
const responseUrl = (0, utils_js_1.appendQueryParams)({
|
|
50
50
|
url: responseEndpoint,
|
|
51
|
-
params: { response: responseJwt },
|
|
51
|
+
params: { response: responseJwt, state },
|
|
52
52
|
});
|
|
53
53
|
const response = yield fetch(responseUrl, { method: 'POST' });
|
|
54
54
|
return response;
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
|
-
function handleFragmentJwt(responseEndpoint, responseJwt) {
|
|
57
|
+
function handleFragmentJwt(responseEndpoint, responseJwt, state) {
|
|
58
58
|
return __awaiter(this, void 0, void 0, function* () {
|
|
59
59
|
const responseUrl = (0, utils_js_1.appendFragmentParams)({
|
|
60
60
|
url: responseEndpoint,
|
|
61
|
-
fragments: { response: responseJwt },
|
|
61
|
+
fragments: { response: responseJwt, state },
|
|
62
62
|
});
|
|
63
63
|
const response = yield fetch(responseUrl, { method: 'POST' });
|
|
64
64
|
return response;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jarm-auth-response-send.js","sourceRoot":"","sources":["../../lib/jarm-auth-response-send/jarm-auth-response-send.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,0CAAsE;AAEtE,gFAAkG;
|
|
1
|
+
{"version":3,"file":"jarm-auth-response-send.js","sourceRoot":"","sources":["../../lib/jarm-auth-response-send/jarm-auth-response-send.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,0CAAsE;AAEtE,gFAAkG;AAoB3F,MAAM,oBAAoB,GAAG,CAAO,KAAgC,EAAqB,EAAE;IAChG,MAAM,EAAE,iBAAiB,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IAEzD,MAAM,gBAAgB,GAAG,cAAc,IAAI,iBAAiB,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAEjJ,MAAM,YAAY,GAChB,iBAAiB,CAAC,aAAa,IAAI,iBAAiB,CAAC,aAAa,KAAK,KAAK;QAC1E,CAAC,CAAC,iBAAiB,CAAC,aAAa;QACjC,CAAC,CAAC,IAAA,wDAA0B,EAAC,iBAAiB,CAAC,CAAC;IAEpD,IAAA,kDAAoB,EAAC;QACnB,aAAa,EAAE,iBAAiB,CAAC,aAAa;QAC9C,aAAa,EAAE,YAAY;KAC5B,CAAC,CAAC;IAEH,QAAQ,YAAY,EAAE,CAAC;QACrB,KAAK,iBAAiB;YACpB,OAAO,mBAAmB,CAAC,gBAAgB,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;QACpE,KAAK,WAAW;YACd,OAAO,cAAc,CAAC,gBAAgB,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;QAC/D,KAAK,cAAc;YACjB,OAAO,iBAAiB,CAAC,gBAAgB,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;QAClE,KAAK,eAAe;YAClB,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC5E,CAAC;AACH,CAAC,CAAA,CAAC;AAzBW,QAAA,oBAAoB,wBAyB/B;AAEF,SAAe,mBAAmB,CAAC,gBAAqB,EAAE,WAAmB,EAAE,KAAa;;QAC1F,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,gBAAgB,EAAE;YAC7C,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;YAChE,IAAI,EAAE,YAAY,WAAW,UAAU,KAAK,EAAE;SAC/C,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC;IAClB,CAAC;CAAA;AAED,SAAe,cAAc,CAAC,gBAAqB,EAAE,WAAmB,EAAE,KAAa;;QACrF,MAAM,WAAW,GAAG,IAAA,4BAAiB,EAAC;YACpC,GAAG,EAAE,gBAAgB;YACrB,MAAM,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE;SACzC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC9D,OAAO,QAAQ,CAAC;IAClB,CAAC;CAAA;AAED,SAAe,iBAAiB,CAAC,gBAAqB,EAAE,WAAmB,EAAE,KAAa;;QACxF,MAAM,WAAW,GAAG,IAAA,+BAAoB,EAAC;YACvC,GAAG,EAAE,gBAAgB;YACrB,SAAS,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE;SAC5C,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC9D,OAAO,QAAQ,CAAC;IAClB,CAAC;CAAA"}
|
|
@@ -6,7 +6,7 @@ export const vJarmDirectPostJwtParams = v.looseObject({
|
|
|
6
6
|
...v.omit(vJarmAuthResponseParams, ['iss', 'aud', 'exp']).entries,
|
|
7
7
|
...v.partial(v.pick(vJarmAuthResponseParams, ['iss', 'aud', 'exp'])).entries,
|
|
8
8
|
|
|
9
|
-
vp_token: v.string(),
|
|
9
|
+
vp_token: v.union([v.string(), v.array(v.pipe(v.string(), v.nonEmpty()))]),
|
|
10
10
|
presentation_submission: v.unknown(),
|
|
11
11
|
nonce: v.optional(v.string()),
|
|
12
12
|
});
|
|
@@ -17,10 +17,11 @@ interface JarmAuthResponseSendInput {
|
|
|
17
17
|
);
|
|
18
18
|
|
|
19
19
|
authResponse: string;
|
|
20
|
+
state: string;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
export const jarmAuthResponseSend = async (input: JarmAuthResponseSendInput): Promise<Response> => {
|
|
23
|
-
const { authRequestParams, authResponse } = input;
|
|
24
|
+
const { authRequestParams, authResponse, state } = input;
|
|
24
25
|
|
|
25
26
|
const responseEndpoint = 'response_uri' in authRequestParams ? new URL(authRequestParams.response_uri) : new URL(authRequestParams.redirect_uri);
|
|
26
27
|
|
|
@@ -36,40 +37,39 @@ export const jarmAuthResponseSend = async (input: JarmAuthResponseSendInput): Pr
|
|
|
36
37
|
|
|
37
38
|
switch (responseMode) {
|
|
38
39
|
case 'direct_post.jwt':
|
|
39
|
-
return handleDirectPostJwt(responseEndpoint, authResponse);
|
|
40
|
+
return handleDirectPostJwt(responseEndpoint, authResponse, state);
|
|
40
41
|
case 'query.jwt':
|
|
41
|
-
return handleQueryJwt(responseEndpoint, authResponse);
|
|
42
|
+
return handleQueryJwt(responseEndpoint, authResponse, state);
|
|
42
43
|
case 'fragment.jwt':
|
|
43
|
-
return handleFragmentJwt(responseEndpoint, authResponse);
|
|
44
|
+
return handleFragmentJwt(responseEndpoint, authResponse, state);
|
|
44
45
|
case 'form_post.jwt':
|
|
45
46
|
throw new Error('Not implemented. form_post.jwt is not yet supported.');
|
|
46
47
|
}
|
|
47
48
|
};
|
|
48
49
|
|
|
49
|
-
async function handleDirectPostJwt(responseEndpoint: URL, responseJwt: string) {
|
|
50
|
+
async function handleDirectPostJwt(responseEndpoint: URL, responseJwt: string, state: string) {
|
|
50
51
|
const response = await fetch(responseEndpoint, {
|
|
51
52
|
method: 'POST',
|
|
52
53
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
53
|
-
body: `response=${responseJwt}`,
|
|
54
|
+
body: `response=${responseJwt}&state=${state}`,
|
|
54
55
|
});
|
|
55
|
-
|
|
56
56
|
return response;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
async function handleQueryJwt(responseEndpoint: URL, responseJwt: string) {
|
|
59
|
+
async function handleQueryJwt(responseEndpoint: URL, responseJwt: string, state: string) {
|
|
60
60
|
const responseUrl = appendQueryParams({
|
|
61
61
|
url: responseEndpoint,
|
|
62
|
-
params: { response: responseJwt },
|
|
62
|
+
params: { response: responseJwt, state },
|
|
63
63
|
});
|
|
64
64
|
|
|
65
65
|
const response = await fetch(responseUrl, { method: 'POST' });
|
|
66
66
|
return response;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
async function handleFragmentJwt(responseEndpoint: URL, responseJwt: string) {
|
|
69
|
+
async function handleFragmentJwt(responseEndpoint: URL, responseJwt: string, state: string) {
|
|
70
70
|
const responseUrl = appendFragmentParams({
|
|
71
71
|
url: responseEndpoint,
|
|
72
|
-
fragments: { response: responseJwt },
|
|
72
|
+
fragments: { response: responseJwt, state },
|
|
73
73
|
});
|
|
74
74
|
const response = await fetch(responseUrl, { method: 'POST' });
|
|
75
75
|
return response;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sphereon/jarm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "Sphereon JARM",
|
|
5
5
|
"source": "lib/index.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"build:clean": "tsc --build --clean && tsc --build"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@sphereon/oid4vc-common": "0.
|
|
13
|
+
"@sphereon/oid4vc-common": "0.17.0",
|
|
14
14
|
"valibot": "^0.42.1"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
@@ -43,5 +43,5 @@
|
|
|
43
43
|
"publishConfig": {
|
|
44
44
|
"access": "public"
|
|
45
45
|
},
|
|
46
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "730c459314d3831431a924920a0de39500f72c9d"
|
|
47
47
|
}
|