From 0db991ccb8fc987eae9dd35c60d86070701db09e Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 24 Aug 2022 11:00:23 +0200 Subject: [PATCH] add call to validate database endpoint if database requires it --- src/Umbraco.Web.UI.Client/schemas/api/api.yml | 9 +- .../schemas/generated-schema.ts | 5 +- .../installer/installer-database.element.ts | 58 ++++++++- .../src/installer/installer.stories.ts | 4 +- .../src/mocks/domains/install.handlers.ts | 27 ++++- .../temp-schema-generator/installer.ts | 114 +++++++++--------- 6 files changed, 137 insertions(+), 80 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/schemas/api/api.yml b/src/Umbraco.Web.UI.Client/schemas/api/api.yml index 59e42377b1..974f5dc74a 100644 --- a/src/Umbraco.Web.UI.Client/schemas/api/api.yml +++ b/src/Umbraco.Web.UI.Client/schemas/api/api.yml @@ -46,7 +46,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/InstallValidateDatabaseRequest' + $ref: '#/components/schemas/InstallSetupDatabaseConfiguration' required: true responses: '201': @@ -341,13 +341,6 @@ components: required: - user - telemetryLevel - InstallValidateDatabaseRequest: - type: object - properties: - database: - $ref: '#/components/schemas/InstallSetupDatabaseConfiguration' - required: - - database ServerStatus: type: string enum: diff --git a/src/Umbraco.Web.UI.Client/schemas/generated-schema.ts b/src/Umbraco.Web.UI.Client/schemas/generated-schema.ts index 664b9b012f..4c9f3aa57f 100644 --- a/src/Umbraco.Web.UI.Client/schemas/generated-schema.ts +++ b/src/Umbraco.Web.UI.Client/schemas/generated-schema.ts @@ -102,9 +102,6 @@ export interface components { telemetryLevel: components["schemas"]["ConsentLevel"]; database?: components["schemas"]["InstallSetupDatabaseConfiguration"]; }; - InstallValidateDatabaseRequest: { - database: components["schemas"]["InstallSetupDatabaseConfiguration"]; - }; /** @enum {string} */ ServerStatus: "running" | "must-install" | "must-upgrade"; StatusResponse: { @@ -184,7 +181,7 @@ export interface operations { }; requestBody: { content: { - "application/json": components["schemas"]["InstallValidateDatabaseRequest"]; + "application/json": components["schemas"]["InstallSetupDatabaseConfiguration"]; }; }; }; diff --git a/src/Umbraco.Web.UI.Client/src/installer/installer-database.element.ts b/src/Umbraco.Web.UI.Client/src/installer/installer-database.element.ts index f3ccdab29d..ab9f21e11b 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/installer-database.element.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/installer-database.element.ts @@ -1,8 +1,9 @@ import { UUIButtonElement } from '@umbraco-ui/uui'; -import { css, CSSResultGroup, html, LitElement } from 'lit'; +import { css, CSSResultGroup, html, LitElement, nothing } from 'lit'; import { customElement, property, query, state } from 'lit/decorators.js'; import { Subscription } from 'rxjs'; +import { postInstallSetup, postInstallValidateDatabase } from '../core/api/fetcher'; import { UmbContextConsumerMixin } from '../core/context'; import { UmbracoInstallerDatabaseModel, UmbracoPerformInstallDatabaseConfiguration } from '../core/models'; import { UmbInstallerContext } from './installer-context'; @@ -69,6 +70,11 @@ export class UmbInstallerDatabase extends UmbContextConsumerMixin(LitElement) { margin-left: auto; min-width: 120px; } + + .error { + color: var(--uui-color-danger); + padding: var(--uui-size-space-2) 0; + } `, ]; @@ -90,6 +96,9 @@ export class UmbInstallerDatabase extends UmbContextConsumerMixin(LitElement) { @state() private _installerStore?: UmbInstallerContext; + @state() + private _validationErrorMessage = ''; + private storeDataSubscription?: Subscription; private storeSettingsSubscription?: Subscription; @@ -136,15 +145,19 @@ export class UmbInstallerDatabase extends UmbContextConsumerMixin(LitElement) { this._installerStore?.appendData({ database }); } - private _handleSubmit = (e: SubmitEvent) => { - e.preventDefault(); + private _handleSubmit = async (evt: SubmitEvent) => { + evt.preventDefault(); - const form = e.target as HTMLFormElement; + const form = evt.target as HTMLFormElement; if (!form) return; const isValid = form.checkValidity(); if (!isValid) return; + if (!this._installerStore) return; + + this._installButton.state = 'waiting'; + // Only append the database if it's not pre-configured if (!this._preConfiguredDatabase) { const formData = new FormData(form); @@ -154,6 +167,39 @@ export class UmbInstallerDatabase extends UmbContextConsumerMixin(LitElement) { const server = formData.get('server') as string; const name = formData.get('name') as string; const useIntegratedAuthentication = formData.has('useIntegratedAuthentication'); + const connectionString = formData.get('connectionString') as string; + + // Validate connection + const selectedDatabase = this._databases.find((x) => x.id === id); + if (selectedDatabase?.requiresConnectionTest) { + try { + let databaseDetails: UmbracoPerformInstallDatabaseConfiguration = {}; + + if (connectionString) { + databaseDetails.connectionString = connectionString; + } else { + databaseDetails = { + id, + username, + password, + server, + useIntegratedAuthentication, + name, + }; + } + await postInstallValidateDatabase(databaseDetails); + } catch (e) { + if (e instanceof postInstallSetup.Error) { + const error = e.getActualType(); + console.warn('Database validation failed', error.data); + this._validationErrorMessage = error.data.detail ?? 'Could not verify database connection'; + } else { + this._validationErrorMessage = 'A server error happened when trying to validate the database'; + } + this._installButton.state = 'failed'; + return; + } + } const database = { ...this._installerStore?.getData().database, @@ -163,14 +209,13 @@ export class UmbInstallerDatabase extends UmbContextConsumerMixin(LitElement) { server, name, useIntegratedAuthentication, + connectionString, } as UmbracoPerformInstallDatabaseConfiguration; this._installerStore?.appendData({ database }); } this.dispatchEvent(new CustomEvent('submit', { bubbles: true, composed: true })); - - this._installButton.state = 'waiting'; }; private _onBack() { @@ -321,6 +366,7 @@ export class UmbInstallerDatabase extends UmbContextConsumerMixin(LitElement) { ${this._preConfiguredDatabase ? this._renderPreConfiguredDatabase(this._preConfiguredDatabase) : this._renderDatabaseSelection()} + ${this._validationErrorMessage ? html`