@c8y/ngx-components 1024.1.5 → 1024.1.8

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.
@@ -2,7 +2,7 @@ import * as i0 from '@angular/core';
2
2
  import { Input, Component, Injectable, EventEmitter, inject, NgModule, Output, ChangeDetectorRef, ElementRef, Renderer2, TemplateRef, ContentChild, ViewChild } from '@angular/core';
3
3
  import { map, catchError, tap, switchMap, shareReplay, take, filter, mergeAll, toArray } from 'rxjs/operators';
4
4
  import * as i2 from '@c8y/ngx-components';
5
- import { FormGroupComponent, C8yTranslatePipe, Permissions, C8yTranslateDirective, RequiredInputPlaceholderDirective, MinValidationDirective, MaxValidationDirective, MessagesComponent, MessageDirective, TitleComponent, BreadcrumbComponent, BreadcrumbItemComponent, ActionBarItemComponent, IconDirective, HelpComponent, CoreModule, hookRoute, DefaultValidationDirective, memoize, DropAreaComponent, SelectLegacyComponent, MoNamePipe, EmptyStateComponent, Status, TabsService, NavigatorNode, hookTab, hookNavigator, hookPatternMessages } from '@c8y/ngx-components';
5
+ import { FormGroupComponent, C8yTranslatePipe, Permissions, C8yTranslateDirective, RequiredInputPlaceholderDirective, MinValidationDirective, MaxValidationDirective, MessagesComponent, MessageDirective, TitleComponent, BreadcrumbComponent, BreadcrumbItemComponent, ActionBarItemComponent, IconDirective, HelpComponent, CoreModule, hookRoute, DefaultValidationDirective, memoize, AppStateService, DropAreaComponent, SelectLegacyComponent, MoNamePipe, EmptyStateComponent, Status, TabsService, NavigatorNode, hookTab, hookNavigator, hookPatternMessages } from '@c8y/ngx-components';
6
6
  import * as i1$1 from '@c8y/client';
7
7
  import { TenantLoginOptionType, TfaStrategy, GrantType, UserManagementSource, TenantLoginOptionsService } from '@c8y/client';
8
8
  import * as i1 from '@angular/forms';
@@ -1521,12 +1521,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
1521
1521
  }] } });
1522
1522
 
