Add utils to edit the realm

This commit is contained in:
Joseph Garrone 2024-12-13 09:07:11 +01:00
parent 1e43343529
commit 0cae2c68d8
3 changed files with 423 additions and 17 deletions

View File

@ -0,0 +1,123 @@
import { z } from "zod";
import { assert, type Equals } from "tsafe/assert";
import { is } from "tsafe/is";
import { id } from "tsafe/id";
import * as fs from "fs";
import { join as pathJoin } from "path";
import { getThisCodebaseRootDirPath } from "../tools/getThisCodebaseRootDirPath";
export type ParsedRealmJson = {
name: string;
users: {
id: string;
email: string;
username: string;
attributes: Record<string, unknown>;
credentials: {
type: string /* "password" or something else */;
}[];
clientRoles: Record<string, string[]>;
}[];
roles: {
client: {
name: string;
containerId: string; // client id
}[];
};
clients: {
id: string;
clientId: string; // example: realm-management
baseUrl?: string;
redirectUris?: string[];
webOrigins?: string[];
attributes?: {
"post.logout.redirect.uris"?: string;
};
protocol?: string;
protocolMappers?: unknown[];
}[];
};
export function readRealmJsonFile(params: {
realmJsonFilePath: string;
}): ParsedRealmJson {
const { realmJsonFilePath } = params;
const parsedRealmJson = JSON.parse(
fs.readFileSync(realmJsonFilePath).toString("utf8")
) as unknown;
const zParsedRealmJson = (() => {
type TargetType = ParsedRealmJson;
const zTargetType = z.object({
name: z.string(),
users: z.array(
z.object({
id: z.string(),
email: z.string(),
username: z.string(),
attributes: z.record(z.unknown()),
credentials: z.array(
z.object({
type: z.string()
})
),
clientRoles: z.record(z.array(z.string()))
})
),
roles: z.object({
client: z.array(
z.object({
name: z.string(),
containerId: z.string()
})
)
}),
clients: z.array(
z.object({
id: z.string(),
clientId: z.string(),
baseUrl: z.string().optional(),
redirectUris: z.array(z.string()).optional(),
webOrigins: z.array(z.string()).optional(),
attributes: z
.object({
"post.logout.redirect.uris": z.string().optional()
})
.optional(),
protocol: z.string().optional(),
protocolMappers: z.array(z.unknown()).optional()
})
)
});
type InferredType = z.infer<typeof zTargetType>;
assert<Equals<TargetType, InferredType>>;
return id<z.ZodType<TargetType>>(zTargetType);
})();
zParsedRealmJson.parse(parsedRealmJson);
assert(is<ParsedRealmJson>(parsedRealmJson));
return parsedRealmJson;
}
export function getDefaultConfig(params: {
keycloakMajorVersionNumber: number;
}): ParsedRealmJson {
const { keycloakMajorVersionNumber } = params;
const realmJsonFilePath = pathJoin(
getThisCodebaseRootDirPath(),
"src",
"bin",
"start-keycloak",
`myrealm-realm-${keycloakMajorVersionNumber}.json`
);
return readRealmJsonFile({ realmJsonFilePath });
}

View File

