From 4bcea8a2e0d4940fe8135203a2bd2bad426e96d5 Mon Sep 17 00:00:00 2001 From: Lucas ONeil Date: Mon, 6 Nov 2023 14:59:57 -0800 Subject: [PATCH 1/5] server config endpoints Signed-off-by: Lucas ONeil --- .../v1_0/innkeeper/routes.py | 42 ++++++++++++++ .../traction_innkeeper/v1_0/tenant/routes.py | 56 +++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/plugins/traction_innkeeper/traction_innkeeper/v1_0/innkeeper/routes.py b/plugins/traction_innkeeper/traction_innkeeper/v1_0/innkeeper/routes.py index 16bca1080..185e5dc22 100644 --- a/plugins/traction_innkeeper/traction_innkeeper/v1_0/innkeeper/routes.py +++ b/plugins/traction_innkeeper/traction_innkeeper/v1_0/innkeeper/routes.py @@ -11,6 +11,7 @@ use_kwargs, ) from aries_cloudagent.admin.request_context import AdminRequestContext +from aries_cloudagent.admin.server import AdminConfigSchema from aries_cloudagent.messaging.models.base import BaseModelError from aries_cloudagent.messaging.models.openapi import OpenAPISchema from aries_cloudagent.messaging.valid import JSONWebToken, UUIDFour @@ -21,6 +22,7 @@ from aries_cloudagent.multitenant.base import BaseMultitenantManager from aries_cloudagent.multitenant.error import WalletKeyMissingError from aries_cloudagent.storage.error import StorageError, StorageNotFoundError +from aries_cloudagent.version import __version__ from aries_cloudagent.wallet.error import WalletSettingsError from aries_cloudagent.wallet.models.wallet_record import WalletRecord from marshmallow import fields, validate @@ -917,6 +919,41 @@ async def innkeeper_authentications_api_delete(request: web.BaseRequest): return web.json_response({"success": result}) +@docs(tags=[SWAGGER_CATEGORY], summary="Fetch the server configuration") +@response_schema(AdminConfigSchema(), 200, description="") +@innkeeper_only +@error_handler +async def innkeeper_config_handler(request: web.BaseRequest): + context: AdminRequestContext = request["context"] + # use base/root profile for server config, use Tenant Manager profile + # this is to not get the Innkeeper tenant's config, but the server cfg + mgr = context.inject(TenantManager) + profile = mgr.profile + + config = { + k: ( + profile.context.settings[k] + ) + for k in profile.context.settings + if k + not in [ + "admin.admin_api_key", + "multitenant.jwt_secret", + "wallet.key", + "wallet.rekey", + "wallet.seed", + "wallet.storage_creds", + ] + } + try: + del config["plugin_config"]["traction_innkeeper"]["innkeeper_wallet"]["wallet_key"] + except KeyError as e: + LOGGER.warn(f"The key to be removed: '{e.args[0]}' is missing from the dictionary.") + config["version"] = __version__ + + return web.json_response({"config": config}) + + async def register(app: web.Application): """Register routes.""" LOGGER.info("> registering routes") @@ -987,6 +1024,11 @@ async def register(app: web.Application): "/innkeeper/authentications/api/{tenant_authentication_api_id}", innkeeper_authentications_api_delete, ), + web.get( + "/innkeeper/server/status/config", + innkeeper_config_handler, + allow_head=False, + ), ] ) LOGGER.info("< registering routes") diff --git a/plugins/traction_innkeeper/traction_innkeeper/v1_0/tenant/routes.py b/plugins/traction_innkeeper/traction_innkeeper/v1_0/tenant/routes.py index 5e823cba0..285e26b7c 100644 --- a/plugins/traction_innkeeper/traction_innkeeper/v1_0/tenant/routes.py +++ b/plugins/traction_innkeeper/traction_innkeeper/v1_0/tenant/routes.py @@ -8,6 +8,7 @@ request_schema, ) from aries_cloudagent.admin.request_context import AdminRequestContext +from aries_cloudagent.admin.server import AdminConfigSchema from aries_cloudagent.messaging.models.openapi import OpenAPISchema from aries_cloudagent.multitenant.admin.routes import ( format_wallet_record, @@ -16,6 +17,7 @@ ) from aries_cloudagent.multitenant.base import BaseMultitenantManager from aries_cloudagent.storage.error import StorageNotFoundError +from aries_cloudagent.version import __version__ from aries_cloudagent.wallet.models.wallet_record import ( WalletRecordSchema, WalletRecord, @@ -352,6 +354,55 @@ async def tenant_api_key_delete(request: web.BaseRequest): return web.json_response({"success": result}) +@docs(tags=[SWAGGER_CATEGORY], summary="Fetch the server configuration") +@response_schema(AdminConfigSchema(), 200, description="") +@error_handler +async def tenant_server_config_handler(request: web.BaseRequest): + context: AdminRequestContext = request["context"] + # use base/root profile for server config, use Tenant Manager profile + # this is to not get the Innkeeper tenant's config, but the server cfg + mgr = context.inject(TenantManager) + profile = mgr.profile + + config = { + k: ( + profile.context.settings[k] + ) + for k in profile.context.settings + if k + not in [ + "default_label", + "admin.admin_api_key", + "admin.admin_insecure_mode", + "admin.enabled", + "admin.host", + "admin.port", + "admin.webhook_urls", + "admin.admin_client_max_request_size", + "multitenant.jwt_secret", + "wallet.key", + "wallet.name", + "multitenant.wallet_name", + "wallet.storage_type", + "wallet.storage_config", + "wallet.rekey", + "wallet.seed", + "wallet.storage_creds", + ] + } + try: + del config["plugin_config"]["traction_innkeeper"]["innkeeper_wallet"] + config["config"]["ledger.ledger_config_list"] = [ + {k: v for k, v in d.items() if k != "genesis_transactions"} + for d in config["config"]["ledger.ledger_config_list"] + ] + except KeyError as e: + LOGGER.warn(f"The key to be removed: '{e.args[0]}' is missing from the dictionary.") + config["version"] = __version__ + + return web.json_response({"config": config}) + + async def register(app: web.Application): """Register routes.""" LOGGER.info("> registering routes") @@ -376,6 +427,11 @@ async def register(app: web.Application): "/tenant/authentications/api/{tenant_authentication_api_id}", tenant_api_key_delete, ), + web.get( + "/tenant/server/status/config", + tenant_server_config_handler, + allow_head=False + ), ] ) LOGGER.info("< registering routes") From 675fc5670013f06ebd5dfe8f78cad0fb867662e0 Mon Sep 17 00:00:00 2001 From: Lucas ONeil Date: Tue, 7 Nov 2023 21:48:34 -0800 Subject: [PATCH 2/5] server config FE Signed-off-by: Lucas ONeil --- .../frontend/src/components/about/Acapy.vue | 42 +---- .../src/components/about/PluginList.vue | 31 ++++ .../innkeeper/config/ServerConfig.vue | 95 +++++++++++ .../components/layout/innkeeper/Sidebar.vue | 5 + .../frontend/src/helpers/constants.ts | 2 + .../frontend/src/plugins/i18n/locales/en.json | 4 + .../frontend/src/router/innkeeperRoutes.ts | 8 + .../store/innkeeper/innkeeperTenantsStore.ts | 32 +++- .../frontend/src/store/utils/fetchItem.ts | 4 +- .../src/types/acapyApi/acapyInterface.ts | 157 +++++++++++++++--- .../views/innkeeper/InnkeeperServerConfig.vue | 7 + 11 files changed, 316 insertions(+), 71 deletions(-) create mode 100644 services/tenant-ui/frontend/src/components/about/PluginList.vue create mode 100644 services/tenant-ui/frontend/src/components/innkeeper/config/ServerConfig.vue create mode 100644 services/tenant-ui/frontend/src/views/innkeeper/InnkeeperServerConfig.vue diff --git a/services/tenant-ui/frontend/src/components/about/Acapy.vue b/services/tenant-ui/frontend/src/components/about/Acapy.vue index f5354ad87..35cf92874 100644 --- a/services/tenant-ui/frontend/src/components/about/Acapy.vue +++ b/services/tenant-ui/frontend/src/components/about/Acapy.vue @@ -16,38 +16,8 @@
-
- {{ $t('about.acaPy.ledger') }} -
-
- {{ config.frontend.ariesDetails.ledgerName }} -
- -
- {{ $t('about.acaPy.ledgerBrowser') }} -
-
- {{ config.frontend.ariesDetails.ledgerBrowser }} -
- -
- {{ $t('about.acaPy.tailsServer') }} -
-
- {{ config.frontend.ariesDetails.tailsServer }} -
-
- -
- - -
- -
- -
-
+
@@ -56,15 +26,9 @@ import { storeToRefs } from 'pinia'; import { useConfigStore } from '@/store/configStore'; // PrimeVue -import Accordion from 'primevue/accordion'; -import AccordionTab from 'primevue/accordiontab'; -import ProgressSpinner from 'primevue/progressspinner'; -import VueJsonPretty from 'vue-json-pretty'; - -const { acapyPlugins, config, loading } = storeToRefs(useConfigStore()); -const configStore = useConfigStore(); +import PluginList from './PluginList.vue'; -configStore.getPluginList(); +const { config } = storeToRefs(useConfigStore()); diff --git a/services/tenant-ui/frontend/src/components/innkeeper/config/ServerConfig.vue b/services/tenant-ui/frontend/src/components/innkeeper/config/ServerConfig.vue new file mode 100644 index 000000000..70538aef8 --- /dev/null +++ b/services/tenant-ui/frontend/src/components/innkeeper/config/ServerConfig.vue @@ -0,0 +1,95 @@ + + + + + diff --git a/services/tenant-ui/frontend/src/components/layout/innkeeper/Sidebar.vue b/services/tenant-ui/frontend/src/components/layout/innkeeper/Sidebar.vue index fdbeedc70..b2af5e807 100644 --- a/services/tenant-ui/frontend/src/components/layout/innkeeper/Sidebar.vue +++ b/services/tenant-ui/frontend/src/components/layout/innkeeper/Sidebar.vue @@ -43,6 +43,11 @@ const items = ref([ icon: 'pi pi-fw pi-key', to: { name: 'InnkeeperApiKeys' }, }, + { + label: () => t('serverConfig.serverConfig'), + icon: 'pi pi-fw pi-wrench', + to: { name: 'InnkeeperServerConfig' }, + }, { label: () => t('about.about'), icon: 'pi pi-fw pi-question-circle', diff --git a/services/tenant-ui/frontend/src/helpers/constants.ts b/services/tenant-ui/frontend/src/helpers/constants.ts index 30ac8a191..d24a7bd04 100644 --- a/services/tenant-ui/frontend/src/helpers/constants.ts +++ b/services/tenant-ui/frontend/src/helpers/constants.ts @@ -56,6 +56,7 @@ export const API_PATH = { INNKEEPER_AUTHENTICATIONS_API_RECORD: (id: string) => `/innkeeper/authentications/api/${id}`, INNKEEPER_AUTHENTICATIONS_API_POST: '/innkeeper/authentications/api', + INNKEEPER_SERVER_CONFIG: '/innkeeper/server/status/config', INNKEEPER_TOKEN: '/innkeeper/token', INNKEEPER_TENANTS: '/innkeeper/tenants/', INNKEEPER_TENANT: (id: string) => `/innkeeper/tenants/${id}`, @@ -136,6 +137,7 @@ export const API_PATH = { TENANT_TOKEN: '/tenant/token', TENANT_WALLET: '/tenant/wallet', TENANT_CONFIG: '/tenant/config', + TENANT_SERVER_CONFIG: '/tenant/server/status/config', TENANT_AUTHENTICATIONS_API: '/tenant/authentications/api/', TENANT_AUTHENTICATIONS_API_RECORD: (id: string) => diff --git a/services/tenant-ui/frontend/src/plugins/i18n/locales/en.json b/services/tenant-ui/frontend/src/plugins/i18n/locales/en.json index 9ceb972ab..a421376c4 100644 --- a/services/tenant-ui/frontend/src/plugins/i18n/locales/en.json +++ b/services/tenant-ui/frontend/src/plugins/i18n/locales/en.json @@ -405,6 +405,10 @@ "fullName": "Full Name", "phone": "Phone / Mobile" }, + "serverConfig": { + "expand": "Show full server status config", + "serverConfig": "Server Configuration" + }, "session": { "countdown": "You are going to be logged out in { seconds } seconds...", "countdownHeader": "Session timing out", diff --git a/services/tenant-ui/frontend/src/router/innkeeperRoutes.ts b/services/tenant-ui/frontend/src/router/innkeeperRoutes.ts index e609e897c..d1d7535dc 100644 --- a/services/tenant-ui/frontend/src/router/innkeeperRoutes.ts +++ b/services/tenant-ui/frontend/src/router/innkeeperRoutes.ts @@ -4,6 +4,7 @@ import InnkeeperUi from '@/views/InnkeeperUi.vue'; import InnkeeperApiKeys from '@/views/innkeeper/InnkeeperApiKeys.vue'; import InnkeeperReservations from '@/views/innkeeper/InnkeeperReservations.vue'; import InnkeeperReservationsHistory from '@/views/innkeeper/InnkeeperReservationsHistory.vue'; +import InnkeeperServerConfig from '@/views/innkeeper/InnkeeperServerConfig.vue'; import InnkeeperTenants from '@/views/innkeeper/InnkeeperTenants.vue'; const innkeeperRoutes = [ @@ -38,6 +39,13 @@ const innkeeperRoutes = [ component: InnkeeperApiKeys, }, + // Authentications + { + path: 'server', + name: 'InnkeeperServerConfig', + component: InnkeeperServerConfig, + }, + // About { path: 'about', diff --git a/services/tenant-ui/frontend/src/store/innkeeper/innkeeperTenantsStore.ts b/services/tenant-ui/frontend/src/store/innkeeper/innkeeperTenantsStore.ts index d360eb353..bf08fb9d9 100644 --- a/services/tenant-ui/frontend/src/store/innkeeper/innkeeperTenantsStore.ts +++ b/services/tenant-ui/frontend/src/store/innkeeper/innkeeperTenantsStore.ts @@ -1,5 +1,6 @@ // Types import { + AdminConfig, ReservationRecord, TenantAuthenticationApiRecord, TenantAuthenticationsApiRequest, @@ -40,6 +41,7 @@ export const useInnkeeperTenantsStore = defineStore('innkeeperTenants', () => { const reservations: Ref = ref([]); const tenants: Ref = ref([]); const defaultConfigValues: any = ref(null); + const serverConfig: any = ref(null); // getters const currentReservations = computed(() => @@ -98,6 +100,16 @@ export const useInnkeeperTenantsStore = defineStore('innkeeperTenants', () => { ); } + async function getServerConfig() { + loading.value = true; + serverConfig.value = await fetchItem( + API_PATH.INNKEEPER_SERVER_CONFIG, + '', + error, + loading + ); + } + async function listTenants() { return fetchListFromAPI( acapyApi, @@ -372,27 +384,29 @@ export const useInnkeeperTenantsStore = defineStore('innkeeperTenants', () => { }; return { - loading, - error, apiKeys, + currentReservations, + defaultConfigValues, + error, findTenantName, + loading, + reservationHistory, + reservations, + serverConfig, tenants, tenantsDropdown, - defaultConfigValues, - reservations, - currentReservations, - reservationHistory, approveReservation, - refreshCheckInPassword, createApiKey, deleteApiKey, + deleteTenant, denyReservation, + getDefaultConfigValues, + getServerConfig, listApiKeys, listTenants, listReservations, + refreshCheckInPassword, updateTenantConfig, - getDefaultConfigValues, - deleteTenant, }; }); diff --git a/services/tenant-ui/frontend/src/store/utils/fetchItem.ts b/services/tenant-ui/frontend/src/store/utils/fetchItem.ts index 807a5cdfa..0f2abe5a9 100644 --- a/services/tenant-ui/frontend/src/store/utils/fetchItem.ts +++ b/services/tenant-ui/frontend/src/store/utils/fetchItem.ts @@ -2,13 +2,13 @@ import { useAcapyApi } from '../acapyApi'; import { AxiosRequestConfig } from 'axios'; import { Ref } from 'vue'; -export async function fetchItem( +export async function fetchItem( url: string, id: string | undefined, error: Ref, loading: Ref, params: object = {} -): Promise { +): Promise { const acapyApi = useAcapyApi(); let dataUrl = url; if (id) { diff --git a/services/tenant-ui/frontend/src/types/acapyApi/acapyInterface.ts b/services/tenant-ui/frontend/src/types/acapyApi/acapyInterface.ts index b69834649..9a3bab841 100644 --- a/services/tenant-ui/frontend/src/types/acapyApi/acapyInterface.ts +++ b/services/tenant-ui/frontend/src/types/acapyApi/acapyInterface.ts @@ -285,6 +285,11 @@ export interface ClearPendingRevocationsRequest { purge?: Record; } +export interface ConfigurableWriteLedgers { + /** List of configurable write ledgers identifiers */ + write_ledgers?: string[]; +} + export interface ConnRecord { /** * Connection acceptance: manual or auto @@ -587,7 +592,7 @@ export interface CreateWalletResponse { export interface CreateWalletTokenRequest { /** - * Master key used for key derivation. Only required for unamanged wallets. + * Master key used for key derivation. Only required for unamanged wallets. * @example "MySecretKey123" */ wallet_key?: string; @@ -946,6 +951,19 @@ export interface CredentialStatusOptions { type: string; } +export interface CustomCreateWalletTokenRequest { + /** + * API key for this wallet + * @example "3bd14a1e8fb645ddadf9913c0922ff3b" + */ + api_key?: string; + /** + * Master key used for key derivation. Only required for unamanged wallets. + * @example "MySecretKey123" + */ + wallet_key?: string; +} + export interface CustomUpdateWalletRequest { /** Agent config key-value pairs */ extra_settings?: object; @@ -955,12 +973,12 @@ export interface CustomUpdateWalletRequest { */ image_url?: string; /** - * Label for this wallet. This label is publicized (self-attested) to other agents as part of forming a connection. + * Label for this wallet. This label is publicized (self-attested) to other agents as part of forming a connection. * @example "Alice" */ label?: string; /** - * Webhook target dispatch type for this wallet. default - Dispatch only to webhooks associated with this wallet. base - Dispatch only to webhooks associated with the base wallet. both - Dispatch to both webhook targets. + * Webhook target dispatch type for this wallet. default - Dispatch only to webhooks associated with this wallet. base - Dispatch only to webhooks associated with the base wallet. both - Dispatch to both webhook targets. * @example "default" */ wallet_dispatch_type?: 'default' | 'both' | 'base'; @@ -1071,6 +1089,14 @@ export interface DIDResult { result?: DID; } +export interface DIDXRejectRequest { + /** + * Reason for rejecting the DID Exchange + * @example "Request rejected" + */ + reason?: string; +} + export interface DIDXRequest { /** * Message identifier @@ -1084,8 +1110,8 @@ export interface DIDXRequest { '@type'?: string; /** * DID of exchange - * @pattern ^(did:sov:)?[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}$ - * @example "WgWxqztrNooG92RXvxSTWv" + * @pattern ^(did:sov:)?[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}$|^did:([a-zA-Z0-9_]+):([a-zA-Z0-9_.%-]+(:[a-zA-Z0-9_.%-]+)*)((;[a-zA-Z0-9_.:%-]+=[a-zA-Z0-9_.:%-]*)*)(\/[^#?]*)?([?][^#]*)?(\#.*)?$$ + * @example "did:peer:WgWxqztrNooG92RXvxSTWv" */ did?: string; /** As signed attachment, DID Doc associated with DID */ @@ -1173,6 +1199,13 @@ export interface Date { expires_time: string; } +export interface DefaultConfigValues { + /** Endorser config */ + connected_to_endorsers?: EndorserLedgerConfig[]; + /** Public DID config */ + created_public_did?: string[]; +} + export interface Disclose { /** * Message identifier @@ -2858,7 +2891,7 @@ export interface PluginCreateWalletRequest { /** Agent config key-value pairs */ extra_settings?: object; /** - * Image url for this wallet. This image url is publicized (self-attested) to other agents as part of forming a connection. + * Image url for this wallet. This image url is publicized (self-attested) to other agents as part of forming a connection. * @example "https://aries.ca/images/sample.png" */ image_url?: string; @@ -2868,12 +2901,12 @@ export interface PluginCreateWalletRequest { */ key_management_mode?: 'managed'; /** - * Label for this wallet. This label is publicized (self-attested) to other agents as part of forming a connection. + * Label for this wallet. This label is publicized (self-attested) to other agents as part of forming a connection. * @example "Alice" */ label?: string; /** - * Webhook target dispatch type for this wallet. default - Dispatch only to webhooks associated with this wallet. base - Dispatch only to webhooks associated with the base wallet. both - Dispatch to both webhook targets. + * Webhook target dispatch type for this wallet. default - Dispatch only to webhooks associated with this wallet. base - Dispatch only to webhooks associated with the base wallet. both - Dispatch to both webhook targets. * @example "default" */ wallet_dispatch_type?: 'default' | 'both' | 'base'; @@ -3056,7 +3089,7 @@ export interface ReceiveInvitationRequest { export interface RemoveWalletRequest { /** - * Master key used for key derivation. Only required for unmanaged wallets. + * Master key used for key derivation. Only required for unmanaged wallets. * @example "MySecretKey123" */ wallet_key?: string; @@ -3090,12 +3123,18 @@ export interface ReservationList { export interface ReservationRecord { /** @example "{"endorser_alias": " ... ", "ledger_id": " ... "}" */ - connect_to_endorsers?: object[]; - /** Object for storing text data */ - context_data: object; + connect_to_endorser?: object[]; /** Contact email for this tenant request */ contact_email: string; - + /** Contact name for this tenant request */ + contact_name: string; + /** Contact phone number for this tenant request */ + contact_phone: string; + /** + * Context data for this tenant request + * @example "{"tenant_reason": " ... ", "contact_name": " ... ", "contact_phone": " ... "}" + */ + context_data?: object; create_public_did?: string[]; /** * Time of record creation @@ -3125,6 +3164,11 @@ export interface ReservationRecord { * @example "line of business short name" */ tenant_name: string; + /** + * Reason(s) for requesting a tenant + * @example "Issue permits to clients" + */ + tenant_reason: string; /** * Time of last record update * @pattern ^\d{4}-\d\d-\d\d[T ]\d\d:\d\d(?:\:(?:\d\d(?:\.\d{1,6})?))?(?:[+-]\d\d:?\d\d|Z|)$ @@ -3138,9 +3182,16 @@ export interface ReservationRecord { wallet_id?: string; } +export type ReservationRefresh = object; + export interface ReservationRequest { /** Contact email for this tenant request */ contact_email: string; + /** + * Optional context data for this tenant request + * @example {"contact_phone":"555-555-5555"} + */ + context_data?: object; /** * Proposed name of Tenant * @example "line of business short name" @@ -3612,10 +3663,15 @@ export interface TenantConfig { connect_to_endorser?: EndorserLedgerConfig[]; /** Public DID config */ create_public_did?: string[]; - /** Enable ledger switch config */ - enable_ledger_switch?: boolean; - /** Current set ledger ident */ + /** Current ledger identifier */ curr_ledger_id?: string; + /** True if tenant can switch endorser/ledger */ + enable_ledger_switch?: boolean; +} + +export interface TenantLedgerIdConfig { + /** Ledger identifier */ + ledger_id: string; } export interface TenantList { @@ -3634,8 +3690,16 @@ export interface TenantRecord { * @example "2021-12-31T23:59:59Z" */ created_at?: string; - enable_ledger_switch?: boolean; created_public_did?: string[]; + /** Current ledger identifier */ + curr_ledger_id?: string; + /** + * Timestamp of the deletion + * @example "2023-10-30T01:01:01Z" + */ + deleted_at?: string; + /** True if tenant can switch endorser/ledger */ + enable_ledger_switch?: boolean; /** * The state of the tenant. * @example "active" @@ -3789,17 +3853,17 @@ export interface UpdateWalletRequest { /** Agent config key-value pairs */ extra_settings?: object; /** - * Image url for this wallet. This image url is publicized (self-attested) to other agents as part of forming a connection. + * Image url for this wallet. This image url is publicized (self-attested) to other agents as part of forming a connection. * @example "https://aries.ca/images/sample.png" */ image_url?: string; /** - * Label for this wallet. This label is publicized (self-attested) to other agents as part of forming a connection. + * Label for this wallet. This label is publicized (self-attested) to other agents as part of forming a connection. * @example "Alice" */ label?: string; /** - * Webhook target dispatch type for this wallet. default - Dispatch only to webhooks associated with this wallet. base - Dispatch only to webhooks associated with the base wallet. both - Dispatch to both webhook targets. + * Webhook target dispatch type for this wallet. default - Dispatch only to webhooks associated with this wallet. base - Dispatch only to webhooks associated with the base wallet. both - Dispatch to both webhook targets. * @example "default" */ wallet_dispatch_type?: 'default' | 'both' | 'base'; @@ -3982,6 +4046,11 @@ export interface V10CredentialExchange { updated_at?: string; } +export interface V10CredentialExchangeAutoRemoveRequest { + /** Whether to remove the credential exchange record on completion (overrides --preserve-exchange-records configuration setting) */ + auto_remove?: boolean; +} + export interface V10CredentialExchangeListResult { /** Aries#0036 v1.0 credential exchange records */ results?: V10CredentialExchange[]; @@ -4174,6 +4243,8 @@ export interface V10DiscoveryRecord { export type V10PresentProofModuleResponse = object; export interface V10PresentationCreateRequestRequest { + /** Whether to remove the presentation exchange record on completion (overrides --preserve-exchange-records configuration setting) */ + auto_remove?: boolean; /** * Verifier choice to auto-verify proof presentation * @example false @@ -4194,6 +4265,11 @@ export interface V10PresentationExchange { * @example false */ auto_present?: boolean; + /** + * Verifier choice to remove this presentation exchange record when complete + * @example false + */ + auto_remove?: boolean; /** Verifier choice to auto-verify proof presentation */ auto_verify?: boolean; /** @@ -4273,6 +4349,8 @@ export interface V10PresentationProblemReportRequest { export interface V10PresentationProposalRequest { /** Whether to respond automatically to presentation requests, building and presenting requested proof */ auto_present?: boolean; + /** Whether to remove the presentation exchange record on completion (overrides --preserve-exchange-records configuration setting) */ + auto_remove?: boolean; /** Human-readable comment */ comment?: string | null; /** @@ -4289,7 +4367,25 @@ export interface V10PresentationProposalRequest { trace?: boolean; } +export interface V10PresentationSendRequest { + /** Whether to remove the presentation exchange record on completion (overrides --preserve-exchange-records configuration setting) */ + auto_remove?: boolean; + /** Nested object mapping proof request attribute referents to requested-attribute specifiers */ + requested_attributes: Record; + /** Nested object mapping proof request predicate referents to requested-predicate specifiers */ + requested_predicates: Record; + /** Self-attested attributes to build into proof */ + self_attested_attributes: Record; + /** + * Whether to trace event (default false) + * @example false + */ + trace?: boolean; +} + export interface V10PresentationSendRequestRequest { + /** Whether to remove the presentation exchange record on completion (overrides --preserve-exchange-records configuration setting) */ + auto_remove?: boolean; /** * Verifier choice to auto-verify proof presentation * @example false @@ -4311,6 +4407,8 @@ export interface V10PresentationSendRequestRequest { } export interface V10PresentationSendRequestToProposal { + /** Whether to remove the presentation exchange record on completion (overrides --preserve-exchange-records configuration setting) */ + auto_remove?: boolean; /** * Verifier choice to auto-verify proof presentation * @example false @@ -4812,6 +4910,8 @@ export interface V20CredRequestFree { } export interface V20CredRequestRequest { + /** Whether to remove the credential exchange record on completion (overrides --preserve-exchange-records configuration setting) */ + auto_remove?: boolean; /** * Holder DID to substitute for the credentialSubject.id * @example "did:key:ahsdkjahsdkjhaskjdhakjshdkajhsdkjahs" @@ -4911,6 +5011,8 @@ export interface V20Pres { } export interface V20PresCreateRequestRequest { + /** Whether to remove the presentation exchange record on completion (overrides --preserve-exchange-records configuration setting) */ + auto_remove?: boolean; /** * Verifier choice to auto-verify proof presentation * @example false @@ -4931,6 +5033,11 @@ export interface V20PresExRecord { * @example false */ auto_present?: boolean; + /** + * Verifier choice to remove this presentation exchange record when complete + * @example false + */ + auto_remove?: boolean; /** Verifier choice to auto-verify proof presentation */ auto_verify?: boolean; /** Attachment content by format for proposal, request, and presentation */ @@ -5060,6 +5167,8 @@ export interface V20PresProposalByFormat { export interface V20PresProposalRequest { /** Whether to respond automatically to presentation requests, building and presenting requested proof */ auto_present?: boolean; + /** Whether to remove the presentation exchange record on completion (overrides --preserve-exchange-records configuration setting) */ + auto_remove?: boolean; /** Human-readable comment */ comment?: string | null; /** @@ -5104,6 +5213,8 @@ export interface V20PresRequestByFormat { } export interface V20PresSendRequestRequest { + /** Whether to remove the presentation exchange record on completion (overrides --preserve-exchange-records configuration setting) */ + auto_remove?: boolean; /** * Verifier choice to auto-verify proof presentation * @example false @@ -5125,6 +5236,8 @@ export interface V20PresSendRequestRequest { } export interface V20PresSpecByFormatRequest { + /** Whether to remove the presentation exchange record on completion (overrides --preserve-exchange-records configuration setting) */ + auto_remove?: boolean; /** Optional Presentation specification for DIF, overrides the PresentionExchange record's PresRequest */ dif?: DIFPresSpec; /** Presentation specification for indy */ @@ -5136,6 +5249,8 @@ export interface V20PresSpecByFormatRequest { export type V20PresentProofModuleResponse = object; export interface V20PresentationSendRequestToProposal { + /** Whether to remove the presentation exchange record on completion (overrides --preserve-exchange-records configuration setting) */ + auto_remove?: boolean; /** * Verifier choice to auto-verify proof presentation * @example false @@ -5248,6 +5363,6 @@ export interface WalletRecord { wallet_id: string; } -export interface WriteLedgerRequest { +export interface WriteLedger { ledger_id?: string; } diff --git a/services/tenant-ui/frontend/src/views/innkeeper/InnkeeperServerConfig.vue b/services/tenant-ui/frontend/src/views/innkeeper/InnkeeperServerConfig.vue new file mode 100644 index 000000000..fe23e5f73 --- /dev/null +++ b/services/tenant-ui/frontend/src/views/innkeeper/InnkeeperServerConfig.vue @@ -0,0 +1,7 @@ + + + From 6e493645b97bd89caf7d1da4bbed094673f26134 Mon Sep 17 00:00:00 2001 From: Lucas ONeil Date: Wed, 8 Nov 2023 16:27:05 -0800 Subject: [PATCH 3/5] Show write ledger on tenant list Signed-off-by: Lucas ONeil --- .../components/innkeeper/tenants/Tenants.vue | 35 ++++++++++++------- .../frontend/src/helpers/tableFormatters.ts | 22 +++++++++++- .../about/__snapshots__/Acapy.test.ts.snap | 12 ++----- 3 files changed, 46 insertions(+), 23 deletions(-) diff --git a/services/tenant-ui/frontend/src/components/innkeeper/tenants/Tenants.vue b/services/tenant-ui/frontend/src/components/innkeeper/tenants/Tenants.vue index a390f3978..6cb6c6337 100644 --- a/services/tenant-ui/frontend/src/components/innkeeper/tenants/Tenants.vue +++ b/services/tenant-ui/frontend/src/components/innkeeper/tenants/Tenants.vue @@ -56,6 +56,23 @@ /> + + + { }; // Formatting the Tenant table row -const formattedTenants = computed(() => - tenants.value.map((ten: any) => ({ - tenant_id: ten.tenant_id, - tenant_name: ten.tenant_name, - connect_to_endorser: ten.connect_to_endorser, - created_public_did: ten.created_public_did, - created: formatDateLong(ten.created_at), - created_at: ten.created_at, - enable_ledger_switch: ten.enable_ledger_switch, - })) -); +const formattedTenants = computed(() => formatTenants(tenants)); onMounted(async () => { loadTable(); @@ -147,6 +154,10 @@ const filter = ref({ value: null, matchMode: FilterMatchMode.CONTAINS, }, + curr_ledger_id: { + value: null, + matchMode: FilterMatchMode.CONTAINS, + }, }); // necessary for expanding rows, we don't do anything with this diff --git a/services/tenant-ui/frontend/src/helpers/tableFormatters.ts b/services/tenant-ui/frontend/src/helpers/tableFormatters.ts index f8b1eacc1..adfc77919 100644 --- a/services/tenant-ui/frontend/src/helpers/tableFormatters.ts +++ b/services/tenant-ui/frontend/src/helpers/tableFormatters.ts @@ -2,16 +2,20 @@ import { SchemaStorageRecord } from '@/types'; import { CredDefStorageRecord, CredentialDefinition, + TenantRecord, } from '@/types/acapyApi/acapyInterface'; import { Ref } from 'vue'; import { formatDateLong } from '.'; +export interface FormattedCredDef extends CredDefStorageRecord { + created: string; +} export interface FormattedSchema extends SchemaStorageRecord { created: string; credentialDefinitions: CredentialDefinition[]; } -export interface FormattedCredDef extends CredDefStorageRecord { +export interface FormattedTenantRecord extends TenantRecord { created: string; } @@ -40,3 +44,19 @@ export const formatStoredCredDefs = ( created_at: credDef.created_at, created: formatDateLong(credDef.created_at), })); + +export const formatTenants = ( + tenants: Ref +): FormattedTenantRecord[] => + tenants.value.map((tenant: any) => ({ + deleted_at: tenant.deleted_at, + tenant_id: tenant.tenant_id, + tenant_name: tenant.tenant_name, + connect_to_endorser: tenant.connect_to_endorser, + created_public_did: tenant.created_public_did, + created: formatDateLong(tenant.created_at), + created_at: tenant.created_at, + enable_ledger_switch: tenant.enable_ledger_switch, + state: tenant.state, + curr_ledger_id: tenant.curr_ledger_id, + })); diff --git a/services/tenant-ui/frontend/test/components/about/__snapshots__/Acapy.test.ts.snap b/services/tenant-ui/frontend/test/components/about/__snapshots__/Acapy.test.ts.snap index 70771ec59..222756dad 100644 --- a/services/tenant-ui/frontend/test/components/about/__snapshots__/Acapy.test.ts.snap +++ b/services/tenant-ui/frontend/test/components/about/__snapshots__/Acapy.test.ts.snap @@ -8,16 +8,8 @@ exports[`Acapy > mount matches snapshot with expected values 1`] = `
-
about.acaPy.ledger
-
ledgerName
-
about.acaPy.ledgerBrowser
-
ledgerBrowser
-
about.acaPy.tailsServer
-
tailsServer
-
-
-
+
@@ -27,7 +19,7 @@ exports[`Acapy > mount matches snapshot with expected values 1`] = `
-
+
From 5d31ee936bcd5a3d753cab0bb754d62403e45da6 Mon Sep 17 00:00:00 2001 From: Lucas ONeil Date: Thu, 9 Nov 2023 13:21:13 -0800 Subject: [PATCH 4/5] More ledger information Signed-off-by: Lucas ONeil --- .../innkeeper/config/ServerConfig.vue | 53 +++++++++++++------ .../src/components/profile/Developer.vue | 2 +- .../frontend/src/plugins/i18n/locales/en.json | 15 +++++- 3 files changed, 50 insertions(+), 20 deletions(-) diff --git a/services/tenant-ui/frontend/src/components/innkeeper/config/ServerConfig.vue b/services/tenant-ui/frontend/src/components/innkeeper/config/ServerConfig.vue index 70538aef8..c6874b716 100644 --- a/services/tenant-ui/frontend/src/components/innkeeper/config/ServerConfig.vue +++ b/services/tenant-ui/frontend/src/components/innkeeper/config/ServerConfig.vue @@ -6,20 +6,41 @@

- ACA-Py Version: {{ serverConfig?.config?.version }} + {{ $t('serverConfig.acapyVersion') }} + {{ serverConfig?.config?.version }} +

+

+ {{ $t('serverConfig.tractionProxy') }} + {{ config.frontend.tenantProxyPath }} +

-
-

Ledger List

+
+

+ {{ $t('serverConfig.ledger.ledgerList') }} +

+

+ {{ $t('serverConfig.ledger.quickConnect') }} + {{ config.frontend.quickConnectEndorserName }} +

+

+ {{ $t('serverConfig.ledger.default') }} + {{ serverConfig?.config?.['ledger.write_ledger'] }} +

+ +
@@ -31,22 +52,16 @@
-
-

- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do - eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut - enim ad minim veniam, quis nostrud exercitation ullamco laboris - nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in - reprehenderit in voluptate velit esse cillum dolore eu fugiat - nulla pariatur. Excepteur sint occaecat cupidatat non proident, - sunt in culpa qui officia deserunt mollit anim id est laborum. -

+
+

- -
+ @@ -63,12 +78,13 @@ import { computed, onMounted } from 'vue'; import VueJsonPretty from 'vue-json-pretty'; import { useToast } from 'vue-toastification'; // Components -import { useInnkeeperTenantsStore } from '@/store'; +import { useConfigStore, useInnkeeperTenantsStore } from '@/store'; import MainCardContent from '../../layout/mainCard/MainCardContent.vue'; import PluginList from '@/components/about/PluginList.vue'; const toast = useToast(); +const { config } = storeToRefs(useConfigStore()); const innkeeperTenantsStore = useInnkeeperTenantsStore(); const { loading, serverConfig } = storeToRefs(useInnkeeperTenantsStore()); @@ -83,13 +99,16 @@ const loadConfig = async () => { }); }; -// computed list of the "ledger.ledger_config_list" array in serverConfig const ledgerConfigList = computed(() => { if (serverConfig.value?.config) { return serverConfig.value.config['ledger.ledger_config_list']; } return []; }); + +const swaggerUrl = computed( + () => `${config.value.frontend.tenantProxyPath}/api/doc` +); diff --git a/services/tenant-ui/frontend/src/components/profile/Developer.vue b/services/tenant-ui/frontend/src/components/profile/Developer.vue index e79835e71..20b5aeeda 100644 --- a/services/tenant-ui/frontend/src/components/profile/Developer.vue +++ b/services/tenant-ui/frontend/src/components/profile/Developer.vue @@ -9,7 +9,7 @@ import VueJsonPretty from 'vue-json-pretty'; import 'vue-json-pretty/lib/styles.css'; import { storeToRefs } from 'pinia'; -import { useConfigStore, useTokenStore } from '@/store'; +import { useConfigStore } from '@/store'; import JWT from './JWT.vue'; import 'primeicons/primeicons.css'; diff --git a/services/tenant-ui/frontend/src/plugins/i18n/locales/en.json b/services/tenant-ui/frontend/src/plugins/i18n/locales/en.json index a421376c4..3a56c788c 100644 --- a/services/tenant-ui/frontend/src/plugins/i18n/locales/en.json +++ b/services/tenant-ui/frontend/src/plugins/i18n/locales/en.json @@ -406,8 +406,19 @@ "phone": "Phone / Mobile" }, "serverConfig": { - "expand": "Show full server status config", - "serverConfig": "Server Configuration" + "acapyVersion": "ACA-Py Version:", + "expand": "Show full ACA-Py server config", + "ledger": { + "default": "Default base ledger:", + "ledgerDetails": "Ledger Details", + "ledgerList": "Ledger List", + "quickConnect": "Tenant UI quick-connect endorser:" + }, + "tractionProxy": "Traction Proxy URL:", + "serverConfig": "Server Configuration", + "tenantUi": { + "tenantUi": "Tenant UI" + } }, "session": { "countdown": "You are going to be logged out in { seconds } seconds...", From ae96c2bc60868f4bf54392eefbf5e487e40c26a8 Mon Sep 17 00:00:00 2001 From: Lucas ONeil Date: Thu, 9 Nov 2023 14:33:57 -0800 Subject: [PATCH 5/5] unused field Signed-off-by: Lucas ONeil --- .../frontend/src/components/profile/issuance/Endorser.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/tenant-ui/frontend/src/components/profile/issuance/Endorser.vue b/services/tenant-ui/frontend/src/components/profile/issuance/Endorser.vue index dc5123d3a..ef34c625f 100644 --- a/services/tenant-ui/frontend/src/components/profile/issuance/Endorser.vue +++ b/services/tenant-ui/frontend/src/components/profile/issuance/Endorser.vue @@ -84,7 +84,7 @@ import EndorserConnect from './EndorserConnect.vue'; const configStore = useConfigStore(); const tenantStore = useTenantStore(); const { config } = storeToRefs(configStore); -const { endorserConnection, endorserInfo, tenantConfig, writeLedger, loading } = +const { endorserConnection, endorserInfo, tenantConfig, loading } = storeToRefs(tenantStore); const endorserList = tenantConfig.value.connect_to_endorser.map(