1523
1523
  class BasicConfigurationComponent {
1524
- get isMtlsPrivateKeyEncrypted() {
1525
- const value = this.templateModel?.mtlsPrivateKeyPem;
1526
- return !!value && !value.includes('-----BEGIN');
1527
- }
1528
- constructor(tenantService) {
1529
- this.tenantService = tenantService;
1524
+ constructor() {
1530
1525
  this.REDIRECT_TO_THE_USER_INTERFACE_APPLICATION_TOOLTIP = gettext("The redirect URL is automatically set to the application used by the user. In case of an error, it will be correctly displayed on the application's page.");
1531
1526
  this.MTLS_ENABLED_TOOLTIP = gettext('Use a client certificate (mTLS) instead of a client secret to authenticate the platform with the authorization server. Use this option only if the authorization server enforces certificate-based client authentication.');
1532
1527
  this.MTLS_CERTIFICATE_TOOLTIP = gettext('Public X.509 client certificate in PEM format, issued for this tenant by a CA trusted by your authorization server. Accepted file extension: .pem.');
@@ -1540,20 +1535,20 @@ class BasicConfigurationComponent {
1540
1535
  mtlsCertificatePem: '',
1541
1536
  mtlsPrivateKeyPem: ''
1542
1537
  };
1538
+ this.appStateService = inject(AppStateService);
1539
+ }
1540
+ get isMtlsPrivateKeyEncrypted() {
1541
+ const value = this.templateModel?.mtlsPrivateKeyPem;
1542
+ return !!value && !value.includes('-----BEGIN');
1543
1543
  }
1544
1544
  shouldShow(field) {
1545
1545
  return field in this.templateModel;
1546
1546
  }
1547
- async ngOnChanges() {
1548
- const currentTenant = (await this.tenantService.current()).data;
1549
- const { domainName } = currentTenant;
1550
- this.redirectToPlatformWarningParams = {
1551
- host: `https://${domainName}`,
1552
- defaultRedirectUrl: `https://${domainName}/tenant/oauth`
1553
- };
1547
+ ngOnChanges() {
1554
1548
  this.redirectToPlatform = this.templateModel.redirectToPlatform || '';
1555
1549
  this.flowControlledByUI = !this.templateModel.redirectToPlatform;
1556
1550
  this.mtlsEnabled = !!(this.templateModel.mtlsCertificatePem || this.templateModel.mtlsPrivateKeyPem);
1551
+ this.loadRedirectToPlatformWarningParams();
1557
1552
  }
1558
1553
  onMtlsEnabledChange() {
1559
1554
  if (this.mtlsEnabled) {
@@ -1589,7 +1584,14 @@ class BasicConfigurationComponent {
1589
1584
  reader.onload = () => onLoaded(reader.result);
1590
1585
  reader.readAsText(dropped[0].file);
1591
1586
  }
1592
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: BasicConfigurationComponent, deps: [{ token: i1$1.TenantService }], target: i0.ɵɵFactoryTarget.Component }); }
1587
+ loadRedirectToPlatformWarningParams() {
1588
+ const { domainName } = this.appStateService.currentTenant.value || {};
1589
+ this.redirectToPlatformWarningParams = {
1590
+ host: `https://${domainName}`,
1591
+ defaultRedirectUrl: `https://${domainName}/tenant/oauth`
1592
+ };
1593
+ }
1594
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: BasicConfigurationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1593
1595
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: BasicConfigurationComponent, isStandalone: true, selector: "c8y-basic-configuration", inputs: { templateModel: "templateModel" }, usesOnChanges: true, ngImport: i0, template: "<fieldset class=\"p-24\">\n <div class=\"row\">\n <div class=\"col-xs-12 col-sm-3 col-md-2 m-b-xs-8\">\n <div\n class=\"h4 text-normal text-right text-left-xs\"\n translate\n >\n Basic\n </div>\n </div>\n\n @if (templateModel) {\n <div class=\"col-xs-12 col-sm-9 col-md-10 col-lg-9\">\n <div class=\"row\">\n @if (shouldShow('keyCloakAddress')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"keyCloakAddress\"\n translate\n >\n Keycloak address\n </label>\n <input\n class=\"form-control\"\n id=\"keyCloakAddress\"\n name=\"keyCloakAddress\"\n type=\"url\"\n required\n [(ngModel)]=\"templateModel.keyCloakAddress\"\n [placeholder]=\"\n 'e.g. {{ example }}' | translate: { example: 'https://example.de' }\n \"\n />\n </c8y-form-group>\n </div>\n }\n @if (shouldShow('aadAddress')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"aadAddress\"\n translate\n >\n Azure AD address\n </label>\n <input\n class=\"form-control\"\n id=\"aadAddress\"\n name=\"aadAddress\"\n type=\"url\"\n required\n [(ngModel)]=\"templateModel.aadAddress\"\n [placeholder]=\"\n 'e.g. {{ example }}'\n | translate: { example: 'https://login.microsoftonline.de' }\n \"\n />\n </c8y-form-group>\n </div>\n }\n @if (shouldShow('tenant')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"tenant\"\n translate\n >\n Tenant\n </label>\n <input\n class=\"form-control\"\n id=\"tenant\"\n name=\"tenant\"\n required\n [(ngModel)]=\"templateModel.tenant\"\n [placeholder]=\"\n 'e.g. {{ example }}' | translate: { example: 'c8y.onmicrosoft.de' }\n \"\n />\n </c8y-form-group>\n </div>\n }\n @if (shouldShow('applicationId')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"applicationId\"\n translate\n >\n Application ID\n </label>\n <input\n class=\"form-control\"\n id=\"applicationId\"\n name=\"applicationId\"\n required\n [(ngModel)]=\"templateModel.applicationId\"\n />\n </c8y-form-group>\n </div>\n }\n\n @if (shouldShow('realmName')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"realmName\"\n translate\n >\n Realm name\n </label>\n <input\n class=\"form-control\"\n id=\"realmName\"\n name=\"realmName\"\n required\n [(ngModel)]=\"templateModel.realmName\"\n />\n </c8y-form-group>\n </div>\n }\n </div>\n\n @if (shouldShow('redirectToPlatform')) {\n <div class=\"row\">\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"redirectToPlatform\"\n >\n {{ 'Redirect URL' | translate }}\n @if (\n !flowControlledByUI &&\n redirectToPlatformWarningParams &&\n templateModel.redirectToPlatform !==\n redirectToPlatformWarningParams.defaultRedirectUrl\n ) {\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"helpContent\"\n placement=\"bottom\"\n triggers=\"focus\"\n type=\"button\"\n [adaptivePosition]=\"false\"\n ></button>\n }\n <ng-template #helpContent>\n <span\n ngNonBindable\n translate\n [translateParams]=\"redirectToPlatformWarningParams\"\n >\n For correct application behavior you can use only \"{{ host }}\" or \"{{\n defaultRedirectUrl\n }}\", the latter one is recommended.\n </span>\n </ng-template>\n </label>\n <input\n class=\"form-control\"\n id=\"redirectToPlatform\"\n name=\"redirectToPlatform\"\n type=\"url\"\n [required]=\"!flowControlledByUI\"\n [disabled]=\"flowControlledByUI\"\n [(ngModel)]=\"templateModel.redirectToPlatform\"\n [placeholder]=\"\n 'e.g. {{ example }}'\n | translate\n : {\n example:\n redirectToPlatformWarningParams?.defaultRedirectUrl ||\n 'https://tenant.domain.com'\n }\n \"\n />\n </c8y-form-group>\n </div>\n <div class=\"col-sm-6\">\n <div class=\"form-group\">\n <label\n class=\"c8y-switch m-t-24\"\n title=\"{{\n 'Redirect to the user interface application`SSO authentication`' | translate\n }}\"\n for=\"flowControlledByUI\"\n >\n <input\n id=\"flowControlledByUI\"\n name=\"flowControlledByUI\"\n type=\"checkbox\"\n [(ngModel)]=\"flowControlledByUI\"\n (change)=\"\n templateModel.redirectToPlatform = flowControlledByUI\n ? ''\n : redirectToPlatform\n \"\n />\n <span></span>\n <span class=\"control-label\">{{\n 'Redirect to the user interface application`SSO authentication`' | translate\n }}</span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{ REDIRECT_TO_THE_USER_INTERFACE_APPLICATION_TOOLTIP | translate }}\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n ></button>\n </label>\n </div>\n </div>\n <div class=\"col-sm-12\">\n @if (flowControlledByUI && redirectToPlatform !== '') {\n <div>\n <div\n class=\"alert alert-warning max-width-100 m-b-32\"\n ngNonBindable\n translate\n [translateParams]=\"{\n redirectURI: '<tenant_domain>/apps/*'\n }\"\n >\n Make sure that \"Valid Redirect URIs\" in the authorization server is set to \"{{\n redirectURI\n }}\" or to the full URIs of the used applications if the authorization server\n does not support patterns.\n </div>\n </div>\n }\n @if (!flowControlledByUI && redirectToPlatform === '') {\n <div>\n <div\n class=\"alert alert-warning max-width-100 m-b-32\"\n ngNonBindable\n translate\n [translateParams]=\"{\n redirectURI: '<tenant_domain>/tenant/oauth'\n }\"\n >\n Make sure that \"Valid Redirect URIs\" in the authorization server is set to \"{{\n redirectURI\n }}\".\n </div>\n </div>\n }\n </div>\n </div>\n }\n <div class=\"row\">\n @if (shouldShow('clientSecret')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"clientSecret\"\n translate\n >\n Client secret\n </label>\n <input\n class=\"form-control\"\n id=\"clientSecret\"\n name=\"clientSecret\"\n required\n [(ngModel)]=\"templateModel.clientSecret\"\n />\n </c8y-form-group>\n </div>\n }\n\n @if (shouldShow('clientId')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"clientId\"\n translate\n >\n Client ID\n </label>\n <input\n class=\"form-control\"\n id=\"clientId\"\n name=\"clientId\"\n required\n [(ngModel)]=\"templateModel.clientId\"\n [placeholder]=\"\n 'e.g. {{ example }}' | translate: { example: '254234981c-78a8-4588\u2026' }\n \"\n />\n </c8y-form-group>\n </div>\n }\n\n @if (shouldShow('issuer')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"issuer\"\n translate\n >\n Token issuer\n </label>\n <input\n class=\"form-control\"\n id=\"issuer\"\n name=\"issuer\"\n required\n [(ngModel)]=\"templateModel.issuer\"\n [placeholder]=\"\n 'e.g. {{ example }}'\n | translate: { example: 'https://login.microsoftonline.de/237652-3727' }\n \"\n />\n </c8y-form-group>\n </div>\n }\n @if (shouldShow('scopeId')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"scopeId\"\n translate\n >\n Scope ID\n </label>\n <input\n class=\"form-control\"\n id=\"scopeId\"\n name=\"scopeId\"\n [(ngModel)]=\"templateModel.scopeId\"\n [placeholder]=\"'e.g. {{ example }}' | translate: { example: '237652-3727' }\"\n />\n </c8y-form-group>\n </div>\n }\n\n @if (shouldShow('buttonName')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"buttonName\"\n translate\n >\n Button name\n </label>\n <input\n class=\"form-control\"\n id=\"buttonName\"\n name=\"buttonName\"\n required\n [(ngModel)]=\"templateModel.buttonName\"\n [placeholder]=\"'e.g. Log in with Azure AD' | translate\"\n />\n </c8y-form-group>\n </div>\n }\n\n @if (shouldShow('providerName')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"providerName\"\n translate\n >\n Provider name\n </label>\n <input\n class=\"form-control\"\n id=\"providerName\"\n name=\"providerName\"\n required\n [(ngModel)]=\"templateModel.providerName\"\n [placeholder]=\"'e.g. {{ example }}' | translate: { example: 'Azure AD' }\"\n />\n </c8y-form-group>\n </div>\n }\n\n @if (shouldShow('audience')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"audience\"\n translate\n >\n Audience\n </label>\n <input\n class=\"form-control\"\n id=\"audience\"\n name=\"audience\"\n required\n [(ngModel)]=\"templateModel.audience\"\n [placeholder]=\"\n 'e.g. {{ example }}' | translate: { example: 'https://test.example.com' }\n \"\n />\n </c8y-form-group>\n </div>\n }\n </div>\n\n @if (shouldShow('mtlsCertificatePem')) {\n <div class=\"row\">\n <div class=\"col-sm-12\">\n <label\n class=\"c8y-switch m-b-16\"\n title=\"{{ 'Enable mTLS authentication' | translate }}\"\n for=\"mtlsEnabled\"\n >\n <input\n id=\"mtlsEnabled\"\n name=\"mtlsEnabled\"\n type=\"checkbox\"\n [(ngModel)]=\"mtlsEnabled\"\n (change)=\"onMtlsEnabledChange()\"\n />\n <span></span>\n <span class=\"control-label\">{{ 'Enable mTLS authentication' | translate }}</span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{ MTLS_ENABLED_TOOLTIP | translate }}\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n ></button>\n </label>\n </div>\n <div\n class=\"col-sm-12\"\n [class.hidden]=\"!mtlsEnabled\"\n >\n <div class=\"row\">\n <div class=\"col-sm-6\">\n <fieldset class=\"c8y-fieldset\">\n <legend>\n {{ 'Certificate (PEM)' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{ MTLS_CERTIFICATE_TOOLTIP | translate }}\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n ></button>\n </legend>\n <c8y-form-group>\n <textarea\n class=\"form-control m-b-8 text-monospace\"\n [class.hidden]=\"!templateModel.mtlsCertificatePem\"\n aria-label=\"{{ 'Currently saved certificate' | translate }}\"\n id=\"mtlsCertificatePem\"\n name=\"mtlsCertificatePem\"\n rows=\"4\"\n readonly\n [(ngModel)]=\"templateModel.mtlsCertificatePem\"\n [required]=\"mtlsEnabled\"\n ></textarea>\n @let mtlsAddCertificateLabel = 'Drop file here' | translate;\n @let mtlsReplaceCertificateLabel =\n 'Drop a new certificate to replace' | translate;\n <c8y-drop-area\n class=\"drop-area-sm\"\n [title]=\"'Drop the certificate in PEM format.' | translate\"\n name=\"mtlsCertificateFile\"\n [(ngModel)]=\"mtlsCertificateFile\"\n [message]=\"\n templateModel.mtlsCertificatePem\n ? mtlsReplaceCertificateLabel\n : mtlsAddCertificateLabel\n \"\n data-cy=\"c8y-sso-mtls--certificate-drop-area\"\n (dropped)=\"uploadMtlsCertificate($event)\"\n [maxAllowedFiles]=\"1\"\n [maxFileSizeInMegaBytes]=\"1\"\n [accept]=\"'.pem'\"\n ></c8y-drop-area>\n </c8y-form-group>\n </fieldset>\n </div>\n <div class=\"col-sm-6\">\n <fieldset class=\"c8y-fieldset\">\n <legend>\n {{ 'Private key (PEM)' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{ MTLS_PRIVATE_KEY_TOOLTIP | translate }}\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n ></button>\n </legend>\n <c8y-form-group>\n <textarea\n class=\"form-control m-b-8 text-monospace\"\n [class.hidden]=\"!templateModel.mtlsPrivateKeyPem\"\n aria-label=\"{{ 'Currently saved private key' | translate }}\"\n id=\"mtlsPrivateKeyPem\"\n name=\"mtlsPrivateKeyPem\"\n rows=\"{{ templateModel.mtlsPrivateKeyPem ? '3' : '4' }}\"\n readonly\n [(ngModel)]=\"templateModel.mtlsPrivateKeyPem\"\n [required]=\"mtlsEnabled\"\n ></textarea>\n @let mtlsAddPrivateKeyLabel = 'Drop file here' | translate;\n @let mtlsReplacePrivateKeyLabel =\n 'Drop a new private key to replace' | translate;\n <c8y-drop-area\n class=\"drop-area-sm\"\n [title]=\"'Drop the private key in PEM format.' | translate\"\n name=\"mtlsPrivateKeyFile\"\n [(ngModel)]=\"mtlsPrivateKeyFile\"\n [message]=\"\n templateModel.mtlsPrivateKeyPem\n ? mtlsReplacePrivateKeyLabel\n : mtlsAddPrivateKeyLabel\n \"\n data-cy=\"c8y-sso-mtls--private-key-drop-area\"\n (dropped)=\"uploadMtlsPrivateKey($event)\"\n [maxAllowedFiles]=\"1\"\n [maxFileSizeInMegaBytes]=\"1\"\n [accept]=\"'.pem,.key'\"\n ></c8y-drop-area>\n\n @if (templateModel.mtlsPrivateKeyPem) {\n <small class=\"text-muted d-flex a-i-center gap-4 m-t-4\">\n <i\n class=\"text-info\"\n c8yIcon=\"info-circle\"\n aria-hidden=\"true\"\n ></i>\n @if (isMtlsPrivateKeyEncrypted) {\n <span translate>\n The private key is encrypted for security reasons.\n </span>\n } @else {\n <span translate>\n The private key will be encrypted on the server after saving.\n </span>\n }\n </small>\n }\n </c8y-form-group>\n </fieldset>\n </div>\n </div>\n </div>\n </div>\n }\n\n @if (shouldShow('visibleOnLoginPage')) {\n <div class=\"row\">\n <div class=\"col-sm-6\">\n <label\n class=\"c8y-switch\"\n title=\"{{ 'Visible on login page' | translate }}\"\n for=\"visibleOnLoginPage\"\n >\n <input\n id=\"visibleOnLoginPage\"\n name=\"visibleOnLoginPage\"\n type=\"checkbox\"\n [(ngModel)]=\"templateModel.visibleOnLoginPage\"\n />\n <span></span>\n <span class=\"control-label\">{{ 'Visible on login page' | translate }}</span>\n </label>\n </div>\n </div>\n }\n </div>\n }\n </div>\n</fieldset>\n", dependencies: [{ kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "component", type: DropAreaComponent, selector: "c8y-drop-area", inputs: ["formControl", "title", "message", "icon", "loadingMessage", "forceHideList", "alwaysShow", "clickToOpen", "loading", "progress", "maxAllowedFiles", "files", "maxFileSizeInMegaBytes", "accept"], outputs: ["dropped"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }] }); }
1594
1596
  }