@ -0,0 +1,271 @@
import { assert } from "tsafe/assert";
import { getDefaultConfig, type ParsedRealmJson } from "./ParsedRealmJson";
function addOrEditTestUser(params: {
parsedRealmJson: ParsedRealmJson;
keycloakMajorVersionNumber: number;
}): { username: string } {
const { parsedRealmJson, keycloakMajorVersionNumber } = params;
const parsedRealmJson_default = getDefaultConfig({ keycloakMajorVersionNumber });
const [defaultUser_default] = parsedRealmJson_default.users;
assert(defaultUser_default !== undefined);
const defaultUser_preexisting = parsedRealmJson.users.find(
user => user.username === defaultUser_default.username
);
const newUser = structuredClone(
defaultUser_preexisting ??
(() => {
const firstUser = parsedRealmJson.users[0];
if (firstUser === undefined) {
return undefined;
}
const firstUserCopy = structuredClone(firstUser);
firstUserCopy.id = defaultUser_default.id;
return firstUserCopy;
})() ??
defaultUser_default
);
newUser.username = defaultUser_default.username;
newUser.email = defaultUser_default.email;
delete_existing_password_credential_if_any: {
const i = newUser.credentials.findIndex(
credential => credential.type === "password"
);
if (i === -1) {
break delete_existing_password_credential_if_any;
}
newUser.credentials.splice(i, 1);
}
{
const credential = defaultUser_default.credentials.find(
credential => credential.type === "password"
);
assert(credential !== undefined);
newUser.credentials.push(credential);
}
{
const nameByClientId = Object.fromEntries(
parsedRealmJson.clients.map(client => [client.id, client.clientId] as const)
);
newUser.clientRoles = {};
for (const clientRole of parsedRealmJson.roles.client) {
const clientName = nameByClientId[clientRole.containerId];
assert(clientName !== undefined);
(newUser.clientRoles[clientName] ??= []).push(clientRole.name);
}
}
if (defaultUser_preexisting === undefined) {
parsedRealmJson.users.push(newUser);
} else {
const i = parsedRealmJson.users.indexOf(defaultUser_preexisting);
assert(i !== -1);
parsedRealmJson.users[i] = newUser;
}
return { username: newUser.username };
}
const TEST_APP_URL = "https://my-theme.keycloakify.dev";
function addOrEditClient(params: {
parsedRealmJson: ParsedRealmJson;
keycloakMajorVersionNumber: number;
}): { clientId: string } {
const { parsedRealmJson, keycloakMajorVersionNumber } = params;
const parsedRealmJson_default = getDefaultConfig({ keycloakMajorVersionNumber });
const testClient_default = (() => {
const clients = parsedRealmJson_default.clients.filter(client => {
return JSON.stringify(client).includes(TEST_APP_URL);
});
assert(clients.length === 1);
return clients[0];
})();
const clientIds_builtIn = parsedRealmJson_default.clients
.map(client => client.clientId)
.filter(clientId => clientId !== testClient_default.clientId);
const testClient_preexisting = (() => {
const clients = parsedRealmJson.clients
.filter(client => !clientIds_builtIn.includes(client.clientId))
.filter(client => client.protocol === "openid-connect");
{
const client = clients.find(
client => client.clientId === testClient_default.clientId
);
if (client !== undefined) {
return client;
}
}
{
const client = clients.find(
client =>
client.redirectUris?.find(redirectUri =>
redirectUri.startsWith(TEST_APP_URL)
) !== undefined
);
if (client !== undefined) {
return client;
}
}
const [client] = clients;
if (client === undefined) {
return undefined;
}
return client;
})();
let testClient: typeof testClient_default;
if (testClient_preexisting !== undefined) {
testClient = testClient_preexisting;
} else {
testClient = structuredClone(testClient_default);
delete testClient.protocolMappers;
parsedRealmJson.clients.push(testClient);
}
{
for (const redirectUri of [
`${TEST_APP_URL}/*`,
"http://localhost*",
"http://127.0.0.1*"
]) {
for (const propertyName of ["webOrigins", "redirectUris"] as const) {
const arr = (testClient[propertyName] ??= []);
if (arr.includes(redirectUri)) {
continue;
}
arr.push(redirectUri);
}
{
if (testClient.attributes === undefined) {
testClient.attributes = {};
}
const arr = (testClient.attributes["post.logout.redirect.uris"] ?? "")
.split("##")
.map(s => s.trim());
if (!arr.includes(redirectUri)) {
arr.push(redirectUri);
testClient.attributes["post.logout.redirect.uris"] = arr.join("##");
}
}
}
}
return { clientId: testClient.clientId };
}
function editAccountConsoleAndSecurityAdminConsole(params: {
parsedRealmJson: ParsedRealmJson;
}) {
const { parsedRealmJson } = params;
for (const clientId of ["account-console", "security-admin-console"]) {
const client = parsedRealmJson.clients.find(
client => client.clientId === clientId
);
assert(client !== undefined);
{
for (const redirectUri of [
`${TEST_APP_URL}/*`,
"http://localhost*",
"http://127.0.0.1*"
]) {
for (const propertyName of ["webOrigins", "redirectUris"] as const) {
const arr = (client[propertyName] ??= []);
if (arr.includes(redirectUri)) {
continue;
}
arr.push(redirectUri);
}
{
if (client.attributes === undefined) {
client.attributes = {};
}
const arr = (client.attributes["post.logout.redirect.uris"] ?? "")
.split("##")
.map(s => s.trim());
if (!arr.includes(redirectUri)) {
arr.push(redirectUri);
client.attributes["post.logout.redirect.uris"] = arr.join("##");
}
}
}
}
}
}
export function makeRealmConfigTestable(params: {
parsedRealmJson: ParsedRealmJson;
keycloakMajorVersionNumber: number;
}): {
realmName: string;
clientName: string;
username: string;
} {
const { parsedRealmJson, keycloakMajorVersionNumber } = params;
const { username } = addOrEditTestUser({
parsedRealmJson,
keycloakMajorVersionNumber
});
const { clientId } = addOrEditClient({
parsedRealmJson,
keycloakMajorVersionNumber
});
editAccountConsoleAndSecurityAdminConsole({ parsedRealmJson });
return {
realmName: parsedRealmJson.name,
clientName: clientId,
username
};
}

View File

