@eudiplo/cli 8.1.0 → 9.0.0-main.410b294
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 +6 -6
- package/dist/commands/completion/action.js +1 -1
- package/dist/commands/completion/action.js.map +1 -1
- package/dist/commands/completion/index.d.ts.map +1 -1
- package/dist/commands/completion/index.js +6 -1
- package/dist/commands/completion/index.js.map +1 -1
- package/dist/commands/config/action.d.ts.map +1 -1
- package/dist/commands/config/action.js.map +1 -1
- package/dist/commands/config/portability/migrations.spec.js +5 -3
- package/dist/commands/config/portability/migrations.spec.js.map +1 -1
- package/dist/commands/config/validate/schemas.js.map +1 -1
- package/dist/commands/config/validate/validator.js +7 -4
- package/dist/commands/config/validate/validator.js.map +1 -1
- package/dist/commands/doctor/action.d.ts +2 -1
- package/dist/commands/doctor/action.d.ts.map +1 -1
- package/dist/commands/doctor/action.js +25 -7
- package/dist/commands/doctor/action.js.map +1 -1
- package/dist/commands/doctor/index.d.ts.map +1 -1
- package/dist/commands/doctor/index.js +2 -0
- package/dist/commands/doctor/index.js.map +1 -1
- package/dist/commands/instance/action.d.ts.map +1 -1
- package/dist/commands/instance/action.js.map +1 -1
- package/dist/commands/upgrade/action.d.ts.map +1 -1
- package/dist/commands/upgrade/action.js +3 -1
- package/dist/commands/upgrade/action.js.map +1 -1
- package/dist/index.js +3328 -495
- package/dist/runtime.js +1 -1
- package/dist/runtime.js.map +1 -1
- package/dist/services/api-auth.d.ts +31 -0
- package/dist/services/api-auth.d.ts.map +1 -0
- package/dist/services/api-auth.js +78 -0
- package/dist/services/api-auth.js.map +1 -0
- package/dist/services/backend-checks.d.ts +24 -0
- package/dist/services/backend-checks.d.ts.map +1 -0
- package/dist/services/backend-checks.js +105 -0
- package/dist/services/backend-checks.js.map +1 -0
- package/dist/services/cli-config.d.ts.map +1 -1
- package/dist/services/cli-config.js +5 -2
- package/dist/services/cli-config.js.map +1 -1
- package/dist/services/compose-project.d.ts.map +1 -1
- package/dist/services/compose-project.js +20 -15
- package/dist/services/compose-project.js.map +1 -1
- package/dist/services/compose-upgrade.d.ts +8 -5
- package/dist/services/compose-upgrade.d.ts.map +1 -1
- package/dist/services/compose-upgrade.js +37 -12
- package/dist/services/compose-upgrade.js.map +1 -1
- package/dist/services/container-state.d.ts +14 -0
- package/dist/services/container-state.d.ts.map +1 -0
- package/dist/services/container-state.js +70 -0
- package/dist/services/container-state.js.map +1 -0
- package/dist/services/deployment-drivers.d.ts.map +1 -1
- package/dist/services/deployment-drivers.js +77 -0
- package/dist/services/deployment-drivers.js.map +1 -1
- package/dist/services/diagnostics.d.ts +19 -2
- package/dist/services/diagnostics.d.ts.map +1 -1
- package/dist/services/diagnostics.js +219 -50
- package/dist/services/diagnostics.js.map +1 -1
- package/dist/services/kubectl.d.ts.map +1 -1
- package/dist/services/kubectl.js +1 -6
- package/dist/services/kubectl.js.map +1 -1
- package/dist/services/tls-expiry.d.ts +16 -0
- package/dist/services/tls-expiry.d.ts.map +1 -0
- package/dist/services/tls-expiry.js +80 -0
- package/dist/services/tls-expiry.js.map +1 -0
- package/dist/types.d.ts +4 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +12 -10
- package/templates/demo-config/trust-lists/trustlist-580831bc-ef11-43f4-a3be-a2b6bf1b29a3-config.json +1 -97
- package/templates/docker-compose.yml +37 -30
- package/templates/schemas/DCQL.schema.json +30 -4
- package/templates/schemas/IssuanceConfig.schema.json +13 -0
- package/templates/schemas/IssuanceConfigFile.schema.json +663 -1
- package/templates/schemas/PresentationConfigCreateDto.schema.json +33 -10
- package/templates/schemas/PresentationConfigFile.schema.json +1442 -1
package/dist/index.js
CHANGED
|
@@ -2216,20 +2216,20 @@ var require_resolve = __commonJS({
|
|
|
2216
2216
|
return false;
|
|
2217
2217
|
}
|
|
2218
2218
|
function countKeys(schema) {
|
|
2219
|
-
let
|
|
2219
|
+
let count2 = 0;
|
|
2220
2220
|
for (const key in schema) {
|
|
2221
2221
|
if (key === "$ref")
|
|
2222
2222
|
return Infinity;
|
|
2223
|
-
|
|
2223
|
+
count2++;
|
|
2224
2224
|
if (SIMPLE_INLINED.has(key))
|
|
2225
2225
|
continue;
|
|
2226
2226
|
if (typeof schema[key] == "object") {
|
|
2227
|
-
(0, util_1.eachItem)(schema[key], (sch) =>
|
|
2227
|
+
(0, util_1.eachItem)(schema[key], (sch) => count2 += countKeys(sch));
|
|
2228
2228
|
}
|
|
2229
|
-
if (
|
|
2229
|
+
if (count2 === Infinity)
|
|
2230
2230
|
return Infinity;
|
|
2231
2231
|
}
|
|
2232
|
-
return
|
|
2232
|
+
return count2;
|
|
2233
2233
|
}
|
|
2234
2234
|
function getFullPath(resolver, id = "", normalize) {
|
|
2235
2235
|
if (normalize !== false)
|
|
@@ -3099,12 +3099,13 @@ var require_data = __commonJS({
|
|
|
3099
3099
|
}
|
|
3100
3100
|
});
|
|
3101
3101
|
|
|
3102
|
-
// ../../node_modules/.pnpm/fast-uri@3.1.
|
|
3102
|
+
// ../../node_modules/.pnpm/fast-uri@3.1.8/node_modules/fast-uri/lib/utils.js
|
|
3103
3103
|
var require_utils = __commonJS({
|
|
3104
|
-
"../../node_modules/.pnpm/fast-uri@3.1.
|
|
3104
|
+
"../../node_modules/.pnpm/fast-uri@3.1.8/node_modules/fast-uri/lib/utils.js"(exports, module) {
|
|
3105
3105
|
"use strict";
|
|
3106
3106
|
var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
|
|
3107
3107
|
var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
|
|
3108
|
+
var isPort = RegExp.prototype.test.bind(/^\d*$/u);
|
|
3108
3109
|
var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
|
|
3109
3110
|
var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
|
|
3110
3111
|
var isPathCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/]$/u);
|
|
@@ -3570,8 +3571,12 @@ var require_utils = __commonJS({
|
|
|
3570
3571
|
uriTokens.push(host);
|
|
3571
3572
|
}
|
|
3572
3573
|
if (typeof component.port === "number" || typeof component.port === "string") {
|
|
3574
|
+
const port = String(component.port);
|
|
3575
|
+
if (!isPort(port)) {
|
|
3576
|
+
throw new TypeError("URI port is malformed.");
|
|
3577
|
+
}
|
|
3573
3578
|
uriTokens.push(":");
|
|
3574
|
-
uriTokens.push(
|
|
3579
|
+
uriTokens.push(port);
|
|
3575
3580
|
}
|
|
3576
3581
|
return uriTokens.length ? uriTokens.join("") : void 0;
|
|
3577
3582
|
}
|
|
@@ -3596,9 +3601,9 @@ var require_utils = __commonJS({
|
|
|
3596
3601
|
}
|
|
3597
3602
|
});
|
|
3598
3603
|
|
|
3599
|
-
// ../../node_modules/.pnpm/fast-uri@3.1.
|
|
3604
|
+
// ../../node_modules/.pnpm/fast-uri@3.1.8/node_modules/fast-uri/lib/schemes.js
|
|
3600
3605
|
var require_schemes = __commonJS({
|
|
3601
|
-
"../../node_modules/.pnpm/fast-uri@3.1.
|
|
3606
|
+
"../../node_modules/.pnpm/fast-uri@3.1.8/node_modules/fast-uri/lib/schemes.js"(exports, module) {
|
|
3602
3607
|
"use strict";
|
|
3603
3608
|
var { isUUID } = require_utils();
|
|
3604
3609
|
var URN_REG = /^([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-./:;=@]|%[\da-f]{2})+)$/iu;
|
|
@@ -3807,9 +3812,9 @@ var require_schemes = __commonJS({
|
|
|
3807
3812
|
}
|
|
3808
3813
|
});
|
|
3809
3814
|
|
|
3810
|
-
// ../../node_modules/.pnpm/fast-uri@3.1.
|
|
3815
|
+
// ../../node_modules/.pnpm/fast-uri@3.1.8/node_modules/fast-uri/index.js
|
|
3811
3816
|
var require_fast_uri = __commonJS({
|
|
3812
|
-
"../../node_modules/.pnpm/fast-uri@3.1.
|
|
3817
|
+
"../../node_modules/.pnpm/fast-uri@3.1.8/node_modules/fast-uri/index.js"(exports, module) {
|
|
3813
3818
|
"use strict";
|
|
3814
3819
|
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
|
|
3815
3820
|
var { SCHEMES, getSchemeHandler } = require_schemes();
|
|
@@ -3828,7 +3833,7 @@ var require_fast_uri = __commonJS({
|
|
|
3828
3833
|
normalizeString(uri, options);
|
|
3829
3834
|
} else if (typeof uri === "object") {
|
|
3830
3835
|
uri = /** @type {T} */
|
|
3831
|
-
|
|
3836
|
+
parse5(serialize(uri, options), options);
|
|
3832
3837
|
}
|
|
3833
3838
|
return uri;
|
|
3834
3839
|
}
|
|
@@ -3868,8 +3873,8 @@ var require_fast_uri = __commonJS({
|
|
|
3868
3873
|
function resolveComponent(base, relative3, options, skipNormalization) {
|
|
3869
3874
|
const target = {};
|
|
3870
3875
|
if (!skipNormalization) {
|
|
3871
|
-
base =
|
|
3872
|
-
relative3 =
|
|
3876
|
+
base = parse5(serialize(base, options), options);
|
|
3877
|
+
relative3 = parse5(serialize(relative3, options), options);
|
|
3873
3878
|
}
|
|
3874
3879
|
options = options || {};
|
|
3875
3880
|
if (!options.tolerant && relative3.scheme) {
|
|
@@ -4014,12 +4019,15 @@ var require_fast_uri = __commonJS({
|
|
|
4014
4019
|
}
|
|
4015
4020
|
return false;
|
|
4016
4021
|
}
|
|
4022
|
+
function isIPLiteral(host) {
|
|
4023
|
+
return host[0] === "[" && host[host.length - 1] === "]";
|
|
4024
|
+
}
|
|
4017
4025
|
function hasMalformedComponentPercentEncoding(matches) {
|
|
4018
4026
|
const host = matches[4];
|
|
4019
|
-
return hasMalformedPercentEncoding(matches[3]) || host !== void 0 && !(host
|
|
4027
|
+
return hasMalformedPercentEncoding(matches[3]) || host !== void 0 && !isIPLiteral(host) && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
|
|
4020
4028
|
}
|
|
4021
4029
|
function canonicalizeHost(parsed, options, schemeHandler, isIP) {
|
|
4022
|
-
if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && parsed.host
|
|
4030
|
+
if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && !isIPLiteral(parsed.host) && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
|
|
4023
4031
|
try {
|
|
4024
4032
|
parsed.host = new URL("http://" + parsed.host).hostname;
|
|
4025
4033
|
} catch (e) {
|
|
@@ -4106,10 +4114,11 @@ var require_fast_uri = __commonJS({
|
|
|
4106
4114
|
if (parsed.host) {
|
|
4107
4115
|
const ipv4result = isIPv4(parsed.host);
|
|
4108
4116
|
if (ipv4result === false) {
|
|
4109
|
-
const bracketedIPLiteral = parsed.host
|
|
4117
|
+
const bracketedIPLiteral = isIPLiteral(parsed.host);
|
|
4118
|
+
const hasIPLiteralBracket = parsed.host.indexOf("[") !== -1 || parsed.host.indexOf("]") !== -1;
|
|
4110
4119
|
const ipv6result = normalizeIPv6(parsed.host);
|
|
4111
4120
|
isIP = ipv6result.isIPV6 || ipv6result.isIPVFuture === true;
|
|
4112
|
-
malformedIPLiteral =
|
|
4121
|
+
malformedIPLiteral = hasIPLiteralBracket && (!bracketedIPLiteral || ipv6result.error === true);
|
|
4113
4122
|
parsed.host = isIP ? ipv6result.host : ipv6result.host.toLowerCase();
|
|
4114
4123
|
if (malformedIPLiteral) {
|
|
4115
4124
|
parsed.error = parsed.error || "URI host is malformed.";
|
|
@@ -4132,14 +4141,17 @@ var require_fast_uri = __commonJS({
|
|
|
4132
4141
|
parsed.error = parsed.error || "URI is not a " + options.reference + " reference.";
|
|
4133
4142
|
}
|
|
4134
4143
|
const schemeHandler = getSchemeHandler(options.scheme || parsed.scheme);
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
|
|
4144
|
+
if (!malformedIPLiteral) {
|
|
4145
|
+
malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
|
|
4146
|
+
}
|
|
4147
|
+
if (uri.indexOf("%") !== -1 && parsed.host !== void 0 && !malformedIPLiteral) {
|
|
4148
|
+
let host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
|
|
4149
|
+
if (!isIP) {
|
|
4150
|
+
host = normalizePercentEncoding(host.toLowerCase());
|
|
4142
4151
|
}
|
|
4152
|
+
parsed.host = reescapeHostDelimiters(host, isIP);
|
|
4153
|
+
}
|
|
4154
|
+
if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
|
|
4143
4155
|
if (parsed.path) {
|
|
4144
4156
|
parsed.path = normalizePathEncoding(parsed.path);
|
|
4145
4157
|
}
|
|
@@ -4161,7 +4173,7 @@ var require_fast_uri = __commonJS({
|
|
|
4161
4173
|
}
|
|
4162
4174
|
return { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme };
|
|
4163
4175
|
}
|
|
4164
|
-
function
|
|
4176
|
+
function parse5(uri, opts) {
|
|
4165
4177
|
return parseWithStatus(uri, opts).parsed;
|
|
4166
4178
|
}
|
|
4167
4179
|
function normalizeString(uri, opts) {
|
|
@@ -4198,7 +4210,7 @@ var require_fast_uri = __commonJS({
|
|
|
4198
4210
|
resolveComponent,
|
|
4199
4211
|
equal,
|
|
4200
4212
|
serialize,
|
|
4201
|
-
parse:
|
|
4213
|
+
parse: parse5
|
|
4202
4214
|
};
|
|
4203
4215
|
module.exports = fastUri;
|
|
4204
4216
|
module.exports.default = fastUri;
|
|
@@ -5699,8 +5711,8 @@ var require_contains = __commonJS({
|
|
|
5699
5711
|
cxt.result(valid, () => cxt.reset());
|
|
5700
5712
|
function validateItemsWithCount() {
|
|
5701
5713
|
const schValid = gen.name("_valid");
|
|
5702
|
-
const
|
|
5703
|
-
validateItems(schValid, () => gen.if(schValid, () => checkLimits(
|
|
5714
|
+
const count2 = gen.let("count", 0);
|
|
5715
|
+
validateItems(schValid, () => gen.if(schValid, () => checkLimits(count2)));
|
|
5704
5716
|
}
|
|
5705
5717
|
function validateItems(_valid, block) {
|
|
5706
5718
|
gen.forRange("i", 0, len, (i2) => {
|
|
@@ -5713,16 +5725,16 @@ var require_contains = __commonJS({
|
|
|
5713
5725
|
block();
|
|
5714
5726
|
});
|
|
5715
5727
|
}
|
|
5716
|
-
function checkLimits(
|
|
5717
|
-
gen.code((0, codegen_1._)`${
|
|
5728
|
+
function checkLimits(count2) {
|
|
5729
|
+
gen.code((0, codegen_1._)`${count2}++`);
|
|
5718
5730
|
if (max2 === void 0) {
|
|
5719
|
-
gen.if((0, codegen_1._)`${
|
|
5731
|
+
gen.if((0, codegen_1._)`${count2} >= ${min}`, () => gen.assign(valid, true).break());
|
|
5720
5732
|
} else {
|
|
5721
|
-
gen.if((0, codegen_1._)`${
|
|
5733
|
+
gen.if((0, codegen_1._)`${count2} > ${max2}`, () => gen.assign(valid, false).break());
|
|
5722
5734
|
if (min === 1)
|
|
5723
5735
|
gen.assign(valid, true);
|
|
5724
5736
|
else
|
|
5725
|
-
gen.if((0, codegen_1._)`${
|
|
5737
|
+
gen.if((0, codegen_1._)`${count2} >= ${min}`, () => gen.assign(valid, true));
|
|
5726
5738
|
}
|
|
5727
5739
|
}
|
|
5728
5740
|
}
|
|
@@ -11388,12 +11400,7 @@ import { homedir } from "node:os";
|
|
|
11388
11400
|
|
|
11389
11401
|
// src/services/kubectl.ts
|
|
11390
11402
|
function scopeArgs(scope) {
|
|
11391
|
-
return [
|
|
11392
|
-
"--context",
|
|
11393
|
-
scope.context,
|
|
11394
|
-
"--namespace",
|
|
11395
|
-
scope.namespace
|
|
11396
|
-
];
|
|
11403
|
+
return ["--context", scope.context, "--namespace", scope.namespace];
|
|
11397
11404
|
}
|
|
11398
11405
|
function resolveScope(instance, instanceName) {
|
|
11399
11406
|
if (!instance.context) {
|
|
@@ -11922,7 +11929,12 @@ function powershellCompletion() {
|
|
|
11922
11929
|
}
|
|
11923
11930
|
|
|
11924
11931
|
// src/commands/completion/index.ts
|
|
11925
|
-
var supportedShells = [
|
|
11932
|
+
var supportedShells = [
|
|
11933
|
+
"bash",
|
|
11934
|
+
"zsh",
|
|
11935
|
+
"fish",
|
|
11936
|
+
"powershell"
|
|
11937
|
+
];
|
|
11926
11938
|
function createCompletionCommand(context, setExitCode) {
|
|
11927
11939
|
return new Command("completion").description("Generate shell completion scripts").addArgument(
|
|
11928
11940
|
new Argument("<shell>", "shell to generate completion for").choices(
|
|
@@ -11933,14 +11945,22 @@ function createCompletionCommand(context, setExitCode) {
|
|
|
11933
11945
|
});
|
|
11934
11946
|
}
|
|
11935
11947
|
function createCompletionCandidatesCommand(context, setExitCode) {
|
|
11936
|
-
return new Command("_complete").argument("[words...]").allowUnknownOption(true).action(
|
|
11937
|
-
|
|
11938
|
-
|
|
11948
|
+
return new Command("_complete").argument("[words...]").allowUnknownOption(true).action(
|
|
11949
|
+
async (words, _options, command) => {
|
|
11950
|
+
if (!command.parent) {
|
|
11951
|
+
throw new Error(
|
|
11952
|
+
"Completion command is not attached to the CLI root."
|
|
11953
|
+
);
|
|
11954
|
+
}
|
|
11955
|
+
setExitCode(
|
|
11956
|
+
await runCompletionCandidates(
|
|
11957
|
+
command.parent,
|
|
11958
|
+
words,
|
|
11959
|
+
context
|
|
11960
|
+
)
|
|
11961
|
+
);
|
|
11939
11962
|
}
|
|
11940
|
-
|
|
11941
|
-
await runCompletionCandidates(command.parent, words, context)
|
|
11942
|
-
);
|
|
11943
|
-
});
|
|
11963
|
+
);
|
|
11944
11964
|
}
|
|
11945
11965
|
|
|
11946
11966
|
// src/commands/commands/render.ts
|
|
@@ -12028,8 +12048,10 @@ function runConfigShow(configPath, config, json, context) {
|
|
|
12028
12048
|
}
|
|
12029
12049
|
context.stdout.write(`Config: ${configPath}
|
|
12030
12050
|
`);
|
|
12031
|
-
context.stdout.write(
|
|
12032
|
-
`
|
|
12051
|
+
context.stdout.write(
|
|
12052
|
+
`Default instance: ${config.defaultInstance ?? "none"}
|
|
12053
|
+
`
|
|
12054
|
+
);
|
|
12033
12055
|
const instances = Object.entries(config.instances).sort(
|
|
12034
12056
|
([left], [right]) => left.localeCompare(right)
|
|
12035
12057
|
);
|
|
@@ -12065,10 +12087,10 @@ import { isAbsolute as isAbsolute2, join as join2, relative, resolve as resolve2
|
|
|
12065
12087
|
function createScanner(text, ignoreTrivia = false) {
|
|
12066
12088
|
const len = text.length;
|
|
12067
12089
|
let pos = 0, value = "", tokenOffset = 0, token = 16, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0;
|
|
12068
|
-
function scanHexDigits(
|
|
12090
|
+
function scanHexDigits(count2, exact) {
|
|
12069
12091
|
let digits = 0;
|
|
12070
12092
|
let value2 = 0;
|
|
12071
|
-
while (digits <
|
|
12093
|
+
while (digits < count2 || !exact) {
|
|
12072
12094
|
let ch = text.charCodeAt(pos);
|
|
12073
12095
|
if (ch >= 48 && ch <= 57) {
|
|
12074
12096
|
value2 = value2 * 16 + ch - 48;
|
|
@@ -12082,7 +12104,7 @@ function createScanner(text, ignoreTrivia = false) {
|
|
|
12082
12104
|
pos++;
|
|
12083
12105
|
digits++;
|
|
12084
12106
|
}
|
|
12085
|
-
if (digits <
|
|
12107
|
+
if (digits < count2) {
|
|
12086
12108
|
value2 = -1;
|
|
12087
12109
|
}
|
|
12088
12110
|
return value2;
|
|
@@ -12707,9 +12729,9 @@ function format(documentText, range, options) {
|
|
|
12707
12729
|
}
|
|
12708
12730
|
return editOperations;
|
|
12709
12731
|
}
|
|
12710
|
-
function repeat(s,
|
|
12732
|
+
function repeat(s, count2) {
|
|
12711
12733
|
let result = "";
|
|
12712
|
-
for (let i2 = 0; i2 <
|
|
12734
|
+
for (let i2 = 0; i2 < count2; i2++) {
|
|
12713
12735
|
result += s;
|
|
12714
12736
|
}
|
|
12715
12737
|
return result;
|
|
@@ -14887,7 +14909,7 @@ var CONFIG_FORMATS = {
|
|
|
14887
14909
|
IssuanceConfig: {
|
|
14888
14910
|
slug: "issuance-config",
|
|
14889
14911
|
file: "IssuanceConfigFile",
|
|
14890
|
-
version:
|
|
14912
|
+
version: 2
|
|
14891
14913
|
},
|
|
14892
14914
|
CredentialConfig: {
|
|
14893
14915
|
slug: "credential-config",
|
|
@@ -14897,7 +14919,7 @@ var CONFIG_FORMATS = {
|
|
|
14897
14919
|
PresentationConfig: {
|
|
14898
14920
|
slug: "presentation-config",
|
|
14899
14921
|
file: "PresentationConfigFile",
|
|
14900
|
-
version:
|
|
14922
|
+
version: 3
|
|
14901
14923
|
},
|
|
14902
14924
|
AttributeProvider: {
|
|
14903
14925
|
slug: "attribute-provider",
|
|
@@ -14936,7 +14958,53 @@ function resourceId(input) {
|
|
|
14936
14958
|
throw new Error(`Configuration spec.${field} is required`);
|
|
14937
14959
|
return id;
|
|
14938
14960
|
}
|
|
14939
|
-
var
|
|
14961
|
+
var presentationConfigV1ToV2 = {
|
|
14962
|
+
id: "presentation-config-v2-provides-attestations",
|
|
14963
|
+
kind: "PresentationConfig",
|
|
14964
|
+
from: 1,
|
|
14965
|
+
to: 2,
|
|
14966
|
+
migrate(spec) {
|
|
14967
|
+
const registrationCert = spec.registration_cert;
|
|
14968
|
+
if (!object(registrationCert) || !object(registrationCert.body) || !("provided_attestations" in registrationCert.body)) {
|
|
14969
|
+
return { spec };
|
|
14970
|
+
}
|
|
14971
|
+
const { provided_attestations: _, ...body } = registrationCert.body;
|
|
14972
|
+
return {
|
|
14973
|
+
spec: { ...spec, registration_cert: { ...registrationCert, body } },
|
|
14974
|
+
issues: [
|
|
14975
|
+
{
|
|
14976
|
+
severity: "warning",
|
|
14977
|
+
code: "PROVIDED_ATTESTATIONS_REMOVED",
|
|
14978
|
+
path: "/spec/registration_cert/body/provided_attestations",
|
|
14979
|
+
message: "provided_attestations is not part of the registrar API and was removed. Set provides_attestations to the credential type identifiers (SD-JWT VC vct or mdoc doctype) the issuer provides."
|
|
14980
|
+
}
|
|
14981
|
+
]
|
|
14982
|
+
};
|
|
14983
|
+
}
|
|
14984
|
+
};
|
|
14985
|
+
var CONFIG_MIGRATIONS = [
|
|
14986
|
+
{
|
|
14987
|
+
id: "issuance-config-v2-offer-lifetime",
|
|
14988
|
+
kind: "IssuanceConfig",
|
|
14989
|
+
from: 1,
|
|
14990
|
+
to: 2,
|
|
14991
|
+
// v2 only adds the optional offerLifetimeSeconds: a v1 spec is a
|
|
14992
|
+
// valid v2 spec whose offers keep having no lifetime.
|
|
14993
|
+
migrate: (spec) => ({ spec })
|
|
14994
|
+
},
|
|
14995
|
+
presentationConfigV1ToV2,
|
|
14996
|
+
{
|
|
14997
|
+
id: "presentation-config-v3-typed-claim-values",
|
|
14998
|
+
kind: "PresentationConfig",
|
|
14999
|
+
from: 2,
|
|
15000
|
+
to: 3,
|
|
15001
|
+
// v3 accepts integer and boolean DCQL claim `values` besides strings
|
|
15002
|
+
// and requires them to be non-empty. A v2 spec with non-empty string
|
|
15003
|
+
// values is a valid v3 spec; an empty `values` array fails v3
|
|
15004
|
+
// validation, since it could never match a disclosed claim.
|
|
15005
|
+
migrate: (spec) => ({ spec })
|
|
15006
|
+
}
|
|
15007
|
+
];
|
|
14940
15008
|
function schemaUrl(kind, version = CONFIG_FORMATS[kind].version) {
|
|
14941
15009
|
if (!Number.isSafeInteger(version) || version < 1)
|
|
14942
15010
|
throw new Error("Invalid config version");
|
|
@@ -15260,12 +15328,43 @@ function assertConfigBundle(input) {
|
|
|
15260
15328
|
}
|
|
15261
15329
|
|
|
15262
15330
|
// ../../packages/eudiplo-config-format/dist/config-values.js
|
|
15331
|
+
var isVariableChar = (char) => char >= "A" && char <= "Z" || char >= "0" && char <= "9" || char === "_";
|
|
15332
|
+
function replacePlaceholders(input, replace) {
|
|
15333
|
+
let output = "";
|
|
15334
|
+
let copied = 0;
|
|
15335
|
+
let start = input.indexOf("${");
|
|
15336
|
+
while (start !== -1) {
|
|
15337
|
+
let cursor = start + 2;
|
|
15338
|
+
while (cursor < input.length && isVariableChar(input[cursor]))
|
|
15339
|
+
cursor++;
|
|
15340
|
+
const variable = input.slice(start + 2, cursor);
|
|
15341
|
+
let end = -1;
|
|
15342
|
+
let fallback;
|
|
15343
|
+
if (variable && input[cursor] === "}")
|
|
15344
|
+
end = cursor;
|
|
15345
|
+
else if (variable && input[cursor] === ":") {
|
|
15346
|
+
end = input.indexOf("}", cursor + 1);
|
|
15347
|
+
if (end === -1)
|
|
15348
|
+
break;
|
|
15349
|
+
fallback = input.slice(cursor + 1, end);
|
|
15350
|
+
}
|
|
15351
|
+
if (end === -1) {
|
|
15352
|
+
start = input.indexOf("${", start + 2);
|
|
15353
|
+
continue;
|
|
15354
|
+
}
|
|
15355
|
+
output += input.slice(copied, start);
|
|
15356
|
+
output += replace(input.slice(start, end + 1), variable, fallback);
|
|
15357
|
+
copied = end + 1;
|
|
15358
|
+
start = input.indexOf("${", copied);
|
|
15359
|
+
}
|
|
15360
|
+
return output + input.slice(copied);
|
|
15361
|
+
}
|
|
15263
15362
|
function resolveConfigVariables(input, env) {
|
|
15264
15363
|
const issues = [];
|
|
15265
15364
|
const seen = /* @__PURE__ */ new WeakMap();
|
|
15266
15365
|
function visit2(value, path2) {
|
|
15267
15366
|
if (typeof value === "string")
|
|
15268
|
-
return value
|
|
15367
|
+
return replacePlaceholders(value, (match, variable, fallback) => {
|
|
15269
15368
|
if (env[variable] !== void 0 && env[variable] !== "")
|
|
15270
15369
|
return env[variable];
|
|
15271
15370
|
if (fallback !== void 0)
|
|
@@ -19970,218 +20069,2357 @@ var CONFIG_SCHEMAS = [
|
|
|
19970
20069
|
"title": "CreateWebhookEndpointDto"
|
|
19971
20070
|
}
|
|
19972
20071
|
}
|
|
19973
|
-
}
|
|
19974
|
-
|
|
19975
|
-
|
|
19976
|
-
|
|
19977
|
-
|
|
19978
|
-
|
|
19979
|
-
|
|
19980
|
-
|
|
19981
|
-
|
|
19982
|
-
|
|
19983
|
-
|
|
19984
|
-
|
|
19985
|
-
|
|
19986
|
-
|
|
19987
|
-
|
|
19988
|
-
|
|
19989
|
-
|
|
19990
|
-
|
|
19991
|
-
|
|
19992
|
-
|
|
19993
|
-
|
|
19994
|
-
|
|
19995
|
-
|
|
19996
|
-
|
|
19997
|
-
|
|
19998
|
-
|
|
19999
|
-
|
|
20000
|
-
|
|
20001
|
-
|
|
20002
|
-
|
|
20003
|
-
|
|
20004
|
-
|
|
20005
|
-
|
|
20006
|
-
|
|
20007
|
-
|
|
20008
|
-
|
|
20009
|
-
|
|
20010
|
-
|
|
20011
|
-
|
|
20012
|
-
|
|
20013
|
-
|
|
20014
|
-
|
|
20015
|
-
|
|
20016
|
-
|
|
20017
|
-
|
|
20018
|
-
|
|
20019
|
-
|
|
20020
|
-
|
|
20021
|
-
|
|
20022
|
-
|
|
20023
|
-
|
|
20024
|
-
|
|
20025
|
-
}
|
|
20026
|
-
|
|
20027
|
-
|
|
20028
|
-
|
|
20029
|
-
|
|
20030
|
-
|
|
20031
|
-
|
|
20032
|
-
|
|
20033
|
-
|
|
20034
|
-
|
|
20035
|
-
|
|
20036
|
-
|
|
20037
|
-
|
|
20038
|
-
|
|
20039
|
-
|
|
20040
|
-
|
|
20041
|
-
|
|
20042
|
-
|
|
20043
|
-
|
|
20044
|
-
|
|
20045
|
-
|
|
20046
|
-
|
|
20047
|
-
|
|
20048
|
-
|
|
20049
|
-
|
|
20050
|
-
|
|
20051
|
-
|
|
20052
|
-
|
|
20053
|
-
|
|
20054
|
-
|
|
20055
|
-
|
|
20056
|
-
|
|
20057
|
-
|
|
20058
|
-
|
|
20059
|
-
|
|
20060
|
-
|
|
20061
|
-
|
|
20062
|
-
|
|
20063
|
-
|
|
20064
|
-
|
|
20065
|
-
|
|
20066
|
-
|
|
20067
|
-
|
|
20068
|
-
|
|
20069
|
-
|
|
20070
|
-
|
|
20071
|
-
|
|
20072
|
-
|
|
20073
|
-
|
|
20074
|
-
|
|
20075
|
-
|
|
20076
|
-
|
|
20077
|
-
|
|
20078
|
-
|
|
20079
|
-
|
|
20080
|
-
|
|
20081
|
-
|
|
20082
|
-
|
|
20083
|
-
|
|
20084
|
-
|
|
20085
|
-
|
|
20086
|
-
|
|
20087
|
-
|
|
20088
|
-
|
|
20089
|
-
|
|
20090
|
-
|
|
20091
|
-
|
|
20092
|
-
|
|
20093
|
-
|
|
20094
|
-
|
|
20095
|
-
|
|
20096
|
-
|
|
20097
|
-
|
|
20098
|
-
|
|
20099
|
-
|
|
20100
|
-
|
|
20101
|
-
|
|
20102
|
-
|
|
20103
|
-
|
|
20104
|
-
|
|
20105
|
-
|
|
20106
|
-
|
|
20107
|
-
|
|
20108
|
-
|
|
20109
|
-
|
|
20110
|
-
|
|
20111
|
-
|
|
20112
|
-
|
|
20113
|
-
|
|
20114
|
-
|
|
20115
|
-
|
|
20116
|
-
|
|
20117
|
-
|
|
20118
|
-
|
|
20119
|
-
|
|
20120
|
-
|
|
20121
|
-
|
|
20122
|
-
|
|
20123
|
-
|
|
20124
|
-
|
|
20125
|
-
|
|
20126
|
-
|
|
20127
|
-
|
|
20128
|
-
|
|
20129
|
-
|
|
20130
|
-
|
|
20131
|
-
|
|
20132
|
-
|
|
20133
|
-
|
|
20134
|
-
|
|
20135
|
-
|
|
20136
|
-
|
|
20137
|
-
|
|
20138
|
-
|
|
20139
|
-
|
|
20140
|
-
|
|
20141
|
-
|
|
20142
|
-
|
|
20143
|
-
|
|
20144
|
-
|
|
20145
|
-
|
|
20146
|
-
|
|
20147
|
-
|
|
20148
|
-
|
|
20149
|
-
|
|
20150
|
-
|
|
20151
|
-
|
|
20152
|
-
|
|
20153
|
-
|
|
20154
|
-
|
|
20155
|
-
|
|
20156
|
-
|
|
20157
|
-
|
|
20158
|
-
|
|
20159
|
-
|
|
20160
|
-
|
|
20161
|
-
|
|
20162
|
-
|
|
20163
|
-
|
|
20164
|
-
|
|
20165
|
-
|
|
20166
|
-
|
|
20167
|
-
|
|
20168
|
-
|
|
20169
|
-
|
|
20170
|
-
|
|
20171
|
-
|
|
20172
|
-
|
|
20173
|
-
|
|
20174
|
-
|
|
20175
|
-
|
|
20176
|
-
|
|
20177
|
-
|
|
20178
|
-
|
|
20179
|
-
|
|
20180
|
-
|
|
20181
|
-
|
|
20182
|
-
|
|
20183
|
-
|
|
20184
|
-
|
|
20072
|
+
},
|
|
20073
|
+
{
|
|
20074
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
20075
|
+
"$id": "https://eudiplo.dev/schemas/v2/IssuanceConfigFile.schema.json",
|
|
20076
|
+
"title": "IssuanceConfigFile",
|
|
20077
|
+
"type": "object",
|
|
20078
|
+
"properties": {
|
|
20079
|
+
"$schema": {
|
|
20080
|
+
"type": "string",
|
|
20081
|
+
"const": "https://eudiplo.dev/schemas/v2/IssuanceConfigFile.schema.json"
|
|
20082
|
+
},
|
|
20083
|
+
"metadata": {
|
|
20084
|
+
"type": "object",
|
|
20085
|
+
"properties": {
|
|
20086
|
+
"generation": {
|
|
20087
|
+
"type": "integer",
|
|
20088
|
+
"minimum": 1,
|
|
20089
|
+
"description": "Monotonically increasing configuration generation."
|
|
20090
|
+
},
|
|
20091
|
+
"ownership": {
|
|
20092
|
+
"type": "string",
|
|
20093
|
+
"enum": [
|
|
20094
|
+
"unmanaged",
|
|
20095
|
+
"file-managed"
|
|
20096
|
+
],
|
|
20097
|
+
"description": "Requested ownership recorded when the document is applied."
|
|
20098
|
+
}
|
|
20099
|
+
},
|
|
20100
|
+
"additionalProperties": false
|
|
20101
|
+
},
|
|
20102
|
+
"spec": {
|
|
20103
|
+
"$ref": "#/$defs/IssuanceConfig"
|
|
20104
|
+
}
|
|
20105
|
+
},
|
|
20106
|
+
"required": [
|
|
20107
|
+
"$schema",
|
|
20108
|
+
"spec"
|
|
20109
|
+
],
|
|
20110
|
+
"additionalProperties": false,
|
|
20111
|
+
"$defs": {
|
|
20112
|
+
"IssuanceConfig": {
|
|
20113
|
+
"type": "object",
|
|
20114
|
+
"properties": {
|
|
20115
|
+
"batchSize": {
|
|
20116
|
+
"description": "Optional issuance batch size.",
|
|
20117
|
+
"type": "integer",
|
|
20118
|
+
"minimum": 1,
|
|
20119
|
+
"maximum": 9007199254740991
|
|
20120
|
+
},
|
|
20121
|
+
"dPopRequired": {
|
|
20122
|
+
"description": "Require DPoP proofs for issuance endpoints.",
|
|
20123
|
+
"type": "boolean"
|
|
20124
|
+
},
|
|
20125
|
+
"walletAttestationRequired": {
|
|
20126
|
+
"description": "Default wallet attestation requirement for managed authorization servers.",
|
|
20127
|
+
"type": "boolean"
|
|
20128
|
+
},
|
|
20129
|
+
"walletProviderTrustLists": {
|
|
20130
|
+
"description": "Shared wallet provider trust lists for key attestations and default authorization server wallet authentication.",
|
|
20131
|
+
"type": "array",
|
|
20132
|
+
"items": {
|
|
20133
|
+
"type": "object",
|
|
20134
|
+
"properties": {
|
|
20135
|
+
"trustListId": {
|
|
20136
|
+
"type": "string",
|
|
20137
|
+
"minLength": 1
|
|
20138
|
+
},
|
|
20139
|
+
"url": {
|
|
20140
|
+
"description": "URL of the wallet provider trust list.",
|
|
20141
|
+
"type": "string",
|
|
20142
|
+
"format": "uri"
|
|
20143
|
+
},
|
|
20144
|
+
"verifierKey": {
|
|
20145
|
+
"description": "Optional verifier key material used for trust list verification.",
|
|
20146
|
+
"type": "object",
|
|
20147
|
+
"propertyNames": {
|
|
20148
|
+
"type": "string"
|
|
20149
|
+
},
|
|
20150
|
+
"additionalProperties": {}
|
|
20151
|
+
},
|
|
20152
|
+
"verifierX509Der": {
|
|
20153
|
+
"description": "Optional verifier certificate in DER/base64 form.",
|
|
20154
|
+
"type": "string"
|
|
20155
|
+
}
|
|
20156
|
+
},
|
|
20157
|
+
"additionalProperties": false
|
|
20158
|
+
}
|
|
20159
|
+
},
|
|
20160
|
+
"signingKeyId": {
|
|
20161
|
+
"description": "Default signing key chain id for credential issuance.",
|
|
20162
|
+
"type": "string",
|
|
20163
|
+
"minLength": 1
|
|
20164
|
+
},
|
|
20165
|
+
"authorizationServers": {
|
|
20166
|
+
"minItems": 1,
|
|
20167
|
+
"type": "array",
|
|
20168
|
+
"items": {
|
|
20169
|
+
"oneOf": [
|
|
20170
|
+
{
|
|
20171
|
+
"type": "object",
|
|
20172
|
+
"properties": {
|
|
20173
|
+
"type": {
|
|
20174
|
+
"type": "string",
|
|
20175
|
+
"const": "external",
|
|
20176
|
+
"description": "Use an externally managed authorization server."
|
|
20177
|
+
},
|
|
20178
|
+
"id": {
|
|
20179
|
+
"type": "string",
|
|
20180
|
+
"minLength": 1,
|
|
20181
|
+
"description": "Authorization server identifier."
|
|
20182
|
+
},
|
|
20183
|
+
"issuer": {
|
|
20184
|
+
"type": "string",
|
|
20185
|
+
"format": "uri",
|
|
20186
|
+
"description": "Issuer URL for the external authorization server."
|
|
20187
|
+
},
|
|
20188
|
+
"sessionBinding": {
|
|
20189
|
+
"description": "Explicit mapping from an external access-token claim to an existing issuance session.",
|
|
20190
|
+
"type": "object",
|
|
20191
|
+
"properties": {
|
|
20192
|
+
"method": {
|
|
20193
|
+
"type": "string",
|
|
20194
|
+
"const": "access_token_claim",
|
|
20195
|
+
"description": "Read the correlation value from a configured access-token claim."
|
|
20196
|
+
},
|
|
20197
|
+
"claim": {
|
|
20198
|
+
"type": "string",
|
|
20199
|
+
"minLength": 1,
|
|
20200
|
+
"description": "Claim name that contains the issuance-session correlation value."
|
|
20201
|
+
}
|
|
20202
|
+
},
|
|
20203
|
+
"required": [
|
|
20204
|
+
"method",
|
|
20205
|
+
"claim"
|
|
20206
|
+
],
|
|
20207
|
+
"additionalProperties": false
|
|
20208
|
+
},
|
|
20209
|
+
"label": {
|
|
20210
|
+
"description": "Optional display label for UI selection.",
|
|
20211
|
+
"type": "string"
|
|
20212
|
+
},
|
|
20213
|
+
"enabled": {
|
|
20214
|
+
"description": "Whether this authorization server entry is enabled.",
|
|
20215
|
+
"type": "boolean"
|
|
20216
|
+
}
|
|
20217
|
+
},
|
|
20218
|
+
"required": [
|
|
20219
|
+
"type",
|
|
20220
|
+
"id",
|
|
20221
|
+
"issuer"
|
|
20222
|
+
],
|
|
20223
|
+
"additionalProperties": false
|
|
20224
|
+
},
|
|
20225
|
+
{
|
|
20226
|
+
"type": "object",
|
|
20227
|
+
"properties": {
|
|
20228
|
+
"type": {
|
|
20229
|
+
"type": "string",
|
|
20230
|
+
"const": "oid4vp",
|
|
20231
|
+
"description": "Use OID4VP-based authorization server chaining."
|
|
20232
|
+
},
|
|
20233
|
+
"id": {
|
|
20234
|
+
"type": "string",
|
|
20235
|
+
"minLength": 1,
|
|
20236
|
+
"description": "Authorization server identifier."
|
|
20237
|
+
},
|
|
20238
|
+
"presentationConfigId": {
|
|
20239
|
+
"type": "string",
|
|
20240
|
+
"minLength": 1,
|
|
20241
|
+
"description": "Presentation configuration id used during authorization."
|
|
20242
|
+
},
|
|
20243
|
+
"immediateWalletRedirect": {
|
|
20244
|
+
"description": "Redirect wallets immediately after authorization response creation.",
|
|
20245
|
+
"type": "boolean"
|
|
20246
|
+
},
|
|
20247
|
+
"token": {
|
|
20248
|
+
"description": "Optional token issuance settings.",
|
|
20249
|
+
"type": "object",
|
|
20250
|
+
"properties": {
|
|
20251
|
+
"lifetimeSeconds": {
|
|
20252
|
+
"description": "Access token lifetime in seconds.",
|
|
20253
|
+
"type": "number",
|
|
20254
|
+
"minimum": 60
|
|
20255
|
+
},
|
|
20256
|
+
"signingKeyId": {
|
|
20257
|
+
"description": "Optional key chain id used to sign issued tokens.",
|
|
20258
|
+
"type": "string",
|
|
20259
|
+
"minLength": 1
|
|
20260
|
+
},
|
|
20261
|
+
"refreshTokenEnabled": {
|
|
20262
|
+
"description": "Enable issuing refresh tokens.",
|
|
20263
|
+
"type": "boolean"
|
|
20264
|
+
},
|
|
20265
|
+
"refreshTokenExpiresInSeconds": {
|
|
20266
|
+
"description": "Refresh token lifetime in seconds.",
|
|
20267
|
+
"type": "number",
|
|
20268
|
+
"minimum": 60
|
|
20269
|
+
}
|
|
20270
|
+
},
|
|
20271
|
+
"additionalProperties": false
|
|
20272
|
+
},
|
|
20273
|
+
"requireDPoP": {
|
|
20274
|
+
"description": "Require DPoP proofs for token/credential requests.",
|
|
20275
|
+
"type": "boolean"
|
|
20276
|
+
},
|
|
20277
|
+
"walletAttestationRequired": {
|
|
20278
|
+
"description": "Require wallet attestation for this authorization server.",
|
|
20279
|
+
"type": "boolean"
|
|
20280
|
+
},
|
|
20281
|
+
"walletProviderTrustLists": {
|
|
20282
|
+
"description": "Optional wallet provider trust list references for this authorization server.",
|
|
20283
|
+
"type": "array",
|
|
20284
|
+
"items": {
|
|
20285
|
+
"type": "object",
|
|
20286
|
+
"properties": {
|
|
20287
|
+
"trustListId": {
|
|
20288
|
+
"type": "string",
|
|
20289
|
+
"minLength": 1
|
|
20290
|
+
},
|
|
20291
|
+
"url": {
|
|
20292
|
+
"description": "URL of the wallet provider trust list.",
|
|
20293
|
+
"type": "string",
|
|
20294
|
+
"format": "uri"
|
|
20295
|
+
},
|
|
20296
|
+
"verifierKey": {
|
|
20297
|
+
"description": "Optional verifier key material used for trust list verification.",
|
|
20298
|
+
"type": "object",
|
|
20299
|
+
"propertyNames": {
|
|
20300
|
+
"type": "string"
|
|
20301
|
+
},
|
|
20302
|
+
"additionalProperties": {}
|
|
20303
|
+
},
|
|
20304
|
+
"verifierX509Der": {
|
|
20305
|
+
"description": "Optional verifier certificate in DER/base64 form.",
|
|
20306
|
+
"type": "string"
|
|
20307
|
+
}
|
|
20308
|
+
},
|
|
20309
|
+
"additionalProperties": false
|
|
20310
|
+
}
|
|
20311
|
+
},
|
|
20312
|
+
"label": {
|
|
20313
|
+
"description": "Optional display label for UI selection.",
|
|
20314
|
+
"type": "string"
|
|
20315
|
+
},
|
|
20316
|
+
"enabled": {
|
|
20317
|
+
"description": "Whether this authorization server entry is enabled.",
|
|
20318
|
+
"type": "boolean"
|
|
20319
|
+
}
|
|
20320
|
+
},
|
|
20321
|
+
"required": [
|
|
20322
|
+
"type",
|
|
20323
|
+
"id",
|
|
20324
|
+
"presentationConfigId"
|
|
20325
|
+
],
|
|
20326
|
+
"additionalProperties": false
|
|
20327
|
+
},
|
|
20328
|
+
{
|
|
20329
|
+
"type": "object",
|
|
20330
|
+
"properties": {
|
|
20331
|
+
"type": {
|
|
20332
|
+
"type": "string",
|
|
20333
|
+
"const": "chained",
|
|
20334
|
+
"description": "Use upstream OIDC as authorization source."
|
|
20335
|
+
},
|
|
20336
|
+
"id": {
|
|
20337
|
+
"type": "string",
|
|
20338
|
+
"minLength": 1,
|
|
20339
|
+
"description": "Authorization server identifier."
|
|
20340
|
+
},
|
|
20341
|
+
"upstream": {
|
|
20342
|
+
"type": "object",
|
|
20343
|
+
"properties": {
|
|
20344
|
+
"issuer": {
|
|
20345
|
+
"type": "string",
|
|
20346
|
+
"format": "uri",
|
|
20347
|
+
"description": "Upstream OIDC issuer URL."
|
|
20348
|
+
},
|
|
20349
|
+
"clientId": {
|
|
20350
|
+
"type": "string",
|
|
20351
|
+
"minLength": 1,
|
|
20352
|
+
"description": "Client id for upstream OIDC authentication."
|
|
20353
|
+
},
|
|
20354
|
+
"clientSecret": {
|
|
20355
|
+
"description": "Optional client secret for upstream OIDC authentication.",
|
|
20356
|
+
"type": "string",
|
|
20357
|
+
"minLength": 1
|
|
20358
|
+
},
|
|
20359
|
+
"scopes": {
|
|
20360
|
+
"description": "Optional scopes requested from the upstream issuer.",
|
|
20361
|
+
"type": "array",
|
|
20362
|
+
"items": {
|
|
20363
|
+
"type": "string",
|
|
20364
|
+
"minLength": 1
|
|
20365
|
+
}
|
|
20366
|
+
}
|
|
20367
|
+
},
|
|
20368
|
+
"required": [
|
|
20369
|
+
"issuer",
|
|
20370
|
+
"clientId"
|
|
20371
|
+
],
|
|
20372
|
+
"additionalProperties": false,
|
|
20373
|
+
"description": "Upstream OIDC connection settings."
|
|
20374
|
+
},
|
|
20375
|
+
"token": {
|
|
20376
|
+
"description": "Optional token issuance settings.",
|
|
20377
|
+
"type": "object",
|
|
20378
|
+
"properties": {
|
|
20379
|
+
"lifetimeSeconds": {
|
|
20380
|
+
"description": "Access token lifetime in seconds.",
|
|
20381
|
+
"type": "number",
|
|
20382
|
+
"minimum": 60
|
|
20383
|
+
},
|
|
20384
|
+
"signingKeyId": {
|
|
20385
|
+
"description": "Optional key chain id used to sign issued tokens.",
|
|
20386
|
+
"type": "string",
|
|
20387
|
+
"minLength": 1
|
|
20388
|
+
},
|
|
20389
|
+
"refreshTokenEnabled": {
|
|
20390
|
+
"description": "Enable issuing refresh tokens.",
|
|
20391
|
+
"type": "boolean"
|
|
20392
|
+
},
|
|
20393
|
+
"refreshTokenExpiresInSeconds": {
|
|
20394
|
+
"description": "Refresh token lifetime in seconds.",
|
|
20395
|
+
"type": "number",
|
|
20396
|
+
"minimum": 60
|
|
20397
|
+
}
|
|
20398
|
+
},
|
|
20399
|
+
"additionalProperties": false
|
|
20400
|
+
},
|
|
20401
|
+
"requireDPoP": {
|
|
20402
|
+
"description": "Require DPoP proofs for token/credential requests.",
|
|
20403
|
+
"type": "boolean"
|
|
20404
|
+
},
|
|
20405
|
+
"walletAttestationRequired": {
|
|
20406
|
+
"description": "Require wallet attestation for this authorization server.",
|
|
20407
|
+
"type": "boolean"
|
|
20408
|
+
},
|
|
20409
|
+
"walletProviderTrustLists": {
|
|
20410
|
+
"description": "Optional wallet provider trust list references for this authorization server.",
|
|
20411
|
+
"type": "array",
|
|
20412
|
+
"items": {
|
|
20413
|
+
"type": "object",
|
|
20414
|
+
"properties": {
|
|
20415
|
+
"trustListId": {
|
|
20416
|
+
"type": "string",
|
|
20417
|
+
"minLength": 1
|
|
20418
|
+
},
|
|
20419
|
+
"url": {
|
|
20420
|
+
"description": "URL of the wallet provider trust list.",
|
|
20421
|
+
"type": "string",
|
|
20422
|
+
"format": "uri"
|
|
20423
|
+
},
|
|
20424
|
+
"verifierKey": {
|
|
20425
|
+
"description": "Optional verifier key material used for trust list verification.",
|
|
20426
|
+
"type": "object",
|
|
20427
|
+
"propertyNames": {
|
|
20428
|
+
"type": "string"
|
|
20429
|
+
},
|
|
20430
|
+
"additionalProperties": {}
|
|
20431
|
+
},
|
|
20432
|
+
"verifierX509Der": {
|
|
20433
|
+
"description": "Optional verifier certificate in DER/base64 form.",
|
|
20434
|
+
"type": "string"
|
|
20435
|
+
}
|
|
20436
|
+
},
|
|
20437
|
+
"additionalProperties": false
|
|
20438
|
+
}
|
|
20439
|
+
},
|
|
20440
|
+
"label": {
|
|
20441
|
+
"description": "Optional display label for UI selection.",
|
|
20442
|
+
"type": "string"
|
|
20443
|
+
},
|
|
20444
|
+
"enabled": {
|
|
20445
|
+
"description": "Whether this authorization server entry is enabled.",
|
|
20446
|
+
"type": "boolean"
|
|
20447
|
+
}
|
|
20448
|
+
},
|
|
20449
|
+
"required": [
|
|
20450
|
+
"type",
|
|
20451
|
+
"id",
|
|
20452
|
+
"upstream"
|
|
20453
|
+
],
|
|
20454
|
+
"additionalProperties": false
|
|
20455
|
+
},
|
|
20456
|
+
{
|
|
20457
|
+
"type": "object",
|
|
20458
|
+
"properties": {
|
|
20459
|
+
"type": {
|
|
20460
|
+
"type": "string",
|
|
20461
|
+
"const": "built-in",
|
|
20462
|
+
"description": "Use EUDIPLO built-in authorization server."
|
|
20463
|
+
},
|
|
20464
|
+
"id": {
|
|
20465
|
+
"type": "string",
|
|
20466
|
+
"minLength": 1,
|
|
20467
|
+
"description": "Authorization server identifier."
|
|
20468
|
+
},
|
|
20469
|
+
"token": {
|
|
20470
|
+
"description": "Optional token issuance settings.",
|
|
20471
|
+
"type": "object",
|
|
20472
|
+
"properties": {
|
|
20473
|
+
"lifetimeSeconds": {
|
|
20474
|
+
"description": "Access token lifetime in seconds.",
|
|
20475
|
+
"type": "number",
|
|
20476
|
+
"minimum": 60
|
|
20477
|
+
},
|
|
20478
|
+
"signingKeyId": {
|
|
20479
|
+
"description": "Optional key chain id used to sign issued tokens.",
|
|
20480
|
+
"type": "string",
|
|
20481
|
+
"minLength": 1
|
|
20482
|
+
},
|
|
20483
|
+
"refreshTokenEnabled": {
|
|
20484
|
+
"description": "Enable issuing refresh tokens.",
|
|
20485
|
+
"type": "boolean"
|
|
20486
|
+
},
|
|
20487
|
+
"refreshTokenExpiresInSeconds": {
|
|
20488
|
+
"description": "Refresh token lifetime in seconds.",
|
|
20489
|
+
"type": "number",
|
|
20490
|
+
"minimum": 60
|
|
20491
|
+
}
|
|
20492
|
+
},
|
|
20493
|
+
"additionalProperties": false
|
|
20494
|
+
},
|
|
20495
|
+
"requireDPoP": {
|
|
20496
|
+
"description": "Require DPoP proofs for token/credential requests.",
|
|
20497
|
+
"type": "boolean"
|
|
20498
|
+
},
|
|
20499
|
+
"walletAttestationRequired": {
|
|
20500
|
+
"description": "Require wallet attestation for this authorization server.",
|
|
20501
|
+
"type": "boolean"
|
|
20502
|
+
},
|
|
20503
|
+
"walletProviderTrustLists": {
|
|
20504
|
+
"description": "Optional wallet provider trust list references for this authorization server.",
|
|
20505
|
+
"type": "array",
|
|
20506
|
+
"items": {
|
|
20507
|
+
"type": "object",
|
|
20508
|
+
"properties": {
|
|
20509
|
+
"trustListId": {
|
|
20510
|
+
"type": "string",
|
|
20511
|
+
"minLength": 1
|
|
20512
|
+
},
|
|
20513
|
+
"url": {
|
|
20514
|
+
"description": "URL of the wallet provider trust list.",
|
|
20515
|
+
"type": "string",
|
|
20516
|
+
"format": "uri"
|
|
20517
|
+
},
|
|
20518
|
+
"verifierKey": {
|
|
20519
|
+
"description": "Optional verifier key material used for trust list verification.",
|
|
20520
|
+
"type": "object",
|
|
20521
|
+
"propertyNames": {
|
|
20522
|
+
"type": "string"
|
|
20523
|
+
},
|
|
20524
|
+
"additionalProperties": {}
|
|
20525
|
+
},
|
|
20526
|
+
"verifierX509Der": {
|
|
20527
|
+
"description": "Optional verifier certificate in DER/base64 form.",
|
|
20528
|
+
"type": "string"
|
|
20529
|
+
}
|
|
20530
|
+
},
|
|
20531
|
+
"additionalProperties": false
|
|
20532
|
+
}
|
|
20533
|
+
},
|
|
20534
|
+
"label": {
|
|
20535
|
+
"description": "Optional display label for UI selection.",
|
|
20536
|
+
"type": "string"
|
|
20537
|
+
},
|
|
20538
|
+
"enabled": {
|
|
20539
|
+
"description": "Whether this authorization server entry is enabled.",
|
|
20540
|
+
"type": "boolean"
|
|
20541
|
+
}
|
|
20542
|
+
},
|
|
20543
|
+
"required": [
|
|
20544
|
+
"type",
|
|
20545
|
+
"id"
|
|
20546
|
+
],
|
|
20547
|
+
"additionalProperties": false
|
|
20548
|
+
}
|
|
20549
|
+
],
|
|
20550
|
+
"description": "Supported authorization server configurations."
|
|
20551
|
+
},
|
|
20552
|
+
"description": "Configured authorization server entries."
|
|
20553
|
+
},
|
|
20554
|
+
"federation": {
|
|
20555
|
+
"description": "Optional OpenID Federation settings.",
|
|
20556
|
+
"anyOf": [
|
|
20557
|
+
{
|
|
20558
|
+
"type": "object",
|
|
20559
|
+
"properties": {
|
|
20560
|
+
"role": {
|
|
20561
|
+
"description": "Federation role for this issuer.",
|
|
20562
|
+
"type": "string",
|
|
20563
|
+
"enum": [
|
|
20564
|
+
"trust_anchor",
|
|
20565
|
+
"intermediate",
|
|
20566
|
+
"leaf"
|
|
20567
|
+
]
|
|
20568
|
+
},
|
|
20569
|
+
"mode": {
|
|
20570
|
+
"description": "Federation operation mode.",
|
|
20571
|
+
"type": "string",
|
|
20572
|
+
"enum": [
|
|
20573
|
+
"federation-only",
|
|
20574
|
+
"hybrid"
|
|
20575
|
+
]
|
|
20576
|
+
},
|
|
20577
|
+
"entityId": {
|
|
20578
|
+
"description": "Optional local federation entity id.",
|
|
20579
|
+
"type": "string"
|
|
20580
|
+
},
|
|
20581
|
+
"enforceSigningPolicy": {
|
|
20582
|
+
"description": "Enforce strict signing policy checks.",
|
|
20583
|
+
"type": "boolean"
|
|
20584
|
+
},
|
|
20585
|
+
"cacheTtlSeconds": {
|
|
20586
|
+
"description": "Cache time-to-live for federation metadata in seconds.",
|
|
20587
|
+
"type": "integer",
|
|
20588
|
+
"minimum": 1,
|
|
20589
|
+
"maximum": 9007199254740991
|
|
20590
|
+
},
|
|
20591
|
+
"trustAnchors": {
|
|
20592
|
+
"type": "array",
|
|
20593
|
+
"items": {
|
|
20594
|
+
"type": "object",
|
|
20595
|
+
"properties": {
|
|
20596
|
+
"entityId": {
|
|
20597
|
+
"type": "string",
|
|
20598
|
+
"minLength": 1,
|
|
20599
|
+
"description": "Federation trust anchor entity id."
|
|
20600
|
+
},
|
|
20601
|
+
"entityConfigurationUri": {
|
|
20602
|
+
"type": "string",
|
|
20603
|
+
"format": "uri",
|
|
20604
|
+
"description": "Entity configuration URI for the trust anchor."
|
|
20605
|
+
}
|
|
20606
|
+
},
|
|
20607
|
+
"required": [
|
|
20608
|
+
"entityId",
|
|
20609
|
+
"entityConfigurationUri"
|
|
20610
|
+
],
|
|
20611
|
+
"additionalProperties": false
|
|
20612
|
+
},
|
|
20613
|
+
"description": "Federation trust anchors."
|
|
20614
|
+
}
|
|
20615
|
+
},
|
|
20616
|
+
"required": [
|
|
20617
|
+
"trustAnchors"
|
|
20618
|
+
],
|
|
20619
|
+
"additionalProperties": false
|
|
20620
|
+
},
|
|
20621
|
+
{
|
|
20622
|
+
"type": "null"
|
|
20623
|
+
}
|
|
20624
|
+
]
|
|
20625
|
+
},
|
|
20626
|
+
"registrationCertificate": {
|
|
20627
|
+
"description": "Optional registration certificate settings.",
|
|
20628
|
+
"anyOf": [
|
|
20629
|
+
{
|
|
20630
|
+
"type": "object",
|
|
20631
|
+
"properties": {
|
|
20632
|
+
"enabled": {
|
|
20633
|
+
"description": "Enable issuer registration certificate support.",
|
|
20634
|
+
"type": "boolean"
|
|
20635
|
+
},
|
|
20636
|
+
"mode": {
|
|
20637
|
+
"description": "How registration certificate data is provided.",
|
|
20638
|
+
"type": "string",
|
|
20639
|
+
"enum": [
|
|
20640
|
+
"import",
|
|
20641
|
+
"generate"
|
|
20642
|
+
]
|
|
20643
|
+
},
|
|
20644
|
+
"jwt": {
|
|
20645
|
+
"description": "Optional registration certificate JWT when using import mode.",
|
|
20646
|
+
"type": "string"
|
|
20647
|
+
},
|
|
20648
|
+
"privacyPolicy": {
|
|
20649
|
+
"description": "Optional privacy policy URI.",
|
|
20650
|
+
"type": "string"
|
|
20651
|
+
},
|
|
20652
|
+
"supportUri": {
|
|
20653
|
+
"description": "Optional support URI.",
|
|
20654
|
+
"type": "string"
|
|
20655
|
+
}
|
|
20656
|
+
},
|
|
20657
|
+
"additionalProperties": false
|
|
20658
|
+
},
|
|
20659
|
+
{
|
|
20660
|
+
"type": "null"
|
|
20661
|
+
}
|
|
20662
|
+
]
|
|
20663
|
+
},
|
|
20664
|
+
"display": {
|
|
20665
|
+
"description": "Localized issuer metadata shown to wallets.",
|
|
20666
|
+
"type": "array",
|
|
20667
|
+
"items": {
|
|
20668
|
+
"type": "object",
|
|
20669
|
+
"properties": {
|
|
20670
|
+
"name": {
|
|
20671
|
+
"description": "Issuer display name.",
|
|
20672
|
+
"type": "string"
|
|
20673
|
+
},
|
|
20674
|
+
"locale": {
|
|
20675
|
+
"description": "Locale tag for this display entry.",
|
|
20676
|
+
"type": "string"
|
|
20677
|
+
},
|
|
20678
|
+
"logo": {
|
|
20679
|
+
"description": "Optional issuer logo metadata.",
|
|
20680
|
+
"type": "object",
|
|
20681
|
+
"properties": {
|
|
20682
|
+
"uri": {
|
|
20683
|
+
"type": "string",
|
|
20684
|
+
"minLength": 1,
|
|
20685
|
+
"description": "Logo URI."
|
|
20686
|
+
},
|
|
20687
|
+
"alt_text": {
|
|
20688
|
+
"description": "Optional localized alternative text.",
|
|
20689
|
+
"type": "string"
|
|
20690
|
+
}
|
|
20691
|
+
},
|
|
20692
|
+
"required": [
|
|
20693
|
+
"uri"
|
|
20694
|
+
],
|
|
20695
|
+
"additionalProperties": {}
|
|
20696
|
+
}
|
|
20697
|
+
},
|
|
20698
|
+
"additionalProperties": {}
|
|
20699
|
+
}
|
|
20700
|
+
},
|
|
20701
|
+
"notificationEndpointEnabled": {
|
|
20702
|
+
"description": "Whether the OID4VCI notification endpoint is exposed for this issuance configuration.",
|
|
20703
|
+
"type": "boolean"
|
|
20704
|
+
},
|
|
20705
|
+
"credentialResponseEncryption": {
|
|
20706
|
+
"description": "Enable encrypted credential responses.",
|
|
20707
|
+
"type": "boolean"
|
|
20708
|
+
},
|
|
20709
|
+
"credentialRequestEncryption": {
|
|
20710
|
+
"description": "Require encrypted credential requests.",
|
|
20711
|
+
"type": "boolean"
|
|
20712
|
+
},
|
|
20713
|
+
"txCodeMaxAttempts": {
|
|
20714
|
+
"description": "Maximum verification attempts for transaction codes. Null resets to defaults.",
|
|
20715
|
+
"anyOf": [
|
|
20716
|
+
{
|
|
20717
|
+
"type": "integer",
|
|
20718
|
+
"minimum": 1,
|
|
20719
|
+
"maximum": 9007199254740991
|
|
20720
|
+
},
|
|
20721
|
+
{
|
|
20722
|
+
"type": "null"
|
|
20723
|
+
}
|
|
20724
|
+
]
|
|
20725
|
+
},
|
|
20726
|
+
"offerLifetimeSeconds": {
|
|
20727
|
+
"description": "Default lifetime of credential offers in seconds. Can be overridden per offer request. Null or unset: offers do not expire.",
|
|
20728
|
+
"anyOf": [
|
|
20729
|
+
{
|
|
20730
|
+
"type": "integer",
|
|
20731
|
+
"minimum": 1,
|
|
20732
|
+
"maximum": 9007199254740991
|
|
20733
|
+
},
|
|
20734
|
+
{
|
|
20735
|
+
"type": "null"
|
|
20736
|
+
}
|
|
20737
|
+
]
|
|
20738
|
+
}
|
|
20739
|
+
},
|
|
20740
|
+
"required": [
|
|
20741
|
+
"authorizationServers"
|
|
20742
|
+
],
|
|
20743
|
+
"additionalProperties": false,
|
|
20744
|
+
"title": "IssuanceConfig"
|
|
20745
|
+
}
|
|
20746
|
+
}
|
|
20747
|
+
},
|
|
20748
|
+
{
|
|
20749
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
20750
|
+
"$id": "https://eudiplo.dev/schemas/v2/PresentationConfigFile.schema.json",
|
|
20751
|
+
"title": "PresentationConfigFile",
|
|
20752
|
+
"type": "object",
|
|
20753
|
+
"properties": {
|
|
20754
|
+
"$schema": {
|
|
20755
|
+
"type": "string",
|
|
20756
|
+
"const": "https://eudiplo.dev/schemas/v2/PresentationConfigFile.schema.json"
|
|
20757
|
+
},
|
|
20758
|
+
"metadata": {
|
|
20759
|
+
"type": "object",
|
|
20760
|
+
"properties": {
|
|
20761
|
+
"generation": {
|
|
20762
|
+
"type": "integer",
|
|
20763
|
+
"minimum": 1,
|
|
20764
|
+
"description": "Monotonically increasing configuration generation."
|
|
20765
|
+
},
|
|
20766
|
+
"ownership": {
|
|
20767
|
+
"type": "string",
|
|
20768
|
+
"enum": [
|
|
20769
|
+
"unmanaged",
|
|
20770
|
+
"file-managed"
|
|
20771
|
+
],
|
|
20772
|
+
"description": "Requested ownership recorded when the document is applied."
|
|
20773
|
+
}
|
|
20774
|
+
},
|
|
20775
|
+
"additionalProperties": false
|
|
20776
|
+
},
|
|
20777
|
+
"spec": {
|
|
20778
|
+
"allOf": [
|
|
20779
|
+
{
|
|
20780
|
+
"$ref": "#/$defs/PresentationConfigCreateDto"
|
|
20781
|
+
},
|
|
20782
|
+
{
|
|
20783
|
+
"type": "object",
|
|
20784
|
+
"required": [
|
|
20785
|
+
"id"
|
|
20786
|
+
],
|
|
20787
|
+
"properties": {
|
|
20788
|
+
"id": {
|
|
20789
|
+
"type": "string",
|
|
20790
|
+
"minLength": 1
|
|
20791
|
+
}
|
|
20792
|
+
}
|
|
20793
|
+
}
|
|
20794
|
+
]
|
|
20795
|
+
}
|
|
20796
|
+
},
|
|
20797
|
+
"required": [
|
|
20798
|
+
"$schema",
|
|
20799
|
+
"spec"
|
|
20800
|
+
],
|
|
20801
|
+
"additionalProperties": false,
|
|
20802
|
+
"$defs": {
|
|
20803
|
+
"PresentationConfigCreateDto": {
|
|
20804
|
+
"type": "object",
|
|
20805
|
+
"properties": {
|
|
20806
|
+
"id": {
|
|
20807
|
+
"type": "string",
|
|
20808
|
+
"minLength": 1,
|
|
20809
|
+
"description": "Presentation configuration identifier."
|
|
20810
|
+
},
|
|
20811
|
+
"description": {
|
|
20812
|
+
"description": "Optional presentation configuration description.",
|
|
20813
|
+
"type": [
|
|
20814
|
+
"string",
|
|
20815
|
+
"null"
|
|
20816
|
+
]
|
|
20817
|
+
},
|
|
20818
|
+
"lifeTime": {
|
|
20819
|
+
"description": "Presentation request lifetime in seconds.",
|
|
20820
|
+
"type": "integer",
|
|
20821
|
+
"minimum": 1,
|
|
20822
|
+
"maximum": 9007199254740991
|
|
20823
|
+
},
|
|
20824
|
+
"skewSeconds": {
|
|
20825
|
+
"description": "Clock skew tolerance in seconds.",
|
|
20826
|
+
"type": "integer",
|
|
20827
|
+
"minimum": 0,
|
|
20828
|
+
"maximum": 9007199254740991
|
|
20829
|
+
},
|
|
20830
|
+
"statusCheckMode": {
|
|
20831
|
+
"description": "Revocation/status check mode.",
|
|
20832
|
+
"type": "string",
|
|
20833
|
+
"enum": [
|
|
20834
|
+
"strict",
|
|
20835
|
+
"best_effort",
|
|
20836
|
+
"disabled"
|
|
20837
|
+
]
|
|
20838
|
+
},
|
|
20839
|
+
"dcql_query": {
|
|
20840
|
+
"type": "object",
|
|
20841
|
+
"properties": {
|
|
20842
|
+
"credentials": {
|
|
20843
|
+
"minItems": 1,
|
|
20844
|
+
"type": "array",
|
|
20845
|
+
"items": {
|
|
20846
|
+
"oneOf": [
|
|
20847
|
+
{
|
|
20848
|
+
"type": "object",
|
|
20849
|
+
"properties": {
|
|
20850
|
+
"id": {
|
|
20851
|
+
"type": "string",
|
|
20852
|
+
"minLength": 1,
|
|
20853
|
+
"pattern": "^[A-Za-z0-9_-]+$",
|
|
20854
|
+
"description": "Credential query identifier."
|
|
20855
|
+
},
|
|
20856
|
+
"multiple": {
|
|
20857
|
+
"description": "Allow multiple matching credentials.",
|
|
20858
|
+
"type": "boolean"
|
|
20859
|
+
},
|
|
20860
|
+
"claim_sets": {
|
|
20861
|
+
"description": "Optional claim set constraints.",
|
|
20862
|
+
"type": "array",
|
|
20863
|
+
"items": {
|
|
20864
|
+
"type": "array",
|
|
20865
|
+
"items": {
|
|
20866
|
+
"type": "string"
|
|
20867
|
+
}
|
|
20868
|
+
}
|
|
20869
|
+
},
|
|
20870
|
+
"trusted_authorities": {
|
|
20871
|
+
"description": "Optional trusted authority constraints.",
|
|
20872
|
+
"type": "array",
|
|
20873
|
+
"items": {
|
|
20874
|
+
"oneOf": [
|
|
20875
|
+
{
|
|
20876
|
+
"type": "object",
|
|
20877
|
+
"properties": {
|
|
20878
|
+
"type": {
|
|
20879
|
+
"type": "string",
|
|
20880
|
+
"const": "etsi_tl",
|
|
20881
|
+
"description": "Trusted authority type discriminator for ETSI trust lists."
|
|
20882
|
+
},
|
|
20883
|
+
"values": {
|
|
20884
|
+
"type": "array",
|
|
20885
|
+
"items": {
|
|
20886
|
+
"type": "object",
|
|
20887
|
+
"properties": {
|
|
20888
|
+
"trustListId": {
|
|
20889
|
+
"description": "Optional trust list id reference.",
|
|
20890
|
+
"type": "string"
|
|
20891
|
+
},
|
|
20892
|
+
"url": {
|
|
20893
|
+
"description": "Optional trust list URL reference.",
|
|
20894
|
+
"anyOf": [
|
|
20895
|
+
{
|
|
20896
|
+
"type": "string",
|
|
20897
|
+
"format": "uri"
|
|
20898
|
+
},
|
|
20899
|
+
{
|
|
20900
|
+
"type": "string",
|
|
20901
|
+
"pattern": "^<TENANT_URL>(?:\\/.*)?$"
|
|
20902
|
+
}
|
|
20903
|
+
]
|
|
20904
|
+
},
|
|
20905
|
+
"verifierKey": {
|
|
20906
|
+
"description": "Optional verifier key material.",
|
|
20907
|
+
"type": "object",
|
|
20908
|
+
"propertyNames": {
|
|
20909
|
+
"type": "string"
|
|
20910
|
+
},
|
|
20911
|
+
"additionalProperties": {}
|
|
20912
|
+
},
|
|
20913
|
+
"verifierX509Der": {
|
|
20914
|
+
"description": "Optional verifier certificate in DER/base64 form.",
|
|
20915
|
+
"type": "string"
|
|
20916
|
+
}
|
|
20917
|
+
},
|
|
20918
|
+
"additionalProperties": false
|
|
20919
|
+
},
|
|
20920
|
+
"description": "Trust list references for ETSI TL verification."
|
|
20921
|
+
}
|
|
20922
|
+
},
|
|
20923
|
+
"required": [
|
|
20924
|
+
"type",
|
|
20925
|
+
"values"
|
|
20926
|
+
],
|
|
20927
|
+
"additionalProperties": false
|
|
20928
|
+
},
|
|
20929
|
+
{
|
|
20930
|
+
"type": "object",
|
|
20931
|
+
"properties": {
|
|
20932
|
+
"type": {
|
|
20933
|
+
"type": "string",
|
|
20934
|
+
"const": "openid_federation",
|
|
20935
|
+
"description": "Trusted authority type discriminator for OpenID Federation."
|
|
20936
|
+
},
|
|
20937
|
+
"values": {
|
|
20938
|
+
"type": "array",
|
|
20939
|
+
"items": {
|
|
20940
|
+
"type": "string"
|
|
20941
|
+
},
|
|
20942
|
+
"description": "OpenID Federation authority identifiers."
|
|
20943
|
+
}
|
|
20944
|
+
},
|
|
20945
|
+
"required": [
|
|
20946
|
+
"type",
|
|
20947
|
+
"values"
|
|
20948
|
+
],
|
|
20949
|
+
"additionalProperties": false
|
|
20950
|
+
}
|
|
20951
|
+
]
|
|
20952
|
+
}
|
|
20953
|
+
},
|
|
20954
|
+
"format": {
|
|
20955
|
+
"type": "string",
|
|
20956
|
+
"const": "dc+sd-jwt",
|
|
20957
|
+
"description": "Credential format discriminator."
|
|
20958
|
+
},
|
|
20959
|
+
"meta": {
|
|
20960
|
+
"type": "object",
|
|
20961
|
+
"properties": {
|
|
20962
|
+
"vct_values": {
|
|
20963
|
+
"minItems": 1,
|
|
20964
|
+
"type": "array",
|
|
20965
|
+
"items": {
|
|
20966
|
+
"type": "string"
|
|
20967
|
+
},
|
|
20968
|
+
"description": "Accepted VCT values."
|
|
20969
|
+
}
|
|
20970
|
+
},
|
|
20971
|
+
"required": [
|
|
20972
|
+
"vct_values"
|
|
20973
|
+
],
|
|
20974
|
+
"additionalProperties": false
|
|
20975
|
+
},
|
|
20976
|
+
"claims": {
|
|
20977
|
+
"description": "Optional claim-level constraints.",
|
|
20978
|
+
"type": "array",
|
|
20979
|
+
"items": {
|
|
20980
|
+
"type": "object",
|
|
20981
|
+
"properties": {
|
|
20982
|
+
"id": {
|
|
20983
|
+
"description": "Optional claim query id.",
|
|
20984
|
+
"type": "string"
|
|
20985
|
+
},
|
|
20986
|
+
"path": {
|
|
20987
|
+
"type": "array",
|
|
20988
|
+
"items": {
|
|
20989
|
+
"type": [
|
|
20990
|
+
"string",
|
|
20991
|
+
"number"
|
|
20992
|
+
]
|
|
20993
|
+
},
|
|
20994
|
+
"description": "Path to the claim value in presented credentials."
|
|
20995
|
+
},
|
|
20996
|
+
"values": {
|
|
20997
|
+
"description": "Optional allowed values for the claim.",
|
|
20998
|
+
"type": "array",
|
|
20999
|
+
"items": {
|
|
21000
|
+
"type": "string"
|
|
21001
|
+
}
|
|
21002
|
+
}
|
|
21003
|
+
},
|
|
21004
|
+
"required": [
|
|
21005
|
+
"path"
|
|
21006
|
+
],
|
|
21007
|
+
"additionalProperties": false
|
|
21008
|
+
}
|
|
21009
|
+
}
|
|
21010
|
+
},
|
|
21011
|
+
"required": [
|
|
21012
|
+
"id",
|
|
21013
|
+
"format",
|
|
21014
|
+
"meta"
|
|
21015
|
+
],
|
|
21016
|
+
"additionalProperties": false
|
|
21017
|
+
},
|
|
21018
|
+
{
|
|
21019
|
+
"type": "object",
|
|
21020
|
+
"properties": {
|
|
21021
|
+
"id": {
|
|
21022
|
+
"type": "string",
|
|
21023
|
+
"minLength": 1,
|
|
21024
|
+
"pattern": "^[A-Za-z0-9_-]+$",
|
|
21025
|
+
"description": "Credential query identifier."
|
|
21026
|
+
},
|
|
21027
|
+
"multiple": {
|
|
21028
|
+
"description": "Allow multiple matching credentials.",
|
|
21029
|
+
"type": "boolean"
|
|
21030
|
+
},
|
|
21031
|
+
"claim_sets": {
|
|
21032
|
+
"description": "Optional claim set constraints.",
|
|
21033
|
+
"type": "array",
|
|
21034
|
+
"items": {
|
|
21035
|
+
"type": "array",
|
|
21036
|
+
"items": {
|
|
21037
|
+
"type": "string"
|
|
21038
|
+
}
|
|
21039
|
+
}
|
|
21040
|
+
},
|
|
21041
|
+
"trusted_authorities": {
|
|
21042
|
+
"description": "Optional trusted authority constraints.",
|
|
21043
|
+
"type": "array",
|
|
21044
|
+
"items": {
|
|
21045
|
+
"oneOf": [
|
|
21046
|
+
{
|
|
21047
|
+
"type": "object",
|
|
21048
|
+
"properties": {
|
|
21049
|
+
"type": {
|
|
21050
|
+
"type": "string",
|
|
21051
|
+
"const": "etsi_tl",
|
|
21052
|
+
"description": "Trusted authority type discriminator for ETSI trust lists."
|
|
21053
|
+
},
|
|
21054
|
+
"values": {
|
|
21055
|
+
"type": "array",
|
|
21056
|
+
"items": {
|
|
21057
|
+
"type": "object",
|
|
21058
|
+
"properties": {
|
|
21059
|
+
"trustListId": {
|
|
21060
|
+
"description": "Optional trust list id reference.",
|
|
21061
|
+
"type": "string"
|
|
21062
|
+
},
|
|
21063
|
+
"url": {
|
|
21064
|
+
"description": "Optional trust list URL reference.",
|
|
21065
|
+
"anyOf": [
|
|
21066
|
+
{
|
|
21067
|
+
"type": "string",
|
|
21068
|
+
"format": "uri"
|
|
21069
|
+
},
|
|
21070
|
+
{
|
|
21071
|
+
"type": "string",
|
|
21072
|
+
"pattern": "^<TENANT_URL>(?:\\/.*)?$"
|
|
21073
|
+
}
|
|
21074
|
+
]
|
|
21075
|
+
},
|
|
21076
|
+
"verifierKey": {
|
|
21077
|
+
"description": "Optional verifier key material.",
|
|
21078
|
+
"type": "object",
|
|
21079
|
+
"propertyNames": {
|
|
21080
|
+
"type": "string"
|
|
21081
|
+
},
|
|
21082
|
+
"additionalProperties": {}
|
|
21083
|
+
},
|
|
21084
|
+
"verifierX509Der": {
|
|
21085
|
+
"description": "Optional verifier certificate in DER/base64 form.",
|
|
21086
|
+
"type": "string"
|
|
21087
|
+
}
|
|
21088
|
+
},
|
|
21089
|
+
"additionalProperties": false
|
|
21090
|
+
},
|
|
21091
|
+
"description": "Trust list references for ETSI TL verification."
|
|
21092
|
+
}
|
|
21093
|
+
},
|
|
21094
|
+
"required": [
|
|
21095
|
+
"type",
|
|
21096
|
+
"values"
|
|
21097
|
+
],
|
|
21098
|
+
"additionalProperties": false
|
|
21099
|
+
},
|
|
21100
|
+
{
|
|
21101
|
+
"type": "object",
|
|
21102
|
+
"properties": {
|
|
21103
|
+
"type": {
|
|
21104
|
+
"type": "string",
|
|
21105
|
+
"const": "openid_federation",
|
|
21106
|
+
"description": "Trusted authority type discriminator for OpenID Federation."
|
|
21107
|
+
},
|
|
21108
|
+
"values": {
|
|
21109
|
+
"type": "array",
|
|
21110
|
+
"items": {
|
|
21111
|
+
"type": "string"
|
|
21112
|
+
},
|
|
21113
|
+
"description": "OpenID Federation authority identifiers."
|
|
21114
|
+
}
|
|
21115
|
+
},
|
|
21116
|
+
"required": [
|
|
21117
|
+
"type",
|
|
21118
|
+
"values"
|
|
21119
|
+
],
|
|
21120
|
+
"additionalProperties": false
|
|
21121
|
+
}
|
|
21122
|
+
]
|
|
21123
|
+
}
|
|
21124
|
+
},
|
|
21125
|
+
"format": {
|
|
21126
|
+
"type": "string",
|
|
21127
|
+
"const": "mso_mdoc",
|
|
21128
|
+
"description": "Credential format discriminator."
|
|
21129
|
+
},
|
|
21130
|
+
"meta": {
|
|
21131
|
+
"type": "object",
|
|
21132
|
+
"properties": {
|
|
21133
|
+
"doctype_value": {
|
|
21134
|
+
"type": "string",
|
|
21135
|
+
"minLength": 1,
|
|
21136
|
+
"description": "Expected mDoc doctype value."
|
|
21137
|
+
}
|
|
21138
|
+
},
|
|
21139
|
+
"required": [
|
|
21140
|
+
"doctype_value"
|
|
21141
|
+
],
|
|
21142
|
+
"additionalProperties": false
|
|
21143
|
+
},
|
|
21144
|
+
"claims": {
|
|
21145
|
+
"description": "Optional mDoc claim-level constraints.",
|
|
21146
|
+
"type": "array",
|
|
21147
|
+
"items": {
|
|
21148
|
+
"type": "object",
|
|
21149
|
+
"properties": {
|
|
21150
|
+
"id": {
|
|
21151
|
+
"description": "Optional claim query id.",
|
|
21152
|
+
"type": "string"
|
|
21153
|
+
},
|
|
21154
|
+
"path": {
|
|
21155
|
+
"type": "array",
|
|
21156
|
+
"items": {
|
|
21157
|
+
"type": [
|
|
21158
|
+
"string",
|
|
21159
|
+
"number"
|
|
21160
|
+
]
|
|
21161
|
+
},
|
|
21162
|
+
"description": "Path to the claim value in presented credentials."
|
|
21163
|
+
},
|
|
21164
|
+
"values": {
|
|
21165
|
+
"description": "Optional allowed values for the claim.",
|
|
21166
|
+
"type": "array",
|
|
21167
|
+
"items": {
|
|
21168
|
+
"type": "string"
|
|
21169
|
+
}
|
|
21170
|
+
},
|
|
21171
|
+
"intent_to_retain": {
|
|
21172
|
+
"description": "Whether relying party intends to retain the claim.",
|
|
21173
|
+
"type": "boolean"
|
|
21174
|
+
}
|
|
21175
|
+
},
|
|
21176
|
+
"required": [
|
|
21177
|
+
"path"
|
|
21178
|
+
],
|
|
21179
|
+
"additionalProperties": false
|
|
21180
|
+
}
|
|
21181
|
+
}
|
|
21182
|
+
},
|
|
21183
|
+
"required": [
|
|
21184
|
+
"id",
|
|
21185
|
+
"format",
|
|
21186
|
+
"meta"
|
|
21187
|
+
],
|
|
21188
|
+
"additionalProperties": false
|
|
21189
|
+
}
|
|
21190
|
+
]
|
|
21191
|
+
},
|
|
21192
|
+
"description": "Credential queries requested by the verifier."
|
|
21193
|
+
},
|
|
21194
|
+
"credential_sets": {
|
|
21195
|
+
"description": "Optional higher-level credential set requirements.",
|
|
21196
|
+
"type": "array",
|
|
21197
|
+
"items": {
|
|
21198
|
+
"type": "object",
|
|
21199
|
+
"properties": {
|
|
21200
|
+
"options": {
|
|
21201
|
+
"minItems": 1,
|
|
21202
|
+
"type": "array",
|
|
21203
|
+
"items": {
|
|
21204
|
+
"minItems": 1,
|
|
21205
|
+
"type": "array",
|
|
21206
|
+
"items": {
|
|
21207
|
+
"type": "string"
|
|
21208
|
+
}
|
|
21209
|
+
},
|
|
21210
|
+
"description": "Alternative credential query id combinations."
|
|
21211
|
+
},
|
|
21212
|
+
"required": {
|
|
21213
|
+
"description": "Whether this credential set is mandatory.",
|
|
21214
|
+
"type": "boolean"
|
|
21215
|
+
}
|
|
21216
|
+
},
|
|
21217
|
+
"required": [
|
|
21218
|
+
"options"
|
|
21219
|
+
],
|
|
21220
|
+
"additionalProperties": false
|
|
21221
|
+
}
|
|
21222
|
+
}
|
|
21223
|
+
},
|
|
21224
|
+
"required": [
|
|
21225
|
+
"credentials"
|
|
21226
|
+
],
|
|
21227
|
+
"additionalProperties": false,
|
|
21228
|
+
"description": "DCQL query defining requested credentials and claims."
|
|
21229
|
+
},
|
|
21230
|
+
"transaction_data": {
|
|
21231
|
+
"description": "Optional transaction data descriptors.",
|
|
21232
|
+
"anyOf": [
|
|
21233
|
+
{
|
|
21234
|
+
"type": "array",
|
|
21235
|
+
"items": {
|
|
21236
|
+
"type": "object",
|
|
21237
|
+
"properties": {
|
|
21238
|
+
"type": {
|
|
21239
|
+
"type": "string",
|
|
21240
|
+
"description": "Transaction data type identifier."
|
|
21241
|
+
},
|
|
21242
|
+
"credential_ids": {
|
|
21243
|
+
"type": "array",
|
|
21244
|
+
"items": {
|
|
21245
|
+
"type": "string"
|
|
21246
|
+
},
|
|
21247
|
+
"description": "Credential query ids this transaction data applies to."
|
|
21248
|
+
},
|
|
21249
|
+
"payload": {
|
|
21250
|
+
"description": "Transaction details. Required for TS12 SCA transaction data."
|
|
21251
|
+
}
|
|
21252
|
+
},
|
|
21253
|
+
"required": [
|
|
21254
|
+
"type",
|
|
21255
|
+
"credential_ids"
|
|
21256
|
+
],
|
|
21257
|
+
"additionalProperties": {}
|
|
21258
|
+
}
|
|
21259
|
+
},
|
|
21260
|
+
{
|
|
21261
|
+
"type": "null"
|
|
21262
|
+
}
|
|
21263
|
+
]
|
|
21264
|
+
},
|
|
21265
|
+
"registration_cert": {
|
|
21266
|
+
"description": "Optional registration certificate request settings.",
|
|
21267
|
+
"anyOf": [
|
|
21268
|
+
{
|
|
21269
|
+
"type": "object",
|
|
21270
|
+
"properties": {
|
|
21271
|
+
"id": {
|
|
21272
|
+
"type": "string"
|
|
21273
|
+
},
|
|
21274
|
+
"body": {
|
|
21275
|
+
"type": "object",
|
|
21276
|
+
"properties": {
|
|
21277
|
+
"privacy_policy": {
|
|
21278
|
+
"type": "string"
|
|
21279
|
+
},
|
|
21280
|
+
"support_uri": {
|
|
21281
|
+
"type": "string"
|
|
21282
|
+
},
|
|
21283
|
+
"intermediary": {
|
|
21284
|
+
"type": "string"
|
|
21285
|
+
},
|
|
21286
|
+
"purpose": {
|
|
21287
|
+
"type": "array",
|
|
21288
|
+
"items": {
|
|
21289
|
+
"type": "object",
|
|
21290
|
+
"properties": {
|
|
21291
|
+
"lang": {
|
|
21292
|
+
"type": "string"
|
|
21293
|
+
},
|
|
21294
|
+
"content": {
|
|
21295
|
+
"type": "string"
|
|
21296
|
+
}
|
|
21297
|
+
},
|
|
21298
|
+
"required": [
|
|
21299
|
+
"lang",
|
|
21300
|
+
"content"
|
|
21301
|
+
],
|
|
21302
|
+
"additionalProperties": false
|
|
21303
|
+
}
|
|
21304
|
+
},
|
|
21305
|
+
"credentials": {
|
|
21306
|
+
"type": "array",
|
|
21307
|
+
"items": {
|
|
21308
|
+
"type": "object",
|
|
21309
|
+
"propertyNames": {
|
|
21310
|
+
"type": "string"
|
|
21311
|
+
},
|
|
21312
|
+
"additionalProperties": {}
|
|
21313
|
+
}
|
|
21314
|
+
},
|
|
21315
|
+
"provides_attestations": {
|
|
21316
|
+
"type": "array",
|
|
21317
|
+
"items": {
|
|
21318
|
+
"type": "string",
|
|
21319
|
+
"minLength": 1
|
|
21320
|
+
}
|
|
21321
|
+
}
|
|
21322
|
+
},
|
|
21323
|
+
"additionalProperties": false
|
|
21324
|
+
},
|
|
21325
|
+
"jwt": {
|
|
21326
|
+
"type": "string"
|
|
21327
|
+
}
|
|
21328
|
+
},
|
|
21329
|
+
"additionalProperties": false
|
|
21330
|
+
},
|
|
21331
|
+
{
|
|
21332
|
+
"type": "null"
|
|
21333
|
+
}
|
|
21334
|
+
]
|
|
21335
|
+
},
|
|
21336
|
+
"registrationCertImportJwt": {
|
|
21337
|
+
"description": "Optional imported registration certificate JWT.",
|
|
21338
|
+
"type": [
|
|
21339
|
+
"string",
|
|
21340
|
+
"null"
|
|
21341
|
+
]
|
|
21342
|
+
},
|
|
21343
|
+
"registrationCertImportId": {
|
|
21344
|
+
"description": "Optional registrar-side registration certificate id.",
|
|
21345
|
+
"type": [
|
|
21346
|
+
"string",
|
|
21347
|
+
"null"
|
|
21348
|
+
]
|
|
21349
|
+
},
|
|
21350
|
+
"registrationCertBodyPrivacyPolicy": {
|
|
21351
|
+
"description": "Optional registration certificate privacy policy URI.",
|
|
21352
|
+
"type": [
|
|
21353
|
+
"string",
|
|
21354
|
+
"null"
|
|
21355
|
+
]
|
|
21356
|
+
},
|
|
21357
|
+
"registrationCertBodySupportUri": {
|
|
21358
|
+
"description": "Optional registration certificate support URI.",
|
|
21359
|
+
"type": [
|
|
21360
|
+
"string",
|
|
21361
|
+
"null"
|
|
21362
|
+
]
|
|
21363
|
+
},
|
|
21364
|
+
"registrationCertBodyIntermediary": {
|
|
21365
|
+
"description": "Optional registration certificate intermediary.",
|
|
21366
|
+
"type": [
|
|
21367
|
+
"string",
|
|
21368
|
+
"null"
|
|
21369
|
+
]
|
|
21370
|
+
},
|
|
21371
|
+
"registrationCertBodyPurpose": {
|
|
21372
|
+
"description": "Optional registration certificate purpose entries.",
|
|
21373
|
+
"anyOf": [
|
|
21374
|
+
{
|
|
21375
|
+
"type": "array",
|
|
21376
|
+
"items": {
|
|
21377
|
+
"type": "object",
|
|
21378
|
+
"properties": {
|
|
21379
|
+
"lang": {
|
|
21380
|
+
"type": "string"
|
|
21381
|
+
},
|
|
21382
|
+
"content": {
|
|
21383
|
+
"type": "string"
|
|
21384
|
+
}
|
|
21385
|
+
},
|
|
21386
|
+
"additionalProperties": false
|
|
21387
|
+
}
|
|
21388
|
+
},
|
|
21389
|
+
{
|
|
21390
|
+
"type": "null"
|
|
21391
|
+
}
|
|
21392
|
+
]
|
|
21393
|
+
},
|
|
21394
|
+
"webhookEndpointId": {
|
|
21395
|
+
"description": "Optional webhook endpoint id for presentation callbacks.",
|
|
21396
|
+
"type": [
|
|
21397
|
+
"string",
|
|
21398
|
+
"null"
|
|
21399
|
+
]
|
|
21400
|
+
},
|
|
21401
|
+
"attached": {
|
|
21402
|
+
"description": "Optional attachments included with presentation requests.",
|
|
21403
|
+
"anyOf": [
|
|
21404
|
+
{
|
|
21405
|
+
"type": "array",
|
|
21406
|
+
"items": {
|
|
21407
|
+
"type": "object",
|
|
21408
|
+
"properties": {
|
|
21409
|
+
"format": {
|
|
21410
|
+
"type": "string",
|
|
21411
|
+
"description": "Attachment format identifier."
|
|
21412
|
+
},
|
|
21413
|
+
"data": {
|
|
21414
|
+
"description": "Attachment payload."
|
|
21415
|
+
},
|
|
21416
|
+
"credential_ids": {
|
|
21417
|
+
"description": "Optional credential query ids bound to this attachment.",
|
|
21418
|
+
"type": "array",
|
|
21419
|
+
"items": {
|
|
21420
|
+
"type": "string"
|
|
21421
|
+
}
|
|
21422
|
+
}
|
|
21423
|
+
},
|
|
21424
|
+
"required": [
|
|
21425
|
+
"format",
|
|
21426
|
+
"data"
|
|
21427
|
+
],
|
|
21428
|
+
"additionalProperties": false
|
|
21429
|
+
}
|
|
21430
|
+
},
|
|
21431
|
+
{
|
|
21432
|
+
"type": "null"
|
|
21433
|
+
}
|
|
21434
|
+
]
|
|
21435
|
+
},
|
|
21436
|
+
"redirectUri": {
|
|
21437
|
+
"description": "Optional redirect URI after presentation completion.",
|
|
21438
|
+
"type": [
|
|
21439
|
+
"string",
|
|
21440
|
+
"null"
|
|
21441
|
+
]
|
|
21442
|
+
},
|
|
21443
|
+
"accessKeyChainId": {
|
|
21444
|
+
"description": "Optional key chain id for access token/auth operations.",
|
|
21445
|
+
"type": [
|
|
21446
|
+
"string",
|
|
21447
|
+
"null"
|
|
21448
|
+
]
|
|
21449
|
+
},
|
|
21450
|
+
"readerAuth": {
|
|
21451
|
+
"description": "Whether reader authentication is required for mDoc requests.",
|
|
21452
|
+
"type": [
|
|
21453
|
+
"boolean",
|
|
21454
|
+
"null"
|
|
21455
|
+
]
|
|
21456
|
+
}
|
|
21457
|
+
},
|
|
21458
|
+
"required": [
|
|
21459
|
+
"id",
|
|
21460
|
+
"dcql_query"
|
|
21461
|
+
],
|
|
21462
|
+
"additionalProperties": false,
|
|
21463
|
+
"title": "PresentationConfigCreateDto"
|
|
21464
|
+
}
|
|
21465
|
+
}
|
|
21466
|
+
},
|
|
21467
|
+
{
|
|
21468
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
21469
|
+
"$id": "https://eudiplo.dev/schemas/v3/PresentationConfigFile.schema.json",
|
|
21470
|
+
"title": "PresentationConfigFile",
|
|
21471
|
+
"type": "object",
|
|
21472
|
+
"properties": {
|
|
21473
|
+
"$schema": {
|
|
21474
|
+
"type": "string",
|
|
21475
|
+
"const": "https://eudiplo.dev/schemas/v3/PresentationConfigFile.schema.json"
|
|
21476
|
+
},
|
|
21477
|
+
"metadata": {
|
|
21478
|
+
"type": "object",
|
|
21479
|
+
"properties": {
|
|
21480
|
+
"generation": {
|
|
21481
|
+
"type": "integer",
|
|
21482
|
+
"minimum": 1,
|
|
21483
|
+
"description": "Monotonically increasing configuration generation."
|
|
21484
|
+
},
|
|
21485
|
+
"ownership": {
|
|
21486
|
+
"type": "string",
|
|
21487
|
+
"enum": [
|
|
21488
|
+
"unmanaged",
|
|
21489
|
+
"file-managed"
|
|
21490
|
+
],
|
|
21491
|
+
"description": "Requested ownership recorded when the document is applied."
|
|
21492
|
+
}
|
|
21493
|
+
},
|
|
21494
|
+
"additionalProperties": false
|
|
21495
|
+
},
|
|
21496
|
+
"spec": {
|
|
21497
|
+
"allOf": [
|
|
21498
|
+
{
|
|
21499
|
+
"$ref": "#/$defs/PresentationConfigCreateDto"
|
|
21500
|
+
},
|
|
21501
|
+
{
|
|
21502
|
+
"type": "object",
|
|
21503
|
+
"required": [
|
|
21504
|
+
"id"
|
|
21505
|
+
],
|
|
21506
|
+
"properties": {
|
|
21507
|
+
"id": {
|
|
21508
|
+
"type": "string",
|
|
21509
|
+
"minLength": 1
|
|
21510
|
+
}
|
|
21511
|
+
}
|
|
21512
|
+
}
|
|
21513
|
+
]
|
|
21514
|
+
}
|
|
21515
|
+
},
|
|
21516
|
+
"required": [
|
|
21517
|
+
"$schema",
|
|
21518
|
+
"spec"
|
|
21519
|
+
],
|
|
21520
|
+
"additionalProperties": false,
|
|
21521
|
+
"$defs": {
|
|
21522
|
+
"PresentationConfigCreateDto": {
|
|
21523
|
+
"type": "object",
|
|
21524
|
+
"properties": {
|
|
21525
|
+
"id": {
|
|
21526
|
+
"type": "string",
|
|
21527
|
+
"minLength": 1,
|
|
21528
|
+
"description": "Presentation configuration identifier."
|
|
21529
|
+
},
|
|
21530
|
+
"description": {
|
|
21531
|
+
"description": "Optional presentation configuration description.",
|
|
21532
|
+
"type": [
|
|
21533
|
+
"string",
|
|
21534
|
+
"null"
|
|
21535
|
+
]
|
|
21536
|
+
},
|
|
21537
|
+
"lifeTime": {
|
|
21538
|
+
"description": "Presentation request lifetime in seconds.",
|
|
21539
|
+
"type": "integer",
|
|
21540
|
+
"minimum": 1,
|
|
21541
|
+
"maximum": 9007199254740991
|
|
21542
|
+
},
|
|
21543
|
+
"skewSeconds": {
|
|
21544
|
+
"description": "Clock skew tolerance in seconds.",
|
|
21545
|
+
"type": "integer",
|
|
21546
|
+
"minimum": 0,
|
|
21547
|
+
"maximum": 9007199254740991
|
|
21548
|
+
},
|
|
21549
|
+
"statusCheckMode": {
|
|
21550
|
+
"description": "Revocation/status check mode.",
|
|
21551
|
+
"type": "string",
|
|
21552
|
+
"enum": [
|
|
21553
|
+
"strict",
|
|
21554
|
+
"best_effort",
|
|
21555
|
+
"disabled"
|
|
21556
|
+
]
|
|
21557
|
+
},
|
|
21558
|
+
"dcql_query": {
|
|
21559
|
+
"type": "object",
|
|
21560
|
+
"properties": {
|
|
21561
|
+
"credentials": {
|
|
21562
|
+
"minItems": 1,
|
|
21563
|
+
"type": "array",
|
|
21564
|
+
"items": {
|
|
21565
|
+
"oneOf": [
|
|
21566
|
+
{
|
|
21567
|
+
"type": "object",
|
|
21568
|
+
"properties": {
|
|
21569
|
+
"id": {
|
|
21570
|
+
"type": "string",
|
|
21571
|
+
"minLength": 1,
|
|
21572
|
+
"pattern": "^[A-Za-z0-9_-]+$",
|
|
21573
|
+
"description": "Credential query identifier."
|
|
21574
|
+
},
|
|
21575
|
+
"multiple": {
|
|
21576
|
+
"description": "Allow multiple matching credentials.",
|
|
21577
|
+
"type": "boolean"
|
|
21578
|
+
},
|
|
21579
|
+
"claim_sets": {
|
|
21580
|
+
"description": "Optional claim set constraints.",
|
|
21581
|
+
"type": "array",
|
|
21582
|
+
"items": {
|
|
21583
|
+
"type": "array",
|
|
21584
|
+
"items": {
|
|
21585
|
+
"type": "string"
|
|
21586
|
+
}
|
|
21587
|
+
}
|
|
21588
|
+
},
|
|
21589
|
+
"trusted_authorities": {
|
|
21590
|
+
"description": "Optional trusted authority constraints.",
|
|
21591
|
+
"type": "array",
|
|
21592
|
+
"items": {
|
|
21593
|
+
"oneOf": [
|
|
21594
|
+
{
|
|
21595
|
+
"type": "object",
|
|
21596
|
+
"properties": {
|
|
21597
|
+
"type": {
|
|
21598
|
+
"type": "string",
|
|
21599
|
+
"const": "etsi_tl",
|
|
21600
|
+
"description": "Trusted authority type discriminator for ETSI trust lists."
|
|
21601
|
+
},
|
|
21602
|
+
"values": {
|
|
21603
|
+
"type": "array",
|
|
21604
|
+
"items": {
|
|
21605
|
+
"type": "object",
|
|
21606
|
+
"properties": {
|
|
21607
|
+
"trustListId": {
|
|
21608
|
+
"description": "Optional trust list id reference.",
|
|
21609
|
+
"type": "string"
|
|
21610
|
+
},
|
|
21611
|
+
"url": {
|
|
21612
|
+
"description": "Optional trust list URL reference.",
|
|
21613
|
+
"anyOf": [
|
|
21614
|
+
{
|
|
21615
|
+
"type": "string",
|
|
21616
|
+
"format": "uri"
|
|
21617
|
+
},
|
|
21618
|
+
{
|
|
21619
|
+
"type": "string",
|
|
21620
|
+
"pattern": "^<TENANT_URL>(?:\\/.*)?$"
|
|
21621
|
+
}
|
|
21622
|
+
]
|
|
21623
|
+
},
|
|
21624
|
+
"verifierKey": {
|
|
21625
|
+
"description": "Optional verifier key material.",
|
|
21626
|
+
"type": "object",
|
|
21627
|
+
"propertyNames": {
|
|
21628
|
+
"type": "string"
|
|
21629
|
+
},
|
|
21630
|
+
"additionalProperties": {}
|
|
21631
|
+
},
|
|
21632
|
+
"verifierX509Der": {
|
|
21633
|
+
"description": "Optional verifier certificate in DER/base64 form.",
|
|
21634
|
+
"type": "string"
|
|
21635
|
+
}
|
|
21636
|
+
},
|
|
21637
|
+
"additionalProperties": false
|
|
21638
|
+
},
|
|
21639
|
+
"description": "Trust list references for ETSI TL verification."
|
|
21640
|
+
}
|
|
21641
|
+
},
|
|
21642
|
+
"required": [
|
|
21643
|
+
"type",
|
|
21644
|
+
"values"
|
|
21645
|
+
],
|
|
21646
|
+
"additionalProperties": false
|
|
21647
|
+
},
|
|
21648
|
+
{
|
|
21649
|
+
"type": "object",
|
|
21650
|
+
"properties": {
|
|
21651
|
+
"type": {
|
|
21652
|
+
"type": "string",
|
|
21653
|
+
"const": "openid_federation",
|
|
21654
|
+
"description": "Trusted authority type discriminator for OpenID Federation."
|
|
21655
|
+
},
|
|
21656
|
+
"values": {
|
|
21657
|
+
"type": "array",
|
|
21658
|
+
"items": {
|
|
21659
|
+
"type": "string"
|
|
21660
|
+
},
|
|
21661
|
+
"description": "OpenID Federation authority identifiers."
|
|
21662
|
+
}
|
|
21663
|
+
},
|
|
21664
|
+
"required": [
|
|
21665
|
+
"type",
|
|
21666
|
+
"values"
|
|
21667
|
+
],
|
|
21668
|
+
"additionalProperties": false
|
|
21669
|
+
}
|
|
21670
|
+
]
|
|
21671
|
+
}
|
|
21672
|
+
},
|
|
21673
|
+
"format": {
|
|
21674
|
+
"type": "string",
|
|
21675
|
+
"const": "dc+sd-jwt",
|
|
21676
|
+
"description": "Credential format discriminator."
|
|
21677
|
+
},
|
|
21678
|
+
"meta": {
|
|
21679
|
+
"type": "object",
|
|
21680
|
+
"properties": {
|
|
21681
|
+
"vct_values": {
|
|
21682
|
+
"minItems": 1,
|
|
21683
|
+
"type": "array",
|
|
21684
|
+
"items": {
|
|
21685
|
+
"type": "string"
|
|
21686
|
+
},
|
|
21687
|
+
"description": "Accepted VCT values."
|
|
21688
|
+
}
|
|
21689
|
+
},
|
|
21690
|
+
"required": [
|
|
21691
|
+
"vct_values"
|
|
21692
|
+
],
|
|
21693
|
+
"additionalProperties": false
|
|
21694
|
+
},
|
|
21695
|
+
"claims": {
|
|
21696
|
+
"description": "Optional claim-level constraints.",
|
|
21697
|
+
"type": "array",
|
|
21698
|
+
"items": {
|
|
21699
|
+
"type": "object",
|
|
21700
|
+
"properties": {
|
|
21701
|
+
"id": {
|
|
21702
|
+
"description": "Optional claim query id.",
|
|
21703
|
+
"type": "string"
|
|
21704
|
+
},
|
|
21705
|
+
"path": {
|
|
21706
|
+
"type": "array",
|
|
21707
|
+
"items": {
|
|
21708
|
+
"type": [
|
|
21709
|
+
"string",
|
|
21710
|
+
"number"
|
|
21711
|
+
]
|
|
21712
|
+
},
|
|
21713
|
+
"description": "Path to the claim value in presented credentials."
|
|
21714
|
+
},
|
|
21715
|
+
"values": {
|
|
21716
|
+
"description": "Optional allowed values for the claim. A disclosed value must equal one of them in type and value.",
|
|
21717
|
+
"minItems": 1,
|
|
21718
|
+
"type": "array",
|
|
21719
|
+
"items": {
|
|
21720
|
+
"anyOf": [
|
|
21721
|
+
{
|
|
21722
|
+
"type": "string"
|
|
21723
|
+
},
|
|
21724
|
+
{
|
|
21725
|
+
"type": "integer",
|
|
21726
|
+
"minimum": -9007199254740991,
|
|
21727
|
+
"maximum": 9007199254740991
|
|
21728
|
+
},
|
|
21729
|
+
{
|
|
21730
|
+
"type": "boolean"
|
|
21731
|
+
}
|
|
21732
|
+
]
|
|
21733
|
+
}
|
|
21734
|
+
}
|
|
21735
|
+
},
|
|
21736
|
+
"required": [
|
|
21737
|
+
"path"
|
|
21738
|
+
],
|
|
21739
|
+
"additionalProperties": false
|
|
21740
|
+
}
|
|
21741
|
+
}
|
|
21742
|
+
},
|
|
21743
|
+
"required": [
|
|
21744
|
+
"id",
|
|
21745
|
+
"format",
|
|
21746
|
+
"meta"
|
|
21747
|
+
],
|
|
21748
|
+
"additionalProperties": false
|
|
21749
|
+
},
|
|
21750
|
+
{
|
|
21751
|
+
"type": "object",
|
|
21752
|
+
"properties": {
|
|
21753
|
+
"id": {
|
|
21754
|
+
"type": "string",
|
|
21755
|
+
"minLength": 1,
|
|
21756
|
+
"pattern": "^[A-Za-z0-9_-]+$",
|
|
21757
|
+
"description": "Credential query identifier."
|
|
21758
|
+
},
|
|
21759
|
+
"multiple": {
|
|
21760
|
+
"description": "Allow multiple matching credentials.",
|
|
21761
|
+
"type": "boolean"
|
|
21762
|
+
},
|
|
21763
|
+
"claim_sets": {
|
|
21764
|
+
"description": "Optional claim set constraints.",
|
|
21765
|
+
"type": "array",
|
|
21766
|
+
"items": {
|
|
21767
|
+
"type": "array",
|
|
21768
|
+
"items": {
|
|
21769
|
+
"type": "string"
|
|
21770
|
+
}
|
|
21771
|
+
}
|
|
21772
|
+
},
|
|
21773
|
+
"trusted_authorities": {
|
|
21774
|
+
"description": "Optional trusted authority constraints.",
|
|
21775
|
+
"type": "array",
|
|
21776
|
+
"items": {
|
|
21777
|
+
"oneOf": [
|
|
21778
|
+
{
|
|
21779
|
+
"type": "object",
|
|
21780
|
+
"properties": {
|
|
21781
|
+
"type": {
|
|
21782
|
+
"type": "string",
|
|
21783
|
+
"const": "etsi_tl",
|
|
21784
|
+
"description": "Trusted authority type discriminator for ETSI trust lists."
|
|
21785
|
+
},
|
|
21786
|
+
"values": {
|
|
21787
|
+
"type": "array",
|
|
21788
|
+
"items": {
|
|
21789
|
+
"type": "object",
|
|
21790
|
+
"properties": {
|
|
21791
|
+
"trustListId": {
|
|
21792
|
+
"description": "Optional trust list id reference.",
|
|
21793
|
+
"type": "string"
|
|
21794
|
+
},
|
|
21795
|
+
"url": {
|
|
21796
|
+
"description": "Optional trust list URL reference.",
|
|
21797
|
+
"anyOf": [
|
|
21798
|
+
{
|
|
21799
|
+
"type": "string",
|
|
21800
|
+
"format": "uri"
|
|
21801
|
+
},
|
|
21802
|
+
{
|
|
21803
|
+
"type": "string",
|
|
21804
|
+
"pattern": "^<TENANT_URL>(?:\\/.*)?$"
|
|
21805
|
+
}
|
|
21806
|
+
]
|
|
21807
|
+
},
|
|
21808
|
+
"verifierKey": {
|
|
21809
|
+
"description": "Optional verifier key material.",
|
|
21810
|
+
"type": "object",
|
|
21811
|
+
"propertyNames": {
|
|
21812
|
+
"type": "string"
|
|
21813
|
+
},
|
|
21814
|
+
"additionalProperties": {}
|
|
21815
|
+
},
|
|
21816
|
+
"verifierX509Der": {
|
|
21817
|
+
"description": "Optional verifier certificate in DER/base64 form.",
|
|
21818
|
+
"type": "string"
|
|
21819
|
+
}
|
|
21820
|
+
},
|
|
21821
|
+
"additionalProperties": false
|
|
21822
|
+
},
|
|
21823
|
+
"description": "Trust list references for ETSI TL verification."
|
|
21824
|
+
}
|
|
21825
|
+
},
|
|
21826
|
+
"required": [
|
|
21827
|
+
"type",
|
|
21828
|
+
"values"
|
|
21829
|
+
],
|
|
21830
|
+
"additionalProperties": false
|
|
21831
|
+
},
|
|
21832
|
+
{
|
|
21833
|
+
"type": "object",
|
|
21834
|
+
"properties": {
|
|
21835
|
+
"type": {
|
|
21836
|
+
"type": "string",
|
|
21837
|
+
"const": "openid_federation",
|
|
21838
|
+
"description": "Trusted authority type discriminator for OpenID Federation."
|
|
21839
|
+
},
|
|
21840
|
+
"values": {
|
|
21841
|
+
"type": "array",
|
|
21842
|
+
"items": {
|
|
21843
|
+
"type": "string"
|
|
21844
|
+
},
|
|
21845
|
+
"description": "OpenID Federation authority identifiers."
|
|
21846
|
+
}
|
|
21847
|
+
},
|
|
21848
|
+
"required": [
|
|
21849
|
+
"type",
|
|
21850
|
+
"values"
|
|
21851
|
+
],
|
|
21852
|
+
"additionalProperties": false
|
|
21853
|
+
}
|
|
21854
|
+
]
|
|
21855
|
+
}
|
|
21856
|
+
},
|
|
21857
|
+
"format": {
|
|
21858
|
+
"type": "string",
|
|
21859
|
+
"const": "mso_mdoc",
|
|
21860
|
+
"description": "Credential format discriminator."
|
|
21861
|
+
},
|
|
21862
|
+
"meta": {
|
|
21863
|
+
"type": "object",
|
|
21864
|
+
"properties": {
|
|
21865
|
+
"doctype_value": {
|
|
21866
|
+
"type": "string",
|
|
21867
|
+
"minLength": 1,
|
|
21868
|
+
"description": "Expected mDoc doctype value."
|
|
21869
|
+
}
|
|
21870
|
+
},
|
|
21871
|
+
"required": [
|
|
21872
|
+
"doctype_value"
|
|
21873
|
+
],
|
|
21874
|
+
"additionalProperties": false
|
|
21875
|
+
},
|
|
21876
|
+
"claims": {
|
|
21877
|
+
"description": "Optional mDoc claim-level constraints.",
|
|
21878
|
+
"type": "array",
|
|
21879
|
+
"items": {
|
|
21880
|
+
"type": "object",
|
|
21881
|
+
"properties": {
|
|
21882
|
+
"id": {
|
|
21883
|
+
"description": "Optional claim query id.",
|
|
21884
|
+
"type": "string"
|
|
21885
|
+
},
|
|
21886
|
+
"path": {
|
|
21887
|
+
"type": "array",
|
|
21888
|
+
"items": {
|
|
21889
|
+
"type": [
|
|
21890
|
+
"string",
|
|
21891
|
+
"number"
|
|
21892
|
+
]
|
|
21893
|
+
},
|
|
21894
|
+
"description": "Path to the claim value in presented credentials."
|
|
21895
|
+
},
|
|
21896
|
+
"values": {
|
|
21897
|
+
"description": "Optional allowed values for the claim. A disclosed value must equal one of them in type and value.",
|
|
21898
|
+
"minItems": 1,
|
|
21899
|
+
"type": "array",
|
|
21900
|
+
"items": {
|
|
21901
|
+
"anyOf": [
|
|
21902
|
+
{
|
|
21903
|
+
"type": "string"
|
|
21904
|
+
},
|
|
21905
|
+
{
|
|
21906
|
+
"type": "integer",
|
|
21907
|
+
"minimum": -9007199254740991,
|
|
21908
|
+
"maximum": 9007199254740991
|
|
21909
|
+
},
|
|
21910
|
+
{
|
|
21911
|
+
"type": "boolean"
|
|
21912
|
+
}
|
|
21913
|
+
]
|
|
21914
|
+
}
|
|
21915
|
+
},
|
|
21916
|
+
"intent_to_retain": {
|
|
21917
|
+
"description": "Whether relying party intends to retain the claim.",
|
|
21918
|
+
"type": "boolean"
|
|
21919
|
+
}
|
|
21920
|
+
},
|
|
21921
|
+
"required": [
|
|
21922
|
+
"path"
|
|
21923
|
+
],
|
|
21924
|
+
"additionalProperties": false
|
|
21925
|
+
}
|
|
21926
|
+
}
|
|
21927
|
+
},
|
|
21928
|
+
"required": [
|
|
21929
|
+
"id",
|
|
21930
|
+
"format",
|
|
21931
|
+
"meta"
|
|
21932
|
+
],
|
|
21933
|
+
"additionalProperties": false
|
|
21934
|
+
}
|
|
21935
|
+
]
|
|
21936
|
+
},
|
|
21937
|
+
"description": "Credential queries requested by the verifier."
|
|
21938
|
+
},
|
|
21939
|
+
"credential_sets": {
|
|
21940
|
+
"description": "Optional higher-level credential set requirements.",
|
|
21941
|
+
"type": "array",
|
|
21942
|
+
"items": {
|
|
21943
|
+
"type": "object",
|
|
21944
|
+
"properties": {
|
|
21945
|
+
"options": {
|
|
21946
|
+
"minItems": 1,
|
|
21947
|
+
"type": "array",
|
|
21948
|
+
"items": {
|
|
21949
|
+
"minItems": 1,
|
|
21950
|
+
"type": "array",
|
|
21951
|
+
"items": {
|
|
21952
|
+
"type": "string"
|
|
21953
|
+
}
|
|
21954
|
+
},
|
|
21955
|
+
"description": "Alternative credential query id combinations."
|
|
21956
|
+
},
|
|
21957
|
+
"required": {
|
|
21958
|
+
"description": "Whether this credential set is mandatory.",
|
|
21959
|
+
"type": "boolean"
|
|
21960
|
+
}
|
|
21961
|
+
},
|
|
21962
|
+
"required": [
|
|
21963
|
+
"options"
|
|
21964
|
+
],
|
|
21965
|
+
"additionalProperties": false
|
|
21966
|
+
}
|
|
21967
|
+
}
|
|
21968
|
+
},
|
|
21969
|
+
"required": [
|
|
21970
|
+
"credentials"
|
|
21971
|
+
],
|
|
21972
|
+
"additionalProperties": false,
|
|
21973
|
+
"description": "DCQL query defining requested credentials and claims."
|
|
21974
|
+
},
|
|
21975
|
+
"transaction_data": {
|
|
21976
|
+
"description": "Optional transaction data descriptors.",
|
|
21977
|
+
"anyOf": [
|
|
21978
|
+
{
|
|
21979
|
+
"type": "array",
|
|
21980
|
+
"items": {
|
|
21981
|
+
"type": "object",
|
|
21982
|
+
"properties": {
|
|
21983
|
+
"type": {
|
|
21984
|
+
"type": "string",
|
|
21985
|
+
"description": "Transaction data type identifier."
|
|
21986
|
+
},
|
|
21987
|
+
"credential_ids": {
|
|
21988
|
+
"type": "array",
|
|
21989
|
+
"items": {
|
|
21990
|
+
"type": "string"
|
|
21991
|
+
},
|
|
21992
|
+
"description": "Credential query ids this transaction data applies to."
|
|
21993
|
+
},
|
|
21994
|
+
"payload": {
|
|
21995
|
+
"description": "Transaction details. Required for TS12 SCA transaction data."
|
|
21996
|
+
}
|
|
21997
|
+
},
|
|
21998
|
+
"required": [
|
|
21999
|
+
"type",
|
|
22000
|
+
"credential_ids"
|
|
22001
|
+
],
|
|
22002
|
+
"additionalProperties": {}
|
|
22003
|
+
}
|
|
22004
|
+
},
|
|
22005
|
+
{
|
|
22006
|
+
"type": "null"
|
|
22007
|
+
}
|
|
22008
|
+
]
|
|
22009
|
+
},
|
|
22010
|
+
"registration_cert": {
|
|
22011
|
+
"description": "Optional registration certificate request settings.",
|
|
22012
|
+
"anyOf": [
|
|
22013
|
+
{
|
|
22014
|
+
"type": "object",
|
|
22015
|
+
"properties": {
|
|
22016
|
+
"id": {
|
|
22017
|
+
"type": "string"
|
|
22018
|
+
},
|
|
22019
|
+
"body": {
|
|
22020
|
+
"type": "object",
|
|
22021
|
+
"properties": {
|
|
22022
|
+
"privacy_policy": {
|
|
22023
|
+
"type": "string"
|
|
22024
|
+
},
|
|
22025
|
+
"support_uri": {
|
|
22026
|
+
"type": "string"
|
|
22027
|
+
},
|
|
22028
|
+
"intermediary": {
|
|
22029
|
+
"type": "string"
|
|
22030
|
+
},
|
|
22031
|
+
"purpose": {
|
|
22032
|
+
"type": "array",
|
|
22033
|
+
"items": {
|
|
22034
|
+
"type": "object",
|
|
22035
|
+
"properties": {
|
|
22036
|
+
"lang": {
|
|
22037
|
+
"type": "string"
|
|
22038
|
+
},
|
|
22039
|
+
"content": {
|
|
22040
|
+
"type": "string"
|
|
22041
|
+
}
|
|
22042
|
+
},
|
|
22043
|
+
"required": [
|
|
22044
|
+
"lang",
|
|
22045
|
+
"content"
|
|
22046
|
+
],
|
|
22047
|
+
"additionalProperties": false
|
|
22048
|
+
}
|
|
22049
|
+
},
|
|
22050
|
+
"credentials": {
|
|
22051
|
+
"type": "array",
|
|
22052
|
+
"items": {
|
|
22053
|
+
"type": "object",
|
|
22054
|
+
"propertyNames": {
|
|
22055
|
+
"type": "string"
|
|
22056
|
+
},
|
|
22057
|
+
"additionalProperties": {}
|
|
22058
|
+
}
|
|
22059
|
+
},
|
|
22060
|
+
"provides_attestations": {
|
|
22061
|
+
"type": "array",
|
|
22062
|
+
"items": {
|
|
22063
|
+
"type": "string",
|
|
22064
|
+
"minLength": 1
|
|
22065
|
+
}
|
|
22066
|
+
}
|
|
22067
|
+
},
|
|
22068
|
+
"additionalProperties": false
|
|
22069
|
+
},
|
|
22070
|
+
"jwt": {
|
|
22071
|
+
"type": "string"
|
|
22072
|
+
}
|
|
22073
|
+
},
|
|
22074
|
+
"additionalProperties": false
|
|
22075
|
+
},
|
|
22076
|
+
{
|
|
22077
|
+
"type": "null"
|
|
22078
|
+
}
|
|
22079
|
+
]
|
|
22080
|
+
},
|
|
22081
|
+
"registrationCertImportJwt": {
|
|
22082
|
+
"description": "Optional imported registration certificate JWT.",
|
|
22083
|
+
"type": [
|
|
22084
|
+
"string",
|
|
22085
|
+
"null"
|
|
22086
|
+
]
|
|
22087
|
+
},
|
|
22088
|
+
"registrationCertImportId": {
|
|
22089
|
+
"description": "Optional registrar-side registration certificate id.",
|
|
22090
|
+
"type": [
|
|
22091
|
+
"string",
|
|
22092
|
+
"null"
|
|
22093
|
+
]
|
|
22094
|
+
},
|
|
22095
|
+
"registrationCertBodyPrivacyPolicy": {
|
|
22096
|
+
"description": "Optional registration certificate privacy policy URI.",
|
|
22097
|
+
"type": [
|
|
22098
|
+
"string",
|
|
22099
|
+
"null"
|
|
22100
|
+
]
|
|
22101
|
+
},
|
|
22102
|
+
"registrationCertBodySupportUri": {
|
|
22103
|
+
"description": "Optional registration certificate support URI.",
|
|
22104
|
+
"type": [
|
|
22105
|
+
"string",
|
|
22106
|
+
"null"
|
|
22107
|
+
]
|
|
22108
|
+
},
|
|
22109
|
+
"registrationCertBodyIntermediary": {
|
|
22110
|
+
"description": "Optional registration certificate intermediary.",
|
|
22111
|
+
"type": [
|
|
22112
|
+
"string",
|
|
22113
|
+
"null"
|
|
22114
|
+
]
|
|
22115
|
+
},
|
|
22116
|
+
"registrationCertBodyPurpose": {
|
|
22117
|
+
"description": "Optional registration certificate purpose entries.",
|
|
22118
|
+
"anyOf": [
|
|
22119
|
+
{
|
|
22120
|
+
"type": "array",
|
|
22121
|
+
"items": {
|
|
22122
|
+
"type": "object",
|
|
22123
|
+
"properties": {
|
|
22124
|
+
"lang": {
|
|
22125
|
+
"type": "string"
|
|
22126
|
+
},
|
|
22127
|
+
"content": {
|
|
22128
|
+
"type": "string"
|
|
22129
|
+
}
|
|
22130
|
+
},
|
|
22131
|
+
"additionalProperties": false
|
|
22132
|
+
}
|
|
22133
|
+
},
|
|
22134
|
+
{
|
|
22135
|
+
"type": "null"
|
|
22136
|
+
}
|
|
22137
|
+
]
|
|
22138
|
+
},
|
|
22139
|
+
"webhookEndpointId": {
|
|
22140
|
+
"description": "Optional webhook endpoint id for presentation callbacks.",
|
|
22141
|
+
"type": [
|
|
22142
|
+
"string",
|
|
22143
|
+
"null"
|
|
22144
|
+
]
|
|
22145
|
+
},
|
|
22146
|
+
"attached": {
|
|
22147
|
+
"description": "Optional attachments included with presentation requests.",
|
|
22148
|
+
"anyOf": [
|
|
22149
|
+
{
|
|
22150
|
+
"type": "array",
|
|
22151
|
+
"items": {
|
|
22152
|
+
"type": "object",
|
|
22153
|
+
"properties": {
|
|
22154
|
+
"format": {
|
|
22155
|
+
"type": "string",
|
|
22156
|
+
"description": "Attachment format identifier."
|
|
22157
|
+
},
|
|
22158
|
+
"data": {
|
|
22159
|
+
"description": "Attachment payload."
|
|
22160
|
+
},
|
|
22161
|
+
"credential_ids": {
|
|
22162
|
+
"description": "Optional credential query ids bound to this attachment.",
|
|
22163
|
+
"type": "array",
|
|
22164
|
+
"items": {
|
|
22165
|
+
"type": "string"
|
|
22166
|
+
}
|
|
22167
|
+
}
|
|
22168
|
+
},
|
|
22169
|
+
"required": [
|
|
22170
|
+
"format",
|
|
22171
|
+
"data"
|
|
22172
|
+
],
|
|
22173
|
+
"additionalProperties": false
|
|
22174
|
+
}
|
|
22175
|
+
},
|
|
22176
|
+
{
|
|
22177
|
+
"type": "null"
|
|
22178
|
+
}
|
|
22179
|
+
]
|
|
22180
|
+
},
|
|
22181
|
+
"redirectUri": {
|
|
22182
|
+
"description": "Optional redirect URI after presentation completion.",
|
|
22183
|
+
"type": [
|
|
22184
|
+
"string",
|
|
22185
|
+
"null"
|
|
22186
|
+
]
|
|
22187
|
+
},
|
|
22188
|
+
"accessKeyChainId": {
|
|
22189
|
+
"description": "Optional key chain id for access token/auth operations.",
|
|
22190
|
+
"type": [
|
|
22191
|
+
"string",
|
|
22192
|
+
"null"
|
|
22193
|
+
]
|
|
22194
|
+
},
|
|
22195
|
+
"readerAuth": {
|
|
22196
|
+
"description": "Whether reader authentication is required for mDoc requests.",
|
|
22197
|
+
"type": [
|
|
22198
|
+
"boolean",
|
|
22199
|
+
"null"
|
|
22200
|
+
]
|
|
22201
|
+
}
|
|
22202
|
+
},
|
|
22203
|
+
"required": [
|
|
22204
|
+
"id",
|
|
22205
|
+
"dcql_query"
|
|
22206
|
+
],
|
|
22207
|
+
"additionalProperties": false,
|
|
22208
|
+
"title": "PresentationConfigCreateDto"
|
|
22209
|
+
}
|
|
22210
|
+
}
|
|
22211
|
+
}
|
|
22212
|
+
];
|
|
22213
|
+
|
|
22214
|
+
// ../../packages/eudiplo-config-format/dist/config-validator.js
|
|
22215
|
+
var ajv = new import__.Ajv2020({
|
|
22216
|
+
allErrors: true,
|
|
22217
|
+
strict: false,
|
|
22218
|
+
validateFormats: false
|
|
22219
|
+
});
|
|
22220
|
+
for (const schema of CONFIG_SCHEMAS)
|
|
22221
|
+
ajv.addSchema(schema);
|
|
22222
|
+
function validateConfigDocument(document) {
|
|
22223
|
+
const file = serializeDocument(document);
|
|
22224
|
+
const validate = ajv.getSchema(file.$schema);
|
|
22225
|
+
if (!validate)
|
|
22226
|
+
throw new Error(`No bundled validator for ${file.$schema}`);
|
|
22227
|
+
const issues = [];
|
|
22228
|
+
if (!validate(file)) {
|
|
22229
|
+
for (const issue of validate.errors ?? [])
|
|
22230
|
+
issues.push({
|
|
22231
|
+
severity: "error",
|
|
22232
|
+
code: "CONFIG_SCHEMA_VALIDATION_FAILED",
|
|
22233
|
+
path: issue.instancePath || "/",
|
|
22234
|
+
message: issue.keyword === "additionalProperties" ? `Unknown property: ${String(issue.params.additionalProperty)}` : issue.message ?? "Invalid configuration",
|
|
22235
|
+
resource: { kind: document.kind, id: resourceId(document) }
|
|
22236
|
+
});
|
|
22237
|
+
}
|
|
22238
|
+
const id = document.kind === "Client" ? document.spec.clientId : document.spec.id;
|
|
22239
|
+
if (id !== void 0 && id !== resourceId(document))
|
|
22240
|
+
issues.push({
|
|
22241
|
+
severity: "error",
|
|
22242
|
+
code: "RESOURCE_ID_MISMATCH",
|
|
22243
|
+
path: document.kind === "Client" ? "/spec/clientId" : "/spec/id",
|
|
22244
|
+
message: "Resource identifier does not match metadata.id"
|
|
22245
|
+
});
|
|
22246
|
+
return issues;
|
|
22247
|
+
}
|
|
22248
|
+
|
|
22249
|
+
// src/commands/config/portability/migrations.ts
|
|
22250
|
+
function upgradeDocument(input) {
|
|
22251
|
+
const result = migrateDocument(input, validateConfigDocument);
|
|
22252
|
+
return { ...result, document: serializeDocument(result.document) };
|
|
22253
|
+
}
|
|
22254
|
+
|
|
22255
|
+
// src/commands/config/portability/upgrade.ts
|
|
22256
|
+
var codec = new ConfigBundleCodec();
|
|
22257
|
+
function parse3(text, path2) {
|
|
22258
|
+
try {
|
|
22259
|
+
return JSON.parse(text);
|
|
22260
|
+
} catch {
|
|
22261
|
+
throw new Error(`Invalid JSON in ${path2}`);
|
|
22262
|
+
}
|
|
22263
|
+
}
|
|
22264
|
+
function upgradeJson(input, file, context) {
|
|
22265
|
+
const bundle = Array.isArray(input?.documents);
|
|
22266
|
+
if (bundle) assertConfigBundle(input);
|
|
22267
|
+
const results = (bundle ? input.documents : [input]).map(
|
|
22268
|
+
(document) => upgradeDocument(document)
|
|
22269
|
+
);
|
|
22270
|
+
let blocked = false;
|
|
22271
|
+
for (const result of results) {
|
|
22272
|
+
for (const issue of result.issues) {
|
|
22273
|
+
context.stderr.write(
|
|
22274
|
+
`${file}${issue.path}: ${issue.severity} ${issue.code}: ${issue.message}
|
|
22275
|
+
`
|
|
22276
|
+
);
|
|
22277
|
+
if (issue.severity !== "warning") blocked = true;
|
|
22278
|
+
}
|
|
22279
|
+
for (const migration of result.migrations)
|
|
22280
|
+
context.stdout.write(`${file}: migration ${migration}
|
|
22281
|
+
`);
|
|
22282
|
+
}
|
|
22283
|
+
if (blocked) throw new Error(`${file}: upgrade blocked; no output written`);
|
|
22284
|
+
if (!bundle) return results[0].document;
|
|
22285
|
+
const documents = results.map(
|
|
22286
|
+
(result) => result.document
|
|
22287
|
+
);
|
|
22288
|
+
const resources = input.manifest.resources.map(
|
|
22289
|
+
(resource) => {
|
|
22290
|
+
const index = input.documents.findIndex(
|
|
22291
|
+
(candidate) => normalizeDocument(candidate).kind === resource.kind && resourceId(candidate) === resource.id
|
|
22292
|
+
);
|
|
22293
|
+
const document = documents[index];
|
|
22294
|
+
return {
|
|
22295
|
+
...resource,
|
|
22296
|
+
id: resourceId(document),
|
|
22297
|
+
$schema: document.$schema,
|
|
22298
|
+
sha256: createHash2("sha256").update(JSON.stringify(document)).digest("hex")
|
|
22299
|
+
};
|
|
22300
|
+
}
|
|
22301
|
+
);
|
|
22302
|
+
const output = {
|
|
22303
|
+
...input,
|
|
22304
|
+
manifest: { ...input.manifest, formatVersion: 2, resources },
|
|
22305
|
+
documents
|
|
22306
|
+
};
|
|
22307
|
+
assertConfigBundle(output);
|
|
22308
|
+
return output;
|
|
22309
|
+
}
|
|
22310
|
+
function report(input, output, file, parsed, context) {
|
|
22311
|
+
const changed = stableConfigJson(input) !== stableConfigJson(output);
|
|
22312
|
+
context.stdout.write(
|
|
22313
|
+
`${file}: ${changed ? "upgrade required" : "current"}
|
|
22314
|
+
`
|
|
22315
|
+
);
|
|
22316
|
+
if (parsed.flags.diff === true)
|
|
22317
|
+
for (const change of configChanges(input, output)) {
|
|
22318
|
+
context.stdout.write(
|
|
22319
|
+
` ${change.path}: ${JSON.stringify(change.before) ?? "(absent)"} -> ${JSON.stringify(change.after) ?? "(absent)"}
|
|
22320
|
+
`
|
|
22321
|
+
);
|
|
22322
|
+
}
|
|
22323
|
+
return changed;
|
|
22324
|
+
}
|
|
22325
|
+
function inferredKind(path2) {
|
|
22326
|
+
const normalized = path2.split(sep2).join("/");
|
|
22327
|
+
const match = TENANT_RESOURCE_REGISTRY.find(
|
|
22328
|
+
(entry) => entry.kind === "file" ? normalized === entry.file || normalized.endsWith(`/${entry.file}`) : normalized.endsWith(`/${entry.subfolder}/${basename2(path2)}`) || normalized === `${entry.subfolder}/${basename2(path2)}`
|
|
22329
|
+
);
|
|
22330
|
+
return CONFIG_RESOURCE_KINDS.find(
|
|
22331
|
+
(kind) => `${CONFIG_FORMATS[kind].file}.schema.json` === match?.schemaFile
|
|
22332
|
+
);
|
|
22333
|
+
}
|
|
22334
|
+
function wrapBare(kind, input, path2) {
|
|
22335
|
+
if (!input || typeof input !== "object" || Array.isArray(input))
|
|
22336
|
+
throw new Error(`${path2}: configuration must be an object`);
|
|
22337
|
+
const singleton = {
|
|
22338
|
+
Tenant: "tenant",
|
|
22339
|
+
KmsConfig: "kms",
|
|
22340
|
+
RegistrarConfig: "registrar",
|
|
22341
|
+
IssuanceConfig: "issuance"
|
|
22342
|
+
};
|
|
22343
|
+
const spec = structuredClone(input);
|
|
22344
|
+
if (kind === "KeyChain" && spec.key && !spec.keySource) {
|
|
22345
|
+
spec.keySource = { type: "private-jwk", jwk: spec.key };
|
|
22346
|
+
delete spec.key;
|
|
22347
|
+
}
|
|
22348
|
+
const id = String(
|
|
22349
|
+
singleton[kind] ?? spec.id ?? spec.clientId ?? basename2(path2, ".json")
|
|
22350
|
+
);
|
|
22351
|
+
if (!singleton[kind]) spec[kind === "Client" ? "clientId" : "id"] = id;
|
|
22352
|
+
return { $schema: schemaUrl(kind, 1), metadata: { generation: 1 }, spec };
|
|
22353
|
+
}
|
|
22354
|
+
async function folderFiles(path2) {
|
|
22355
|
+
const files = [];
|
|
22356
|
+
for (const entry of await readdir(path2, { withFileTypes: true })) {
|
|
22357
|
+
if (entry.name.startsWith(".")) continue;
|
|
22358
|
+
const file = join4(path2, entry.name);
|
|
22359
|
+
if (entry.isSymbolicLink())
|
|
22360
|
+
throw new Error(`Config folder contains a symbolic link: ${file}`);
|
|
22361
|
+
if (entry.isDirectory()) files.push(...await folderFiles(file));
|
|
22362
|
+
else if (entry.isFile()) files.push(file);
|
|
22363
|
+
}
|
|
22364
|
+
return files.sort();
|
|
22365
|
+
}
|
|
22366
|
+
async function upgradeFolder(source, parsed, context) {
|
|
22367
|
+
const outputs = /* @__PURE__ */ new Map();
|
|
22368
|
+
let changed = 0;
|
|
22369
|
+
for (const file of await folderFiles(source)) {
|
|
22370
|
+
if (extname(file) !== ".json" || relative2(source, file).split(sep2).includes("images"))
|
|
22371
|
+
continue;
|
|
22372
|
+
const input = parse3(await readFile4(file, "utf8"), file);
|
|
22373
|
+
const kind = inferredKind(relative2(source, file));
|
|
22374
|
+
if (!kind && !isConfigDocument(input)) continue;
|
|
22375
|
+
const candidate = isConfigDocument(input) ? input : wrapBare(kind, input, file);
|
|
22376
|
+
const output = upgradeJson(candidate, file, context);
|
|
22377
|
+
if (kind && normalizeDocument(output).kind !== kind)
|
|
22378
|
+
throw new Error(`${file}: expected ${kind} configuration`);
|
|
22379
|
+
if (report(input, output, relative2(source, file), parsed, context))
|
|
22380
|
+
changed++;
|
|
22381
|
+
outputs.set(
|
|
22382
|
+
relative2(source, file),
|
|
22383
|
+
`${JSON.stringify(output, null, 2)}
|
|
22384
|
+
`
|
|
22385
|
+
);
|
|
22386
|
+
}
|
|
22387
|
+
if (!outputs.size)
|
|
22388
|
+
throw new Error(`No configuration documents found in ${source}`);
|
|
22389
|
+
context.stdout.write(
|
|
22390
|
+
`${outputs.size - changed} current, ${changed} require upgrading
|
|
22391
|
+
`
|
|
22392
|
+
);
|
|
22393
|
+
if (parsed.flags.check === true) return changed ? 1 : 0;
|
|
22394
|
+
if (parsed.flags["dry-run"] === true) return 0;
|
|
22395
|
+
const destination = resolve3(
|
|
22396
|
+
context.cwd,
|
|
22397
|
+
readStringFlag(parsed.flags, "output") ?? `${source}.upgraded`
|
|
22398
|
+
);
|
|
22399
|
+
const overlap = (parent, child) => {
|
|
22400
|
+
const path2 = relative2(parent, child);
|
|
22401
|
+
return path2 === "" || !path2.startsWith(`..${sep2}`) && path2 !== "..";
|
|
22402
|
+
};
|
|
22403
|
+
if (overlap(source, destination) || overlap(destination, source))
|
|
22404
|
+
throw new Error(
|
|
22405
|
+
"Folder output must be separate from the source directory"
|
|
22406
|
+
);
|
|
22407
|
+
await lstat(destination).then(
|
|
22408
|
+
() => {
|
|
22409
|
+
throw new Error(`Output already exists: ${destination}`);
|
|
22410
|
+
},
|
|
22411
|
+
(error) => {
|
|
22412
|
+
if (error.code !== "ENOENT") throw error;
|
|
22413
|
+
}
|
|
22414
|
+
);
|
|
22415
|
+
await mkdir3(dirname3(destination), { recursive: true });
|
|
22416
|
+
const staging = await mkdtemp(
|
|
22417
|
+
join4(dirname3(destination), ".eudiplo-upgrade-")
|
|
22418
|
+
);
|
|
22419
|
+
try {
|
|
22420
|
+
await cp(source, staging, {
|
|
22421
|
+
recursive: true,
|
|
22422
|
+
filter: (path2) => path2 === source || !relative2(source, path2).split(sep2).some((part) => part.startsWith("."))
|
|
20185
22423
|
});
|
|
20186
22424
|
for (const [path2, contents] of outputs)
|
|
20187
22425
|
await atomicWriteFile(join4(staging, path2), contents);
|
|
@@ -20526,8 +22764,8 @@ function createComposeEnv(options) {
|
|
|
20526
22764
|
const authClientSecret = options.authClientSecret ?? "root";
|
|
20527
22765
|
const lines = [
|
|
20528
22766
|
`EUDIPLO_ENV_FILE=${envFileName}`,
|
|
20529
|
-
`EUDIPLO_IMAGE=ghcr.io/
|
|
20530
|
-
`EUDIPLO_CLIENT_IMAGE=ghcr.io/
|
|
22767
|
+
`EUDIPLO_IMAGE=ghcr.io/eudiplo/eudiplo:${imageTag}`,
|
|
22768
|
+
`EUDIPLO_CLIENT_IMAGE=ghcr.io/eudiplo/eudiplo-client:${imageTag}`,
|
|
20531
22769
|
...options.mode === "demo" ? ["EUDIPLO_BIND_ADDRESS=127.0.0.1"] : [],
|
|
20532
22770
|
`EUDIPLO_CONFIG_MOUNT=./${configDirectoryName}:/app/config`,
|
|
20533
22771
|
"CONFIG_FOLDER=/app/config",
|
|
@@ -20537,14 +22775,11 @@ function createComposeEnv(options) {
|
|
|
20537
22775
|
`AUTH_CLIENT_ID=${escapeEnvValue(authClientId)}`,
|
|
20538
22776
|
`AUTH_CLIENT_SECRET=${escapeEnvValue(authClientSecret)}`
|
|
20539
22777
|
];
|
|
20540
|
-
lines.push(
|
|
20541
|
-
|
|
20542
|
-
|
|
20543
|
-
"",
|
|
20544
|
-
|
|
20545
|
-
"",
|
|
20546
|
-
...kmsEnv(kms)
|
|
20547
|
-
);
|
|
22778
|
+
lines.push("", ...databaseEnv(database), "", ...storageEnv(storage));
|
|
22779
|
+
const kmsLines = kmsEnv(kms);
|
|
22780
|
+
if (kmsLines.length > 0) {
|
|
22781
|
+
lines.push("", ...kmsLines);
|
|
22782
|
+
}
|
|
20548
22783
|
return `${lines.join("\n")}
|
|
20549
22784
|
`;
|
|
20550
22785
|
}
|
|
@@ -20592,28 +22827,24 @@ function storageEnv(storage) {
|
|
|
20592
22827
|
if (storage === "local") {
|
|
20593
22828
|
return ["STORAGE_DRIVER=local", "LOCAL_STORAGE_DIR=/app/uploads"];
|
|
20594
22829
|
}
|
|
20595
|
-
const
|
|
22830
|
+
const rustfsPassword = randomSecret();
|
|
20596
22831
|
return [
|
|
20597
22832
|
"STORAGE_DRIVER=s3",
|
|
20598
|
-
"S3_ENDPOINT=http://
|
|
22833
|
+
"S3_ENDPOINT=http://rustfs:9000",
|
|
20599
22834
|
"S3_REGION=us-east-1",
|
|
20600
|
-
"S3_ACCESS_KEY_ID=
|
|
20601
|
-
`S3_SECRET_ACCESS_KEY=${
|
|
22835
|
+
"S3_ACCESS_KEY_ID=rustfsadmin",
|
|
22836
|
+
`S3_SECRET_ACCESS_KEY=${rustfsPassword}`,
|
|
20602
22837
|
"S3_BUCKET=uploads",
|
|
20603
22838
|
"S3_FORCE_PATH_STYLE=true",
|
|
20604
|
-
"
|
|
20605
|
-
`
|
|
22839
|
+
"RUSTFS_ACCESS_KEY=rustfsadmin",
|
|
22840
|
+
`RUSTFS_SECRET_KEY=${rustfsPassword}`
|
|
20606
22841
|
];
|
|
20607
22842
|
}
|
|
20608
22843
|
function kmsEnv(kms) {
|
|
20609
22844
|
if (kms === "db") {
|
|
20610
|
-
return [
|
|
22845
|
+
return [];
|
|
20611
22846
|
}
|
|
20612
|
-
return [
|
|
20613
|
-
"KM_TYPE=vault",
|
|
20614
|
-
"VAULT_ADDR=http://vault:8200",
|
|
20615
|
-
"VAULT_TOKEN=root"
|
|
20616
|
-
];
|
|
22847
|
+
return ["VAULT_ADDR=http://vault:8200", "VAULT_TOKEN=root"];
|
|
20617
22848
|
}
|
|
20618
22849
|
function randomSecret() {
|
|
20619
22850
|
return randomBytes(24).toString("base64url");
|
|
@@ -20755,10 +22986,10 @@ function formatTextReport(scope, rootPath, results) {
|
|
|
20755
22986
|
function formatTenantBlock(result) {
|
|
20756
22987
|
const lines = [`${result.valid ? "PASS" : "FAIL"} ${result.id}`];
|
|
20757
22988
|
if (result.valid) {
|
|
20758
|
-
for (const [resourceType,
|
|
22989
|
+
for (const [resourceType, count2] of Object.entries(
|
|
20759
22990
|
result.resourceCounts
|
|
20760
22991
|
)) {
|
|
20761
|
-
lines.push(` ${
|
|
22992
|
+
lines.push(` ${count2} ${pluralize(resourceType, count2)}`);
|
|
20762
22993
|
}
|
|
20763
22994
|
} else {
|
|
20764
22995
|
lines.push(...formatTenantErrors(result.errors));
|
|
@@ -20804,8 +23035,8 @@ function groupErrorsByFile(errors) {
|
|
|
20804
23035
|
}
|
|
20805
23036
|
return Array.from(grouped.entries());
|
|
20806
23037
|
}
|
|
20807
|
-
function pluralize(label,
|
|
20808
|
-
return
|
|
23038
|
+
function pluralize(label, count2) {
|
|
23039
|
+
return count2 === 1 ? label : `${label}s`;
|
|
20809
23040
|
}
|
|
20810
23041
|
|
|
20811
23042
|
// src/commands/config/validate/validator.ts
|
|
@@ -21000,7 +23231,10 @@ async function validateResourceFile(filePath, relativeFile, schemaFile, getValid
|
|
|
21000
23231
|
delete spec.key;
|
|
21001
23232
|
}
|
|
21002
23233
|
if (!CONFIG_SINGLETON_IDS[kind])
|
|
21003
|
-
spec[kind === "Client" ? "clientId" : "id"] ??= basename4(
|
|
23234
|
+
spec[kind === "Client" ? "clientId" : "id"] ??= basename4(
|
|
23235
|
+
relativeFile,
|
|
23236
|
+
".json"
|
|
23237
|
+
);
|
|
21004
23238
|
resolved = {
|
|
21005
23239
|
$schema: schemaUrl(kind),
|
|
21006
23240
|
metadata: { generation: 1 },
|
|
@@ -21650,6 +23884,68 @@ function assertKnownService(service, known) {
|
|
|
21650
23884
|
}
|
|
21651
23885
|
}
|
|
21652
23886
|
|
|
23887
|
+
// src/services/container-state.ts
|
|
23888
|
+
function parseContainerStates(stdout) {
|
|
23889
|
+
const trimmed = stdout.trim();
|
|
23890
|
+
if (!trimmed) {
|
|
23891
|
+
return [];
|
|
23892
|
+
}
|
|
23893
|
+
const entries = trimmed.startsWith("[") ? asArray(JSON.parse(trimmed)) : trimmed.split("\n").map((line) => line.trim()).filter((line) => line.startsWith("{")).map((line) => JSON.parse(line));
|
|
23894
|
+
return entries.map((entry) => {
|
|
23895
|
+
const record = entry;
|
|
23896
|
+
const names = record.Names;
|
|
23897
|
+
return {
|
|
23898
|
+
name: Array.isArray(names) ? String(names[0] ?? "") : String(names ?? record.Name ?? ""),
|
|
23899
|
+
state: String(record.State ?? ""),
|
|
23900
|
+
status: String(record.Status ?? "")
|
|
23901
|
+
};
|
|
23902
|
+
});
|
|
23903
|
+
}
|
|
23904
|
+
function summarizeContainerStates(containers, projectName) {
|
|
23905
|
+
const name = "service containers";
|
|
23906
|
+
if (containers.length === 0) {
|
|
23907
|
+
return {
|
|
23908
|
+
name,
|
|
23909
|
+
status: "warn",
|
|
23910
|
+
message: `No containers found for project ${projectName}. Start it with eudiplo up.`
|
|
23911
|
+
};
|
|
23912
|
+
}
|
|
23913
|
+
const unhealthy = containers.filter(
|
|
23914
|
+
(container) => container.status.toLowerCase().includes("unhealthy")
|
|
23915
|
+
);
|
|
23916
|
+
if (unhealthy.length > 0) {
|
|
23917
|
+
return {
|
|
23918
|
+
name,
|
|
23919
|
+
status: "fail",
|
|
23920
|
+
message: `Unhealthy: ${describe(unhealthy)}`
|
|
23921
|
+
};
|
|
23922
|
+
}
|
|
23923
|
+
const notRunning = containers.filter(
|
|
23924
|
+
(container) => container.state.toLowerCase() !== "running"
|
|
23925
|
+
);
|
|
23926
|
+
if (notRunning.length > 0) {
|
|
23927
|
+
return {
|
|
23928
|
+
name,
|
|
23929
|
+
status: "warn",
|
|
23930
|
+
message: `${containers.length - notRunning.length}/${containers.length} running. Not running: ${describe(notRunning)}`
|
|
23931
|
+
};
|
|
23932
|
+
}
|
|
23933
|
+
const starting = containers.filter(
|
|
23934
|
+
(container) => container.status.toLowerCase().includes("starting")
|
|
23935
|
+
).length;
|
|
23936
|
+
return {
|
|
23937
|
+
name,
|
|
23938
|
+
status: "pass",
|
|
23939
|
+
message: `${containers.length} container(s) running${starting > 0 ? `, ${starting} still starting` : ""}.`
|
|
23940
|
+
};
|
|
23941
|
+
}
|
|
23942
|
+
function asArray(value) {
|
|
23943
|
+
return Array.isArray(value) ? value : [];
|
|
23944
|
+
}
|
|
23945
|
+
function describe(containers) {
|
|
23946
|
+
return containers.map((container) => `${container.name} (${container.status})`).join(", ");
|
|
23947
|
+
}
|
|
23948
|
+
|
|
21653
23949
|
// src/services/deployment-drivers.ts
|
|
21654
23950
|
var drivers = {
|
|
21655
23951
|
compose: {
|
|
@@ -21663,6 +23959,12 @@ var drivers = {
|
|
|
21663
23959
|
status: runtime ? "pass" : "warn",
|
|
21664
23960
|
message: runtime ? `${runtime.name} found at ${runtime.command}` : "Docker or Podman was not found in a supported install location."
|
|
21665
23961
|
});
|
|
23962
|
+
if (runtime) {
|
|
23963
|
+
checks.push(await composeProviderCheck(runtime, context));
|
|
23964
|
+
checks.push(
|
|
23965
|
+
await composeServicesCheck(runtime, instance, context)
|
|
23966
|
+
);
|
|
23967
|
+
}
|
|
21666
23968
|
for (const composeFile of getComposeFiles(instance)) {
|
|
21667
23969
|
let found = true;
|
|
21668
23970
|
try {
|
|
@@ -22258,6 +24560,89 @@ async function resolveComposeService(options) {
|
|
|
22258
24560
|
assertKnownService(service, parseServiceList(listed.stdout));
|
|
22259
24561
|
return service;
|
|
22260
24562
|
}
|
|
24563
|
+
async function composeProviderCheck(runtime, context) {
|
|
24564
|
+
const version = await captureRuntime(
|
|
24565
|
+
runtime.command,
|
|
24566
|
+
["compose", "version"],
|
|
24567
|
+
context
|
|
24568
|
+
);
|
|
24569
|
+
if (version.code !== 0) {
|
|
24570
|
+
return {
|
|
24571
|
+
name: "compose provider",
|
|
24572
|
+
status: "fail",
|
|
24573
|
+
message: `${runtime.name} compose is not usable: ${firstLine(version.stderr) || `exit code ${version.code}`}`
|
|
24574
|
+
};
|
|
24575
|
+
}
|
|
24576
|
+
return {
|
|
24577
|
+
name: "compose provider",
|
|
24578
|
+
status: "pass",
|
|
24579
|
+
message: firstLine(version.stdout) || `${runtime.name} compose works`
|
|
24580
|
+
};
|
|
24581
|
+
}
|
|
24582
|
+
async function composeServicesCheck(runtime, instance, context) {
|
|
24583
|
+
if (!instance.projectName) {
|
|
24584
|
+
return {
|
|
24585
|
+
name: "service containers",
|
|
24586
|
+
status: "skip",
|
|
24587
|
+
message: "This instance has no Compose project name, so its containers cannot be identified."
|
|
24588
|
+
};
|
|
24589
|
+
}
|
|
24590
|
+
const listed = await captureRuntime(
|
|
24591
|
+
runtime.command,
|
|
24592
|
+
[
|
|
24593
|
+
"ps",
|
|
24594
|
+
"--all",
|
|
24595
|
+
"--filter",
|
|
24596
|
+
`label=com.docker.compose.project=${instance.projectName}`,
|
|
24597
|
+
"--format",
|
|
24598
|
+
"json"
|
|
24599
|
+
],
|
|
24600
|
+
context
|
|
24601
|
+
);
|
|
24602
|
+
if (listed.code !== 0) {
|
|
24603
|
+
return {
|
|
24604
|
+
name: "service containers",
|
|
24605
|
+
status: "warn",
|
|
24606
|
+
message: `Containers could not be listed: ${firstLine(listed.stderr) || `exit code ${listed.code}`}`
|
|
24607
|
+
};
|
|
24608
|
+
}
|
|
24609
|
+
try {
|
|
24610
|
+
return summarizeContainerStates(
|
|
24611
|
+
parseContainerStates(listed.stdout),
|
|
24612
|
+
instance.projectName
|
|
24613
|
+
);
|
|
24614
|
+
} catch {
|
|
24615
|
+
return {
|
|
24616
|
+
name: "service containers",
|
|
24617
|
+
status: "warn",
|
|
24618
|
+
message: `The container list returned by ${runtime.name} could not be read.`
|
|
24619
|
+
};
|
|
24620
|
+
}
|
|
24621
|
+
}
|
|
24622
|
+
function captureRuntime(command, args, context) {
|
|
24623
|
+
return new Promise((resolveProcess) => {
|
|
24624
|
+
const child = spawn(command, args, {
|
|
24625
|
+
env: context.env,
|
|
24626
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
24627
|
+
});
|
|
24628
|
+
let stdout = "";
|
|
24629
|
+
let stderr = "";
|
|
24630
|
+
child.stdout?.on("data", (chunk) => {
|
|
24631
|
+
stdout += String(chunk);
|
|
24632
|
+
});
|
|
24633
|
+
child.stderr?.on("data", (chunk) => {
|
|
24634
|
+
stderr += String(chunk);
|
|
24635
|
+
});
|
|
24636
|
+
child.on(
|
|
24637
|
+
"error",
|
|
24638
|
+
(error) => resolveProcess({ code: 1, stdout, stderr: error.message })
|
|
24639
|
+
);
|
|
24640
|
+
child.on(
|
|
24641
|
+
"close",
|
|
24642
|
+
(code) => resolveProcess({ code: code ?? 1, stdout, stderr })
|
|
24643
|
+
);
|
|
24644
|
+
});
|
|
24645
|
+
}
|
|
22261
24646
|
async function resolveComposeRuntime(env) {
|
|
22262
24647
|
const preferredRuntime = parsePreferredRuntime(
|
|
22263
24648
|
env.EUDIPLO_CONTAINER_RUNTIME
|
|
@@ -22486,120 +24871,606 @@ async function runDriverCommand(config, command, parsed, context) {
|
|
|
22486
24871
|
context
|
|
22487
24872
|
});
|
|
22488
24873
|
}
|
|
22489
|
-
|
|
22490
|
-
// src/commands/deployment/index.ts
|
|
22491
|
-
var descriptions = {
|
|
22492
|
-
up: "Start the selected Compose deployment",
|
|
22493
|
-
down: "Stop the selected Compose deployment",
|
|
22494
|
-
logs: "Stream logs for the selected deployment",
|
|
22495
|
-
ps: "List the running containers or pods for the selected deployment",
|
|
22496
|
-
restart: "Restart the workloads of the selected deployment",
|
|
22497
|
-
pull: "Download the configured images without changing configuration"
|
|
22498
|
-
};
|
|
22499
|
-
var serviceScoped = /* @__PURE__ */ new Set([
|
|
22500
|
-
"logs",
|
|
22501
|
-
"restart",
|
|
22502
|
-
"pull"
|
|
22503
|
-
]);
|
|
22504
|
-
function createDeploymentCommands(context, setExitCode) {
|
|
22505
|
-
return ["up", "down", "logs", "ps", "restart", "pull"].map(
|
|
22506
|
-
(name) => {
|
|
22507
|
-
const command = new Command(name).description(descriptions[name]).argument(
|
|
22508
|
-
"[args...]",
|
|
22509
|
-
"additional arguments passed to the deployment runtime"
|
|
22510
|
-
).option("--instance <name>", "select a configured instance");
|
|
22511
|
-
if (serviceScoped.has(name)) {
|
|
22512
|
-
command.option(
|
|
22513
|
-
"--service <name>",
|
|
22514
|
-
"select a single service (Compose) or configured workload (Kubernetes)"
|
|
22515
|
-
);
|
|
22516
|
-
}
|
|
22517
|
-
if (name === "logs") {
|
|
22518
|
-
command.option("--follow", "stream new output as it arrives").option("--tail <lines>", "number of recent lines to show").option(
|
|
22519
|
-
"--since <time>",
|
|
22520
|
-
"show logs since a duration (10m, 2h) or timestamp (Compose instances)"
|
|
22521
|
-
);
|
|
22522
|
-
}
|
|
22523
|
-
if (name === "restart") {
|
|
22524
|
-
command.option(
|
|
22525
|
-
"--no-wait",
|
|
22526
|
-
"return without waiting for the rollout to finish (Kubernetes instances)"
|
|
22527
|
-
);
|
|
24874
|
+
|
|
24875
|
+
// src/commands/deployment/index.ts
|
|
24876
|
+
var descriptions = {
|
|
24877
|
+
up: "Start the selected Compose deployment",
|
|
24878
|
+
down: "Stop the selected Compose deployment",
|
|
24879
|
+
logs: "Stream logs for the selected deployment",
|
|
24880
|
+
ps: "List the running containers or pods for the selected deployment",
|
|
24881
|
+
restart: "Restart the workloads of the selected deployment",
|
|
24882
|
+
pull: "Download the configured images without changing configuration"
|
|
24883
|
+
};
|
|
24884
|
+
var serviceScoped = /* @__PURE__ */ new Set([
|
|
24885
|
+
"logs",
|
|
24886
|
+
"restart",
|
|
24887
|
+
"pull"
|
|
24888
|
+
]);
|
|
24889
|
+
function createDeploymentCommands(context, setExitCode) {
|
|
24890
|
+
return ["up", "down", "logs", "ps", "restart", "pull"].map(
|
|
24891
|
+
(name) => {
|
|
24892
|
+
const command = new Command(name).description(descriptions[name]).argument(
|
|
24893
|
+
"[args...]",
|
|
24894
|
+
"additional arguments passed to the deployment runtime"
|
|
24895
|
+
).option("--instance <name>", "select a configured instance");
|
|
24896
|
+
if (serviceScoped.has(name)) {
|
|
24897
|
+
command.option(
|
|
24898
|
+
"--service <name>",
|
|
24899
|
+
"select a single service (Compose) or configured workload (Kubernetes)"
|
|
24900
|
+
);
|
|
24901
|
+
}
|
|
24902
|
+
if (name === "logs") {
|
|
24903
|
+
command.option("--follow", "stream new output as it arrives").option("--tail <lines>", "number of recent lines to show").option(
|
|
24904
|
+
"--since <time>",
|
|
24905
|
+
"show logs since a duration (10m, 2h) or timestamp (Compose instances)"
|
|
24906
|
+
);
|
|
24907
|
+
}
|
|
24908
|
+
if (name === "restart") {
|
|
24909
|
+
command.option(
|
|
24910
|
+
"--no-wait",
|
|
24911
|
+
"return without waiting for the rollout to finish (Kubernetes instances)"
|
|
24912
|
+
);
|
|
24913
|
+
}
|
|
24914
|
+
return command.action(async (args, options) => {
|
|
24915
|
+
const { config } = await loadCliState(context);
|
|
24916
|
+
setExitCode(
|
|
24917
|
+
await runDriverCommand(
|
|
24918
|
+
config,
|
|
24919
|
+
name,
|
|
24920
|
+
parsedArgs(name, void 0, args, options),
|
|
24921
|
+
context
|
|
24922
|
+
)
|
|
24923
|
+
);
|
|
24924
|
+
});
|
|
24925
|
+
}
|
|
24926
|
+
);
|
|
24927
|
+
}
|
|
24928
|
+
|
|
24929
|
+
// package.json
|
|
24930
|
+
var package_default = {
|
|
24931
|
+
name: "@eudiplo/cli",
|
|
24932
|
+
version: "9.0.0-main.410b294",
|
|
24933
|
+
description: "Deployment-aware command line tools for EUDIPLO",
|
|
24934
|
+
private: false,
|
|
24935
|
+
type: "module",
|
|
24936
|
+
bin: {
|
|
24937
|
+
eudiplo: "dist/index.js"
|
|
24938
|
+
},
|
|
24939
|
+
files: [
|
|
24940
|
+
"dist",
|
|
24941
|
+
"templates",
|
|
24942
|
+
"README.md"
|
|
24943
|
+
],
|
|
24944
|
+
scripts: {
|
|
24945
|
+
"assets:sync": "node scripts/sync-cli-assets.cjs",
|
|
24946
|
+
"assets:check": "node scripts/check-cli-assets.cjs",
|
|
24947
|
+
build: "pnpm assets:sync && pnpm assets:check && tsc -p tsconfig.json",
|
|
24948
|
+
"build:publish": "pnpm build && esbuild src/index.ts --bundle --platform=node --format=esm --target=node22.12 --alias:jsonc-parser=jsonc-parser/lib/esm/main.js --outfile=dist/index.js",
|
|
24949
|
+
"build:sea:bundle": "pnpm assets:sync && pnpm assets:check && esbuild src/index.ts --bundle --platform=node --format=esm --target=node22.12 --alias:jsonc-parser=jsonc-parser/lib/esm/main.js --outfile=dist-sea/index.js",
|
|
24950
|
+
"build:sea": "node scripts/build-cli-sea.mjs",
|
|
24951
|
+
dev: "tsx src/index.ts",
|
|
24952
|
+
test: "vitest run --root ../.. --project cli",
|
|
24953
|
+
lint: "biome lint .",
|
|
24954
|
+
format: "biome format --write .",
|
|
24955
|
+
"format:check": "biome format .",
|
|
24956
|
+
prepublishOnly: "pnpm build:publish"
|
|
24957
|
+
},
|
|
24958
|
+
keywords: [
|
|
24959
|
+
"eudiplo",
|
|
24960
|
+
"cli",
|
|
24961
|
+
"eudi",
|
|
24962
|
+
"wallet",
|
|
24963
|
+
"oid4vci",
|
|
24964
|
+
"oid4vp"
|
|
24965
|
+
],
|
|
24966
|
+
repository: {
|
|
24967
|
+
type: "git",
|
|
24968
|
+
url: "git+https://github.com/EUDIPLO/eudiplo.git",
|
|
24969
|
+
directory: "apps/cli"
|
|
24970
|
+
},
|
|
24971
|
+
homepage: "https://github.com/EUDIPLO/eudiplo/tree/main/apps/cli#readme",
|
|
24972
|
+
bugs: {
|
|
24973
|
+
url: "https://github.com/EUDIPLO/eudiplo/issues"
|
|
24974
|
+
},
|
|
24975
|
+
author: "LF Decentralized Trust",
|
|
24976
|
+
license: "Apache-2.0",
|
|
24977
|
+
engines: {
|
|
24978
|
+
node: ">=22.12.0"
|
|
24979
|
+
},
|
|
24980
|
+
publishConfig: {
|
|
24981
|
+
access: "public"
|
|
24982
|
+
},
|
|
24983
|
+
dependencies: {
|
|
24984
|
+
"@eudiplo/config-format": "workspace:*",
|
|
24985
|
+
ajv: "^8.20.0",
|
|
24986
|
+
"ajv-formats": "^3.0.1",
|
|
24987
|
+
commander: "^15.0.0",
|
|
24988
|
+
fflate: "^0.8.3",
|
|
24989
|
+
"jsonc-parser": "^3.3.1"
|
|
24990
|
+
},
|
|
24991
|
+
devDependencies: {
|
|
24992
|
+
"@biomejs/biome": "2.5.15",
|
|
24993
|
+
"@types/node": "^26.6.4",
|
|
24994
|
+
esbuild: "^0.28.2",
|
|
24995
|
+
tsx: "^4.23.15",
|
|
24996
|
+
typescript: "^7.0.2",
|
|
24997
|
+
vitest: "5.0.3"
|
|
24998
|
+
}
|
|
24999
|
+
};
|
|
25000
|
+
|
|
25001
|
+
// src/services/api-auth.ts
|
|
25002
|
+
async function requestAccessToken(baseUrl, context) {
|
|
25003
|
+
const clientId = context.env.EUDIPLO_CLIENT_ID;
|
|
25004
|
+
const clientSecret = context.env.EUDIPLO_CLIENT_SECRET;
|
|
25005
|
+
if (!clientId || !clientSecret) {
|
|
25006
|
+
return {
|
|
25007
|
+
kind: "unavailable",
|
|
25008
|
+
reason: "EUDIPLO_CLIENT_ID and EUDIPLO_CLIENT_SECRET are not set"
|
|
25009
|
+
};
|
|
25010
|
+
}
|
|
25011
|
+
const tokenUrl = new URL("api/oauth2/token", withTrailingSlash(baseUrl));
|
|
25012
|
+
try {
|
|
25013
|
+
const response = await context.fetch(tokenUrl, {
|
|
25014
|
+
method: "POST",
|
|
25015
|
+
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
25016
|
+
body: new URLSearchParams({
|
|
25017
|
+
grant_type: "client_credentials",
|
|
25018
|
+
client_id: clientId,
|
|
25019
|
+
client_secret: clientSecret
|
|
25020
|
+
}).toString()
|
|
25021
|
+
});
|
|
25022
|
+
if (!response.ok) {
|
|
25023
|
+
return {
|
|
25024
|
+
kind: "error",
|
|
25025
|
+
reason: `the token endpoint returned HTTP ${response.status}`
|
|
25026
|
+
};
|
|
25027
|
+
}
|
|
25028
|
+
const payload = await response.json();
|
|
25029
|
+
const accessToken = typeof payload === "object" && payload !== null && "access_token" in payload ? String(payload.access_token) : "";
|
|
25030
|
+
if (!accessToken) {
|
|
25031
|
+
return {
|
|
25032
|
+
kind: "error",
|
|
25033
|
+
reason: "the token response did not contain an access token"
|
|
25034
|
+
};
|
|
25035
|
+
}
|
|
25036
|
+
return { kind: "token", accessToken };
|
|
25037
|
+
} catch (error) {
|
|
25038
|
+
return {
|
|
25039
|
+
kind: "error",
|
|
25040
|
+
reason: `the token endpoint could not be reached: ${error instanceof Error ? error.message : String(error)}`
|
|
25041
|
+
};
|
|
25042
|
+
}
|
|
25043
|
+
}
|
|
25044
|
+
async function fetchAuthenticated(url, accessToken, context) {
|
|
25045
|
+
try {
|
|
25046
|
+
const response = await context.fetch(url, {
|
|
25047
|
+
method: "GET",
|
|
25048
|
+
headers: { authorization: `Bearer ${accessToken}` }
|
|
25049
|
+
});
|
|
25050
|
+
if (!response.ok) {
|
|
25051
|
+
return {
|
|
25052
|
+
ok: false,
|
|
25053
|
+
status: response.status,
|
|
25054
|
+
reason: `${url.pathname} returned HTTP ${response.status}`
|
|
25055
|
+
};
|
|
25056
|
+
}
|
|
25057
|
+
return { ok: true, body: await response.json() };
|
|
25058
|
+
} catch (error) {
|
|
25059
|
+
return {
|
|
25060
|
+
ok: false,
|
|
25061
|
+
reason: `${url.pathname} could not be reached: ${error instanceof Error ? error.message : String(error)}`
|
|
25062
|
+
};
|
|
25063
|
+
}
|
|
25064
|
+
}
|
|
25065
|
+
function withTrailingSlash(url) {
|
|
25066
|
+
return url.href.endsWith("/") ? url : new URL(`${url.href}/`);
|
|
25067
|
+
}
|
|
25068
|
+
|
|
25069
|
+
// src/services/backend-checks.ts
|
|
25070
|
+
function compareVersions(cliVersion, backendVersion) {
|
|
25071
|
+
const name = "version compatibility";
|
|
25072
|
+
const cli = parse4(cliVersion);
|
|
25073
|
+
const backend = parse4(backendVersion);
|
|
25074
|
+
if (!cli || !backend) {
|
|
25075
|
+
return {
|
|
25076
|
+
name,
|
|
25077
|
+
status: "warn",
|
|
25078
|
+
message: `CLI ${cliVersion} and backend ${backendVersion} cannot be compared as versions.`
|
|
25079
|
+
};
|
|
25080
|
+
}
|
|
25081
|
+
if (cli.major !== backend.major) {
|
|
25082
|
+
return {
|
|
25083
|
+
name,
|
|
25084
|
+
status: "fail",
|
|
25085
|
+
message: `CLI ${cliVersion} and backend ${backendVersion} are different major versions. Install a matching CLI with npm install -g @eudiplo/cli@${backend.major}.`
|
|
25086
|
+
};
|
|
25087
|
+
}
|
|
25088
|
+
if (cli.minor !== backend.minor) {
|
|
25089
|
+
return {
|
|
25090
|
+
name,
|
|
25091
|
+
status: "warn",
|
|
25092
|
+
message: `CLI ${cliVersion} and backend ${backendVersion} differ in minor version; some commands may not be supported.`
|
|
25093
|
+
};
|
|
25094
|
+
}
|
|
25095
|
+
return {
|
|
25096
|
+
name,
|
|
25097
|
+
status: "pass",
|
|
25098
|
+
message: `CLI ${cliVersion} matches backend ${backendVersion}.`
|
|
25099
|
+
};
|
|
25100
|
+
}
|
|
25101
|
+
function readBackendVersion(body) {
|
|
25102
|
+
if (typeof body === "object" && body !== null && "version" in body) {
|
|
25103
|
+
const version = body.version;
|
|
25104
|
+
return typeof version === "string" && version ? version : void 0;
|
|
25105
|
+
}
|
|
25106
|
+
return void 0;
|
|
25107
|
+
}
|
|
25108
|
+
function readProviderHealth(body) {
|
|
25109
|
+
if (!Array.isArray(body)) {
|
|
25110
|
+
throw new Error("the provider health response was not a list");
|
|
25111
|
+
}
|
|
25112
|
+
return body.map((entry) => {
|
|
25113
|
+
const record = entry;
|
|
25114
|
+
return {
|
|
25115
|
+
providerId: String(record.providerId ?? "unknown"),
|
|
25116
|
+
type: String(record.type ?? "unknown"),
|
|
25117
|
+
ok: record.ok === true,
|
|
25118
|
+
latencyMs: typeof record.latencyMs === "number" ? record.latencyMs : void 0,
|
|
25119
|
+
error: typeof record.error === "string" ? record.error : void 0
|
|
25120
|
+
};
|
|
25121
|
+
});
|
|
25122
|
+
}
|
|
25123
|
+
function summarizeProviderHealth(providers) {
|
|
25124
|
+
const name = "KMS providers";
|
|
25125
|
+
if (providers.length === 0) {
|
|
25126
|
+
return {
|
|
25127
|
+
name,
|
|
25128
|
+
status: "warn",
|
|
25129
|
+
message: "No KMS providers are registered for this tenant."
|
|
25130
|
+
};
|
|
25131
|
+
}
|
|
25132
|
+
const failing = providers.filter((provider) => !provider.ok);
|
|
25133
|
+
if (failing.length > 0) {
|
|
25134
|
+
return {
|
|
25135
|
+
name,
|
|
25136
|
+
status: "fail",
|
|
25137
|
+
message: `${failing.length}/${providers.length} provider(s) unhealthy: ${failing.map(
|
|
25138
|
+
(provider) => `${provider.providerId} (${provider.type})${provider.error ? ", health check reported an error" : ""}`
|
|
25139
|
+
).join(", ")}`
|
|
25140
|
+
};
|
|
25141
|
+
}
|
|
25142
|
+
return {
|
|
25143
|
+
name,
|
|
25144
|
+
status: "pass",
|
|
25145
|
+
message: `${providers.length} provider(s) healthy: ${providers.map(
|
|
25146
|
+
(provider) => `${provider.providerId} (${provider.type}${provider.latencyMs === void 0 ? "" : `, ${provider.latencyMs}ms`})`
|
|
25147
|
+
).join(", ")}`
|
|
25148
|
+
};
|
|
25149
|
+
}
|
|
25150
|
+
function parse4(version) {
|
|
25151
|
+
const match = /^v?(\d+)\.(\d+)\.(\d+)/.exec(version.trim());
|
|
25152
|
+
if (!match) {
|
|
25153
|
+
return void 0;
|
|
25154
|
+
}
|
|
25155
|
+
return {
|
|
25156
|
+
major: Number(match[1]),
|
|
25157
|
+
minor: Number(match[2]),
|
|
25158
|
+
patch: Number(match[3])
|
|
25159
|
+
};
|
|
25160
|
+
}
|
|
25161
|
+
|
|
25162
|
+
// src/services/tls-expiry.ts
|
|
25163
|
+
import { connect } from "node:tls";
|
|
25164
|
+
var defaultExpiryWarningDays = 30;
|
|
25165
|
+
var dayInMs = 24 * 60 * 60 * 1e3;
|
|
25166
|
+
function evaluateCertificate(certificate, now, warningDays = defaultExpiryWarningDays) {
|
|
25167
|
+
const remainingDays = Math.floor(
|
|
25168
|
+
(certificate.validTo.getTime() - now.getTime()) / dayInMs
|
|
25169
|
+
);
|
|
25170
|
+
const expiresOn = certificate.validTo.toISOString().slice(0, 10);
|
|
25171
|
+
if (remainingDays < 0) {
|
|
25172
|
+
return {
|
|
25173
|
+
name: "TLS certificate",
|
|
25174
|
+
status: "fail",
|
|
25175
|
+
message: `The certificate issued by ${certificate.issuer} expired on ${expiresOn}.`
|
|
25176
|
+
};
|
|
25177
|
+
}
|
|
25178
|
+
if (remainingDays <= warningDays) {
|
|
25179
|
+
return {
|
|
25180
|
+
name: "TLS certificate",
|
|
25181
|
+
status: "warn",
|
|
25182
|
+
message: `The certificate expires on ${expiresOn}, in ${remainingDays} day(s). Renew it before then.`
|
|
25183
|
+
};
|
|
25184
|
+
}
|
|
25185
|
+
return {
|
|
25186
|
+
name: "TLS certificate",
|
|
25187
|
+
status: "pass",
|
|
25188
|
+
message: `Valid until ${expiresOn} (${remainingDays} day(s) left), issued by ${certificate.issuer}.`
|
|
25189
|
+
};
|
|
25190
|
+
}
|
|
25191
|
+
var readPeerCertificate = (url) => new Promise((resolvePeer, rejectPeer) => {
|
|
25192
|
+
const socket = connect(
|
|
25193
|
+
{
|
|
25194
|
+
host: url.hostname,
|
|
25195
|
+
port: Number(url.port || 443),
|
|
25196
|
+
servername: url.hostname,
|
|
25197
|
+
rejectUnauthorized: true
|
|
25198
|
+
},
|
|
25199
|
+
() => {
|
|
25200
|
+
const certificate = socket.getPeerCertificate();
|
|
25201
|
+
socket.end();
|
|
25202
|
+
if (!certificate || !certificate.valid_to) {
|
|
25203
|
+
rejectPeer(new Error("no peer certificate was presented"));
|
|
25204
|
+
return;
|
|
22528
25205
|
}
|
|
22529
|
-
|
|
22530
|
-
|
|
22531
|
-
|
|
22532
|
-
|
|
22533
|
-
config,
|
|
22534
|
-
name,
|
|
22535
|
-
parsedArgs(name, void 0, args, options),
|
|
22536
|
-
context
|
|
22537
|
-
)
|
|
22538
|
-
);
|
|
25206
|
+
resolvePeer({
|
|
25207
|
+
subject: String(certificate.subject?.CN ?? url.hostname),
|
|
25208
|
+
issuer: String(certificate.issuer?.CN ?? "unknown issuer"),
|
|
25209
|
+
validTo: new Date(certificate.valid_to)
|
|
22539
25210
|
});
|
|
22540
25211
|
}
|
|
22541
25212
|
);
|
|
25213
|
+
socket.setTimeout(1e4, () => {
|
|
25214
|
+
socket.destroy();
|
|
25215
|
+
rejectPeer(new Error("the TLS handshake timed out"));
|
|
25216
|
+
});
|
|
25217
|
+
socket.once("error", (error) => {
|
|
25218
|
+
socket.destroy();
|
|
25219
|
+
rejectPeer(error);
|
|
25220
|
+
});
|
|
25221
|
+
});
|
|
25222
|
+
async function checkTlsCertificate(baseUrl, now, read = readPeerCertificate, warningDays = defaultExpiryWarningDays) {
|
|
25223
|
+
if (baseUrl.protocol !== "https:") {
|
|
25224
|
+
return {
|
|
25225
|
+
name: "TLS certificate",
|
|
25226
|
+
status: "skip",
|
|
25227
|
+
message: `${baseUrl.origin} does not use HTTPS, so there is no certificate to check.`
|
|
25228
|
+
};
|
|
25229
|
+
}
|
|
25230
|
+
try {
|
|
25231
|
+
return evaluateCertificate(await read(baseUrl), now, warningDays);
|
|
25232
|
+
} catch (error) {
|
|
25233
|
+
return {
|
|
25234
|
+
name: "TLS certificate",
|
|
25235
|
+
status: "fail",
|
|
25236
|
+
message: `The certificate of ${baseUrl.origin} could not be verified: ${error instanceof Error ? error.message : String(error)}`
|
|
25237
|
+
};
|
|
25238
|
+
}
|
|
22542
25239
|
}
|
|
22543
25240
|
|
|
22544
25241
|
// src/services/diagnostics.ts
|
|
22545
|
-
|
|
22546
|
-
|
|
22547
|
-
|
|
22548
|
-
|
|
22549
|
-
|
|
22550
|
-
{
|
|
25242
|
+
var publicUrlCheck = {
|
|
25243
|
+
id: "public-url",
|
|
25244
|
+
async run({ instance, baseUrl }) {
|
|
25245
|
+
if (!baseUrl) {
|
|
25246
|
+
return {
|
|
22551
25247
|
name: "public URL",
|
|
22552
25248
|
status: "fail",
|
|
22553
25249
|
message: `${instance.url} is not a valid absolute URL`
|
|
22554
|
-
}
|
|
22555
|
-
|
|
25250
|
+
};
|
|
25251
|
+
}
|
|
25252
|
+
return {
|
|
25253
|
+
name: "public URL",
|
|
25254
|
+
status: baseUrl.protocol === "https:" ? "pass" : "warn",
|
|
25255
|
+
message: baseUrl.protocol === "https:" ? `${baseUrl.href} uses HTTPS` : `${baseUrl.href} does not use HTTPS`
|
|
25256
|
+
};
|
|
22556
25257
|
}
|
|
22557
|
-
|
|
22558
|
-
|
|
22559
|
-
|
|
22560
|
-
|
|
22561
|
-
|
|
22562
|
-
|
|
22563
|
-
|
|
22564
|
-
)
|
|
22565
|
-
|
|
22566
|
-
|
|
22567
|
-
|
|
22568
|
-
|
|
22569
|
-
|
|
25258
|
+
};
|
|
25259
|
+
var apiReachabilityCheck = {
|
|
25260
|
+
id: "api-reachability",
|
|
25261
|
+
run: ({ baseUrl, context }) => requireBaseUrl(
|
|
25262
|
+
"API reachability",
|
|
25263
|
+
baseUrl,
|
|
25264
|
+
(url) => checkEndpoint("API reachability", url, "api/docs", context)
|
|
25265
|
+
)
|
|
25266
|
+
};
|
|
25267
|
+
var healthEndpointCheck = {
|
|
25268
|
+
id: "health-endpoint",
|
|
25269
|
+
run: ({ baseUrl, context }) => requireBaseUrl(
|
|
25270
|
+
"health endpoint",
|
|
25271
|
+
baseUrl,
|
|
25272
|
+
(url) => checkEndpoint("health endpoint", url, "health", context)
|
|
25273
|
+
)
|
|
25274
|
+
};
|
|
25275
|
+
var tlsCertificateCheck = {
|
|
25276
|
+
id: "tls-certificate",
|
|
25277
|
+
run: ({ baseUrl, now, readCertificate }) => requireBaseUrl(
|
|
25278
|
+
"TLS certificate",
|
|
25279
|
+
baseUrl,
|
|
25280
|
+
(url) => checkTlsCertificate(url, now, readCertificate)
|
|
25281
|
+
)
|
|
25282
|
+
};
|
|
25283
|
+
var authenticationCheck = {
|
|
25284
|
+
id: "authentication",
|
|
25285
|
+
async run({ context }) {
|
|
25286
|
+
const configured = Boolean(context.env.EUDIPLO_CLIENT_ID) && Boolean(context.env.EUDIPLO_CLIENT_SECRET);
|
|
25287
|
+
return {
|
|
25288
|
+
name: "authentication configuration",
|
|
25289
|
+
status: configured ? "pass" : "warn",
|
|
25290
|
+
message: configured ? "Client credentials are available in environment variables." : "Set EUDIPLO_CLIENT_ID and EUDIPLO_CLIENT_SECRET when commands need authenticated API access."
|
|
25291
|
+
};
|
|
25292
|
+
}
|
|
25293
|
+
};
|
|
25294
|
+
var clientConnectivityCheck = {
|
|
25295
|
+
id: "client-connectivity",
|
|
25296
|
+
async run({ instance, context }) {
|
|
25297
|
+
if (!instance.clientUrl) {
|
|
25298
|
+
return {
|
|
25299
|
+
name: "client connectivity",
|
|
25300
|
+
status: "skip",
|
|
25301
|
+
message: "No client URL configured for this instance."
|
|
25302
|
+
};
|
|
25303
|
+
}
|
|
22570
25304
|
const clientUrl = parseUrl(instance.clientUrl);
|
|
22571
|
-
|
|
22572
|
-
|
|
22573
|
-
"client connectivity",
|
|
22574
|
-
clientUrl,
|
|
22575
|
-
"/",
|
|
22576
|
-
context
|
|
22577
|
-
) : {
|
|
25305
|
+
if (!clientUrl) {
|
|
25306
|
+
return {
|
|
22578
25307
|
name: "client connectivity",
|
|
22579
25308
|
status: "fail",
|
|
22580
25309
|
message: `${instance.clientUrl} is not a valid absolute URL`
|
|
25310
|
+
};
|
|
25311
|
+
}
|
|
25312
|
+
return checkEndpoint("client connectivity", clientUrl, "", context);
|
|
25313
|
+
}
|
|
25314
|
+
};
|
|
25315
|
+
var versionCompatibilityCheck = {
|
|
25316
|
+
id: "version-compatibility",
|
|
25317
|
+
run: ({ baseUrl, context, accessToken }) => requireBaseUrl("version compatibility", baseUrl, async (url) => {
|
|
25318
|
+
const token = await accessToken();
|
|
25319
|
+
if (token.kind !== "token") {
|
|
25320
|
+
return authUnavailable("version compatibility", token);
|
|
25321
|
+
}
|
|
25322
|
+
const response = await fetchAuthenticated(
|
|
25323
|
+
new URL("api/version", withTrailingSlash(url)),
|
|
25324
|
+
token.accessToken,
|
|
25325
|
+
context
|
|
25326
|
+
);
|
|
25327
|
+
if (!response.ok) {
|
|
25328
|
+
if (response.status === 404) {
|
|
25329
|
+
return {
|
|
25330
|
+
name: "version compatibility",
|
|
25331
|
+
status: "skip",
|
|
25332
|
+
message: "This backend does not expose /api/version, so compatibility cannot be checked."
|
|
25333
|
+
};
|
|
22581
25334
|
}
|
|
25335
|
+
return {
|
|
25336
|
+
name: "version compatibility",
|
|
25337
|
+
status: "fail",
|
|
25338
|
+
message: `The backend version could not be read: ${response.reason}`
|
|
25339
|
+
};
|
|
25340
|
+
}
|
|
25341
|
+
const backendVersion = readBackendVersion(response.body);
|
|
25342
|
+
if (!backendVersion) {
|
|
25343
|
+
return {
|
|
25344
|
+
name: "version compatibility",
|
|
25345
|
+
status: "warn",
|
|
25346
|
+
message: "The backend did not report a version."
|
|
25347
|
+
};
|
|
25348
|
+
}
|
|
25349
|
+
return compareVersions(package_default.version, backendVersion);
|
|
25350
|
+
})
|
|
25351
|
+
};
|
|
25352
|
+
var kmsHealthCheck = {
|
|
25353
|
+
id: "kms-health",
|
|
25354
|
+
run: ({ baseUrl, context, accessToken }) => requireBaseUrl("KMS providers", baseUrl, async (url) => {
|
|
25355
|
+
const token = await accessToken();
|
|
25356
|
+
if (token.kind !== "token") {
|
|
25357
|
+
return authUnavailable("KMS providers", token);
|
|
25358
|
+
}
|
|
25359
|
+
const response = await fetchAuthenticated(
|
|
25360
|
+
new URL(
|
|
25361
|
+
"api/key-chain/providers/health",
|
|
25362
|
+
withTrailingSlash(url)
|
|
25363
|
+
),
|
|
25364
|
+
token.accessToken,
|
|
25365
|
+
context
|
|
22582
25366
|
);
|
|
22583
|
-
|
|
22584
|
-
|
|
22585
|
-
|
|
22586
|
-
|
|
22587
|
-
|
|
22588
|
-
|
|
25367
|
+
if (!response.ok) {
|
|
25368
|
+
if (response.status === 404) {
|
|
25369
|
+
return {
|
|
25370
|
+
name: "KMS providers",
|
|
25371
|
+
status: "skip",
|
|
25372
|
+
message: "This backend does not expose the KMS provider health endpoint."
|
|
25373
|
+
};
|
|
25374
|
+
}
|
|
25375
|
+
return {
|
|
25376
|
+
name: "KMS providers",
|
|
25377
|
+
status: "fail",
|
|
25378
|
+
message: `Provider health could not be read: ${response.reason}`
|
|
25379
|
+
};
|
|
25380
|
+
}
|
|
25381
|
+
try {
|
|
25382
|
+
return summarizeProviderHealth(
|
|
25383
|
+
readProviderHealth(response.body)
|
|
25384
|
+
);
|
|
25385
|
+
} catch {
|
|
25386
|
+
return {
|
|
25387
|
+
name: "KMS providers",
|
|
25388
|
+
status: "warn",
|
|
25389
|
+
message: "The provider health response could not be read."
|
|
25390
|
+
};
|
|
25391
|
+
}
|
|
25392
|
+
})
|
|
25393
|
+
};
|
|
25394
|
+
function authUnavailable(name, token) {
|
|
25395
|
+
return {
|
|
25396
|
+
name,
|
|
25397
|
+
status: token.kind === "unavailable" ? "skip" : "fail",
|
|
25398
|
+
message: token.kind === "unavailable" ? `Needs authentication: ${token.reason}.` : `Could not authenticate: ${token.reason}.`
|
|
25399
|
+
};
|
|
25400
|
+
}
|
|
25401
|
+
var coreChecks = [
|
|
25402
|
+
publicUrlCheck,
|
|
25403
|
+
apiReachabilityCheck,
|
|
25404
|
+
healthEndpointCheck,
|
|
25405
|
+
tlsCertificateCheck,
|
|
25406
|
+
authenticationCheck,
|
|
25407
|
+
versionCompatibilityCheck,
|
|
25408
|
+
kmsHealthCheck,
|
|
25409
|
+
clientConnectivityCheck
|
|
25410
|
+
];
|
|
25411
|
+
async function runDoctor(instance, context, driverDiagnostics, options = {}) {
|
|
25412
|
+
const baseUrl = parseUrl(instance.url);
|
|
25413
|
+
let token;
|
|
25414
|
+
const checkContext = {
|
|
25415
|
+
instance,
|
|
25416
|
+
context,
|
|
25417
|
+
baseUrl,
|
|
25418
|
+
now: options.now ?? /* @__PURE__ */ new Date(),
|
|
25419
|
+
readCertificate: options.readCertificate ?? context.readCertificate ?? readPeerCertificate,
|
|
25420
|
+
accessToken: () => {
|
|
25421
|
+
if (!baseUrl) {
|
|
25422
|
+
return Promise.resolve({
|
|
25423
|
+
kind: "unavailable",
|
|
25424
|
+
reason: "the instance URL could not be parsed"
|
|
25425
|
+
});
|
|
25426
|
+
}
|
|
25427
|
+
token ??= requestAccessToken(baseUrl, context);
|
|
25428
|
+
return token;
|
|
25429
|
+
}
|
|
25430
|
+
};
|
|
25431
|
+
const checks = [];
|
|
25432
|
+
for (const check of coreChecks) {
|
|
25433
|
+
checks.push(await check.run(checkContext));
|
|
22589
25434
|
}
|
|
22590
25435
|
checks.push(...driverDiagnostics);
|
|
22591
25436
|
return checks;
|
|
22592
25437
|
}
|
|
22593
|
-
function
|
|
22594
|
-
return
|
|
25438
|
+
function summarizeChecks(checks) {
|
|
25439
|
+
return {
|
|
25440
|
+
pass: count(checks, "pass"),
|
|
25441
|
+
warn: count(checks, "warn"),
|
|
25442
|
+
fail: count(checks, "fail"),
|
|
25443
|
+
skip: count(checks, "skip")
|
|
25444
|
+
};
|
|
25445
|
+
}
|
|
25446
|
+
function hasFailedChecks(checks, strict = false) {
|
|
25447
|
+
return checks.some(
|
|
25448
|
+
(check) => check.status === "fail" || strict && check.status === "warn"
|
|
25449
|
+
);
|
|
22595
25450
|
}
|
|
22596
25451
|
function formatChecks(checks) {
|
|
22597
25452
|
return checks.map(
|
|
22598
25453
|
(check) => `${formatStatus(check.status)} ${check.name}: ${check.message}`
|
|
22599
25454
|
).join("\n");
|
|
22600
25455
|
}
|
|
25456
|
+
function formatSummary(summary) {
|
|
25457
|
+
return `${summary.pass} passed, ${summary.warn} warning(s), ${summary.fail} failure(s), ${summary.skip} skipped`;
|
|
25458
|
+
}
|
|
25459
|
+
function count(checks, status) {
|
|
25460
|
+
return checks.filter((check) => check.status === status).length;
|
|
25461
|
+
}
|
|
25462
|
+
async function requireBaseUrl(name, baseUrl, run) {
|
|
25463
|
+
if (!baseUrl) {
|
|
25464
|
+
return {
|
|
25465
|
+
name,
|
|
25466
|
+
status: "skip",
|
|
25467
|
+
message: "The instance URL could not be parsed."
|
|
25468
|
+
};
|
|
25469
|
+
}
|
|
25470
|
+
return run(baseUrl);
|
|
25471
|
+
}
|
|
22601
25472
|
async function checkEndpoint(name, baseUrl, path2, context) {
|
|
22602
|
-
const url = new URL(path2, baseUrl);
|
|
25473
|
+
const url = new URL(path2, withTrailingSlash(baseUrl));
|
|
22603
25474
|
try {
|
|
22604
25475
|
const response = await context.fetch(url, { method: "GET" });
|
|
22605
25476
|
if (response.ok) {
|
|
@@ -22622,22 +25493,6 @@ async function checkEndpoint(name, baseUrl, path2, context) {
|
|
|
22622
25493
|
};
|
|
22623
25494
|
}
|
|
22624
25495
|
}
|
|
22625
|
-
function checkAuthentication(context) {
|
|
22626
|
-
const hasClientId = Boolean(context.env.EUDIPLO_CLIENT_ID);
|
|
22627
|
-
const hasClientSecret = Boolean(context.env.EUDIPLO_CLIENT_SECRET);
|
|
22628
|
-
if (hasClientId && hasClientSecret) {
|
|
22629
|
-
return {
|
|
22630
|
-
name: "authentication configuration",
|
|
22631
|
-
status: "pass",
|
|
22632
|
-
message: "Client credentials are available in environment variables."
|
|
22633
|
-
};
|
|
22634
|
-
}
|
|
22635
|
-
return {
|
|
22636
|
-
name: "authentication configuration",
|
|
22637
|
-
status: "warn",
|
|
22638
|
-
message: "Set EUDIPLO_CLIENT_ID and EUDIPLO_CLIENT_SECRET when commands need authenticated API access."
|
|
22639
|
-
};
|
|
22640
|
-
}
|
|
22641
25496
|
function parseUrl(value) {
|
|
22642
25497
|
try {
|
|
22643
25498
|
const url = new URL(value);
|
|
@@ -22653,28 +25508,54 @@ function formatStatus(status) {
|
|
|
22653
25508
|
if (status === "warn") {
|
|
22654
25509
|
return "WARN";
|
|
22655
25510
|
}
|
|
25511
|
+
if (status === "skip") {
|
|
25512
|
+
return "SKIP";
|
|
25513
|
+
}
|
|
22656
25514
|
return "FAIL";
|
|
22657
25515
|
}
|
|
22658
25516
|
|
|
22659
25517
|
// src/commands/doctor/action.ts
|
|
22660
|
-
async function runDoctorCommand(config, parsed, context) {
|
|
22661
|
-
const
|
|
25518
|
+
async function runDoctorCommand(config, parsed, context, options = {}) {
|
|
25519
|
+
const strict = parsed.flags.strict === true;
|
|
25520
|
+
const instances = parsed.flags.all === true ? Object.keys(config.instances) : [resolveInstance(config, parsed)[0]];
|
|
25521
|
+
if (instances.length === 0) {
|
|
25522
|
+
throw new Error("No instances are configured.");
|
|
25523
|
+
}
|
|
25524
|
+
let failed = false;
|
|
25525
|
+
for (const [index, instanceName] of instances.entries()) {
|
|
25526
|
+
const instance = config.instances[instanceName];
|
|
25527
|
+
if (index > 0) {
|
|
25528
|
+
context.stdout.write("\n");
|
|
25529
|
+
}
|
|
25530
|
+
const checks = await runDiagnostics(instance, context, options);
|
|
25531
|
+
context.stdout.write(
|
|
25532
|
+
`Doctor for ${instanceName} (${instance.target})
|
|
25533
|
+
`
|
|
25534
|
+
);
|
|
25535
|
+
context.stdout.write(`${formatChecks(checks)}
|
|
25536
|
+
`);
|
|
25537
|
+
context.stdout.write(`${formatSummary(summarizeChecks(checks))}
|
|
25538
|
+
`);
|
|
25539
|
+
failed = hasFailedChecks(checks, strict) || failed;
|
|
25540
|
+
}
|
|
25541
|
+
return failed ? 1 : 0;
|
|
25542
|
+
}
|
|
25543
|
+
async function runDiagnostics(instance, context, options) {
|
|
22662
25544
|
const driver = drivers[instance.target];
|
|
22663
|
-
|
|
25545
|
+
return runDoctor(
|
|
22664
25546
|
instance,
|
|
22665
25547
|
context,
|
|
22666
|
-
await driver.diagnostics(instance, context)
|
|
25548
|
+
await driver.diagnostics(instance, context),
|
|
25549
|
+
options
|
|
22667
25550
|
);
|
|
22668
|
-
context.stdout.write(`Doctor for ${instanceName} (${instance.target})
|
|
22669
|
-
`);
|
|
22670
|
-
context.stdout.write(`${formatChecks(checks)}
|
|
22671
|
-
`);
|
|
22672
|
-
return hasFailedChecks(checks) ? 1 : 0;
|
|
22673
25551
|
}
|
|
22674
25552
|
|
|
22675
25553
|
// src/commands/doctor/index.ts
|
|
22676
25554
|
function createDoctorCommand(context, setExitCode) {
|
|
22677
|
-
return new Command("doctor").description("Run deployment diagnostics").option("--instance <name>", "select a configured instance").
|
|
25555
|
+
return new Command("doctor").description("Run deployment diagnostics").option("--instance <name>", "select a configured instance").option("--all", "run the checks for every configured instance").option(
|
|
25556
|
+
"--strict",
|
|
25557
|
+
"treat warnings as failures (skipped checks never fail)"
|
|
25558
|
+
).action(async (options) => {
|
|
22678
25559
|
const { config } = await loadCliState(context);
|
|
22679
25560
|
setExitCode(
|
|
22680
25561
|
await runDoctorCommand(
|
|
@@ -23070,7 +25951,9 @@ function runInstanceList(config, context) {
|
|
|
23070
25951
|
function runInstanceShow(config, parsed, context) {
|
|
23071
25952
|
const name = parsed.positionals[0] ?? config.defaultInstance;
|
|
23072
25953
|
if (!name) {
|
|
23073
|
-
throw new Error(
|
|
25954
|
+
throw new Error(
|
|
25955
|
+
"No instance selected. Specify a name or add an instance first."
|
|
25956
|
+
);
|
|
23074
25957
|
}
|
|
23075
25958
|
const instance = config.instances[name];
|
|
23076
25959
|
if (!instance) {
|
|
@@ -23396,6 +26279,10 @@ import { resolve as resolve8 } from "node:path";
|
|
|
23396
26279
|
|
|
23397
26280
|
// src/services/compose-upgrade.ts
|
|
23398
26281
|
var managedImages = {
|
|
26282
|
+
EUDIPLO_IMAGE: "ghcr.io/eudiplo/eudiplo",
|
|
26283
|
+
EUDIPLO_CLIENT_IMAGE: "ghcr.io/eudiplo/eudiplo-client"
|
|
26284
|
+
};
|
|
26285
|
+
var legacyImages = {
|
|
23399
26286
|
EUDIPLO_IMAGE: "ghcr.io/openwallet-foundation/eudiplo",
|
|
23400
26287
|
EUDIPLO_CLIENT_IMAGE: "ghcr.io/openwallet-foundation/eudiplo-client"
|
|
23401
26288
|
};
|
|
@@ -23407,6 +26294,14 @@ function assertImageTag(tag) {
|
|
|
23407
26294
|
);
|
|
23408
26295
|
}
|
|
23409
26296
|
}
|
|
26297
|
+
function tagOf(value, repository) {
|
|
26298
|
+
const prefix = `${repository}:`;
|
|
26299
|
+
if (!value.startsWith(prefix)) {
|
|
26300
|
+
return void 0;
|
|
26301
|
+
}
|
|
26302
|
+
const tag = value.slice(prefix.length);
|
|
26303
|
+
return TAG.test(tag) ? tag : void 0;
|
|
26304
|
+
}
|
|
23410
26305
|
function planImageUpgrade(content, tag) {
|
|
23411
26306
|
assertImageTag(tag);
|
|
23412
26307
|
const found = /* @__PURE__ */ new Set();
|
|
@@ -23428,17 +26323,26 @@ function planImageUpgrade(content, tag) {
|
|
|
23428
26323
|
);
|
|
23429
26324
|
}
|
|
23430
26325
|
found.add(key);
|
|
23431
|
-
const
|
|
23432
|
-
const
|
|
23433
|
-
|
|
26326
|
+
const currentTag = tagOf(value, repository);
|
|
26327
|
+
const legacyTag = tagOf(value, legacyImages[key]);
|
|
26328
|
+
const current = currentTag ?? legacyTag;
|
|
26329
|
+
if (current === void 0) {
|
|
23434
26330
|
throw new Error(
|
|
23435
|
-
`${key} is set to ${value}, which is not a CLI-managed image. Update it yourself, or restore ${
|
|
26331
|
+
`${key} is set to ${value}, which is not a CLI-managed image. Update it yourself, or restore ${repository}:<tag> to let the CLI manage it.`
|
|
23436
26332
|
);
|
|
23437
26333
|
}
|
|
23438
|
-
if (
|
|
26334
|
+
if (currentTag === void 0) {
|
|
26335
|
+
changes.push({
|
|
26336
|
+
key,
|
|
26337
|
+
repository,
|
|
26338
|
+
movedFrom: legacyImages[key],
|
|
26339
|
+
from: current,
|
|
26340
|
+
to: tag
|
|
26341
|
+
});
|
|
26342
|
+
} else if (current !== tag) {
|
|
23439
26343
|
changes.push({ key, repository, from: current, to: tag });
|
|
23440
26344
|
}
|
|
23441
|
-
return `${key}=${
|
|
26345
|
+
return `${key}=${repository}:${tag}${lineEnding}`;
|
|
23442
26346
|
});
|
|
23443
26347
|
if (!found.has("EUDIPLO_IMAGE")) {
|
|
23444
26348
|
throw new Error(
|
|
@@ -23458,10 +26362,10 @@ function parseVersion(tag) {
|
|
|
23458
26362
|
patch: Number(match[3])
|
|
23459
26363
|
};
|
|
23460
26364
|
}
|
|
23461
|
-
function
|
|
26365
|
+
function compareVersions2(a, b) {
|
|
23462
26366
|
return a.major - b.major || a.minor - b.minor || a.patch - b.patch;
|
|
23463
26367
|
}
|
|
23464
|
-
var migrationBaseUrl = "https://docs.eudiplo.dev/
|
|
26368
|
+
var migrationBaseUrl = "https://docs.eudiplo.dev/upgrade";
|
|
23465
26369
|
function migrationNotes(from, to) {
|
|
23466
26370
|
const fromVersion = parseVersion(from);
|
|
23467
26371
|
const toVersion = parseVersion(to);
|
|
@@ -23470,7 +26374,7 @@ function migrationNotes(from, to) {
|
|
|
23470
26374
|
`Cannot compare ${from} and ${to} as versions. Check the release notes and ${migrationBaseUrl} before continuing.`
|
|
23471
26375
|
];
|
|
23472
26376
|
}
|
|
23473
|
-
const order =
|
|
26377
|
+
const order = compareVersions2(fromVersion, toVersion);
|
|
23474
26378
|
if (order > 0) {
|
|
23475
26379
|
return [
|
|
23476
26380
|
`${to} is older than ${from}. Downgrades are not supported once database migrations have run; restore a backup instead if you need to go back.`
|
|
@@ -23525,7 +26429,8 @@ async function runUpgradeCommand(config, parsed, context) {
|
|
|
23525
26429
|
`);
|
|
23526
26430
|
for (const change of plan.changes) {
|
|
23527
26431
|
context.stdout.write(
|
|
23528
|
-
` ${change.
|
|
26432
|
+
change.movedFrom ? ` ${change.movedFrom}:${change.from} -> ${change.repository}:${change.to}
|
|
26433
|
+
` : ` ${change.repository}: ${change.from} -> ${change.to}
|
|
23529
26434
|
`
|
|
23530
26435
|
);
|
|
23531
26436
|
}
|
|
@@ -23608,78 +26513,6 @@ function createUpgradeCommand(context, setExitCode) {
|
|
|
23608
26513
|
|
|
23609
26514
|
// src/commands/version/action.ts
|
|
23610
26515
|
import { isSea as isSea2 } from "node:sea";
|
|
23611
|
-
|
|
23612
|
-
// package.json
|
|
23613
|
-
var package_default = {
|
|
23614
|
-
name: "@eudiplo/cli",
|
|
23615
|
-
version: "8.1.0",
|
|
23616
|
-
description: "Deployment-aware command line tools for EUDIPLO",
|
|
23617
|
-
private: false,
|
|
23618
|
-
type: "module",
|
|
23619
|
-
bin: {
|
|
23620
|
-
eudiplo: "dist/index.js"
|
|
23621
|
-
},
|
|
23622
|
-
files: [
|
|
23623
|
-
"dist",
|
|
23624
|
-
"templates",
|
|
23625
|
-
"README.md"
|
|
23626
|
-
],
|
|
23627
|
-
scripts: {
|
|
23628
|
-
"assets:sync": "node scripts/sync-cli-assets.cjs",
|
|
23629
|
-
"assets:check": "node scripts/check-cli-assets.cjs",
|
|
23630
|
-
build: "pnpm assets:sync && pnpm assets:check && tsc -p tsconfig.json",
|
|
23631
|
-
"build:publish": "pnpm build && esbuild src/index.ts --bundle --platform=node --format=esm --target=node22.12 --alias:jsonc-parser=jsonc-parser/lib/esm/main.js --outfile=dist/index.js",
|
|
23632
|
-
"build:sea:bundle": "pnpm assets:sync && pnpm assets:check && esbuild src/index.ts --bundle --platform=node --format=esm --target=node22.12 --alias:jsonc-parser=jsonc-parser/lib/esm/main.js --outfile=dist-sea/index.js",
|
|
23633
|
-
"build:sea": "node scripts/build-cli-sea.mjs",
|
|
23634
|
-
dev: "tsx src/index.ts",
|
|
23635
|
-
test: "vitest run --project cli",
|
|
23636
|
-
lint: "biome lint .",
|
|
23637
|
-
prepublishOnly: "pnpm build:publish"
|
|
23638
|
-
},
|
|
23639
|
-
keywords: [
|
|
23640
|
-
"eudiplo",
|
|
23641
|
-
"cli",
|
|
23642
|
-
"eudi",
|
|
23643
|
-
"wallet",
|
|
23644
|
-
"oid4vci",
|
|
23645
|
-
"oid4vp"
|
|
23646
|
-
],
|
|
23647
|
-
repository: {
|
|
23648
|
-
type: "git",
|
|
23649
|
-
url: "git+https://github.com/openwallet-foundation/eudiplo.git",
|
|
23650
|
-
directory: "apps/cli"
|
|
23651
|
-
},
|
|
23652
|
-
homepage: "https://github.com/openwallet-foundation/eudiplo/tree/main/apps/cli#readme",
|
|
23653
|
-
bugs: {
|
|
23654
|
-
url: "https://github.com/openwallet-foundation/eudiplo/issues"
|
|
23655
|
-
},
|
|
23656
|
-
author: "OpenWallet Foundation",
|
|
23657
|
-
license: "Apache-2.0",
|
|
23658
|
-
engines: {
|
|
23659
|
-
node: ">=22.12.0"
|
|
23660
|
-
},
|
|
23661
|
-
publishConfig: {
|
|
23662
|
-
access: "public"
|
|
23663
|
-
},
|
|
23664
|
-
dependencies: {
|
|
23665
|
-
"@eudiplo/config-format": "workspace:*",
|
|
23666
|
-
ajv: "^8.20.0",
|
|
23667
|
-
"ajv-formats": "^3.0.1",
|
|
23668
|
-
commander: "^15.0.0",
|
|
23669
|
-
fflate: "^0.8.3",
|
|
23670
|
-
"jsonc-parser": "^3.3.1"
|
|
23671
|
-
},
|
|
23672
|
-
devDependencies: {
|
|
23673
|
-
"@biomejs/biome": "2.5.14",
|
|
23674
|
-
"@types/node": "^26.4.0",
|
|
23675
|
-
esbuild: "^0.28.2",
|
|
23676
|
-
tsx: "^4.23.13",
|
|
23677
|
-
typescript: "^7.0.2",
|
|
23678
|
-
vitest: "4.1.11"
|
|
23679
|
-
}
|
|
23680
|
-
};
|
|
23681
|
-
|
|
23682
|
-
// src/commands/version/action.ts
|
|
23683
26516
|
function versionText() {
|
|
23684
26517
|
return `${package_default.name} ${package_default.version}`;
|
|
23685
26518
|
}
|
|
@@ -23779,7 +26612,7 @@ function createProgram(context, setExitCode) {
|
|
|
23779
26612
|
"Print the installed CLI version"
|
|
23780
26613
|
).helpCommand(true).addHelpText(
|
|
23781
26614
|
"afterAll",
|
|
23782
|
-
"\nFor more information, see https://docs.eudiplo.dev/
|
|
26615
|
+
"\nFor more information, see https://docs.eudiplo.dev/cookbooks/foundation"
|
|
23783
26616
|
);
|
|
23784
26617
|
program2.addCommand(createDemoCommand(context, setExitCode));
|
|
23785
26618
|
program2.addCommand(createInitCommand(context, setExitCode));
|