1595
1597
  __decorate([
@@ -1610,7 +1612,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
1610
1612
  DropAreaComponent,
1611
1613
  IconDirective
1612
1614
  ], template: "<fieldset class=\"p-24\">\n <div class=\"row\">\n <div class=\"col-xs-12 col-sm-3 col-md-2 m-b-xs-8\">\n <div\n class=\"h4 text-normal text-right text-left-xs\"\n translate\n >\n Basic\n </div>\n </div>\n\n @if (templateModel) {\n <div class=\"col-xs-12 col-sm-9 col-md-10 col-lg-9\">\n <div class=\"row\">\n @if (shouldShow('keyCloakAddress')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"keyCloakAddress\"\n translate\n >\n Keycloak address\n </label>\n <input\n class=\"form-control\"\n id=\"keyCloakAddress\"\n name=\"keyCloakAddress\"\n type=\"url\"\n required\n [(ngModel)]=\"templateModel.keyCloakAddress\"\n [placeholder]=\"\n 'e.g. {{ example }}' | translate: { example: 'https://example.de' }\n \"\n />\n </c8y-form-group>\n </div>\n }\n @if (shouldShow('aadAddress')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"aadAddress\"\n translate\n >\n Azure AD address\n </label>\n <input\n class=\"form-control\"\n id=\"aadAddress\"\n name=\"aadAddress\"\n type=\"url\"\n required\n [(ngModel)]=\"templateModel.aadAddress\"\n [placeholder]=\"\n 'e.g. {{ example }}'\n | translate: { example: 'https://login.microsoftonline.de' }\n \"\n />\n </c8y-form-group>\n </div>\n }\n @if (shouldShow('tenant')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"tenant\"\n translate\n >\n Tenant\n </label>\n <input\n class=\"form-control\"\n id=\"tenant\"\n name=\"tenant\"\n required\n [(ngModel)]=\"templateModel.tenant\"\n [placeholder]=\"\n 'e.g. {{ example }}' | translate: { example: 'c8y.onmicrosoft.de' }\n \"\n />\n </c8y-form-group>\n </div>\n }\n @if (shouldShow('applicationId')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"applicationId\"\n translate\n >\n Application ID\n </label>\n <input\n class=\"form-control\"\n id=\"applicationId\"\n name=\"applicationId\"\n required\n [(ngModel)]=\"templateModel.applicationId\"\n />\n </c8y-form-group>\n </div>\n }\n\n @if (shouldShow('realmName')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"realmName\"\n translate\n >\n Realm name\n </label>\n <input\n class=\"form-control\"\n id=\"realmName\"\n name=\"realmName\"\n required\n [(ngModel)]=\"templateModel.realmName\"\n />\n </c8y-form-group>\n </div>\n }\n </div>\n\n @if (shouldShow('redirectToPlatform')) {\n <div class=\"row\">\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"redirectToPlatform\"\n >\n {{ 'Redirect URL' | translate }}\n @if (\n !flowControlledByUI &&\n redirectToPlatformWarningParams &&\n templateModel.redirectToPlatform !==\n redirectToPlatformWarningParams.defaultRedirectUrl\n ) {\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"helpContent\"\n placement=\"bottom\"\n triggers=\"focus\"\n type=\"button\"\n [adaptivePosition]=\"false\"\n ></button>\n }\n <ng-template #helpContent>\n <span\n ngNonBindable\n translate\n [translateParams]=\"redirectToPlatformWarningParams\"\n >\n For correct application behavior you can use only \"{{ host }}\" or \"{{\n defaultRedirectUrl\n }}\", the latter one is recommended.\n </span>\n </ng-template>\n </label>\n <input\n class=\"form-control\"\n id=\"redirectToPlatform\"\n name=\"redirectToPlatform\"\n type=\"url\"\n [required]=\"!flowControlledByUI\"\n [disabled]=\"flowControlledByUI\"\n [(ngModel)]=\"templateModel.redirectToPlatform\"\n [placeholder]=\"\n 'e.g. {{ example }}'\n | translate\n : {\n example:\n redirectToPlatformWarningParams?.defaultRedirectUrl ||\n 'https://tenant.domain.com'\n }\n \"\n />\n </c8y-form-group>\n </div>\n <div class=\"col-sm-6\">\n <div class=\"form-group\">\n <label\n class=\"c8y-switch m-t-24\"\n title=\"{{\n 'Redirect to the user interface application`SSO authentication`' | translate\n }}\"\n for=\"flowControlledByUI\"\n >\n <input\n id=\"flowControlledByUI\"\n name=\"flowControlledByUI\"\n type=\"checkbox\"\n [(ngModel)]=\"flowControlledByUI\"\n (change)=\"\n templateModel.redirectToPlatform = flowControlledByUI\n ? ''\n : redirectToPlatform\n \"\n />\n <span></span>\n <span class=\"control-label\">{{\n 'Redirect to the user interface application`SSO authentication`' | translate\n }}</span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{ REDIRECT_TO_THE_USER_INTERFACE_APPLICATION_TOOLTIP | translate }}\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n ></button>\n </label>\n </div>\n </div>\n <div class=\"col-sm-12\">\n @if (flowControlledByUI && redirectToPlatform !== '') {\n <div>\n <div\n class=\"alert alert-warning max-width-100 m-b-32\"\n ngNonBindable\n translate\n [translateParams]=\"{\n redirectURI: '<tenant_domain>/apps/*'\n }\"\n >\n Make sure that \"Valid Redirect URIs\" in the authorization server is set to \"{{\n redirectURI\n }}\" or to the full URIs of the used applications if the authorization server\n does not support patterns.\n </div>\n </div>\n }\n @if (!flowControlledByUI && redirectToPlatform === '') {\n <div>\n <div\n class=\"alert alert-warning max-width-100 m-b-32\"\n ngNonBindable\n translate\n [translateParams]=\"{\n redirectURI: '<tenant_domain>/tenant/oauth'\n }\"\n >\n Make sure that \"Valid Redirect URIs\" in the authorization server is set to \"{{\n redirectURI\n }}\".\n </div>\n </div>\n }\n </div>\n </div>\n }\n <div class=\"row\">\n @if (shouldShow('clientSecret')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"clientSecret\"\n translate\n >\n Client secret\n </label>\n <input\n class=\"form-control\"\n id=\"clientSecret\"\n name=\"clientSecret\"\n required\n [(ngModel)]=\"templateModel.clientSecret\"\n />\n </c8y-form-group>\n </div>\n }\n\n @if (shouldShow('clientId')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"clientId\"\n translate\n >\n Client ID\n </label>\n <input\n class=\"form-control\"\n id=\"clientId\"\n name=\"clientId\"\n required\n [(ngModel)]=\"templateModel.clientId\"\n [placeholder]=\"\n 'e.g. {{ example }}' | translate: { example: '254234981c-78a8-4588\u2026' }\n \"\n />\n </c8y-form-group>\n </div>\n }\n\n @if (shouldShow('issuer')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"issuer\"\n translate\n >\n Token issuer\n </label>\n <input\n class=\"form-control\"\n id=\"issuer\"\n name=\"issuer\"\n required\n [(ngModel)]=\"templateModel.issuer\"\n [placeholder]=\"\n 'e.g. {{ example }}'\n | translate: { example: 'https://login.microsoftonline.de/237652-3727' }\n \"\n />\n </c8y-form-group>\n </div>\n }\n @if (shouldShow('scopeId')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"scopeId\"\n translate\n >\n Scope ID\n </label>\n <input\n class=\"form-control\"\n id=\"scopeId\"\n name=\"scopeId\"\n [(ngModel)]=\"templateModel.scopeId\"\n [placeholder]=\"'e.g. {{ example }}' | translate: { example: '237652-3727' }\"\n />\n </c8y-form-group>\n </div>\n }\n\n @if (shouldShow('buttonName')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"buttonName\"\n translate\n >\n Button name\n </label>\n <input\n class=\"form-control\"\n id=\"buttonName\"\n name=\"buttonName\"\n required\n [(ngModel)]=\"templateModel.buttonName\"\n [placeholder]=\"'e.g. Log in with Azure AD' | translate\"\n />\n </c8y-form-group>\n </div>\n }\n\n @if (shouldShow('providerName')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"providerName\"\n translate\n >\n Provider name\n </label>\n <input\n class=\"form-control\"\n id=\"providerName\"\n name=\"providerName\"\n required\n [(ngModel)]=\"templateModel.providerName\"\n [placeholder]=\"'e.g. {{ example }}' | translate: { example: 'Azure AD' }\"\n />\n </c8y-form-group>\n </div>\n }\n\n @if (shouldShow('audience')) {\n <div class=\"col-sm-6\">\n <c8y-form-group>\n <label\n class=\"control-label\"\n for=\"audience\"\n translate\n >\n Audience\n </label>\n <input\n class=\"form-control\"\n id=\"audience\"\n name=\"audience\"\n required\n [(ngModel)]=\"templateModel.audience\"\n [placeholder]=\"\n 'e.g. {{ example }}' | translate: { example: 'https://test.example.com' }\n \"\n />\n </c8y-form-group>\n </div>\n }\n </div>\n\n @if (shouldShow('mtlsCertificatePem')) {\n <div class=\"row\">\n <div class=\"col-sm-12\">\n <label\n class=\"c8y-switch m-b-16\"\n title=\"{{ 'Enable mTLS authentication' | translate }}\"\n for=\"mtlsEnabled\"\n >\n <input\n id=\"mtlsEnabled\"\n name=\"mtlsEnabled\"\n type=\"checkbox\"\n [(ngModel)]=\"mtlsEnabled\"\n (change)=\"onMtlsEnabledChange()\"\n />\n <span></span>\n <span class=\"control-label\">{{ 'Enable mTLS authentication' | translate }}</span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{ MTLS_ENABLED_TOOLTIP | translate }}\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n ></button>\n </label>\n </div>\n <div\n class=\"col-sm-12\"\n [class.hidden]=\"!mtlsEnabled\"\n >\n <div class=\"row\">\n <div class=\"col-sm-6\">\n <fieldset class=\"c8y-fieldset\">\n <legend>\n {{ 'Certificate (PEM)' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{ MTLS_CERTIFICATE_TOOLTIP | translate }}\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n ></button>\n </legend>\n <c8y-form-group>\n <textarea\n class=\"form-control m-b-8 text-monospace\"\n [class.hidden]=\"!templateModel.mtlsCertificatePem\"\n aria-label=\"{{ 'Currently saved certificate' | translate }}\"\n id=\"mtlsCertificatePem\"\n name=\"mtlsCertificatePem\"\n rows=\"4\"\n readonly\n [(ngModel)]=\"templateModel.mtlsCertificatePem\"\n [required]=\"mtlsEnabled\"\n ></textarea>\n @let mtlsAddCertificateLabel = 'Drop file here' | translate;\n @let mtlsReplaceCertificateLabel =\n 'Drop a new certificate to replace' | translate;\n <c8y-drop-area\n class=\"drop-area-sm\"\n [title]=\"'Drop the certificate in PEM format.' | translate\"\n name=\"mtlsCertificateFile\"\n [(ngModel)]=\"mtlsCertificateFile\"\n [message]=\"\n templateModel.mtlsCertificatePem\n ? mtlsReplaceCertificateLabel\n : mtlsAddCertificateLabel\n \"\n data-cy=\"c8y-sso-mtls--certificate-drop-area\"\n (dropped)=\"uploadMtlsCertificate($event)\"\n [maxAllowedFiles]=\"1\"\n [maxFileSizeInMegaBytes]=\"1\"\n [accept]=\"'.pem'\"\n ></c8y-drop-area>\n </c8y-form-group>\n </fieldset>\n </div>\n <div class=\"col-sm-6\">\n <fieldset class=\"c8y-fieldset\">\n <legend>\n {{ 'Private key (PEM)' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{ MTLS_PRIVATE_KEY_TOOLTIP | translate }}\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n ></button>\n </legend>\n <c8y-form-group>\n <textarea\n class=\"form-control m-b-8 text-monospace\"\n [class.hidden]=\"!templateModel.mtlsPrivateKeyPem\"\n aria-label=\"{{ 'Currently saved private key' | translate }}\"\n id=\"mtlsPrivateKeyPem\"\n name=\"mtlsPrivateKeyPem\"\n rows=\"{{ templateModel.mtlsPrivateKeyPem ? '3' : '4' }}\"\n readonly\n [(ngModel)]=\"templateModel.mtlsPrivateKeyPem\"\n [required]=\"mtlsEnabled\"\n ></textarea>\n @let mtlsAddPrivateKeyLabel = 'Drop file here' | translate;\n @let mtlsReplacePrivateKeyLabel =\n 'Drop a new private key to replace' | translate;\n <c8y-drop-area\n class=\"drop-area-sm\"\n [title]=\"'Drop the private key in PEM format.' | translate\"\n name=\"mtlsPrivateKeyFile\"\n [(ngModel)]=\"mtlsPrivateKeyFile\"\n [message]=\"\n templateModel.mtlsPrivateKeyPem\n ? mtlsReplacePrivateKeyLabel\n : mtlsAddPrivateKeyLabel\n \"\n data-cy=\"c8y-sso-mtls--private-key-drop-area\"\n (dropped)=\"uploadMtlsPrivateKey($event)\"\n [maxAllowedFiles]=\"1\"\n [maxFileSizeInMegaBytes]=\"1\"\n [accept]=\"'.pem,.key'\"\n ></c8y-drop-area>\n\n @if (templateModel.mtlsPrivateKeyPem) {\n <small class=\"text-muted d-flex a-i-center gap-4 m-t-4\">\n <i\n class=\"text-info\"\n c8yIcon=\"info-circle\"\n aria-hidden=\"true\"\n ></i>\n @if (isMtlsPrivateKeyEncrypted) {\n <span translate>\n The private key is encrypted for security reasons.\n </span>\n } @else {\n <span translate>\n The private key will be encrypted on the server after saving.\n </span>\n }\n </small>\n }\n </c8y-form-group>\n </fieldset>\n </div>\n </div>\n </div>\n </div>\n }\n\n @if (shouldShow('visibleOnLoginPage')) {\n <div class=\"row\">\n <div class=\"col-sm-6\">\n <label\n class=\"c8y-switch\"\n title=\"{{ 'Visible on login page' | translate }}\"\n for=\"visibleOnLoginPage\"\n >\n <input\n id=\"visibleOnLoginPage\"\n name=\"visibleOnLoginPage\"\n type=\"checkbox\"\n [(ngModel)]=\"templateModel.visibleOnLoginPage\"\n />\n <span></span>\n <span class=\"control-label\">{{ 'Visible on login page' | translate }}</span>\n </label>\n </div>\n </div>\n }\n </div>\n }\n </div>\n</fieldset>\n" }]
1613
- }], ctorParameters: () => [{ type: i1$1.TenantService }], propDecorators: { templateModel: [{
1615
+ }], propDecorators: { templateModel: [{
1614
1616
  type: Input
1615
1617
  }], shouldShow: [] } });
1616
1618