@ -502,6 +502,11 @@
"disableableCredentialTypes" : [ ],
"requiredActions" : [ ],
"realmRoles" : [ "default-roles-myrealm" ],
"clientRoles" : {
"realm-management" : [ "manage-users", "create-client", "view-users", "view-realm", "query-realms", "impersonation", "view-events", "realm-admin", "manage-authorization", "manage-events", "view-authorization", "manage-clients", "query-users", "query-groups", "manage-realm", "query-clients", "manage-identity-providers", "view-identity-providers", "view-clients" ],
"broker" : [ "read-token" ],
"account" : [ "delete-account", "view-applications", "manage-account", "view-consent", "view-groups", "view-profile", "manage-account-links", "manage-consent" ]
},
"notBefore" : 0,
"groups" : [ ]
} ],
@ -574,7 +579,7 @@
"realm_client" : "false",
"oidc.ciba.grant.enabled" : "false",
"backchannel.logout.session.required" : "true",
"post.logout.redirect.uris" : "+",
"post.logout.redirect.uris" : "*",
"oauth2.device.authorization.grant.enabled" : "false",
"display.on.consent.screen" : "false",
"pkce.code.challenge.method" : "S256",
@ -741,14 +746,16 @@
"id" : "fce8a109-6f32-4814-9a20-2ff2435d2da6",
"clientId" : "security-admin-console",
"name" : "${client_security-admin-console}",
"description" : "",
"rootUrl" : "${authAdminUrl}",
"adminUrl" : "",
"baseUrl" : "/admin/myrealm/console/",
"surrogateAuthRequired" : false,
"enabled" : true,
"alwaysDisplayInConsole" : false,
"clientAuthenticatorType" : "client-secret",
"redirectUris" : [ "/admin/myrealm/console/*" ],
"webOrigins" : [ "+" ],
"redirectUris" : [ "*" ],
"webOrigins" : [ "*" ],
"notBefore" : 0,
"bearerOnly" : false,
"consentRequired" : false,
@ -761,9 +768,14 @@
"protocol" : "openid-connect",
"attributes" : {
"realm_client" : "false",
"oidc.ciba.grant.enabled" : "false",
"client.use.lightweight.access.token.enabled" : "true",
"post.logout.redirect.uris" : "+",
"pkce.code.challenge.method" : "S256"
"backchannel.logout.session.required" : "true",
"post.logout.redirect.uris" : "*",
"oauth2.device.authorization.grant.enabled" : "false",
"display.on.consent.screen" : "false",
"pkce.code.challenge.method" : "S256",
"backchannel.logout.revoke.offline.tokens" : "false"
},
"authenticationFlowBindingOverrides" : { },
"fullScopeAllowed" : true,
@ -1333,8 +1345,8 @@
"adminTheme" : "",
"emailTheme" : "",
"eventsEnabled" : false,
"eventsListeners" : [ "jboss-logging" ],
"enabledEventTypes" : [ ],
"eventsListeners" : [ "keycloakify-logging", "jboss-logging" ],
"enabledEventTypes" : [ "SEND_RESET_PASSWORD", "UPDATE_CONSENT_ERROR", "GRANT_CONSENT", "VERIFY_PROFILE_ERROR", "REMOVE_TOTP", "REVOKE_GRANT", "UPDATE_TOTP", "LOGIN_ERROR", "CLIENT_LOGIN", "RESET_PASSWORD_ERROR", "UPDATE_CREDENTIAL", "IMPERSONATE_ERROR", "CODE_TO_TOKEN_ERROR", "CUSTOM_REQUIRED_ACTION", "OAUTH2_DEVICE_CODE_TO_TOKEN_ERROR", "RESTART_AUTHENTICATION", "IMPERSONATE", "UPDATE_PROFILE_ERROR", "LOGIN", "OAUTH2_DEVICE_VERIFY_USER_CODE", "UPDATE_PASSWORD_ERROR", "CLIENT_INITIATED_ACCOUNT_LINKING", "OAUTH2_EXTENSION_GRANT", "USER_DISABLED_BY_PERMANENT_LOCKOUT", "REMOVE_CREDENTIAL_ERROR", "TOKEN_EXCHANGE", "AUTHREQID_TO_TOKEN", "LOGOUT", "REGISTER", "DELETE_ACCOUNT_ERROR", "CLIENT_REGISTER", "IDENTITY_PROVIDER_LINK_ACCOUNT", "USER_DISABLED_BY_TEMPORARY_LOCKOUT", "DELETE_ACCOUNT", "UPDATE_PASSWORD", "CLIENT_DELETE", "FEDERATED_IDENTITY_LINK_ERROR", "IDENTITY_PROVIDER_FIRST_LOGIN", "CLIENT_DELETE_ERROR", "VERIFY_EMAIL", "CLIENT_LOGIN_ERROR", "RESTART_AUTHENTICATION_ERROR", "EXECUTE_ACTIONS", "REMOVE_FEDERATED_IDENTITY_ERROR", "TOKEN_EXCHANGE_ERROR", "PERMISSION_TOKEN", "FEDERATED_IDENTITY_OVERRIDE_LINK", "SEND_IDENTITY_PROVIDER_LINK_ERROR", "UPDATE_CREDENTIAL_ERROR", "EXECUTE_ACTION_TOKEN_ERROR", "OAUTH2_EXTENSION_GRANT_ERROR", "SEND_VERIFY_EMAIL", "OAUTH2_DEVICE_AUTH", "EXECUTE_ACTIONS_ERROR", "REMOVE_FEDERATED_IDENTITY", "OAUTH2_DEVICE_CODE_TO_TOKEN", "IDENTITY_PROVIDER_POST_LOGIN", "IDENTITY_PROVIDER_LINK_ACCOUNT_ERROR", "FEDERATED_IDENTITY_OVERRIDE_LINK_ERROR", "OAUTH2_DEVICE_VERIFY_USER_CODE_ERROR", "UPDATE_EMAIL", "REGISTER_ERROR", "REVOKE_GRANT_ERROR", "EXECUTE_ACTION_TOKEN", "LOGOUT_ERROR", "UPDATE_EMAIL_ERROR", "CLIENT_UPDATE_ERROR", "AUTHREQID_TO_TOKEN_ERROR", "INVITE_ORG_ERROR", "UPDATE_PROFILE", "CLIENT_REGISTER_ERROR", "FEDERATED_IDENTITY_LINK", "INVITE_ORG", "SEND_IDENTITY_PROVIDER_LINK", "SEND_VERIFY_EMAIL_ERROR", "RESET_PASSWORD", "CLIENT_INITIATED_ACCOUNT_LINKING_ERROR", "OAUTH2_DEVICE_AUTH_ERROR", "REMOVE_CREDENTIAL", "UPDATE_CONSENT", "REMOVE_TOTP_ERROR", "VERIFY_EMAIL_ERROR", "SEND_RESET_PASSWORD_ERROR", "CLIENT_UPDATE", "CUSTOM_REQUIRED_ACTION_ERROR", "IDENTITY_PROVIDER_POST_LOGIN_ERROR", "UPDATE_TOTP_ERROR", "CODE_TO_TOKEN", "VERIFY_PROFILE", "GRANT_CONSENT_ERROR", "IDENTITY_PROVIDER_FIRST_LOGIN_ERROR" ],
"adminEventsEnabled" : false,
"adminEventsDetailsEnabled" : false,
"identityProviders" : [ ],
@ -1356,7 +1368,7 @@
"subType" : "authenticated",
"subComponents" : { },
"config" : {
"allowed-protocol-mapper-types" : [ "saml-user-property-mapper", "saml-role-list-mapper", "saml-user-attribute-mapper", "oidc-address-mapper", "oidc-full-name-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-property-mapper", "oidc-usermodel-attribute-mapper" ]
"allowed-protocol-mapper-types" : [ "oidc-full-name-mapper", "saml-user-property-mapper", "saml-role-list-mapper", "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "oidc-usermodel-property-mapper", "saml-user-attribute-mapper", "oidc-sha256-pairwise-sub-mapper" ]
}
}, {
"id" : "4d3e104f-6fdf-45eb-b756-5fef6840fbed",
@ -1381,7 +1393,7 @@
"subType" : "anonymous",
"subComponents" : { },
"config" : {
"allowed-protocol-mapper-types" : [ "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "saml-role-list-mapper", "oidc-full-name-mapper", "oidc-usermodel-property-mapper", "saml-user-property-mapper", "saml-user-attribute-mapper", "oidc-sha256-pairwise-sub-mapper" ]
"allowed-protocol-mapper-types" : [ "oidc-usermodel-property-mapper", "oidc-usermodel-attribute-mapper", "saml-user-property-mapper", "saml-user-attribute-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-address-mapper", "saml-role-list-mapper", "oidc-full-name-mapper" ]
}
}, {
"id" : "8f7d6ece-e956-4e48-95ab-5ab72b2b7c9a",
@ -1424,8 +1436,8 @@
"providerId" : "rsa-generated",
"subComponents" : { },
"config" : {
"privateKey" : [ "MIIEogIBAAKCAQEA2mfownRnTfANePqv6MfBRedJZE/u/tDreYJzHnsLZ6zAWGDZv/Pj6qZmOdhmkGYAMpuxboQ8EVwn+5u+NPYKP6XaeU2uKMszdVVlZ0wqdAamN0XoWtZQ0xwWI9gAdqv90ZWyX6iqo6QpxdlbvAL96nQz8jXUZebs8ddQSWnOwkMUFhKeRnjWhpTC+UzW8PzrD9OY2vhS+82eZHMJw8cvpAMXvsxdW608wm997y7/upbYgw8jcFqZQXMQjF63pvDwnKIITxR0kuwuR9Hiq2s7D8oNGVMIDze8gBpz9ictebdTmt80GGcxQTUbzexRVFxUXI4D7EbGjuu8/edhayiIXQIDAQABAoIBAAyCGZ5+tCaOh6GqGcZRymE1LHWGQ8BsOVAthxJJJw9k9rnDsjTVbvQoBirB7f3PGavMUY5sHFSSMT1ZChJWak0tiSRGrUwWIc2nz7WUHcpPUdhQifd0gWSAc0l85r86fRWHu+jRQWnlzk6lHXqDDAUQFU7bLl2NACee69uIfRg69sM/XGcZZCflWJT3T4bIxTjaeZtrq6K7OtWM3wmJ8QHYXJrnwitqGvrGT7fR+z0gAA7ZCtFDgeBeiH7RErBKv+vepP8VCx3xNHYLygNEx2kXjew5D3zz/vT7X9u2HkNl7ZgMdxebha5w8IazSZ0lEkHqk7+bhu+G0u1G2e7wjwECgYEA/FlNy569IYsIn6VQn8TVxftWpz4i4N2gLikVPWm65wzxkYVDDyvqJZ1ovzw1w4QEZ6aUHrjLVnP61gQt+DGPJ+7rvDnDlCvW99Wj2/3uvV7OQn73ffQs39eHUb/SokRX4z/ht53eVPnyQq4GHGxBSFa4o4Jb2Ju8F2oFAdxVqRECgYEA3ZDhlY6C1BZ0XqVilPjXetFk27+Twm/rlLy0hClrJMYVLT49kaFriE5/ni24L3ON/reqSQnih+0uJLR2fPpsC7ShaZzFOPUzyXVYfeAKimLvfZc+dTvRB4QhTwSKnDO5ChfquFAo1FLQVRouwaeJN75jOPphzF29h6atxadjyo0CgYBw7UXzKUZaDG3/g2thFCTWRHOyxAu3tXZJMflfUkFhxFkWVhx8XZqa2qZVbgxhQmL2P4VpeikEt0I5JAWuW/9ET5cO1IrBdBzvK5v4htqfxB1phIgcxXiPc1QLMVyBYTQzbhMEqJEmVfQkAtyZO5i7VpOqGFwhww+ZKsiy3Hc5AQKBgCHVth04nhH1O+AYMW2+cml3AIfuQYo3vSoBhy+Hg60h8qnuD0jl9Z3jHunw4Wedpdl4ArEUqVtIhPtl85IyS72d3+hY4GVKTJY/LTxLslBfu2LabddJQyp6qvt+HgyseV1pOZbb5uBFpTrZvLol83ZnxI827ShgSEkm0vKUFVEhAoGAbut8nONPSNR7H9zqww2IOzIY2CUQEDaUqnjKLBpvc8Jszo2vW3HbFH/eWfh5Gmah3H/wIlXEwd5TPzMxO8IuM97VTWFPUkX6Y9qwqBPYncmGioL1uq9ogwHsfmlacS2IBrAlyfKFRNfVzlkUKqzYvRROCxVVVnJDGg9KIwYWqBk=" ],
"certificate" : [ "MIICnTCCAYUCBgGTumCK8TANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdteXJlYWxtMB4XDTI0MTIxMjEwMTY0OVoXDTM0MTIxMjEwMTgyOVowEjEQMA4GA1UEAwwHbXlyZWFsbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANpn6MJ0Z03wDXj6r+jHwUXnSWRP7v7Q63mCcx57C2eswFhg2b/z4+qmZjnYZpBmADKbsW6EPBFcJ/ubvjT2Cj+l2nlNrijLM3VVZWdMKnQGpjdF6FrWUNMcFiPYAHar/dGVsl+oqqOkKcXZW7wC/ep0M/I11GXm7PHXUElpzsJDFBYSnkZ41oaUwvlM1vD86w/TmNr4UvvNnmRzCcPHL6QDF77MXVutPMJvfe8u/7qW2IMPI3BamUFzEIxet6bw8JyiCE8UdJLsLkfR4qtrOw/KDRlTCA83vIAac/YnLXm3U5rfNBhnMUE1G83sUVRcVFyOA+xGxo7rvP3nYWsoiF0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAkiufTKtcxcf8AA8eP31R12Kc+OzyqXlm72Ga7Rbq3p9TwnMDcAsV01zQU48GQcVkQNCXtu8ldePat/Nug6BcuVqdaT9Uez5EvZcC8lPqTMnW9m3Rg6ynL3b+o3GMIE1keAGW38zvIT1Z/YSBAUJH724bSD4yZCG2HbGok8lRH575TqgkLrNrLCBHHUr9cktEh8ENZgJRrKeUBU4r6EJ7D7gItqEoyAEKy37KRQyyE+s7LMTtQYvSSuM4teJfSON7lNXveWffbPbpbirb9K8Me3rYLGCLT0FX6nhdPiQcKpoNFDPmzDrFXD97KSBJUsvMQ2LaBHV9hWo9BSeVl8Lkqg==" ],
"privateKey" : [ "MIIEoQIBAAKCAQEAxTFMvRiNiQjY9zajvLsah6Vy4pn8U7smsnBcHS9SkLJ1j9O8+90B90tIZk4IqEE4gdJA/mbbeUnou1vWuc0k69diQMFelzdIaDqJaFFeOS+J1DoApjThjGIz7FIgmGi6qoN8xnrPVD/6oMYAuxTvQaJH7mENiIG0198dvaufV1mFPg+krTsh7Womo2CJeZmNuAXv7RDQYxwPYDCFZLbppez48D7+2D+1V6Stk6Xwz8IDQZvljxDF6W2P9rhPWV1C5tcJpC/9RPyGDo+ke8UN3fM6X7YOgpbMztVrg8J0aTqPXZ7dt6QFUqVOufo+5wYL2jCafpYNV8cmaGlY+Q3d5QIDAQABAoH/DIPcaZaJTLG4FeUKGOaT40nesEiINRY99aeIkp+hdGj1EgTEn49TyLENGnhrrdbIvOJDeD6Z6dbpJBDvfFevxa589EnVKaGaaW5U91FDyVYH2YPU411dAeOp0z1xwxXzlJqX3h42ZJnvLAp/2l1Xo64vGCoTJtYlppAvpe2MjANxPNObAc65Phdi/sConAlwMeBylWXJ574uryFrJ64W/sUuIUMSunGGz0db4Y1hfkX9U2YnxB3DdXCBH09jQJyKDSj6feNXR87+1KhqcFMd5DUiGSAOqRBzuBMsDf1QDJd8A/DDlK7e/PA1Yk/Dii4hsf+LCeOdmhlifuyROqJBAoGBAOEm4gLvaBWwnUhmr4sW8xywIhGGbU+MX6vm/KkGtScres7pPhmfy6ARUzCxxyBqIE+nhCRNBpOEPhP7dv8naJhZZ4fRvNzuXpUMT2X3bc5yNzdhaOxBJl95YQbrYUHhjcIw2kdXnIkpdbB/RqmY0F5BUTYECrd0tKWbjuL5RIRNAoGBAOA1wTXrYyVorouxV+mGNb62Py+utHJQKSa5cxF9nbbwWJd+FdreiBOJddjATmH8ovKjueQFVqK7koDveOb+pgRY2bpT88/NW8UF6a2wMiI0p6pxrR+hgzas480YiOCWr6XlsprqsSKBbEu4W97GicleZ6P5Iso/gBr9aHj9EWv5AoGAYhRzHj42RESUr4Zz8A5GR3f+z02U7rNCtfrAk80lOvP44ou+jqEKrib961d2XAt/GdPqf3nCZJ6WAFRp6Qq8yKkhrYvTTxbTwvAC4nNftTASF6DqeQiEc9DHUKFW08Ey5KYtYCitOx8BcqpvGNBF7NldTD+Ef5hqXT4fh4Z4r30CgYEAy2OYGMymTRowNKK06C+Kc62plhy6rnRPUESswLIeLwTKqOqE8t4pvOdWk0CoGjVusAOcLuA03jyfwvz5xTo96fWb1W4w31IgLJOXjqsmX2c6reCfNvFyMVgW8keOa4XmYu0C34uFEpMrZWkhVe7usVBFXjczuxptoI4+hnqzoikCgYBICBVR9Z7n2LvmWH19/Nnns8dsMn5peL7H6Mey76Lo9RMEMp4qhiJTqVZzWgxEyVjr0KFCHmdmwkTOm6A1yYmkqqXDdiJ9v4J4fXe0lRAoUoYPTOWynrCyd6uqq+3zlzTKW8jY9luywHq6msn07D636PvveeZ93DNCcO8Whw36rQ==" ],
"certificate" : [ "MIICnTCCAYUCBgGTulJBzTANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdteXJlYWxtMB4XDTI0MTIxMjEwMDExM1oXDTM0MTIxMjEwMDI1M1owEjEQMA4GA1UEAwwHbXlyZWFsbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMUxTL0YjYkI2Pc2o7y7GoelcuKZ/FO7JrJwXB0vUpCydY/TvPvdAfdLSGZOCKhBOIHSQP5m23lJ6Ltb1rnNJOvXYkDBXpc3SGg6iWhRXjkvidQ6AKY04YxiM+xSIJhouqqDfMZ6z1Q/+qDGALsU70GiR+5hDYiBtNffHb2rn1dZhT4PpK07Ie1qJqNgiXmZjbgF7+0Q0GMcD2AwhWS26aXs+PA+/tg/tVekrZOl8M/CA0Gb5Y8Qxeltj/a4T1ldQubXCaQv/UT8hg6PpHvFDd3zOl+2DoKWzM7Va4PCdGk6j12e3bekBVKlTrn6PucGC9owmn6WDVfHJmhpWPkN3eUCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEATZXyOluloTj6Q/Mv0JjstfdvPQbzGFzWtULB1ttOJqQVL+IJoF8V79HIvfP9U5OYaOdYk9dDurQcd2hXvEtX+zQlLYGniRfJlFI7d+m6MDXa7/g1r+OmcvaiXX7O3ol7eJdymPKS79+PSWFsHk0JjfgRJ11jajOscYPoQ+IvxXgwuy6v7VHigsLnGnmmo+KWiKO6Cna6eilm6/awYXaoym4ky9S4T5+WaJwd/tH/n5VY77zyXaXfANd1hU/+4Ux/eaGVnoMAM4ud2emd4qCN2tQQ3HusIVl+5V+S8Uq1y54mBpXv6CAODDGDJeFa+cGPJUSLdv/ZT2F8yfDlDc4J6g==" ],
"priority" : [ "100" ]
}
}, {
@ -1434,8 +1446,8 @@
"providerId" : "rsa-enc-generated",
"subComponents" : { },
"config" : {
"privateKey" : [ "MIIEowIBAAKCAQEAuFPumVkEu26jQZ3+lI0Ipkflg25RKOfW9reECSScPo33syk7YstukJbtjabrBb6OwNS8sz3xoQg4oW0UzQXCeyA5PzDmQuQK/uNyF9CJJm5LUu7uaVz77Kcsv5+zz14t4+PMQVl39xFTB41KPs26AqXY2LOtkM2fXH9Hrr0psIGUYvDBp9vn/Q2OILARMD5jw8Oa843jADUo0qYHIHJy7XmmXkAjj7vWLu6LJdSUhn7J+YJ8Mf+E4uS347OMNAawqnEyb/sh5jhSJ9j6utZUI/r1KLNNFrwSJjF1Ahm9oaKS3p/fr9WuzKvbMughSb4uLRV28IYULeqwFJwWahF33QIDAQABAoIBACvxlohoeIBWuAUErZSsqss5iLX0rtSZsN3QkmG7oKQpJExKICZFaW5/DNMgYBdWfqHqFbKFqf1CAH47iyH1pY/E9uDhv4Ni6lwpzSFwTcIjuUFkROJJkKWylTB52lwtj7Mss51AvyDfuHOsc27VjOrkrvW6oD5NRxi+H1DBOBcj5Mpm9dMDcTAZ446gJo7R7qlq/4SCgiegdgw7K7XGYzecxGtPbQIZn8HJb8R6G4FvO54StN/YwGu4bbe/ociPgzPg+AknptqMRWbejlleikZXSEqeoRUBUVWB/mDmL5V6qTipf1WKbOp6gvFfHFbPaBOMqpQiQMdVH4OXeWdPfAECgYEA99MN5irsPk3FLWPslugbM9IYlDpnxpQpqCALLq3OcuisPcv/bBjsKyPkwV35xJet951ILVDn+1OMcucP/nxlRam3n3L0T+0k5i4hAoUX9Eg5cXTLvIDHFineCDRxDRwTdzbTknfLo0MFowqrRB83GqDjDAOctQaCZBa2aOMHfj0CgYEAvmihtOsF4K4vBPj/863ZCXuJld7/dtUg6Cye6PLNiUruPly1gQpuHSiDAxjU6fW31WtUWEZ0uyqHsm+jymeE6XCZZTTfO9mQvEa6owJHr95aHUw81mReh/+t8Bk3sLlMil0rNDLEZrB1Xl54rJHB8x9SkCOfwU6ig/OO86zoGiECgYBco0ZEzbK1r3iPeRTNbEIO4vBRKGv2bRgNQr0rW8kaZyNLjmASVlah4a73IVvmQxTCxMZgOigdaKPNp9XwuStaGREMx3nQDsOGT6QDPyEvLXhbkt89vZ2uCUR4KLJBxkb4f0QjMiirBLiss6ZFtq1whMeajBceDCrdoyfYmVUJuQKBgBr/4TYzQVEbweUVnc2i8CytDNRom5bxH8psUVg83bJDIsdLBB25KeYOkY1F3yMRybCEmKAv1WuY20cNF4+i4DDt24KDXcgx0Jkx+lMVBq9Ee0i+P74y20izk6mBGemATP8tuOuc60aYbPwlrzzhKjxcS6vOsV+K0/ab+cBJ21uhAoGBAMyoy7slbcRrcqGLApTqamXqsYdu5SzHyHInQPInW7ZPCyuQ98n6XsWpgRFUp/EPbXDqppRusvBiTQ+clNOZeuvCDO/cW4oaBwPvBi4zaTU7iNaM59jmtswGmO40tR0DEYP50O9I77uFKsy8xLxv0AhtyecDgrn8lW6QSPAhFsqy" ],
"certificate" : [ "MIICnTCCAYUCBgGTumCMMTANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdteXJlYWxtMB4XDTI0MTIxMjEwMTY0OVoXDTM0MTIxMjEwMTgyOVowEjEQMA4GA1UEAwwHbXlyZWFsbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALhT7plZBLtuo0Gd/pSNCKZH5YNuUSjn1va3hAkknD6N97MpO2LLbpCW7Y2m6wW+jsDUvLM98aEIOKFtFM0FwnsgOT8w5kLkCv7jchfQiSZuS1Lu7mlc++ynLL+fs89eLePjzEFZd/cRUweNSj7NugKl2NizrZDNn1x/R669KbCBlGLwwafb5/0NjiCwETA+Y8PDmvON4wA1KNKmByBycu15pl5AI4+71i7uiyXUlIZ+yfmCfDH/hOLkt+OzjDQGsKpxMm/7IeY4UifY+rrWVCP69SizTRa8EiYxdQIZvaGikt6f36/Vrsyr2zLoIUm+Li0VdvCGFC3qsBScFmoRd90CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAUjXK1g0j5VqmG+5YwGrvuLT4FwRXf9pDKGhWbRQRk8OTyLv5UkWhYy8owoNyLUYPLTY0ELBKbAPxA+uggHwNX+6I8pb01zirpTLtTtFLsmsGRhFeHNeaUKVseFz09CLXQTmS9kGcdMvwgd/yMEe0VLVt+V0Bw8u5BZk/J8Lv6ArjkKaX8PhJYFv35N+WkHkcW9GM4WlrTxnthpraDVeTjY49aWSSkLSE+hQv3fLG5VIj0j0/2lijBJ3xtP4adBlab32k6Kvw4ywQoaMi0iUeEHX10+4dZ6VEnObjNmX0r2FS+0XE8KjE1yus1r/XBovYltf5AiMVyJISwVWqtpctig==" ],
"privateKey" : [ "MIIEogIBAAKCAQEAungL4osLyP8bE6MSKj8ZMJTG8WBh3K2/xB5BJYCYc7P1CIORZI9o/vKQx1QnP+CXkIKnnR2kzIzC0rnTqlIOkaZfhmSn50jG5vNBS9qPT+WU7Ue3qKxuWJFwcaFU5SEJawJHqnDPK+pktkkxkudeMHz6iaKPs+wKcbfrRJ6+3a3FqQQdHEQg4IjVU8pBZmag1c7JHayiM56OT5y6jmE5JvY60959iPrZPXSTMU3hNoiVwdyK6QwdK+/0wrO681VhIP+u2pe92nQ+hsgMSSQJegLx1UsEEyU87syblG+p3zAKSS+kt2nviV/a2cYiiME0LdlQ3lnKsQ4t1Y6yZBiS2QIDAQABAoIBABhozI18TC+kjWPVrfQPzHlakGxahJUBvZ+rojWJjutefE4AAxFZ4JG3KRKexoCLIuwM3monzkHkj0BMiRO7qCKS1+Bc3snc8gSbhUmrs6Tu1b7162nOIKfBainFx7oyx+vVIZKDL+t8xHBERpQHa4IHajiIKi2QUZGvVMHn0e5srkPK0eSMjb5Z5j61aFb8InQzs7tczr99ke4VavOPT1gmRWGnbTavUbw/zIQ9sxAuMiD2v0nrGlOLZrMhaqzsT6PjIWVCSZrWex1pin9gA4XwGZ39E7+zFWgg+2OX0dEvehVDluAQR0K4PBUknuL1LFFW8dpvCrUSTmGGQOSVuB0CgYEA+bQjbjTNiMTEfoxx/WvVDgtLRL/x9RVyeYTPia2TGNBwpEcU64lLMOwUt5X/QuGXayPr0EGAxMA8kwq/E8Wj2t9+SuqkGK9SIwvghi2fOh0KWghuQbKYMogG5hsJAI8+/mBIOJJ8pyh0RX58vaTlYctbThO22aVahhZQ2weaW58CgYEAvyu4vIe44/7F19Hjh2BW+9lHsHA2zwHvC5T1kFaEdBYEwGsLMW6leCsiEMfpc2Uq3k9+buZgVpTE5APs9cSJX1aUXEG5QHQmYDxAAMiTyvpj0o2cKbDi1A5QZCRo23lC+uDyR7g2zLDJuHek0uyCtd83hbgyxIVFUnfvI9EmfocCgYBtpcZxHEqspgrKrw1XBMTXl+oDVG4A+tv7tHAVutx+5vivim8LRox3/RLT0s/2JG2DJJDmL/1FaEyxHOTu37il4cHpT8Oi+0mMDikXgm0K7bmf81fHDY97kPPGk1SOpFg7BzhvbxPBqyfzZCmOdRwsp0l+rXV7ePqZKq9ynpIPbQKBgFO/LZC5zE9k/vrK4egeVjzCNNugbQJGkJf8S49Nt3y7YJ2Cx0aCeE6qZqP/T8/Tk/IL1RF0LuP/DDnvVlFcJen0Hc5EpIkN2Pnzqv4s4EHdavmEO9MvwE6xbppQMPdkqekJvlmY47jMAbKkBzq3jZNrFAGqbeMVlwbHr6V7LGflAoGANFbzOnUMJwUfIdoI9uEG2QOTAcBb7vzt9MurO67wiTexOYadOSlcV1lQX3RKR9mCFJwy4kud0TN0gD++Ggl10eNB6f8JOF95e5+tWrtz88xZ5EalBOMfh+ATdKq8Q9MBSWZvO9bizhW1dhZZds/QmHgEItdwsTKDAq1PEiXhD0c=" ],
"certificate" : [ "MIICnTCCAYUCBgGTulJDCDANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdteXJlYWxtMB4XDTI0MTIxMjEwMDExM1oXDTM0MTIxMjEwMDI1M1owEjEQMA4GA1UEAwwHbXlyZWFsbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALp4C+KLC8j/GxOjEio/GTCUxvFgYdytv8QeQSWAmHOz9QiDkWSPaP7ykMdUJz/gl5CCp50dpMyMwtK506pSDpGmX4Zkp+dIxubzQUvaj0/llO1Ht6isbliRcHGhVOUhCWsCR6pwzyvqZLZJMZLnXjB8+omij7PsCnG360Sevt2txakEHRxEIOCI1VPKQWZmoNXOyR2sojOejk+cuo5hOSb2OtPefYj62T10kzFN4TaIlcHciukMHSvv9MKzuvNVYSD/rtqXvdp0PobIDEkkCXoC8dVLBBMlPO7Mm5Rvqd8wCkkvpLdp74lf2tnGIojBNC3ZUN5ZyrEOLdWOsmQYktkCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAPhPdLFcXdQT4k06oXB06ZSJ8AkZNXLvQFWCHXI34OmrS2yTse+dLqrqehnC3kPwxElVmawoUVc1sbsk7fUnspfM+Xw20PaABZu4MO2m5TB98f1hEkezP9fSqgPeuWJgTL8ZW5kkZyiD3IaZoqyxzYXaFxKHhU455g+k2+DO+N6FreVKcYz12Q5EMaxZ6U1neZAo3vicNxM3/TA5V8sPK8+oKvon7v5OyjpOH0goJo9v/klKeUk36h4u2h1S67IhVSU7tfzVFYrpns1JhrwGZ2xavVqEoqX8zFp3GKz3yVXkwHRHlrzYkZoGn21rm5boXIP3wEB7yXZbXWTiUko/IFw==" ],
"priority" : [ "100" ],
"algorithm" : [ "RSA-OAEP" ]
}
@ -1445,8 +1457,8 @@
"providerId" : "aes-generated",
"subComponents" : { },
"config" : {
"kid" : [ "a564ea32-7bf8-4983-a1e3-d427815b5e65" ],
"secret" : [ "nGQV8nxA1MTSxdbQ4O1inw" ],
"kid" : [ "c36222c6-6a43-4d32-9d44-d5d355e5cabd" ],
"secret" : [ "rzL4qUQ7wTEkZDbgt595VA" ],
"priority" : [ "100" ]
}
}, {
@ -1455,8 +1467,8 @@
"providerId" : "hmac-generated",
"subComponents" : { },
"config" : {
"kid" : [ "029772e3-eb42-4338-a15e-b20c068f787e" ],
"secret" : [ "rHz9EUPQsdU8Uzn9Mm2n_H6YzPJJQmXN3XiD9SrYXCsOQ2Gii2eZdWM6sfP2i736V2pV2XAZvklYWQeLPn62mzBsim_CiTjXcLOuScvLCEuORxM5w6p50h7ph8GYXRQK05MSPWzkvQgjG48E05zlZcMAFvNc86yWFVLbuPrI-nw" ],
"kid" : [ "06532a54-c310-41c1-829c-58776ce2ab4a" ],
"secret" : [ "9v1ZjFhEFH6UpY6ncFkaCbqJYHMyI4tA0cvx4GuQ5KtMXYbimitSSVDqxIKwa-gBC_8bY2O4FQfpmp1Qn1-L4fFmPFfIF3ZKsO16263BwpADo_FNSBTte8Le4gJLylqFULdsn3ye17FHyq5Jjms_OTt3opzcDLNduCuK22GBBsU" ],
"priority" : [ "100" ],
"algorithm" : [ "HS512" ]
}