diff --git a/console/src/app/modules/policies/notification-policy/notification-policy.component.html b/console/src/app/modules/policies/notification-policy/notification-policy.component.html index 786fe4ec14..f2ba5f04c5 100644 --- a/console/src/app/modules/policies/notification-policy/notification-policy.component.html +++ b/console/src/app/modules/policies/notification-policy/notification-policy.component.html @@ -26,6 +26,7 @@ color="primary" name="hasUppercase" ngDefaultControl + data-e2e="notification-policy-checkbox" [(ngModel)]="notificationData.passwordChange" [disabled]="(['policy.write'] | hasRole | async) === false" > @@ -43,6 +44,7 @@ color="primary" type="submit" mat-raised-button + data-e2e="save-notification-policy-button" > {{ 'ACTIONS.SAVE' | translate }} diff --git a/console/src/app/modules/policies/notification-settings/notification-settings.component.spec.ts b/console/src/app/modules/policies/notification-settings/notification-settings.component.spec.ts deleted file mode 100644 index cd48a053f7..0000000000 --- a/console/src/app/modules/policies/notification-settings/notification-settings.component.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { NotificationSettingsComponent } from './notification-settings.component'; - -describe('NotificationSettingsComponent', () => { - let component: NotificationSettingsComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [NotificationSettingsComponent], - }).compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(NotificationSettingsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/console/src/app/modules/policies/notification-settings/dialog-add-sms-provider/dialog-add-sms-provider.component.html b/console/src/app/modules/policies/notification-sms-provider/dialog-add-sms-provider/dialog-add-sms-provider.component.html similarity index 97% rename from console/src/app/modules/policies/notification-settings/dialog-add-sms-provider/dialog-add-sms-provider.component.html rename to console/src/app/modules/policies/notification-sms-provider/dialog-add-sms-provider/dialog-add-sms-provider.component.html index f9631924d4..b8d239ef18 100644 --- a/console/src/app/modules/policies/notification-settings/dialog-add-sms-provider/dialog-add-sms-provider.component.html +++ b/console/src/app/modules/policies/notification-sms-provider/dialog-add-sms-provider/dialog-add-sms-provider.component.html @@ -33,6 +33,7 @@ class="ok-button" color="primary" (click)="closeDialogWithRequest()" + data-e2e="save-sms-settings-button" > {{ 'ACTIONS.SAVE' | translate }} diff --git a/console/src/app/modules/policies/notification-settings/dialog-add-sms-provider/dialog-add-sms-provider.component.scss b/console/src/app/modules/policies/notification-sms-provider/dialog-add-sms-provider/dialog-add-sms-provider.component.scss similarity index 100% rename from console/src/app/modules/policies/notification-settings/dialog-add-sms-provider/dialog-add-sms-provider.component.scss rename to console/src/app/modules/policies/notification-sms-provider/dialog-add-sms-provider/dialog-add-sms-provider.component.scss diff --git a/console/src/app/modules/policies/notification-settings/dialog-add-sms-provider/dialog-add-sms-provider.component.ts b/console/src/app/modules/policies/notification-sms-provider/dialog-add-sms-provider/dialog-add-sms-provider.component.ts similarity index 99% rename from console/src/app/modules/policies/notification-settings/dialog-add-sms-provider/dialog-add-sms-provider.component.ts rename to console/src/app/modules/policies/notification-sms-provider/dialog-add-sms-provider/dialog-add-sms-provider.component.ts index 18ed54e5ec..2594dd0728 100644 --- a/console/src/app/modules/policies/notification-settings/dialog-add-sms-provider/dialog-add-sms-provider.component.ts +++ b/console/src/app/modules/policies/notification-sms-provider/dialog-add-sms-provider/dialog-add-sms-provider.component.ts @@ -14,7 +14,6 @@ import { import { SMSProvider, TwilioConfig } from 'src/app/proto/generated/zitadel/settings_pb'; import { AdminService } from 'src/app/services/admin.service'; import { ToastService } from 'src/app/services/toast.service'; - import { PasswordDialogComponent } from '../password-dialog/password-dialog.component'; enum SMSProviderType { diff --git a/console/src/app/modules/policies/notification-sms-provider/notification-sms-provider.component.html b/console/src/app/modules/policies/notification-sms-provider/notification-sms-provider.component.html new file mode 100644 index 0000000000..adde321c63 --- /dev/null +++ b/console/src/app/modules/policies/notification-sms-provider/notification-sms-provider.component.html @@ -0,0 +1,56 @@ +

{{ 'SETTING.SMS.TITLE' | translate }}

+ +
+ +
+ +
+ +
+

Twilio

+ + {{ 'SETTING.SMS.SMSPROVIDERSTATE.' + twilio.state | translate }} + + + + + +
+
+
diff --git a/console/src/app/modules/policies/notification-settings/notification-settings.component.scss b/console/src/app/modules/policies/notification-sms-provider/notification-sms-provider.component.scss similarity index 57% rename from console/src/app/modules/policies/notification-settings/notification-settings.component.scss rename to console/src/app/modules/policies/notification-sms-provider/notification-sms-provider.component.scss index f382b0b415..38ea6f44f4 100644 --- a/console/src/app/modules/policies/notification-settings/notification-settings.component.scss +++ b/console/src/app/modules/policies/notification-sms-provider/notification-sms-provider.component.scss @@ -2,35 +2,6 @@ margin: 0.5rem 0; } -.smtp-form-field, -.info-section-warn { - max-width: 400px; - display: block; -} - -.info-section-warn { - margin-bottom: 0.5rem; -} - -.smtp-checkbox { - max-width: 400px; - display: block; - margin: 1rem 0; -} - -.set-password-btn { - margin-bottom: 1rem; -} - -.general-btn-container { - display: flex; - justify-content: flex-start; - - .save-button { - display: block; - } -} - .sms-providers { display: flex; align-items: center; diff --git a/console/src/app/modules/policies/notification-sms-provider/notification-sms-provider.component.spec.ts b/console/src/app/modules/policies/notification-sms-provider/notification-sms-provider.component.spec.ts new file mode 100644 index 0000000000..6d7a487c69 --- /dev/null +++ b/console/src/app/modules/policies/notification-sms-provider/notification-sms-provider.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NotificationSMSProviderComponent } from './notification-sms-provider.component'; + +describe('NotificationSMSProviderComponent', () => { + let component: NotificationSMSProviderComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [NotificationSMSProviderComponent], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(NotificationSMSProviderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/console/src/app/modules/policies/notification-sms-provider/notification-sms-provider.component.ts b/console/src/app/modules/policies/notification-sms-provider/notification-sms-provider.component.ts new file mode 100644 index 0000000000..eb14ce8a0c --- /dev/null +++ b/console/src/app/modules/policies/notification-sms-provider/notification-sms-provider.component.ts @@ -0,0 +1,140 @@ +import { Component, Input } from '@angular/core'; +import { AddSMSProviderTwilioRequest, UpdateSMSProviderTwilioRequest } from 'src/app/proto/generated/zitadel/admin_pb'; +import { SMSProvider, SMSProviderConfigState } from 'src/app/proto/generated/zitadel/settings_pb'; + +import { MatLegacyDialog as MatDialog } from '@angular/material/legacy-dialog'; +import { AdminService } from 'src/app/services/admin.service'; +import { ToastService } from 'src/app/services/toast.service'; +import { InfoSectionType } from '../../info-section/info-section.component'; +import { WarnDialogComponent } from '../../warn-dialog/warn-dialog.component'; +import { PolicyComponentServiceType } from '../policy-component-types.enum'; +import { DialogAddSMSProviderComponent } from './dialog-add-sms-provider/dialog-add-sms-provider.component'; + +@Component({ + selector: 'cnsl-notification-sms-provider', + templateUrl: './notification-sms-provider.component.html', + styleUrls: ['./notification-sms-provider.component.scss'], +}) +export class NotificationSMSProviderComponent { + @Input() public serviceType!: PolicyComponentServiceType; + public smsProviders: SMSProvider.AsObject[] = []; + + public smsProvidersLoading: boolean = false; + + public SMSProviderConfigState: any = SMSProviderConfigState; + public InfoSectionType: any = InfoSectionType; + + constructor( + private service: AdminService, + private dialog: MatDialog, + private toast: ToastService, + ) {} + + private fetchData(): void { + this.smsProvidersLoading = true; + this.service + .listSMSProviders() + .then((smsProviders) => { + this.smsProvidersLoading = false; + if (smsProviders.resultList) { + this.smsProviders = smsProviders.resultList; + } + }) + .catch((error) => { + this.smsProvidersLoading = false; + this.toast.showError(error); + }); + } + + public editSMSProvider(): void { + const dialogRef = this.dialog.open(DialogAddSMSProviderComponent, { + width: '400px', + data: { + smsProviders: this.smsProviders, + }, + }); + + dialogRef.afterClosed().subscribe((req: AddSMSProviderTwilioRequest | UpdateSMSProviderTwilioRequest) => { + if (req) { + if (!!this.twilio) { + this.service + .updateSMSProviderTwilio(req as UpdateSMSProviderTwilioRequest) + .then(() => { + this.toast.showInfo('SETTING.SMS.TWILIO.ADDED', true); + this.fetchData(); + }) + .catch((error) => { + this.toast.showError(error); + }); + } else { + this.service + .addSMSProviderTwilio(req as AddSMSProviderTwilioRequest) + .then(() => { + this.toast.showInfo('SETTING.SMS.TWILIO.ADDED', true); + this.fetchData(); + }) + .catch((error) => { + this.toast.showError(error); + }); + } + } + }); + } + + public toggleSMSProviderState(id: string): void { + const provider = this.smsProviders.find((p) => p.id === id); + if (provider) { + if (provider.state === SMSProviderConfigState.SMS_PROVIDER_CONFIG_ACTIVE) { + this.service + .deactivateSMSProvider(id) + .then(() => { + this.toast.showInfo('SETTING.SMS.DEACTIVATED', true); + this.fetchData(); + }) + .catch((error) => { + this.toast.showError(error); + }); + } else if (provider.state === SMSProviderConfigState.SMS_PROVIDER_CONFIG_INACTIVE) { + this.service + .activateSMSProvider(id) + .then(() => { + this.toast.showInfo('SETTING.SMS.ACTIVATED', true); + this.fetchData(); + }) + .catch((error) => { + this.toast.showError(error); + }); + } + } + } + + public removeSMSProvider(id: string): void { + const dialogRef = this.dialog.open(WarnDialogComponent, { + data: { + confirmKey: 'ACTIONS.DELETE', + cancelKey: 'ACTIONS.CANCEL', + titleKey: 'SETTING.SMS.REMOVEPROVIDER', + descriptionKey: 'SETTING.SMS.REMOVEPROVIDER_DESC', + }, + width: '400px', + }); + + dialogRef.afterClosed().subscribe((resp) => { + if (resp) { + this.service + .removeSMSProvider(id) + .then(() => { + this.toast.showInfo('SETTING.SMS.TWILIO.REMOVED', true); + this.fetchData(); + }) + .catch((error) => { + this.toast.showError(error); + }); + } + }); + } + + public get twilio(): SMSProvider.AsObject | undefined { + return this.smsProviders.find((p) => p.twilio); + } +} diff --git a/console/src/app/modules/policies/notification-settings/notification-settings.module.ts b/console/src/app/modules/policies/notification-sms-provider/notification-sms-provider.module.ts similarity index 81% rename from console/src/app/modules/policies/notification-settings/notification-settings.module.ts rename to console/src/app/modules/policies/notification-sms-provider/notification-sms-provider.module.ts index 8f5be4c19a..4d00252a4f 100644 --- a/console/src/app/modules/policies/notification-settings/notification-settings.module.ts +++ b/console/src/app/modules/policies/notification-sms-provider/notification-sms-provider.module.ts @@ -15,11 +15,10 @@ import { InfoSectionModule } from '../../info-section/info-section.module'; import { InputModule } from '../../input/input.module'; import { WarnDialogModule } from '../../warn-dialog/warn-dialog.module'; import { DialogAddSMSProviderComponent } from './dialog-add-sms-provider/dialog-add-sms-provider.component'; -import { NotificationSettingsComponent } from './notification-settings.component'; -import { PasswordDialogComponent } from './password-dialog/password-dialog.component'; +import { NotificationSMSProviderComponent } from './notification-sms-provider.component'; @NgModule({ - declarations: [NotificationSettingsComponent, DialogAddSMSProviderComponent, PasswordDialogComponent], + declarations: [NotificationSMSProviderComponent, DialogAddSMSProviderComponent], imports: [ CommonModule, CardModule, @@ -38,6 +37,6 @@ import { PasswordDialogComponent } from './password-dialog/password-dialog.compo MatSelectModule, TranslateModule, ], - exports: [NotificationSettingsComponent], + exports: [NotificationSMSProviderComponent], }) -export class NotificationSettingsModule {} +export class NotificationSMSProviderModule {} diff --git a/console/src/app/modules/policies/notification-settings/password-dialog/password-dialog.component.html b/console/src/app/modules/policies/notification-sms-provider/password-dialog/password-dialog.component.html similarity index 74% rename from console/src/app/modules/policies/notification-settings/password-dialog/password-dialog.component.html rename to console/src/app/modules/policies/notification-sms-provider/password-dialog/password-dialog.component.html index 43709eb197..a7e8a624f8 100644 --- a/console/src/app/modules/policies/notification-settings/password-dialog/password-dialog.component.html +++ b/console/src/app/modules/policies/notification-sms-provider/password-dialog/password-dialog.component.html @@ -4,7 +4,13 @@
{{ data.i18nLabel | translate }} - +
@@ -19,6 +25,7 @@ mat-raised-button class="ok-button" (click)="closeDialog(password)" + data-e2e="save-notification-setting-password-button" > {{ 'ACTIONS.OK' | translate }} diff --git a/console/src/app/modules/policies/notification-settings/password-dialog/password-dialog.component.scss b/console/src/app/modules/policies/notification-sms-provider/password-dialog/password-dialog.component.scss similarity index 100% rename from console/src/app/modules/policies/notification-settings/password-dialog/password-dialog.component.scss rename to console/src/app/modules/policies/notification-sms-provider/password-dialog/password-dialog.component.scss diff --git a/console/src/app/modules/policies/notification-settings/password-dialog/password-dialog.component.spec.ts b/console/src/app/modules/policies/notification-sms-provider/password-dialog/password-dialog.component.spec.ts similarity index 100% rename from console/src/app/modules/policies/notification-settings/password-dialog/password-dialog.component.spec.ts rename to console/src/app/modules/policies/notification-sms-provider/password-dialog/password-dialog.component.spec.ts diff --git a/console/src/app/modules/policies/notification-settings/password-dialog/password-dialog.component.ts b/console/src/app/modules/policies/notification-sms-provider/password-dialog/password-dialog.component.ts similarity index 100% rename from console/src/app/modules/policies/notification-settings/password-dialog/password-dialog.component.ts rename to console/src/app/modules/policies/notification-sms-provider/password-dialog/password-dialog.component.ts diff --git a/console/src/app/modules/policies/notification-settings/notification-settings.component.html b/console/src/app/modules/policies/notification-smtp-provider/notification-smtp-provider.component.html similarity index 58% rename from console/src/app/modules/policies/notification-settings/notification-settings.component.html rename to console/src/app/modules/policies/notification-smtp-provider/notification-smtp-provider.component.html index 5895eb58f5..fcde1404df 100644 --- a/console/src/app/modules/policies/notification-settings/notification-settings.component.html +++ b/console/src/app/modules/policies/notification-smtp-provider/notification-smtp-provider.component.html @@ -1,7 +1,7 @@

{{ 'SETTING.SMTP.TITLE' | translate }}

- +
{{ 'SETTING.SMTP.SETPASSWORD' | translate }} @@ -60,55 +61,9 @@ color="primary" type="submit" mat-raised-button + data-e2e="save-smtp-settings-button" > {{ 'ACTIONS.SAVE' | translate }}
- -
-

{{ 'SETTING.SMS.TITLE' | translate }}

-
- -
-

Twilio

- - {{ 'SETTING.SMS.SMSPROVIDERSTATE.' + twilio.state | translate }} - - - - - -
-
-
diff --git a/console/src/app/modules/policies/notification-smtp-provider/notification-smtp-provider.component.scss b/console/src/app/modules/policies/notification-smtp-provider/notification-smtp-provider.component.scss new file mode 100644 index 0000000000..aa056af7e5 --- /dev/null +++ b/console/src/app/modules/policies/notification-smtp-provider/notification-smtp-provider.component.scss @@ -0,0 +1,32 @@ +.spinner-wr { + margin: 0.5rem 0; +} + +.smtp-form-field, +.info-section-warn { + max-width: 400px; + display: block; +} + +.info-section-warn { + margin-bottom: 0.5rem; +} + +.smtp-checkbox { + max-width: 400px; + display: block; + margin: 1rem 0; +} + +.set-password-btn { + margin-bottom: 1rem; +} + +.general-btn-container { + display: flex; + justify-content: flex-start; + + .save-button { + display: block; + } +} diff --git a/console/src/app/modules/policies/notification-smtp-provider/notification-smtp-provider.component.spec.ts b/console/src/app/modules/policies/notification-smtp-provider/notification-smtp-provider.component.spec.ts new file mode 100644 index 0000000000..65d781de8b --- /dev/null +++ b/console/src/app/modules/policies/notification-smtp-provider/notification-smtp-provider.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NotificationSMTPProviderComponent } from './notification-smtp-provider.component'; + +describe('NotificationSMTPProviderComponent', () => { + let component: NotificationSMTPProviderComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [NotificationSMTPProviderComponent], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(NotificationSMTPProviderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/console/src/app/modules/policies/notification-settings/notification-settings.component.ts b/console/src/app/modules/policies/notification-smtp-provider/notification-smtp-provider.component.ts similarity index 50% rename from console/src/app/modules/policies/notification-settings/notification-settings.component.ts rename to console/src/app/modules/policies/notification-smtp-provider/notification-smtp-provider.component.ts index dfd8a9e568..6bdaf0ba10 100644 --- a/console/src/app/modules/policies/notification-settings/notification-settings.component.ts +++ b/console/src/app/modules/policies/notification-smtp-provider/notification-smtp-provider.component.ts @@ -3,45 +3,33 @@ import { AbstractControl, UntypedFormBuilder, UntypedFormGroup } from '@angular/ import { MatLegacyDialog as MatDialog } from '@angular/material/legacy-dialog'; import { take } from 'rxjs'; import { - AddSMSProviderTwilioRequest, AddSMTPConfigRequest, AddSMTPConfigResponse, - UpdateSMSProviderTwilioRequest, UpdateSMTPConfigPasswordRequest, UpdateSMTPConfigRequest, UpdateSMTPConfigResponse, } from 'src/app/proto/generated/zitadel/admin_pb'; -import { DebugNotificationProvider, SMSProvider, SMSProviderConfigState } from 'src/app/proto/generated/zitadel/settings_pb'; import { AdminService } from 'src/app/services/admin.service'; import { GrpcAuthService } from 'src/app/services/grpc-auth.service'; import { ToastService } from 'src/app/services/toast.service'; import { requiredValidator } from '../../form-field/validators/validators'; import { InfoSectionType } from '../../info-section/info-section.component'; -import { WarnDialogComponent } from '../../warn-dialog/warn-dialog.component'; +import { PasswordDialogComponent } from '../notification-sms-provider/password-dialog/password-dialog.component'; import { PolicyComponentServiceType } from '../policy-component-types.enum'; -import { DialogAddSMSProviderComponent } from './dialog-add-sms-provider/dialog-add-sms-provider.component'; -import { PasswordDialogComponent } from './password-dialog/password-dialog.component'; @Component({ - selector: 'cnsl-notification-settings', - templateUrl: './notification-settings.component.html', - styleUrls: ['./notification-settings.component.scss'], + selector: 'cnsl-notification-smtp-provider', + templateUrl: './notification-smtp-provider.component.html', + styleUrls: ['./notification-smtp-provider.component.scss'], }) -export class NotificationSettingsComponent implements OnInit { +export class NotificationSMTPProviderComponent implements OnInit { @Input() public serviceType!: PolicyComponentServiceType; - public smsProviders: SMSProvider.AsObject[] = []; - public logNotificationProvider!: DebugNotificationProvider.AsObject; - public fileNotificationProvider!: DebugNotificationProvider.AsObject; public smtpLoading: boolean = false; - public smsProvidersLoading: boolean = false; - public logProviderLoading: boolean = false; - public fileProviderLoading: boolean = false; public form!: UntypedFormGroup; - public SMSProviderConfigState: any = SMSProviderConfigState; public InfoSectionType: any = InfoSectionType; public hasSMTPConfig: boolean = false; @@ -96,46 +84,6 @@ export class NotificationSettingsComponent implements OnInit { this.hasSMTPConfig = false; } }); - - this.smsProvidersLoading = true; - this.service - .listSMSProviders() - .then((smsProviders) => { - this.smsProvidersLoading = false; - if (smsProviders.resultList) { - this.smsProviders = smsProviders.resultList; - } - }) - .catch((error) => { - this.smsProvidersLoading = false; - this.toast.showError(error); - }); - - this.logProviderLoading = true; - this.service - .getLogNotificationProvider() - .then((logNotificationProvider) => { - this.logProviderLoading = false; - if (logNotificationProvider.provider) { - this.logNotificationProvider = logNotificationProvider.provider; - } - }) - .catch(() => { - this.logProviderLoading = false; - }); - - this.fileProviderLoading = true; - this.service - .getFileSystemNotificationProvider() - .then((fileNotificationProvider) => { - this.fileProviderLoading = false; - if (fileNotificationProvider.provider) { - this.fileNotificationProvider = fileNotificationProvider.provider; - } - }) - .catch(() => { - this.fileProviderLoading = false; - }); } private updateData(): Promise { @@ -175,41 +123,6 @@ export class NotificationSettingsComponent implements OnInit { }); } - public editSMSProvider(): void { - const dialogRef = this.dialog.open(DialogAddSMSProviderComponent, { - width: '400px', - data: { - smsProviders: this.smsProviders, - }, - }); - - dialogRef.afterClosed().subscribe((req: AddSMSProviderTwilioRequest | UpdateSMSProviderTwilioRequest) => { - if (req) { - if (!!this.twilio) { - this.service - .updateSMSProviderTwilio(req as UpdateSMSProviderTwilioRequest) - .then(() => { - this.toast.showInfo('SETTING.SMS.TWILIO.ADDED', true); - this.fetchData(); - }) - .catch((error) => { - this.toast.showError(error); - }); - } else { - this.service - .addSMSProviderTwilio(req as AddSMSProviderTwilioRequest) - .then(() => { - this.toast.showInfo('SETTING.SMS.TWILIO.ADDED', true); - this.fetchData(); - }) - .catch((error) => { - this.toast.showError(error); - }); - } - } - }); - } - public setSMTPPassword(): void { const dialogRef = this.dialog.open(PasswordDialogComponent, { width: '400px', @@ -236,63 +149,6 @@ export class NotificationSettingsComponent implements OnInit { }); } - public toggleSMSProviderState(id: string): void { - const provider = this.smsProviders.find((p) => p.id === id); - if (provider) { - if (provider.state === SMSProviderConfigState.SMS_PROVIDER_CONFIG_ACTIVE) { - this.service - .deactivateSMSProvider(id) - .then(() => { - this.toast.showInfo('SETTING.SMS.DEACTIVATED', true); - this.fetchData(); - }) - .catch((error) => { - this.toast.showError(error); - }); - } else if (provider.state === SMSProviderConfigState.SMS_PROVIDER_CONFIG_INACTIVE) { - this.service - .activateSMSProvider(id) - .then(() => { - this.toast.showInfo('SETTING.SMS.ACTIVATED', true); - this.fetchData(); - }) - .catch((error) => { - this.toast.showError(error); - }); - } - } - } - - public removeSMSProvider(id: string): void { - const dialogRef = this.dialog.open(WarnDialogComponent, { - data: { - confirmKey: 'ACTIONS.DELETE', - cancelKey: 'ACTIONS.CANCEL', - titleKey: 'SETTING.SMS.REMOVEPROVIDER', - descriptionKey: 'SETTING.SMS.REMOVEPROVIDER_DESC', - }, - width: '400px', - }); - - dialogRef.afterClosed().subscribe((resp) => { - if (resp) { - this.service - .removeSMSProvider(id) - .then(() => { - this.toast.showInfo('SETTING.SMS.TWILIO.REMOVED', true); - this.fetchData(); - }) - .catch((error) => { - this.toast.showError(error); - }); - } - }); - } - - public get twilio(): SMSProvider.AsObject | undefined { - return this.smsProviders.find((p) => p.twilio); - } - public get senderAddress(): AbstractControl | null { return this.form.get('senderAddress'); } diff --git a/console/src/app/modules/policies/notification-smtp-provider/notification-smtp-provider.module.ts b/console/src/app/modules/policies/notification-smtp-provider/notification-smtp-provider.module.ts new file mode 100644 index 0000000000..61bb79023e --- /dev/null +++ b/console/src/app/modules/policies/notification-smtp-provider/notification-smtp-provider.module.ts @@ -0,0 +1,42 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatIconModule } from '@angular/material/icon'; +import { MatLegacyButtonModule as MatButtonModule } from '@angular/material/legacy-button'; +import { MatLegacyCheckboxModule as MatCheckboxModule } from '@angular/material/legacy-checkbox'; +import { MatLegacyProgressSpinnerModule as MatProgressSpinnerModule } from '@angular/material/legacy-progress-spinner'; +import { MatLegacySelectModule as MatSelectModule } from '@angular/material/legacy-select'; +import { TranslateModule } from '@ngx-translate/core'; +import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module'; + +import { CardModule } from '../../card/card.module'; +import { FormFieldModule } from '../../form-field/form-field.module'; +import { InfoSectionModule } from '../../info-section/info-section.module'; +import { InputModule } from '../../input/input.module'; +import { WarnDialogModule } from '../../warn-dialog/warn-dialog.module'; +import { PasswordDialogComponent } from '../notification-sms-provider/password-dialog/password-dialog.component'; +import { NotificationSMTPProviderComponent } from './notification-smtp-provider.component'; + +@NgModule({ + declarations: [NotificationSMTPProviderComponent, PasswordDialogComponent], + imports: [ + CommonModule, + CardModule, + InfoSectionModule, + FormsModule, + ReactiveFormsModule, + HasRolePipeModule, + MatButtonModule, + MatCheckboxModule, + InputModule, + MatIconModule, + FormFieldModule, + WarnDialogModule, + MatSelectModule, + MatProgressSpinnerModule, + MatSelectModule, + TranslateModule, + ], + exports: [NotificationSMTPProviderComponent], +}) +export class NotificationSMTPProviderModule {} diff --git a/console/src/app/modules/settings-grid/settinglinks.ts b/console/src/app/modules/settings-grid/settinglinks.ts index 34295104e0..726677ea73 100644 --- a/console/src/app/modules/settings-grid/settinglinks.ts +++ b/console/src/app/modules/settings-grid/settinglinks.ts @@ -51,7 +51,7 @@ export const NOTIFICATION_GROUP: SettingLinks = { i18nTitle: 'SETTINGS.GROUPS.NOTIFICATIONS', i18nDesc: 'SETTINGS.LIST.NOTIFICATIONS_DESC', iamRouterLink: ['/settings'], - queryParams: { id: 'notifications' }, + queryParams: { id: 'smtpprovider' }, iamWithRole: ['iam.policy.read'], icon: 'las la-bell', color: 'red', diff --git a/console/src/app/modules/settings-list/settings-list.component.html b/console/src/app/modules/settings-list/settings-list.component.html index 6f13cda807..44b3521fb7 100644 --- a/console/src/app/modules/settings-list/settings-list.component.html +++ b/console/src/app/modules/settings-list/settings-list.component.html @@ -27,19 +27,18 @@ - + - - - - - + + + + + + - diff --git a/console/src/app/modules/settings-list/settings-list.module.ts b/console/src/app/modules/settings-list/settings-list.module.ts index b42b94a10e..bfe64e07c6 100644 --- a/console/src/app/modules/settings-list/settings-list.module.ts +++ b/console/src/app/modules/settings-list/settings-list.module.ts @@ -13,7 +13,8 @@ import { LoginPolicyModule } from '../policies/login-policy/login-policy.module' import { LoginTextsPolicyModule } from '../policies/login-texts/login-texts.module'; import { MessageTextsPolicyModule } from '../policies/message-texts/message-texts.module'; import { NotificationPolicyModule } from '../policies/notification-policy/notification-policy.module'; -import { NotificationSettingsModule } from '../policies/notification-settings/notification-settings.module'; +import { NotificationSMSProviderModule } from '../policies/notification-sms-provider/notification-sms-provider.module'; +import { NotificationSMTPProviderModule } from '../policies/notification-smtp-provider/notification-smtp-provider.module'; import { OIDCConfigurationModule } from '../policies/oidc-configuration/oidc-configuration.module'; import { PasswordComplexityPolicyModule } from '../policies/password-complexity-policy/password-complexity-policy.module'; import { PasswordLockoutPolicyModule } from '../policies/password-lockout-policy/password-lockout-policy.module'; @@ -46,7 +47,8 @@ import { SettingsListComponent } from './settings-list.component'; DomainPolicyModule, TranslateModule, HasRolePipeModule, - NotificationSettingsModule, + NotificationSMTPProviderModule, + NotificationSMSProviderModule, OIDCConfigurationModule, SecretGeneratorModule, ], diff --git a/console/src/app/modules/settings-list/settings.ts b/console/src/app/modules/settings-list/settings.ts index dba29eac3f..69808e414b 100644 --- a/console/src/app/modules/settings-list/settings.ts +++ b/console/src/app/modules/settings-list/settings.ts @@ -98,15 +98,25 @@ export const NOTIFICATIONS: SidenavSetting = { groupI18nKey: 'SETTINGS.GROUPS.NOTIFICATIONS', requiredRoles: { [PolicyComponentServiceType.ADMIN]: ['iam.policy.read'], + [PolicyComponentServiceType.MGMT]: ['policy.read'], }, }; -export const NOTIFICATION_POLICY: SidenavSetting = { - id: 'notifications', - i18nKey: 'SETTINGS.LIST.NOTIFICATIONS', +export const SMTP_PROVIDER: SidenavSetting = { + id: 'smtpprovider', + i18nKey: 'SETTINGS.LIST.SMTP_PROVIDER', groupI18nKey: 'SETTINGS.GROUPS.NOTIFICATIONS', requiredRoles: { - [PolicyComponentServiceType.MGMT]: ['policy.read'], + [PolicyComponentServiceType.ADMIN]: ['iam.policy.read'], + }, +}; + +export const SMS_PROVIDER: SidenavSetting = { + id: 'smsprovider', + i18nKey: 'SETTINGS.LIST.SMS_PROVIDER', + groupI18nKey: 'SETTINGS.GROUPS.NOTIFICATIONS', + requiredRoles: { + [PolicyComponentServiceType.ADMIN]: ['iam.policy.read'], }, }; diff --git a/console/src/app/pages/instance-settings/instance-settings.component.ts b/console/src/app/pages/instance-settings/instance-settings.component.ts index 8b7db8b85f..2a379df62d 100644 --- a/console/src/app/pages/instance-settings/instance-settings.component.ts +++ b/console/src/app/pages/instance-settings/instance-settings.component.ts @@ -21,6 +21,8 @@ import { PRIVACYPOLICY, SECRETS, SECURITY, + SMS_PROVIDER, + SMTP_PROVIDER, } from '../../modules/settings-list/settings'; @Component({ @@ -36,6 +38,8 @@ export class InstanceSettingsComponent implements OnInit, OnDestroy { // notifications // { showWarn: true, ...NOTIFICATIONS }, NOTIFICATIONS, + SMTP_PROVIDER, + SMS_PROVIDER, // login LOGIN, IDP, @@ -80,7 +84,10 @@ export class InstanceSettingsComponent implements OnInit, OnDestroy { } ngOnInit(): void { - this.settingsList = this.authService.isAllowedMapper(this.defaultSettingsList, (setting) => setting.requiredRoles.admin); + this.settingsList = this.authService.isAllowedMapper( + this.defaultSettingsList, + (setting) => setting.requiredRoles.admin || [], + ); } ngOnDestroy(): void { diff --git a/console/src/app/pages/org-settings/org-settings.component.ts b/console/src/app/pages/org-settings/org-settings.component.ts index b0914fb7cc..79624e204a 100644 --- a/console/src/app/pages/org-settings/org-settings.component.ts +++ b/console/src/app/pages/org-settings/org-settings.component.ts @@ -15,7 +15,7 @@ import { LOGIN, LOGINTEXTS, MESSAGETEXTS, - NOTIFICATION_POLICY, + NOTIFICATIONS, PRIVACYPOLICY, VERIFIED_DOMAINS, } from '../../modules/settings-list/settings'; @@ -34,7 +34,7 @@ export class OrgSettingsComponent implements OnInit { IDP, COMPLEXITY, LOCKOUT, - NOTIFICATION_POLICY, + NOTIFICATIONS, VERIFIED_DOMAINS, DOMAIN, BRANDING, @@ -68,7 +68,7 @@ export class OrgSettingsComponent implements OnInit { ngOnInit(): void { this.settingsList = this.authService - .isAllowedMapper(this.defaultSettingsList, (setting) => setting.requiredRoles.mgmt) + .isAllowedMapper(this.defaultSettingsList, (setting) => setting.requiredRoles.mgmt || []) .pipe(take(1)); } } diff --git a/console/src/app/utils/onboarding.ts b/console/src/app/utils/onboarding.ts index 4f66c15198..97f2de8c52 100644 --- a/console/src/app/utils/onboarding.ts +++ b/console/src/app/utils/onboarding.ts @@ -71,7 +71,7 @@ export const ONBOARDING_EVENTS: OnboardingActions[] = [ eventType: 'instance.smtp.config.added', oneof: ['instance.smtp.config.added', 'instance.smtp.config.changed'], link: ['/settings'], - fragment: 'notifications', + fragment: 'smtpprovider', iconClasses: 'las la-envelope', darkcolor: yellowdark, lightcolor: yellowlight, diff --git a/console/src/assets/i18n/bg.json b/console/src/assets/i18n/bg.json index 33f53c9c56..4137e7538e 100644 --- a/console/src/assets/i18n/bg.json +++ b/console/src/assets/i18n/bg.json @@ -1013,6 +1013,8 @@ "LOCKOUT": "Блокиране", "COMPLEXITY": "Сложност на паролата", "NOTIFICATIONS": "Настройки за известията", + "SMTP_PROVIDER": "SMTP доставчик", + "SMS_PROVIDER": "Доставчик на SMS/телефон", "NOTIFICATIONS_DESC": "Настройки за SMTP и SMS", "MESSAGETEXTS": "Текстове на съобщения", "IDP": "Доставчици на идентичност", diff --git a/console/src/assets/i18n/de.json b/console/src/assets/i18n/de.json index 9e2b39c8de..37cbb671a5 100644 --- a/console/src/assets/i18n/de.json +++ b/console/src/assets/i18n/de.json @@ -1019,6 +1019,8 @@ "LOCKOUT": "Sperrmechanismen", "COMPLEXITY": "Passwordkomplexität", "NOTIFICATIONS": "Benachrichtigungseinstellungen", + "SMTP_PROVIDER": "SMTP-Anbieter", + "SMS_PROVIDER": "SMS / Telefon Anbieter", "NOTIFICATIONS_DESC": "SMTP und SMS Einstellungen", "MESSAGETEXTS": "Benachrichtigungstexte", "IDP": "Identitätsanbieter", diff --git a/console/src/assets/i18n/en.json b/console/src/assets/i18n/en.json index ac804fee34..135b62c82c 100644 --- a/console/src/assets/i18n/en.json +++ b/console/src/assets/i18n/en.json @@ -1019,7 +1019,9 @@ "LOGIN": "Login Behavior and Security", "LOCKOUT": "Lockout", "COMPLEXITY": "Password complexity", - "NOTIFICATIONS": "Notification settings", + "NOTIFICATIONS": "Notifications", + "SMTP_PROVIDER": "SMTP Provider", + "SMS_PROVIDER": "SMS/Phone Provider", "NOTIFICATIONS_DESC": "SMTP and SMS Settings", "MESSAGETEXTS": "Message Texts", "IDP": "Identity Providers", diff --git a/console/src/assets/i18n/es.json b/console/src/assets/i18n/es.json index bbb14c0faf..e2f8f054c5 100644 --- a/console/src/assets/i18n/es.json +++ b/console/src/assets/i18n/es.json @@ -1020,6 +1020,8 @@ "LOCKOUT": "Bloqueo", "COMPLEXITY": "Complejidad de contraseña", "NOTIFICATIONS": "Ajustes de notificación", + "SMTP_PROVIDER": "Proveedor SMTP", + "SMS_PROVIDER": "Proveedor SMS/Teléfono", "NOTIFICATIONS_DESC": "Ajustes SMTP y SMS", "MESSAGETEXTS": "Mensajes de texto", "IDP": "Proveedores de identidad", diff --git a/console/src/assets/i18n/fr.json b/console/src/assets/i18n/fr.json index 39aae0e9d4..ec44f4855a 100644 --- a/console/src/assets/i18n/fr.json +++ b/console/src/assets/i18n/fr.json @@ -1019,6 +1019,8 @@ "LOCKOUT": "Verrouillage", "COMPLEXITY": "Complexité du mot de passe", "NOTIFICATIONS": "Paramètres de notification", + "SMTP_PROVIDER": "Fournisseur SMTP", + "SMS_PROVIDER": "SMS/Téléphone Fournisseur", "NOTIFICATIONS_DESC": "Paramètres SMTP et SMS", "MESSAGETEXTS": "Textes des messages", "IDP": "Fournisseurs d'identité", diff --git a/console/src/assets/i18n/it.json b/console/src/assets/i18n/it.json index b06fc82e68..fa0f76745e 100644 --- a/console/src/assets/i18n/it.json +++ b/console/src/assets/i18n/it.json @@ -1019,6 +1019,8 @@ "LOCKOUT": "Meccanismi di bloccaggio", "COMPLEXITY": "Complessità della password", "NOTIFICATIONS": "Impostazioni di notifica", + "SMTP_PROVIDER": "Fornitore SMTP", + "SMS_PROVIDER": "Fornitore di servizi SMS/telefonici", "NOTIFICATIONS_DESC": "Impostazioni SMTP e SMS", "MESSAGETEXTS": "Testi di notifica", "IDP": "Fornitori di identità", diff --git a/console/src/assets/i18n/ja.json b/console/src/assets/i18n/ja.json index 7f90040d4f..d33e84ce30 100644 --- a/console/src/assets/i18n/ja.json +++ b/console/src/assets/i18n/ja.json @@ -1020,6 +1020,8 @@ "LOCKOUT": "ロックアウト", "COMPLEXITY": "パスワードの複雑さ", "NOTIFICATIONS": "通知設定", + "SMTP_PROVIDER": "SMTPプロバイダー", + "SMS_PROVIDER": "SMS/電話プロバイダー", "NOTIFICATIONS_DESC": "SMTPおよびSMS設定", "MESSAGETEXTS": "メッセージテキスト", "IDP": "IDプロバイダー", diff --git a/console/src/assets/i18n/mk.json b/console/src/assets/i18n/mk.json index e21458534b..51ea7b4e20 100644 --- a/console/src/assets/i18n/mk.json +++ b/console/src/assets/i18n/mk.json @@ -1021,6 +1021,8 @@ "LOCKOUT": "Забрана на пристап", "COMPLEXITY": "Сложеност на лозинката", "NOTIFICATIONS": "Подесувања за известувања", + "SMTP_PROVIDER": "SMTP провајдер", + "SMS_PROVIDER": "СМС/Провајдер на телефон", "NOTIFICATIONS_DESC": "Подесувања за SMTP и SMS", "MESSAGETEXTS": "Текстови на пораки", "IDP": "Identity Providers", diff --git a/console/src/assets/i18n/pl.json b/console/src/assets/i18n/pl.json index 244de0b78a..5aca4919f3 100644 --- a/console/src/assets/i18n/pl.json +++ b/console/src/assets/i18n/pl.json @@ -1019,6 +1019,8 @@ "LOCKOUT": "Blokada", "COMPLEXITY": "Złożoność hasła", "NOTIFICATIONS": "Ustawienia powiadomień", + "SMTP_PROVIDER": "Dostawca SMTP", + "SMS_PROVIDER": "Dostawca SMS-ów/telefonów", "NOTIFICATIONS_DESC": "Ustawienia SMTP i SMS", "MESSAGETEXTS": "Teksty wiadomości", "IDP": "Dostawcy tożsamości", diff --git a/console/src/assets/i18n/pt.json b/console/src/assets/i18n/pt.json index ecbabcc56a..b98860e7de 100644 --- a/console/src/assets/i18n/pt.json +++ b/console/src/assets/i18n/pt.json @@ -1021,6 +1021,8 @@ "LOCKOUT": "Bloqueio", "COMPLEXITY": "Complexidade de Senha", "NOTIFICATIONS": "Configurações de Notificação", + "SMTP_PROVIDER": "Provedor SMTP", + "SMS_PROVIDER": "Provedor de SMS/Telefone", "NOTIFICATIONS_DESC": "Configurações de SMTP e SMS", "MESSAGETEXTS": "Textos de Mensagem", "IDP": "Provedores de Identidade", diff --git a/console/src/assets/i18n/zh.json b/console/src/assets/i18n/zh.json index 9b8606d901..ffd818cb3b 100644 --- a/console/src/assets/i18n/zh.json +++ b/console/src/assets/i18n/zh.json @@ -1019,6 +1019,8 @@ "LOCKOUT": "安全锁策略", "COMPLEXITY": "密码复杂性", "NOTIFICATIONS": "通知设置", + "SMTP_PROVIDER": "SMTP 提供商", + "SMS_PROVIDER": "短信/电话提供商", "NOTIFICATIONS_DESC": "SMTP 和 SMS 设置", "MESSAGETEXTS": "消息文本", "IDP": "身份提供者", diff --git a/docs/static/img/guides/console/smtp.png b/docs/static/img/guides/console/smtp.png index b8c0295685..4334264eda 100644 Binary files a/docs/static/img/guides/console/smtp.png and b/docs/static/img/guides/console/smtp.png differ diff --git a/docs/static/img/guides/console/twilio.png b/docs/static/img/guides/console/twilio.png index 1dfde84a88..eb253128a4 100644 Binary files a/docs/static/img/guides/console/twilio.png and b/docs/static/img/guides/console/twilio.png differ diff --git a/e2e/cypress/e2e/instance/settings/notifications.cy.ts b/e2e/cypress/e2e/instance/settings/notifications.cy.ts new file mode 100644 index 0000000000..02548d6636 --- /dev/null +++ b/e2e/cypress/e2e/instance/settings/notifications.cy.ts @@ -0,0 +1,62 @@ +const notificationPath = `/settings?id=notifications`; +const smtpPath = `/settings?id=smtpprovider`; +const smsPath = `/settings?id=smsprovider`; + +beforeEach(() => { + cy.context().as('ctx'); +}); + +describe('instance notifications', () => { + describe('notification settings', () => { + it(`should show notification settings`, () => { + cy.visit(notificationPath); + cy.contains('Notification'); + }); + }); + + describe('smtp settings', () => { + it(`should show SMTP provider settings`, () => { + cy.visit(smtpPath); + cy.contains('SMTP Settings'); + }); + + it(`should add SMTP provider settings`, () => { + cy.visit(smtpPath); + cy.get('[formcontrolname="senderAddress"]').clear().type('sender@example.com'); + cy.get('[formcontrolname="senderName"]').clear().type('Zitadel'); + cy.get('[formcontrolname="hostAndPort"]').clear().type('smtp.mailtrap.io:2525'); + cy.get('[formcontrolname="user"]').clear().type('user@example.com'); + cy.get('[data-e2e="save-smtp-settings-button"]').click(); + cy.shouldConfirmSuccess(); + cy.get('[formcontrolname="senderAddress"]').should('have.value', 'sender@example.com'); + cy.get('[formcontrolname="senderName"]').should('have.value', 'Zitadel'); + cy.get('[formcontrolname="hostAndPort"]').should('have.value', 'smtp.mailtrap.io:2525'); + cy.get('[formcontrolname="user"]').should('have.value', 'user@example.com'); + }); + + it(`should add SMTP provider password`, () => { + cy.visit(smtpPath); + cy.get('[data-e2e="add-smtp-password-button"]').click(); + cy.get('[data-e2e="notification-setting-password"]').clear().type('dummy@example.com'); + cy.get('[data-e2e="save-notification-setting-password-button"]').click(); + cy.shouldConfirmSuccess(); + }); + }); + + describe('sms settings', () => { + it(`should show SMS provider settings`, () => { + cy.visit(smsPath); + cy.contains('SMS Settings'); + }); + + it(`should add SMS provider`, () => { + cy.visit(smsPath); + cy.get('[data-e2e="new-twilio-button"]').click(); + cy.get('[formcontrolname="sid"]').clear().type('test'); + cy.get('[formcontrolname="token"]').clear().type('token'); + cy.get('[formcontrolname="senderNumber"]').clear().type('2312123132'); + cy.get('[data-e2e="save-sms-settings-button"]').click(); + cy.shouldConfirmSuccess(); + }); + }); +});