mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-14 03:54:21 +00:00
Merge branch 'main' into next
This commit is contained in:
commit
8ce3af2f9d
40
.github/pull_request_template.md
vendored
40
.github/pull_request_template.md
vendored
@ -1,15 +1,27 @@
|
||||
### Definition of Ready
|
||||
# Which Problems Are Solved
|
||||
|
||||
- [ ] I am happy with the code
|
||||
- [ ] Short description of the feature/issue is added in the pr description
|
||||
- [ ] PR is linked to the corresponding user story
|
||||
- [ ] Acceptance criteria are met
|
||||
- [ ] All open todos and follow ups are defined in a new ticket and justified
|
||||
- [ ] Deviations from the acceptance criteria and design are agreed with the PO and documented.
|
||||
- [ ] No debug or dead code
|
||||
- [ ] My code has no repetitions
|
||||
- [ ] Critical parts are tested automatically
|
||||
- [ ] Where possible E2E tests are implemented
|
||||
- [ ] Documentation/examples are up-to-date
|
||||
- [ ] All non-functional requirements are met
|
||||
- [ ] Functionality of the acceptance criteria is checked manually on the dev system.
|
||||
Replace this example text with a concise list of problems that this PR solves.
|
||||
For example:
|
||||
- If the property XY is not given, the system crashes with a nil pointer exception.
|
||||
|
||||
# How the Problems Are Solved
|
||||
|
||||
Replace this example text with a concise list of changes that this PR introduces.
|
||||
For example:
|
||||
- Validates if property XY is given and throws an error if not
|
||||
|
||||
# Additional Changes
|
||||
|
||||
Replace this example text with a concise list of additional changes that this PR introduces, that are not directly solving the initial problem but are related.
|
||||
For example:
|
||||
- The docs explicitly describe that the property XY is mandatory
|
||||
- Adds missing translations for validations.
|
||||
|
||||
# Additional Context
|
||||
|
||||
Replace this example with links to related issues, discussions, discord threads, or other sources with more context.
|
||||
Use the Closing #issue syntax for issues that are resolved with this PR.
|
||||
- Closes #123
|
||||
- Discussion #456
|
||||
- Follow-up for PR #789
|
||||
- https://discord.com/channels/123/456
|
1
.github/workflows/e2e.yml
vendored
1
.github/workflows/e2e.yml
vendored
@ -5,6 +5,7 @@ on:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
timeout-minutes: 10
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
31
.github/workflows/ready_for_review.yml
vendored
Normal file
31
.github/workflows/ready_for_review.yml
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
comment:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const content = `### Thanks for your contribution @${{ github.event.pull_request.user.login }}! 🎉
|
||||
|
||||
Please make sure you tick the following checkboxes before marking this Pull Request (PR) as ready for review:
|
||||
|
||||
- [ ] I am happy with the code
|
||||
- [ ] Documentations and examples are up-to-date
|
||||
- [ ] Logical behavior changes are tested automatically
|
||||
- [ ] No debug or dead code
|
||||
- [ ] My code has no repetitions
|
||||
- [ ] The PR title adheres to the [conventional commit format](https://www.conventionalcommits.org/en/v1.0.0/)
|
||||
- [ ] The example texts in the PR description are replaced.
|
||||
- [ ] If there are any open TODOs or follow-ups, they are described in issues and link to this PR
|
||||
- [ ] If there are deviations from a user stories acceptance criteria or design, they are agreed upon with the PO and documented.
|
||||
`;
|
||||
github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: content
|
||||
})
|
@ -23,7 +23,7 @@ Tracing:
|
||||
Type: none # ZITADEL_TRACING_TYPE
|
||||
Fraction: 1.0 # ZITADEL_TRACING_FRACTION
|
||||
# The endpoint of the otel collector endpoint
|
||||
Endpoint: '' #ZITADEL_TRACING_ENDPOINT
|
||||
Endpoint: "" #ZITADEL_TRACING_ENDPOINT
|
||||
|
||||
Telemetry:
|
||||
# As long as Enabled is true, ZITADEL tries to send usage data to the configured Telemetry.Endpoints.
|
||||
@ -704,6 +704,9 @@ DefaultInstance:
|
||||
PrivacyLink: https://zitadel.com/docs/legal/privacy-policy # ZITADEL_DEFAULTINSTANCE_PRIVACYPOLICY_PRIVACYLINK
|
||||
HelpLink: "" # ZITADEL_DEFAULTINSTANCE_PRIVACYPOLICY_HELPLINK
|
||||
SupportEmail: "" # ZITADEL_DEFAULTINSTANCE_PRIVACYPOLICY_SUPPORTEMAIL
|
||||
DocsLink: https://zitadel.com/docs # ZITADEL_DEFAULTINSTANCE_PRIVACYPOLICY_DOCSLINK
|
||||
CustomLink: "" # ZITADEL_DEFAULTINSTANCE_PRIVACYPOLICY_CUSTOMLINK
|
||||
CustomLinkText: "" # ZITADEL_DEFAULTINSTANCE_PRIVACYPOLICY_CUSTOMLINKTEXT
|
||||
NotificationPolicy:
|
||||
PasswordChange: true # ZITADEL_DEFAULTINSTANCE_NOTIFICATIONPOLICY_PASSWORDCHANGE
|
||||
LabelPolicy:
|
||||
|
@ -19,6 +19,7 @@ var (
|
||||
|
||||
createUserStmt string
|
||||
grantStmt string
|
||||
settingsStmt string
|
||||
databaseStmt string
|
||||
createEventstoreStmt string
|
||||
createProjectionsStmt string
|
||||
@ -53,7 +54,7 @@ The user provided by flags needs privileges to
|
||||
},
|
||||
}
|
||||
|
||||
cmd.AddCommand(newZitadel(), newDatabase(), newUser(), newGrant())
|
||||
cmd.AddCommand(newZitadel(), newDatabase(), newUser(), newGrant(), newSettings())
|
||||
return cmd
|
||||
}
|
||||
|
||||
@ -62,6 +63,7 @@ func InitAll(ctx context.Context, config *Config) {
|
||||
VerifyUser(config.Database.Username(), config.Database.Password()),
|
||||
VerifyDatabase(config.Database.DatabaseName()),
|
||||
VerifyGrant(config.Database.DatabaseName(), config.Database.Username()),
|
||||
VerifySettings(config.Database.DatabaseName(), config.Database.Username()),
|
||||
)
|
||||
logging.OnError(err).Fatal("unable to initialize the database")
|
||||
|
||||
@ -147,6 +149,11 @@ func ReadStmts(typ string) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
settingsStmt, err = readStmt(typ, "11_settings")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
4
cmd/initialise/sql/cockroach/11_settings.sql
Normal file
4
cmd/initialise/sql/cockroach/11_settings.sql
Normal file
@ -0,0 +1,4 @@
|
||||
-- replace the first %[1]q with the database in double quotes
|
||||
-- replace the second \%[2]q with the user in double quotes$
|
||||
-- For more information see technical advisory 10009 (https://zitadel.com/docs/support/advisory/a10009)
|
||||
ALTER ROLE %[2]q IN DATABASE %[1]q SET enable_durable_locking_for_serializable = on;
|
0
cmd/initialise/sql/postgres/11_settings.sql
Normal file
0
cmd/initialise/sql/postgres/11_settings.sql
Normal file
44
cmd/initialise/verify_settings.go
Normal file
44
cmd/initialise/verify_settings.go
Normal file
@ -0,0 +1,44 @@
|
||||
package initialise
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/database"
|
||||
)
|
||||
|
||||
func newSettings() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "settings",
|
||||
Short: "Ensures proper settings on the database",
|
||||
Long: `Ensures proper settings on the database.
|
||||
|
||||
Prerequisites:
|
||||
- cockroachDB or postgreSQL
|
||||
|
||||
Cockroach
|
||||
- Sets enable_durable_locking_for_serializable to on for the zitadel user and database
|
||||
`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
config := MustNewConfig(viper.GetViper())
|
||||
|
||||
err := initialise(config.Database, VerifySettings(config.Database.DatabaseName(), config.Database.Username()))
|
||||
logging.OnError(err).Fatal("unable to set settings")
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func VerifySettings(databaseName, username string) func(*database.DB) error {
|
||||
return func(db *database.DB) error {
|
||||
if db.Type() == "postgres" {
|
||||
return nil
|
||||
}
|
||||
logging.WithFields("user", username, "database", databaseName).Info("verify settings")
|
||||
|
||||
return exec(db, fmt.Sprintf(settingsStmt, databaseName, username), nil)
|
||||
}
|
||||
}
|
27
cmd/setup/26.go
Normal file
27
cmd/setup/26.go
Normal file
@ -0,0 +1,27 @@
|
||||
package setup
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/database"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
)
|
||||
|
||||
var (
|
||||
//go:embed 26.sql
|
||||
authUsers3 string
|
||||
)
|
||||
|
||||
type AuthUsers3 struct {
|
||||
dbClient *database.DB
|
||||
}
|
||||
|
||||
func (mig *AuthUsers3) Execute(ctx context.Context, _ eventstore.Event) error {
|
||||
_, err := mig.dbClient.ExecContext(ctx, authUsers3)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mig *AuthUsers3) String() string {
|
||||
return "26_auth_users3"
|
||||
}
|
16
cmd/setup/26.sql
Normal file
16
cmd/setup/26.sql
Normal file
@ -0,0 +1,16 @@
|
||||
CREATE TABLE IF NOT EXISTS auth.users3 (
|
||||
instance_id TEXT NOT NULL,
|
||||
id TEXT NOT NULL,
|
||||
resource_owner TEXT NOT NULL,
|
||||
change_date TIMESTAMPTZ NULL,
|
||||
password_set BOOL NULL,
|
||||
password_change TIMESTAMPTZ NULL,
|
||||
last_login TIMESTAMPTZ NULL,
|
||||
init_required BOOL NULL,
|
||||
mfa_init_skipped TIMESTAMPTZ NULL,
|
||||
username_change_required BOOL NULL,
|
||||
passwordless_init_required BOOL NULL,
|
||||
password_init_required BOOL NULL,
|
||||
|
||||
PRIMARY KEY (instance_id, id)
|
||||
)
|
27
cmd/setup/27.go
Normal file
27
cmd/setup/27.go
Normal file
@ -0,0 +1,27 @@
|
||||
package setup
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/database"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
)
|
||||
|
||||
var (
|
||||
//go:embed 27.sql
|
||||
addSAMLNameIDFormat string
|
||||
)
|
||||
|
||||
type IDPTemplate6SAMLNameIDFormat struct {
|
||||
dbClient *database.DB
|
||||
}
|
||||
|
||||
func (mig *IDPTemplate6SAMLNameIDFormat) Execute(ctx context.Context, _ eventstore.Event) error {
|
||||
_, err := mig.dbClient.ExecContext(ctx, addSAMLNameIDFormat)
|
||||
return err
|
||||
}
|
||||
|
||||
func (mig *IDPTemplate6SAMLNameIDFormat) String() string {
|
||||
return "26_idp_templates6_add_saml_name_id_format"
|
||||
}
|
2
cmd/setup/27.sql
Normal file
2
cmd/setup/27.sql
Normal file
@ -0,0 +1,2 @@
|
||||
ALTER TABLE IF EXISTS projections.idp_templates6_saml ADD COLUMN IF NOT EXISTS name_id_format SMALLINT;
|
||||
ALTER TABLE IF EXISTS projections.idp_templates6_saml ADD COLUMN IF NOT EXISTS transient_mapping_attribute_name TEXT;
|
@ -108,6 +108,8 @@ type Steps struct {
|
||||
s23CorrectGlobalUniqueConstraints *CorrectGlobalUniqueConstraints
|
||||
s24AddActorToAuthTokens *AddActorToAuthTokens
|
||||
s25User11AddLowerFieldsToVerifiedEmail *User11AddLowerFieldsToVerifiedEmail
|
||||
s26AuthUsers3 *AuthUsers3
|
||||
s27IDPTemplate6SAMLNameIDFormat *IDPTemplate6SAMLNameIDFormat
|
||||
}
|
||||
|
||||
func MustNewSteps(v *viper.Viper) *Steps {
|
||||
|
@ -138,6 +138,8 @@ func Setup(config *Config, steps *Steps, masterKey string) {
|
||||
steps.s23CorrectGlobalUniqueConstraints = &CorrectGlobalUniqueConstraints{dbClient: esPusherDBClient}
|
||||
steps.s24AddActorToAuthTokens = &AddActorToAuthTokens{dbClient: queryDBClient}
|
||||
steps.s25User11AddLowerFieldsToVerifiedEmail = &User11AddLowerFieldsToVerifiedEmail{dbClient: esPusherDBClient}
|
||||
steps.s26AuthUsers3 = &AuthUsers3{dbClient: esPusherDBClient}
|
||||
steps.s27IDPTemplate6SAMLNameIDFormat = &IDPTemplate6SAMLNameIDFormat{dbClient: esPusherDBClient}
|
||||
|
||||
err = projection.Create(ctx, projectionDBClient, eventstoreClient, config.Projections, nil, nil, nil)
|
||||
logging.OnError(err).Fatal("unable to start projections")
|
||||
@ -175,6 +177,7 @@ func Setup(config *Config, steps *Steps, masterKey string) {
|
||||
steps.s22ActiveInstancesIndex,
|
||||
steps.s23CorrectGlobalUniqueConstraints,
|
||||
steps.s24AddActorToAuthTokens,
|
||||
steps.s26AuthUsers3,
|
||||
} {
|
||||
mustExecuteMigration(ctx, eventstoreClient, step, "migration failed")
|
||||
}
|
||||
@ -188,6 +191,7 @@ func Setup(config *Config, steps *Steps, masterKey string) {
|
||||
steps.s18AddLowerFieldsToLoginNames,
|
||||
steps.s21AddBlockFieldToLimits,
|
||||
steps.s25User11AddLowerFieldsToVerifiedEmail,
|
||||
steps.s27IDPTemplate6SAMLNameIDFormat,
|
||||
} {
|
||||
mustExecuteMigration(ctx, eventstoreClient, step, "migration failed")
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Directive, ElementRef, EventEmitter, HostListener, Output } from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
standalone: true,
|
||||
selector: '[cnslScrollable]',
|
||||
})
|
||||
export class ScrollableDirective {
|
||||
@ -15,7 +16,6 @@ export class ScrollableDirective {
|
||||
const top = event.target.scrollTop;
|
||||
const height = this.el.nativeElement.scrollHeight;
|
||||
const offset = this.el.nativeElement.offsetHeight;
|
||||
|
||||
// emit bottom event
|
||||
if (top > height - offset - 1) {
|
||||
this.scrollPosition.emit('bottom');
|
||||
|
@ -1,11 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { ScrollableDirective } from './scrollable.directive';
|
||||
|
||||
@NgModule({
|
||||
declarations: [ScrollableDirective],
|
||||
imports: [CommonModule],
|
||||
exports: [ScrollableDirective],
|
||||
})
|
||||
export class ScrollableModule {}
|
@ -6,7 +6,6 @@ import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { ScrollableModule } from 'src/app/directives/scrollable/scrollable.module';
|
||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
|
||||
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
|
||||
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
|
||||
@ -18,7 +17,6 @@ import { ChangesComponent } from './changes.component';
|
||||
declarations: [ChangesComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
ScrollableModule,
|
||||
MatProgressSpinnerModule,
|
||||
TranslateModule,
|
||||
MatIconModule,
|
||||
@ -30,6 +28,6 @@ import { ChangesComponent } from './changes.component';
|
||||
MatTooltipModule,
|
||||
AvatarModule,
|
||||
],
|
||||
exports: [ChangesComponent, ScrollableModule],
|
||||
exports: [ChangesComponent],
|
||||
})
|
||||
export class ChangesModule {}
|
||||
|
@ -1,11 +1,11 @@
|
||||
<div class="footer-wrapper">
|
||||
<div class="footer-row">
|
||||
<div class="footer-links">
|
||||
<a target="_blank" *ngIf="policy?.tosLink" rel="noreferrer" [href]="policy?.tosLink" external>
|
||||
<div class="footer-links" *ngIf="authService.privacypolicy | async as pP">
|
||||
<a target="_blank" *ngIf="pP?.tosLink" rel="noreferrer" [href]="pP?.tosLink" external>
|
||||
<span>{{ 'FOOTER.LINKS.TOS' | translate }}</span>
|
||||
<i class="las la-external-link-alt"></i>
|
||||
</a>
|
||||
<a target="_blank" *ngIf="policy?.privacyLink" rel="noreferrer" [href]="policy?.privacyLink" external>
|
||||
<a target="_blank" *ngIf="pP?.privacyLink" rel="noreferrer" [href]="pP?.privacyLink" external>
|
||||
<span>{{ 'FOOTER.LINKS.PP' | translate }}</span>
|
||||
<i class="las la-external-link-alt"></i>
|
||||
</a>
|
||||
|
@ -8,16 +8,7 @@ import { faXTwitter } from '@fortawesome/free-brands-svg-icons';
|
||||
templateUrl: './footer.component.html',
|
||||
styleUrls: ['./footer.component.scss'],
|
||||
})
|
||||
export class FooterComponent implements OnInit {
|
||||
public policy?: PrivacyPolicy.AsObject;
|
||||
export class FooterComponent {
|
||||
public faXTwitter = faXTwitter;
|
||||
constructor(public authService: GrpcAuthService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.authService.getMyPrivacyPolicy().then((policyResp) => {
|
||||
if (policyResp.policy) {
|
||||
this.policy = policyResp.policy;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -168,7 +168,11 @@
|
||||
|
||||
<span class="fill-space"></span>
|
||||
|
||||
<a class="doc-link" href="https://zitadel.com/docs" mat-stroked-button target="_blank">
|
||||
<a class="custom-link" *ngIf="customLink && customLinkText" href="{{ customLink }}" mat-stroked-button target="_blank">
|
||||
{{ customLinkText }}
|
||||
</a>
|
||||
|
||||
<a class="doc-link" *ngIf="docsLink" href="{{ docsLink }}" mat-stroked-button target="_blank">
|
||||
{{ 'MENU.DOCUMENTATION' | translate }}
|
||||
</a>
|
||||
|
||||
|
@ -224,7 +224,8 @@
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.doc-link {
|
||||
.doc-link,
|
||||
.custom-link {
|
||||
margin-right: 1rem;
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { ConnectedPosition, ConnectionPositionPair } from '@angular/cdk/overlay';
|
||||
import { Component, ElementRef, EventEmitter, Input, OnDestroy, Output, ViewChild } from '@angular/core';
|
||||
import { Component, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { BehaviorSubject, Observable, of, Subject } from 'rxjs';
|
||||
import { Org } from 'src/app/proto/generated/zitadel/org_pb';
|
||||
@ -8,8 +8,8 @@ import { AuthenticationService } from 'src/app/services/authentication.service';
|
||||
import { BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
|
||||
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
|
||||
import { ActionKeysType } from '../action-keys/action-keys.component';
|
||||
import { GetPrivacyPolicyResponse } from 'src/app/proto/generated/zitadel/management_pb';
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-header',
|
||||
@ -31,6 +31,9 @@ export class HeaderComponent implements OnDestroy {
|
||||
private destroy$: Subject<void> = new Subject();
|
||||
public BreadcrumbType: any = BreadcrumbType;
|
||||
public ActionKeysType: any = ActionKeysType;
|
||||
public docsLink = 'https://zitadel.com/docs';
|
||||
public customLink = '';
|
||||
public customLinkText = '';
|
||||
|
||||
public positions: ConnectedPosition[] = [
|
||||
new ConnectionPositionPair({ originX: 'start', originY: 'bottom' }, { overlayX: 'start', overlayY: 'top' }, 0, 10),
|
||||
@ -47,7 +50,25 @@ export class HeaderComponent implements OnDestroy {
|
||||
public mgmtService: ManagementService,
|
||||
public breadcrumbService: BreadcrumbService,
|
||||
public router: Router,
|
||||
) {}
|
||||
) {
|
||||
this.loadData();
|
||||
}
|
||||
|
||||
public async loadData(): Promise<any> {
|
||||
const getData = (): Promise<GetPrivacyPolicyResponse.AsObject> => {
|
||||
return this.mgmtService.getPrivacyPolicy();
|
||||
};
|
||||
|
||||
getData()
|
||||
.then((resp) => {
|
||||
if (resp.policy) {
|
||||
this.docsLink = resp.policy.docsLink;
|
||||
this.customLink = resp.policy.customLink;
|
||||
this.customLinkText = resp.policy.customLinkText;
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
public ngOnDestroy() {
|
||||
this.destroy$.next();
|
||||
|
@ -15,7 +15,7 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="org-wrapper">
|
||||
<div class="org-wrapper" cnslScrollable (scrollPosition)="onNearEndScroll($event)">
|
||||
<button
|
||||
class="org-button-with-pin"
|
||||
mat-button
|
||||
|
@ -1,11 +1,14 @@
|
||||
import { SelectionModel } from '@angular/cdk/collections';
|
||||
import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
|
||||
import { UntypedFormControl } from '@angular/forms';
|
||||
import { BehaviorSubject, catchError, debounceTime, finalize, from, map, Observable, of, pipe, tap } from 'rxjs';
|
||||
import { BehaviorSubject, catchError, debounceTime, finalize, from, map, Observable, of, pipe, scan, take, tap } from 'rxjs';
|
||||
import { TextQueryMethod } from 'src/app/proto/generated/zitadel/object_pb';
|
||||
import { Org, OrgNameQuery, OrgQuery, OrgState, OrgStateQuery } from 'src/app/proto/generated/zitadel/org_pb';
|
||||
import { Org, OrgFieldName, OrgNameQuery, OrgQuery, OrgState, OrgStateQuery } from 'src/app/proto/generated/zitadel/org_pb';
|
||||
import { AuthenticationService } from 'src/app/services/authentication.service';
|
||||
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
|
||||
const ORG_QUERY_LIMIT = 100;
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-org-context',
|
||||
@ -16,7 +19,30 @@ export class OrgContextComponent implements OnInit {
|
||||
public pinned: SelectionModel<Org.AsObject> = new SelectionModel<Org.AsObject>(true, []);
|
||||
|
||||
public orgLoading$: BehaviorSubject<any> = new BehaviorSubject(false);
|
||||
public orgs$: Observable<Org.AsObject[]> = of([]);
|
||||
|
||||
public bottom: boolean = false;
|
||||
private _done: BehaviorSubject<any> = new BehaviorSubject(false);
|
||||
private _loading: BehaviorSubject<any> = new BehaviorSubject(false);
|
||||
public _orgs: BehaviorSubject<Org.AsObject[]> = new BehaviorSubject<Org.AsObject[]>([]);
|
||||
|
||||
public orgs$: Observable<Org.AsObject[]> = this._orgs.pipe(
|
||||
map((orgs) => {
|
||||
return orgs.sort((left, right) => left.name.localeCompare(right.name));
|
||||
}),
|
||||
pipe(
|
||||
tap((orgs: Org.AsObject[]) => {
|
||||
this.pinned.clear();
|
||||
this.getPrefixedItem('pinned-orgs').then((stringifiedOrgs) => {
|
||||
if (stringifiedOrgs) {
|
||||
const orgIds: string[] = JSON.parse(stringifiedOrgs);
|
||||
const pinnedOrgs = orgs.filter((o) => orgIds.includes(o.id));
|
||||
pinnedOrgs.forEach((o) => this.pinned.select(o));
|
||||
}
|
||||
});
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
public filterControl: UntypedFormControl = new UntypedFormControl('');
|
||||
@Input() public org!: Org.AsObject;
|
||||
@ViewChild('input', { static: false }) input!: ElementRef;
|
||||
@ -26,15 +52,17 @@ export class OrgContextComponent implements OnInit {
|
||||
constructor(
|
||||
public authService: AuthenticationService,
|
||||
private auth: GrpcAuthService,
|
||||
private toast: ToastService,
|
||||
) {
|
||||
this.filterControl.valueChanges.pipe(debounceTime(500)).subscribe((value) => {
|
||||
this.loadOrgs(value.trim().toLowerCase());
|
||||
const filteredValues = this.loadOrgs(0, value.trim().toLowerCase());
|
||||
this.mapAndUpdate(filteredValues, true);
|
||||
});
|
||||
}
|
||||
|
||||
public ngOnInit(): void {
|
||||
this.focusFilter();
|
||||
this.loadOrgs();
|
||||
this.init();
|
||||
}
|
||||
|
||||
public setActiveOrg(org: Org.AsObject) {
|
||||
@ -42,7 +70,24 @@ export class OrgContextComponent implements OnInit {
|
||||
this.closedCard.emit();
|
||||
}
|
||||
|
||||
public loadOrgs(filter?: string): void {
|
||||
public onNearEndScroll(position: 'top' | 'bottom'): void {
|
||||
if (position === 'bottom') {
|
||||
this.more();
|
||||
}
|
||||
}
|
||||
|
||||
public more(): void {
|
||||
const _cursor = this._orgs.getValue().length;
|
||||
let more: Promise<Org.AsObject[]> = this.loadOrgs(_cursor, '');
|
||||
this.mapAndUpdate(more);
|
||||
}
|
||||
|
||||
public init(): void {
|
||||
let first: Promise<Org.AsObject[]> = this.loadOrgs(0);
|
||||
this.mapAndUpdate(first);
|
||||
}
|
||||
|
||||
public loadOrgs(offset: number, filter?: string): Promise<Org.AsObject[]> {
|
||||
if (!filter) {
|
||||
const value = this.input?.nativeElement?.value;
|
||||
if (value) {
|
||||
@ -61,29 +106,52 @@ export class OrgContextComponent implements OnInit {
|
||||
orgNameQuery.setMethod(TextQueryMethod.TEXT_QUERY_METHOD_CONTAINS_IGNORE_CASE);
|
||||
query.setNameQuery(orgNameQuery);
|
||||
}
|
||||
|
||||
this.orgLoading$.next(true);
|
||||
this.orgs$ = from(this.auth.listMyProjectOrgs(undefined, 0, query ? [query] : undefined)).pipe(
|
||||
map((resp) => {
|
||||
return resp.resultList.sort((left, right) => left.name.localeCompare(right.name));
|
||||
}),
|
||||
catchError(() => of([])),
|
||||
pipe(
|
||||
tap((orgs: Org.AsObject[]) => {
|
||||
this.pinned.clear();
|
||||
this.getPrefixedItem('pinned-orgs').then((stringifiedOrgs) => {
|
||||
if (stringifiedOrgs) {
|
||||
const orgIds: string[] = JSON.parse(stringifiedOrgs);
|
||||
const pinnedOrgs = orgs.filter((o) => orgIds.includes(o.id));
|
||||
pinnedOrgs.forEach((o) => this.pinned.select(o));
|
||||
}
|
||||
});
|
||||
}),
|
||||
),
|
||||
finalize(() => {
|
||||
return this.auth
|
||||
.listMyProjectOrgs(ORG_QUERY_LIMIT, offset, query ? [query] : undefined, OrgFieldName.ORG_FIELD_NAME_NAME, 'asc')
|
||||
.then((result) => {
|
||||
this.orgLoading$.next(false);
|
||||
return result.resultList;
|
||||
})
|
||||
.catch((error) => {
|
||||
this.orgLoading$.next(false);
|
||||
this.toast.showError(error);
|
||||
return [];
|
||||
});
|
||||
}
|
||||
|
||||
private mapAndUpdate(col: Promise<Org.AsObject[]>, clear?: boolean): any {
|
||||
if (clear === false && (this._done.value || this._loading.value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.bottom) {
|
||||
this._loading.next(true);
|
||||
|
||||
return from(col)
|
||||
.pipe(
|
||||
take(1),
|
||||
tap((res: Org.AsObject[]) => {
|
||||
const current = this._orgs.getValue();
|
||||
if (clear) {
|
||||
this._orgs.next(res);
|
||||
} else {
|
||||
this._orgs.next([...current, ...res]);
|
||||
}
|
||||
|
||||
this._loading.next(false);
|
||||
if (!res.length) {
|
||||
this._done.next(true);
|
||||
}
|
||||
}),
|
||||
);
|
||||
catchError((_) => {
|
||||
this._loading.next(false);
|
||||
this.bottom = true;
|
||||
return of([]);
|
||||
}),
|
||||
)
|
||||
.subscribe();
|
||||
}
|
||||
}
|
||||
|
||||
public closeCard(element: HTMLElement): void {
|
||||
|
@ -12,11 +12,13 @@ import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||
|
||||
import { InputModule } from '../input/input.module';
|
||||
import { OrgContextComponent } from './org-context.component';
|
||||
import { ScrollableDirective } from 'src/app/directives/scrollable/scrollable.directive';
|
||||
|
||||
@NgModule({
|
||||
declarations: [OrgContextComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
ScrollableDirective,
|
||||
FormsModule,
|
||||
A11yModule,
|
||||
ReactiveFormsModule,
|
||||
|
@ -52,7 +52,7 @@
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef>
|
||||
{{ 'ORG.PAGES.NAME' | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let org" (click)="setAndNavigateToOrg(org)">
|
||||
|
@ -50,4 +50,12 @@
|
||||
<i *ngIf="password?.dirty && !password?.errors?.['errorslowercasemissing']" class="las la-check green"></i>
|
||||
<span class="cnsl-secondary-text">{{ 'ERRORS.LOWERCASEMISSING' | translate }}</span>
|
||||
</div>
|
||||
<div class="val">
|
||||
<i *ngIf="password?.value?.length === 0 || password?.value?.length <= 70" class="las la-check green"></i>
|
||||
<i *ngIf="password?.value?.length > 70" class="las la-times red"></i>
|
||||
|
||||
<span class="cnsl-secondary-text"
|
||||
>{{ 'USER.PASSWORD.MAXLENGTHERROR' | translate: { value: 70 } }} ({{ password?.value?.length }}/{{ 70 }})
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -9,6 +9,7 @@
|
||||
color="warn"
|
||||
(click)="resetDefault()"
|
||||
mat-stroked-button
|
||||
data-e2e="reset-button"
|
||||
>
|
||||
{{ 'POLICY.RESET' | translate }}
|
||||
</button>
|
||||
@ -40,7 +41,23 @@
|
||||
<cnsl-form-field class="privacy-policy-formfield">
|
||||
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.SUPPORTEMAIL' | translate }}</cnsl-label>
|
||||
<input cnslInput name="supportEmail" formControlName="supportEmail" />
|
||||
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{ key: 'supportEmail' }"></template>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="privacy-policy-formfield">
|
||||
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.CUSTOMLINK' | translate }}</cnsl-label>
|
||||
<input cnslInput name="customLink" formControlName="customLink" />
|
||||
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{ key: 'customLink' }"></template>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="privacy-policy-formfield">
|
||||
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.CUSTOMLINKTEXT' | translate }}</cnsl-label>
|
||||
<input cnslInput name="customLinkText" formControlName="customLinkText" />
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="privacy-policy-formfield">
|
||||
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.DOCSLINK' | translate }}</cnsl-label>
|
||||
<input cnslInput name="docsLink" formControlName="docsLink" />
|
||||
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{ key: 'docsLink' }"></template>
|
||||
</cnsl-form-field>
|
||||
</form>
|
||||
</div>
|
||||
@ -53,6 +70,7 @@
|
||||
color="primary"
|
||||
type="submit"
|
||||
mat-raised-button
|
||||
data-e2e="save-button"
|
||||
>
|
||||
{{ 'ACTIONS.SAVE' | translate }}
|
||||
</button>
|
||||
|
@ -61,6 +61,9 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
|
||||
privacyLink: ['', []],
|
||||
helpLink: ['', []],
|
||||
supportEmail: ['', []],
|
||||
docsLink: ['', []],
|
||||
customLink: ['', []],
|
||||
customLinkText: ['', []],
|
||||
});
|
||||
|
||||
this.canWrite$.pipe(take(1)).subscribe((canWrite) => {
|
||||
@ -107,6 +110,9 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
|
||||
privacyLink: '',
|
||||
helpLink: '',
|
||||
supportEmail: '',
|
||||
docsLink: '',
|
||||
customLink: '',
|
||||
customLinkText: '',
|
||||
});
|
||||
}
|
||||
})
|
||||
@ -117,6 +123,9 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
|
||||
privacyLink: '',
|
||||
helpLink: '',
|
||||
supportEmail: '',
|
||||
docsLink: '',
|
||||
customLink: '',
|
||||
customLinkText: '',
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -129,11 +138,16 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
|
||||
req.setTosLink(this.form.get('tosLink')?.value);
|
||||
req.setHelpLink(this.form.get('helpLink')?.value);
|
||||
req.setSupportEmail(this.form.get('supportEmail')?.value);
|
||||
req.setDocsLink(this.form.get('docsLink')?.value);
|
||||
req.setCustomLink(this.form.get('customLink')?.value);
|
||||
req.setCustomLinkText(this.form.get('customLinkText')?.value);
|
||||
(this.service as ManagementService)
|
||||
.addCustomPrivacyPolicy(req)
|
||||
.then(() => {
|
||||
this.toast.showInfo('POLICY.PRIVACY_POLICY.SAVED', true);
|
||||
this.loadData();
|
||||
// Reload console as links may have changed
|
||||
this.reloadConsole();
|
||||
})
|
||||
.catch((error) => this.toast.showError(error));
|
||||
} else {
|
||||
@ -142,12 +156,17 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
|
||||
req.setTosLink(this.form.get('tosLink')?.value);
|
||||
req.setHelpLink(this.form.get('helpLink')?.value);
|
||||
req.setSupportEmail(this.form.get('supportEmail')?.value);
|
||||
req.setDocsLink(this.form.get('docsLink')?.value);
|
||||
req.setCustomLink(this.form.get('customLink')?.value);
|
||||
req.setCustomLinkText(this.form.get('customLinkText')?.value);
|
||||
|
||||
(this.service as ManagementService)
|
||||
.updateCustomPrivacyPolicy(req)
|
||||
.then(() => {
|
||||
this.toast.showInfo('POLICY.PRIVACY_POLICY.SAVED', true);
|
||||
this.loadData();
|
||||
// Reload console as links may have changed
|
||||
this.reloadConsole();
|
||||
})
|
||||
.catch((error) => this.toast.showError(error));
|
||||
}
|
||||
@ -157,12 +176,17 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
|
||||
req.setTosLink(this.form.get('tosLink')?.value);
|
||||
req.setHelpLink(this.form.get('helpLink')?.value);
|
||||
req.setSupportEmail(this.form.get('supportEmail')?.value);
|
||||
req.setDocsLink(this.form.get('docsLink')?.value);
|
||||
req.setCustomLink(this.form.get('customLink')?.value);
|
||||
req.setCustomLinkText(this.form.get('customLinkText')?.value);
|
||||
|
||||
(this.service as AdminService)
|
||||
.updatePrivacyPolicy(req)
|
||||
.then(() => {
|
||||
this.toast.showInfo('POLICY.PRIVACY_POLICY.SAVED', true);
|
||||
this.loadData();
|
||||
// Reload console as links may have changed
|
||||
this.reloadConsole();
|
||||
})
|
||||
.catch((error) => this.toast.showError(error));
|
||||
}
|
||||
@ -188,6 +212,7 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
|
||||
.then(() => {
|
||||
setTimeout(() => {
|
||||
this.loadData();
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
})
|
||||
.catch((error) => {
|
||||
@ -209,4 +234,10 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private reloadConsole(): void {
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
.option-form {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
max-width: 400px;
|
||||
max-width: 500px;
|
||||
padding-bottom: 1rem;
|
||||
|
||||
.checkbox-desc {
|
||||
|
@ -70,6 +70,28 @@
|
||||
</button>
|
||||
</div>
|
||||
<div *ngIf="showOptional">
|
||||
<div class="transient-info">
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.SAML.NAMEIDFORMAT' | translate }}</cnsl-label>
|
||||
<mat-select formControlName="nameIdFormat" [compareWith]="compareNameIDFormat">
|
||||
<mat-option *ngFor="let nameIdFormat of nameIDFormatValues" [value]="nameIdFormat">{{
|
||||
nameIdFormat
|
||||
}}</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-info-section>
|
||||
<div>
|
||||
<p class="transient-info-desc">{{ 'IDP.SAML.TRANSIENTMAPPINGATTRIBUTENAME_DESC' | translate }}</p>
|
||||
</div>
|
||||
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{ 'IDP.SAML.TRANSIENTMAPPINGATTRIBUTENAME' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="transientMappingAttributeName" />
|
||||
</cnsl-form-field>
|
||||
</cnsl-info-section>
|
||||
</div>
|
||||
|
||||
<cnsl-provider-options
|
||||
[initialOptions]="provider?.config?.options"
|
||||
(optionsChanged)="options = $event"
|
||||
|
@ -1,3 +1,12 @@
|
||||
.metadata-xml {
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.transient-info {
|
||||
max-width: 500px;
|
||||
|
||||
.transient-info-desc {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,12 @@
|
||||
import { Component, Injector, Type } from '@angular/core';
|
||||
import { Location } from '@angular/common';
|
||||
import { AutoLinkingOption, Options, Provider, SAMLBinding } from '../../../proto/generated/zitadel/idp_pb';
|
||||
import {
|
||||
AutoLinkingOption,
|
||||
Options,
|
||||
Provider,
|
||||
SAMLBinding,
|
||||
SAMLNameIDFormat,
|
||||
} from '../../../proto/generated/zitadel/idp_pb';
|
||||
import { AbstractControl, FormGroup, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
|
||||
import { PolicyComponentServiceType } from '../../policies/policy-component-types.enum';
|
||||
import { ManagementService } from '../../../services/mgmt.service';
|
||||
@ -46,6 +52,7 @@ export class ProviderSamlSpComponent {
|
||||
// DEPRECATED: use service$ instead
|
||||
private service!: ManagementService | AdminService;
|
||||
bindingValues: string[] = Object.keys(SAMLBinding);
|
||||
nameIDFormatValues: string[] = Object.keys(SAMLNameIDFormat);
|
||||
|
||||
public justCreated$: BehaviorSubject<string> = new BehaviorSubject<string>('');
|
||||
public justActivated$ = new BehaviorSubject<boolean>(false);
|
||||
@ -118,6 +125,8 @@ export class ProviderSamlSpComponent {
|
||||
metadataUrl: new UntypedFormControl('', []),
|
||||
binding: new UntypedFormControl(this.bindingValues[0], [requiredValidator]),
|
||||
withSignedRequest: new UntypedFormControl(true, [requiredValidator]),
|
||||
nameIdFormat: new UntypedFormControl(SAMLNameIDFormat.SAML_NAME_ID_FORMAT_PERSISTENT, []),
|
||||
transientMappingAttributeName: new UntypedFormControl('', []),
|
||||
},
|
||||
atLeastOneIsFilled('metadataXml', 'metadataUrl'),
|
||||
);
|
||||
@ -196,8 +205,12 @@ export class ProviderSamlSpComponent {
|
||||
req.setWithSignedRequest(this.withSignedRequest?.value);
|
||||
// @ts-ignore
|
||||
req.setBinding(SAMLBinding[this.binding?.value]);
|
||||
// @ts-ignore
|
||||
req.setNameIdFormat(SAMLNameIDFormat[this.nameIDFormat?.value]);
|
||||
req.setTransientMappingAttributeName(this.transientMapping?.value);
|
||||
req.setProviderOptions(this.options);
|
||||
|
||||
console.log(req);
|
||||
this.loading = true;
|
||||
this.service
|
||||
.updateSAMLProvider(req)
|
||||
@ -229,6 +242,11 @@ export class ProviderSamlSpComponent {
|
||||
// @ts-ignore
|
||||
req.setBinding(SAMLBinding[this.binding?.value]);
|
||||
req.setWithSignedRequest(this.withSignedRequest?.value);
|
||||
if (this.nameIDFormat) {
|
||||
// @ts-ignore
|
||||
req.setNameIdFormat(SAMLNameIDFormat[this.nameIDFormat.value]);
|
||||
}
|
||||
req.setTransientMappingAttributeName(this.transientMapping?.value);
|
||||
this.loading = true;
|
||||
this.service
|
||||
.addSAMLProvider(req)
|
||||
@ -279,6 +297,14 @@ export class ProviderSamlSpComponent {
|
||||
return false;
|
||||
}
|
||||
|
||||
compareNameIDFormat(value: string, index: number) {
|
||||
console.log(value, index);
|
||||
if (value) {
|
||||
return value === Object.keys(SAMLNameIDFormat)[index];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private get name(): AbstractControl | null {
|
||||
return this.form.get('name');
|
||||
}
|
||||
@ -298,4 +324,12 @@ export class ProviderSamlSpComponent {
|
||||
private get withSignedRequest(): AbstractControl | null {
|
||||
return this.form.get('withSignedRequest');
|
||||
}
|
||||
|
||||
private get nameIDFormat(): AbstractControl | null {
|
||||
return this.form.get('nameIdFormat');
|
||||
}
|
||||
|
||||
private get transientMapping(): AbstractControl | null {
|
||||
return this.form.get('transientMappingAttributeName');
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,7 @@
|
||||
|
||||
.formfield {
|
||||
display: block;
|
||||
max-width: 400px;
|
||||
max-width: 500px;
|
||||
|
||||
&.pwd {
|
||||
display: none;
|
||||
@ -132,7 +132,7 @@
|
||||
}
|
||||
|
||||
.string-list-component-wrapper {
|
||||
max-width: 400px;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
.identity-provider-content {
|
||||
@ -144,7 +144,7 @@
|
||||
}
|
||||
|
||||
.identity-provider-2-col {
|
||||
max-width: 400px;
|
||||
max-width: 500px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
column-gap: 1rem;
|
||||
@ -160,7 +160,7 @@
|
||||
.flex-line {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
max-width: 400px;
|
||||
max-width: 500px;
|
||||
|
||||
.formfield {
|
||||
flex: 1;
|
||||
|
@ -36,7 +36,7 @@ export const APPEARANCE_GROUP: SettingLinks = {
|
||||
};
|
||||
|
||||
export const PRIVACY_POLICY: SettingLinks = {
|
||||
i18nTitle: 'SETTINGS.LIST.PRIVACYPOLICY',
|
||||
i18nTitle: 'DESCRIPTIONS.SETTINGS.PRIVACY_POLICY.TITLE',
|
||||
i18nDesc: 'POLICY.PRIVACY_POLICY.DESCRIPTION',
|
||||
iamRouterLink: ['/settings'],
|
||||
orgRouterLink: ['/org-settings'],
|
||||
|
@ -187,7 +187,7 @@ export const LOGINTEXTS: SidenavSetting = {
|
||||
|
||||
export const PRIVACYPOLICY: SidenavSetting = {
|
||||
id: 'privacypolicy',
|
||||
i18nKey: 'SETTINGS.LIST.PRIVACYPOLICY',
|
||||
i18nKey: 'DESCRIPTIONS.SETTINGS.PRIVACY_POLICY.TITLE',
|
||||
groupI18nKey: 'SETTINGS.GROUPS.OTHER',
|
||||
requiredRoles: {
|
||||
[PolicyComponentServiceType.MGMT]: ['policy.read'],
|
||||
|
@ -2,7 +2,7 @@
|
||||
title="{{
|
||||
id ? ('SMTP.DETAIL.TITLE' | translate) : ('SMTP.CREATE.STEPS.TITLE' | translate: { value: providerDefaultSetting.name })
|
||||
}}"
|
||||
[createSteps]="2"
|
||||
[createSteps]="3"
|
||||
[currentCreateStep]="currentCreateStep"
|
||||
(closed)="close()"
|
||||
>
|
||||
@ -133,7 +133,7 @@
|
||||
class="create-button"
|
||||
color="primary"
|
||||
data-e2e="create-button"
|
||||
(click)="savePolicy()"
|
||||
(click)="savePolicy(stepper)"
|
||||
[disabled]="
|
||||
firstFormGroup.invalid || secondFormGroup.invalid || (['iam.policy.write'] | hasRole | async) === false
|
||||
"
|
||||
@ -143,6 +143,82 @@
|
||||
</div>
|
||||
</mat-step>
|
||||
|
||||
<mat-step [editable]="true">
|
||||
<form>
|
||||
<ng-template matStepLabel>{{ 'SMTP.CREATE.STEPS.NEXT_STEPS' | translate }}</ng-template>
|
||||
<cnsl-info-section *ngIf="!isActive">
|
||||
<div class="title-row">
|
||||
<div class="left">
|
||||
<h2 class="title">{{ 'SMTP.CREATE.STEPS.ACTIVATE.TITLE' | translate }}</h2>
|
||||
<div>
|
||||
<a
|
||||
mat-icon-button
|
||||
card-actions
|
||||
mat-icon-button
|
||||
href="https://zitadel.com/docs/guides/manage/console/default-settings#smtp"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<mat-icon class="next-icon">info_outline</mat-icon>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button
|
||||
color="primary"
|
||||
mat-raised-button
|
||||
class="continue-button"
|
||||
data-e2e="activate-button"
|
||||
(click)="activateSMTPConfig(); $event.stopPropagation()"
|
||||
>
|
||||
{{ 'ACTIONS.ACTIVATE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="cnsl-secondary-text description">{{ 'SMTP.CREATE.STEPS.ACTIVATE.DESCRIPTION' | translate }}</p>
|
||||
</cnsl-info-section>
|
||||
|
||||
<cnsl-info-section *ngIf="isActive">
|
||||
<div class="title-row">
|
||||
<div class="left">
|
||||
<h2 class="title">{{ 'SMTP.CREATE.STEPS.DEACTIVATE.TITLE' | translate }}</h2>
|
||||
<div>
|
||||
<a
|
||||
mat-icon-button
|
||||
card-actions
|
||||
mat-icon-button
|
||||
href="https://zitadel.com/docs/guides/manage/console/default-settings#smtp"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<mat-icon class="next-icon">info_outline</mat-icon>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button
|
||||
color="primary"
|
||||
mat-raised-button
|
||||
class="continue-button"
|
||||
data-e2e="deactivate-button"
|
||||
(click)="deactivateSMTPConfig(); $event.stopPropagation()"
|
||||
>
|
||||
{{ 'ACTIONS.DEACTIVATE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="cnsl-secondary-text description">{{ 'SMTP.CREATE.STEPS.DEACTIVATE.DESCRIPTION' | translate }}</p>
|
||||
</cnsl-info-section>
|
||||
|
||||
<div class="smtp-create-actions">
|
||||
<button mat-stroked-button matStepperPrevious class="bck-button">{{ 'ACTIONS.BACK' | translate }}</button>
|
||||
<button mat-raised-button class="create-button" color="primary" data-e2e="close-button" (click)="this.close()">
|
||||
{{ 'ACTIONS.CLOSE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</mat-step>
|
||||
|
||||
<ng-template matStepperIcon="edit">
|
||||
<mat-icon>check</mat-icon>
|
||||
</ng-template>
|
||||
|
@ -31,6 +31,8 @@ import {
|
||||
OutlookDefaultSettings,
|
||||
SendgridDefaultSettings,
|
||||
} from './known-smtp-providers-settings';
|
||||
import { MatStepper } from '@angular/material/stepper';
|
||||
import { SMTPConfigState } from 'src/app/proto/generated/zitadel/settings_pb';
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-smtp-provider',
|
||||
@ -48,7 +50,7 @@ export class SMTPProviderComponent {
|
||||
|
||||
public smtpLoading: boolean = false;
|
||||
public hasSMTPConfig: boolean = false;
|
||||
|
||||
public isActive: boolean = false;
|
||||
public updateClientSecret: boolean = false;
|
||||
|
||||
// stepper
|
||||
@ -166,6 +168,7 @@ export class SMTPProviderComponent {
|
||||
.then((data) => {
|
||||
this.smtpLoading = false;
|
||||
if (data.smtpConfig) {
|
||||
this.isActive = data.smtpConfig.state === SMTPConfigState.SMTP_CONFIG_ACTIVE;
|
||||
this.hasSMTPConfig = true;
|
||||
this.firstFormGroup.patchValue({
|
||||
['description']: data.smtpConfig.description,
|
||||
@ -188,7 +191,7 @@ export class SMTPProviderComponent {
|
||||
});
|
||||
}
|
||||
|
||||
private updateData(): Promise<UpdateSMTPConfigResponse.AsObject | AddSMTPConfigResponse> {
|
||||
private updateData(): Promise<UpdateSMTPConfigResponse.AsObject | AddSMTPConfigResponse.AsObject> {
|
||||
if (this.hasSMTPConfig) {
|
||||
const req = new UpdateSMTPConfigRequest();
|
||||
req.setId(this.id);
|
||||
@ -228,19 +231,49 @@ export class SMTPProviderComponent {
|
||||
}
|
||||
}
|
||||
|
||||
public savePolicy(): void {
|
||||
this.updateData()
|
||||
public activateSMTPConfig() {
|
||||
this.service
|
||||
.activateSMTPConfig(this.id)
|
||||
.then(() => {
|
||||
this.toast.showInfo('SMTP.LIST.DIALOG.ACTIVATED', true);
|
||||
this.isActive = true;
|
||||
})
|
||||
.catch((error) => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
|
||||
public deactivateSMTPConfig() {
|
||||
this.service
|
||||
.deactivateSMTPConfig(this.id)
|
||||
.then(() => {
|
||||
this.toast.showInfo('SMTP.LIST.DIALOG.DEACTIVATED', true);
|
||||
this.isActive = false;
|
||||
})
|
||||
.catch((error) => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
|
||||
public savePolicy(stepper: MatStepper): void {
|
||||
this.updateData()
|
||||
.then((resp) => {
|
||||
if (!this.id) {
|
||||
// This is a new SMTP provider let's get the ID from the addSMTPConfig response
|
||||
let createResponse = resp as AddSMTPConfigResponse.AsObject;
|
||||
this.id = createResponse.id;
|
||||
}
|
||||
|
||||
this.toast.showInfo('SETTING.SMTP.SAVED', true);
|
||||
setTimeout(() => {
|
||||
this.close();
|
||||
stepper.next();
|
||||
}, 2000);
|
||||
})
|
||||
.catch((error: unknown) => {
|
||||
if (`${error}`.includes('No changes')) {
|
||||
this.toast.showInfo('SETTING.SMTP.NOCHANGES', true);
|
||||
setTimeout(() => {
|
||||
this.close();
|
||||
stepper.next();
|
||||
}, 2000);
|
||||
} else {
|
||||
this.toast.showError(error);
|
||||
|
@ -68,4 +68,32 @@
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.title-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.right {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 1.2rem 0;
|
||||
}
|
||||
|
||||
.next-icon {
|
||||
font-size: 1.2rem;
|
||||
height: 1.2rem;
|
||||
width: 1.2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,10 @@ export class AuthenticationService {
|
||||
return from(this.oauthService.loadUserProfile());
|
||||
}
|
||||
|
||||
public getIdToken(): string {
|
||||
return this.oauthService.getIdToken();
|
||||
}
|
||||
|
||||
public async authenticate(partialConfig?: Partial<AuthConfig>, force: boolean = false): Promise<boolean> {
|
||||
if (partialConfig) {
|
||||
Object.assign(this.authConfig, partialConfig);
|
||||
|
@ -27,7 +27,6 @@ import {
|
||||
GetMyPhoneRequest,
|
||||
GetMyPhoneResponse,
|
||||
GetMyPrivacyPolicyRequest,
|
||||
GetMyPrivacyPolicyResponse,
|
||||
GetMyProfileRequest,
|
||||
GetMyProfileResponse,
|
||||
GetMyUserRequest,
|
||||
@ -99,11 +98,10 @@ import { ChangeQuery } from '../proto/generated/zitadel/change_pb';
|
||||
import { MetadataQuery } from '../proto/generated/zitadel/metadata_pb';
|
||||
import { ListQuery } from '../proto/generated/zitadel/object_pb';
|
||||
import { Org, OrgFieldName, OrgQuery } from '../proto/generated/zitadel/org_pb';
|
||||
import { LabelPolicy } from '../proto/generated/zitadel/policy_pb';
|
||||
import { LabelPolicy, PrivacyPolicy } from '../proto/generated/zitadel/policy_pb';
|
||||
import { Gender, MembershipQuery, User, WebAuthNVerification } from '../proto/generated/zitadel/user_pb';
|
||||
import { GrpcService } from './grpc.service';
|
||||
import { StorageKey, StorageLocation, StorageService } from './storage.service';
|
||||
import { ThemeService } from './theme.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
@ -137,11 +135,18 @@ export class GrpcAuthService {
|
||||
>(undefined);
|
||||
labelPolicyLoading$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
|
||||
|
||||
public privacypolicy$!: Observable<PrivacyPolicy.AsObject>;
|
||||
public privacypolicy: BehaviorSubject<PrivacyPolicy.AsObject | undefined> = new BehaviorSubject<
|
||||
PrivacyPolicy.AsObject | undefined
|
||||
>(undefined);
|
||||
privacyPolicyLoading$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
|
||||
|
||||
public zitadelPermissions: BehaviorSubject<string[]> = new BehaviorSubject<string[]>([]);
|
||||
public readonly fetchedZitadelPermissions: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
||||
|
||||
public cachedOrgs: BehaviorSubject<Org.AsObject[]> = new BehaviorSubject<Org.AsObject[]>([]);
|
||||
private cachedLabelPolicies: { [orgId: string]: LabelPolicy.AsObject } = {};
|
||||
private cachedPrivacyPolicies: { [orgId: string]: PrivacyPolicy.AsObject } = {};
|
||||
|
||||
constructor(
|
||||
private readonly grpcService: GrpcService,
|
||||
@ -169,6 +174,25 @@ export class GrpcAuthService {
|
||||
},
|
||||
});
|
||||
|
||||
this.privacypolicy$ = this.activeOrgChanged.pipe(
|
||||
switchMap((org) => {
|
||||
this.privacyPolicyLoading$.next(true);
|
||||
return from(this.getMyPrivacyPolicy(org ? org.id : ''));
|
||||
}),
|
||||
filter((policy) => !!policy),
|
||||
);
|
||||
|
||||
this.privacypolicy$.subscribe({
|
||||
next: (policy) => {
|
||||
this.privacypolicy.next(policy);
|
||||
this.privacyPolicyLoading$.next(false);
|
||||
},
|
||||
error: (error) => {
|
||||
console.error(error);
|
||||
this.privacyPolicyLoading$.next(false);
|
||||
},
|
||||
});
|
||||
|
||||
this.user = forkJoin([
|
||||
of(this.oauthService.getAccessToken()),
|
||||
this.oauthService.events.pipe(
|
||||
@ -394,9 +418,12 @@ export class GrpcAuthService {
|
||||
if (queryList) {
|
||||
req.setQueriesList(queryList);
|
||||
}
|
||||
// if (sortingColumn) {
|
||||
// req.setSortingColumn(sortingColumn);
|
||||
// }
|
||||
if (sortingDirection) {
|
||||
query.setAsc(sortingDirection === 'asc');
|
||||
}
|
||||
if (sortingColumn) {
|
||||
req.setSortingColumn(sortingColumn);
|
||||
}
|
||||
|
||||
req.setQuery(query);
|
||||
|
||||
@ -697,7 +724,23 @@ export class GrpcAuthService {
|
||||
}
|
||||
}
|
||||
|
||||
public getMyPrivacyPolicy(): Promise<GetMyPrivacyPolicyResponse.AsObject> {
|
||||
return this.grpcService.auth.getMyPrivacyPolicy(new GetMyPrivacyPolicyRequest(), null).then((resp) => resp.toObject());
|
||||
public getMyPrivacyPolicy(orgIdForCache?: string): Promise<PrivacyPolicy.AsObject> {
|
||||
if (orgIdForCache && this.cachedPrivacyPolicies[orgIdForCache]) {
|
||||
return Promise.resolve(this.cachedPrivacyPolicies[orgIdForCache]);
|
||||
} else {
|
||||
return this.grpcService.auth
|
||||
.getMyPrivacyPolicy(new GetMyPrivacyPolicyRequest(), null)
|
||||
.then((resp) => resp.toObject())
|
||||
.then((resp) => {
|
||||
if (resp.policy) {
|
||||
if (orgIdForCache) {
|
||||
this.cachedPrivacyPolicies[orgIdForCache] = resp.policy;
|
||||
}
|
||||
return Promise.resolve(resp.policy);
|
||||
} else {
|
||||
return Promise.reject();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import { I18nInterceptor } from './interceptors/i18n.interceptor';
|
||||
import { OrgInterceptor } from './interceptors/org.interceptor';
|
||||
import { StorageService } from './storage.service';
|
||||
import { FeatureServiceClient } from '../proto/generated/zitadel/feature/v2beta/Feature_serviceServiceClientPb';
|
||||
import { GrpcAuthService } from './grpc-auth.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
|
@ -2,11 +2,13 @@ import { Injectable } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { Request, UnaryInterceptor, UnaryResponse } from 'grpc-web';
|
||||
import { Subject } from 'rxjs';
|
||||
import { debounceTime, filter, first, take } from 'rxjs/operators';
|
||||
import { debounceTime, filter, first, map, take, tap } from 'rxjs/operators';
|
||||
import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component';
|
||||
|
||||
import { AuthenticationService } from '../authentication.service';
|
||||
import { StorageService } from '../storage.service';
|
||||
import { AuthConfig } from 'angular-oauth2-oidc';
|
||||
import { GrpcAuthService } from '../grpc-auth.service';
|
||||
|
||||
const authorizationKey = 'Authorization';
|
||||
const bearerPrefix = 'Bearer';
|
||||
@ -44,7 +46,7 @@ export class AuthInterceptor<TReq = unknown, TResp = unknown> implements UnaryIn
|
||||
return response;
|
||||
})
|
||||
.catch(async (error: any) => {
|
||||
if (error.code === 16) {
|
||||
if (error.code === 16 || (error.code === 7 && error.message === 'mfa required (AUTHZ-Kl3p0)')) {
|
||||
this.triggerDialog.next(true);
|
||||
}
|
||||
return Promise.reject(error);
|
||||
@ -67,7 +69,13 @@ export class AuthInterceptor<TReq = unknown, TResp = unknown> implements UnaryIn
|
||||
.pipe(take(1))
|
||||
.subscribe((resp) => {
|
||||
if (resp) {
|
||||
this.authenticationService.authenticate(undefined, true);
|
||||
const idToken = this.authenticationService.getIdToken();
|
||||
const configWithPrompt: Partial<AuthConfig> = {
|
||||
customQueryParams: {
|
||||
id_token_hint: idToken,
|
||||
},
|
||||
};
|
||||
this.authenticationService.authenticate(configWithPrompt, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -129,7 +129,7 @@
|
||||
},
|
||||
"PRIVACY_POLICY": {
|
||||
"TITLE": "Външни връзки",
|
||||
"DESCRIPTION": "Насочете вашите потребители към персонализирани външни ресурси, показани на страницата за вход. Потребителите трябва да приемат Условията за ползване и Политиката за поверителност, преди да могат да се регистрират."
|
||||
"DESCRIPTION": "Насочете потребителите си към персонализирани външни ресурси, показани на страницата за вход. Потребителите трябва да приемат Общите условия и Политиката за поверителност, преди да могат да се регистрират. Променете връзката към вашата документация или задайте празен низ, за да скриете бутона за документация от конзолата. Добавете персонализирана външна връзка и персонализиран текст за тази връзка в конзолата или ги оставете празни, за да скриете този бутон."
|
||||
},
|
||||
"SMTP_PROVIDER": {
|
||||
"TITLE": "Настройки на SMTP",
|
||||
@ -588,6 +588,7 @@
|
||||
"INVALID_FORMAT": "Форматирането е невалидно.",
|
||||
"NOTANEMAIL": "Дадената стойност не е имейл адрес.",
|
||||
"MINLENGTH": "Трябва да е поне {{requiredLength}} знака дълги.",
|
||||
"MAXLENGTH": "Трябва да е по-малко от {{requiredLength}} символа",
|
||||
"UPPERCASEMISSING": "Трябва да включва главна буква.",
|
||||
"LOWERCASEMISSING": "Трябва да включва малка буква.",
|
||||
"SYMBOLERROR": "Трябва да включва символ или препинателен знак.",
|
||||
@ -873,7 +874,8 @@
|
||||
"SET": "Задайте нова парола",
|
||||
"RESENDNOTIFICATION": "Изпратете връзка за повторно задаване на парола",
|
||||
"REQUIRED": "Някои задължителни полета липсват.",
|
||||
"MINLENGTHERROR": "Трябва да бъде поне {{value}} знака дълги."
|
||||
"MINLENGTHERROR": "Трябва да бъде поне {{value}} знака дълги.",
|
||||
"MAXLENGTHERROR": "Трябва да съдържа по-малко от {{value}} знака."
|
||||
},
|
||||
"ID": "документ за самоличност",
|
||||
"EMAIL": "Електронна поща",
|
||||
@ -1564,6 +1566,9 @@
|
||||
"POLICYLINK": "Връзка към Политика за поверителност",
|
||||
"HELPLINK": "Връзка към Помощ",
|
||||
"SUPPORTEMAIL": "Имейл за поддръжка",
|
||||
"DOCSLINK": "Връзка към документи (Console)",
|
||||
"CUSTOMLINK": "Персонализирана връзка (Console)",
|
||||
"CUSTOMLINKTEXT": "Персонализиран текст на връзката (Console)",
|
||||
"SAVED": "Запазено успешно!",
|
||||
"RESET_TITLE": "Възстановяване на стойностите по подразбиране",
|
||||
"RESET_DESCRIPTION": "На път сте да възстановите връзките по подразбиране за TOS и Политика за поверителност. "
|
||||
@ -2215,7 +2220,7 @@
|
||||
"SMTP": {
|
||||
"LIST": {
|
||||
"TITLE": "SMTP доставчик",
|
||||
"DESCRIPTION": "Това са SMTP доставчиците за вашето копие на Zitadel. Активирайте този, който искате да използвате, за да изпращате известия до вашите потребители.",
|
||||
"DESCRIPTION": "Това са SMTP доставчиците за вашето копие на ZITADEL. Активирайте този, който искате да използвате, за да изпращате известия до вашите потребители.",
|
||||
"EMPTY": "Няма наличен SMTP доставчик",
|
||||
"ACTIVATED": "Активиран",
|
||||
"ACTIVATE": "Активирайте доставчика",
|
||||
@ -2243,7 +2248,16 @@
|
||||
"CURRENT_DESC_TITLE": "Това са вашите SMTP настройки",
|
||||
"PROVIDER_SETTINGS": "Настройки на SMTP доставчик",
|
||||
"SENDER_SETTINGS": "Настройки на изпращача",
|
||||
"TEST_SETTINGS": "Тествайте настройките на SMTP"
|
||||
"TEST_SETTINGS": "Тествайте настройките на SMTP",
|
||||
"NEXT_STEPS": "Следващи стъпки",
|
||||
"ACTIVATE": {
|
||||
"TITLE": "Активирайте вашия SMTP доставчик",
|
||||
"DESCRIPTION": "ZITADEL не може да използва този SMTP доставчик за изпращане на известия, докато не го активирате. Ако активирате този доставчик, всеки друг доставчик, който е бил активен, сега ще бъде деактивиран."
|
||||
},
|
||||
"DEACTIVATE": {
|
||||
"TITLE": "Деактивирайте вашия SMTP доставчик",
|
||||
"DESCRIPTION": "Ако деактивирате този SMTP доставчик, ZITADEL не може да го използва за изпращане на известия, докато не го активирате отново."
|
||||
}
|
||||
}
|
||||
},
|
||||
"DETAIL": {
|
||||
|
@ -129,7 +129,7 @@
|
||||
},
|
||||
"PRIVACY_POLICY": {
|
||||
"TITLE": "Externí odkazy",
|
||||
"DESCRIPTION": "Navede vaše uživatele k vlastním externím zdrojům zobrazeným na přihlašovací stránce. Uživatelé musí přijmout Podmínky služby a Zásady ochrany osobních údajů, než se mohou zaregistrovat."
|
||||
"DESCRIPTION": "Naveďte své uživatele k vlastním externím zdrojům zobrazeným na přihlašovací stránce. Než se uživatelé mohou zaregistrovat, musí přijmout podmínky služby a zásady ochrany osobních údajů. Změňte odkaz na dokumentaci nebo nastavte prázdný řetězec, abyste skryli tlačítko dokumentace z konzoly. Přidejte vlastní externí odkaz a vlastní text pro tento odkaz v konzole nebo je nastavte na prázdné, abyste toto tlačítko skryli."
|
||||
},
|
||||
"SMTP_PROVIDER": {
|
||||
"TITLE": "Nastavení SMTP",
|
||||
@ -595,6 +595,7 @@
|
||||
"INVALID_FORMAT": "Formát je neplatný.",
|
||||
"NOTANEMAIL": "Zadaná hodnota není e-mailová adresa.",
|
||||
"MINLENGTH": "Musí být dlouhé alespoň {{requiredLength}} znaků.",
|
||||
"MAXLENGTH": "Musí být kratší než {{requiredLength}} znaků",
|
||||
"UPPERCASEMISSING": "Musí obsahovat velké písmeno.",
|
||||
"LOWERCASEMISSING": "Musí obsahovat malé písmeno.",
|
||||
"SYMBOLERROR": "Musí obsahovat symbol nebo interpunkční znaménko.",
|
||||
@ -880,7 +881,8 @@
|
||||
"SET": "Nastavit nové heslo",
|
||||
"RESENDNOTIFICATION": "Odeslat odkaz pro reset hesla",
|
||||
"REQUIRED": "Některá povinná pole nejsou vyplněna.",
|
||||
"MINLENGTHERROR": "Musí být alespoň {{value}} znaků dlouhé."
|
||||
"MINLENGTHERROR": "Musí být alespoň {{value}} znaků dlouhé.",
|
||||
"MAXLENGTHERROR": "Musí být kratší než {{value}} znaků."
|
||||
},
|
||||
"ID": "ID",
|
||||
"EMAIL": "E-mail",
|
||||
@ -1571,6 +1573,9 @@
|
||||
"POLICYLINK": "Odkaz na Zásady ochrany osobních údajů",
|
||||
"HELPLINK": "Odkaz na pomoc",
|
||||
"SUPPORTEMAIL": "E-mailová podpora",
|
||||
"DOCSLINK": "Odkaz na Dokumenty (Console)",
|
||||
"CUSTOMLINK": "Vlastní odkaz (Console)",
|
||||
"CUSTOMLINKTEXT": "Text vlastního odkazu (Console)",
|
||||
"SAVED": "Úspěšně uloženo!",
|
||||
"RESET_TITLE": "Obnovit výchozí hodnoty",
|
||||
"RESET_DESCRIPTION": "Chystáte se obnovit výchozí odkazy pro Podmínky služby a Zásady ochrany osobních údajů. Opravdu chcete pokračovat?"
|
||||
@ -2234,7 +2239,7 @@
|
||||
"SMTP": {
|
||||
"LIST": {
|
||||
"TITLE": "Poskytovatel SMTP",
|
||||
"DESCRIPTION": "Toto jsou poskytovatelé SMTP pro vaši instanci Zitadel. Aktivujte ten, který chcete používat k odesílání upozornění svým uživatelům.",
|
||||
"DESCRIPTION": "Toto jsou poskytovatelé SMTP pro vaši instanci ZITADEL. Aktivujte ten, který chcete používat k odesílání upozornění svým uživatelům.",
|
||||
"EMPTY": "Není k dispozici žádný poskytovatel SMTP",
|
||||
"ACTIVATED": "Aktivováno",
|
||||
"ACTIVATE": "Aktivujte poskytovatele",
|
||||
@ -2262,7 +2267,16 @@
|
||||
"CURRENT_DESC_TITLE": "Toto jsou vaše nastavení SMTP",
|
||||
"PROVIDER_SETTINGS": "Nastavení poskytovatele SMTP",
|
||||
"SENDER_SETTINGS": "Nastavení odesílatele",
|
||||
"TEST_SETTINGS": "Otestujte nastavení SMTP"
|
||||
"TEST_SETTINGS": "Otestujte nastavení SMTP",
|
||||
"NEXT_STEPS": "Další kroky",
|
||||
"ACTIVATE": {
|
||||
"TITLE": "Aktivujte svého poskytovatele SMTP",
|
||||
"DESCRIPTION": "ZITADEL nemůže používat tohoto poskytovatele SMTP k odesílání upozornění, dokud jej neaktivujete. Pokud aktivujete tohoto poskytovatele, jakýkoli jiný aktivní poskytovatel bude nyní deaktivován."
|
||||
},
|
||||
"DEACTIVATE": {
|
||||
"TITLE": "Deaktivujte svého poskytovatele SMTP",
|
||||
"DESCRIPTION": "Pokud deaktivujete tohoto poskytovatele SMTP, ZITADEL jej nebude moci používat k odesílání upozornění, dokud jej znovu neaktivujete."
|
||||
}
|
||||
}
|
||||
},
|
||||
"DETAIL": {
|
||||
|
@ -129,7 +129,7 @@
|
||||
},
|
||||
"PRIVACY_POLICY": {
|
||||
"TITLE": "Externe Links",
|
||||
"DESCRIPTION": "Leite deine Benutzer zu benutzerdefinierten externen Ressourcen, die auf der Anmeldeseite angezeigt werden. Benutzer müssen die Allgemeinen Geschäftsbedingungen und die Datenschutzrichtlinie akzeptieren, bevor sie sich anmelden können."
|
||||
"DESCRIPTION": "Leiten Sie Ihre Benutzer zu benutzerdefinierten externen Ressourcen, die auf der Anmeldeseite angezeigt werden. Benutzer müssen die Nutzungsbedingungen und Datenschutzrichtlinien akzeptieren, bevor sie sich anmelden können. Ändern Sie den Link zu Ihrer Dokumentation oder legen Sie eine leere Zeichenfolge fest, um die Dokumentationsschaltfläche in der Konsole auszublenden. Fügen Sie in der Konsole einen benutzerdefinierten externen Link und einen benutzerdefinierten Text für diesen Link hinzu oder setzen Sie sie leer, um diese Schaltfläche auszublenden."
|
||||
},
|
||||
"SMTP_PROVIDER": {
|
||||
"TITLE": "SMTP-Einstellungen",
|
||||
@ -594,6 +594,7 @@
|
||||
"INVALID_FORMAT": "Das Format is ungültig.",
|
||||
"NOTANEMAIL": "Der eingegebene Wert ist keine E-Mail Adresse.",
|
||||
"MINLENGTH": "Muss mindestens {{requiredLength}} Zeichen lang sein.",
|
||||
"MAXLENGTH": "Muss weniger als {{requiredLength}} Zeichen enthalten",
|
||||
"UPPERCASEMISSING": "Muss einen Grossbuchstaben beinhalten.",
|
||||
"LOWERCASEMISSING": "Muss einen Kleinbuchstaben beinhalten.",
|
||||
"SYMBOLERROR": "Muss ein Symbol/Satzzeichen beinhalten.",
|
||||
@ -879,7 +880,8 @@
|
||||
"SET": "Passwort neu setzen",
|
||||
"RESENDNOTIFICATION": "Email zum Zurücksetzen senden",
|
||||
"REQUIRED": "Bitte prüfe, dass alle notwendigen Felder ausgefüllt sind.",
|
||||
"MINLENGTHERROR": "Muss mindestens {{value}} Zeichen lang sein."
|
||||
"MINLENGTHERROR": "Muss mindestens {{value}} Zeichen lang sein.",
|
||||
"MAXLENGTHERROR": "Muss weniger als {{value}} Zeichen umfassen."
|
||||
},
|
||||
"ID": "ID",
|
||||
"EMAIL": "E-Mail",
|
||||
@ -1570,6 +1572,9 @@
|
||||
"POLICYLINK": "Link zur den Datenschutzrichtlinien",
|
||||
"HELPLINK": "Link zur Hilfestellung",
|
||||
"SUPPORTEMAIL": "Support E-Mail",
|
||||
"DOCSLINK": "Link zu Dokumenten (Console)",
|
||||
"CUSTOMLINK": "Benutzerdefinierter Link (Console)",
|
||||
"CUSTOMLINKTEXT": "Benutzerdefinierter Linktext (Console)",
|
||||
"SAVED": "Saved successfully!",
|
||||
"RESET_TITLE": "Standardwerte wiederherstellen",
|
||||
"RESET_DESCRIPTION": "Sie sind im Begriff die Standardlinks für die AGBs und Datenschutzrichtlinie wiederherzustellen. Wollen Sie fortfahren?"
|
||||
@ -2224,7 +2229,7 @@
|
||||
"SMTP": {
|
||||
"LIST": {
|
||||
"TITLE": "SMTP-Anbieter",
|
||||
"DESCRIPTION": "Dies sind die SMTP-Anbieter für Ihre Zitadel-Instanz. Aktivieren Sie diejenige, die Sie zum Senden von Benachrichtigungen an Ihre Benutzer verwenden möchten.",
|
||||
"DESCRIPTION": "Dies sind die SMTP-Anbieter für Ihre ZITADEL-Instanz. Aktivieren Sie diejenige, die Sie zum Senden von Benachrichtigungen an Ihre Benutzer verwenden möchten.",
|
||||
"EMPTY": "Kein SMTP-Anbieter verfügbar",
|
||||
"ACTIVATED": "Aktiviert",
|
||||
"ACTIVATE": "Anbieter aktivieren",
|
||||
@ -2252,7 +2257,16 @@
|
||||
"CURRENT_DESC_TITLE": "Dies sind Ihre SMTP-Einstellungen",
|
||||
"PROVIDER_SETTINGS": "SMTP-Anbietereinstellungen",
|
||||
"SENDER_SETTINGS": "Absendereinstellungen",
|
||||
"TEST_SETTINGS": "Testen Sie die SMTP-Einstellungen"
|
||||
"TEST_SETTINGS": "Testen Sie die SMTP-Einstellungen",
|
||||
"NEXT_STEPS": "Nächste Schritte",
|
||||
"ACTIVATE": {
|
||||
"TITLE": "Aktivieren Sie Ihren SMTP-Anbieter",
|
||||
"DESCRIPTION": "ZITADEL kann diesen SMTP-Anbieter nicht zum Senden von Benachrichtigungen verwenden, bis Sie ihn aktivieren. Wenn Sie diesen Anbieter aktivieren, werden alle anderen aktiven Anbieter nun deaktiviert."
|
||||
},
|
||||
"DEACTIVATE": {
|
||||
"TITLE": "Deaktivieren Sie Ihren SMTP-Anbieter",
|
||||
"DESCRIPTION": "Wenn Sie diesen SMTP-Anbieter deaktivieren, kann ZITADEL ihn nicht zum Versenden von Benachrichtigungen verwenden, bis Sie ihn erneut aktivieren."
|
||||
}
|
||||
}
|
||||
},
|
||||
"DETAIL": {
|
||||
|
@ -54,7 +54,7 @@
|
||||
},
|
||||
"MACHINES": {
|
||||
"TITLE": "Service Users",
|
||||
"DESCRIPTION": "Les utilisateurs du service s'authentifient de manière non interactive à l'aide d'un jeton de porteur JWT signé avec une clé privée. Ils peuvent également utiliser un jeton d'accès personnel.",
|
||||
"DESCRIPTION": "Service Users authenticate non-interactively using a JWT bearer token signed with a private key. They can also use a personal access token.",
|
||||
"METADATA": "Add custom attributes to the user like the authenticating system. You can use this information in your actions."
|
||||
},
|
||||
"SELF": {
|
||||
@ -129,7 +129,7 @@
|
||||
},
|
||||
"PRIVACY_POLICY": {
|
||||
"TITLE": "External Links",
|
||||
"DESCRIPTION": "Guide your users to custom external resources shown on the login page. Users need to accept the Terms of Service and Privacy Policy before they can sign up."
|
||||
"DESCRIPTION": "Guide your users to custom external resources shown on the login page. Users need to accept the Terms of Service and Privacy Policy before they can sign up. Change the link to your documentation or set an empty string to hide the documentation button from the console. Add a custom external link and a custom text for that link in the console, or set them empty to hide that button."
|
||||
},
|
||||
"SMTP_PROVIDER": {
|
||||
"TITLE": "SMTP Settings",
|
||||
@ -595,8 +595,9 @@
|
||||
"INVALID_FORMAT": "The formatting is invalid.",
|
||||
"NOTANEMAIL": "The given value is not an e-mail address.",
|
||||
"MINLENGTH": "Must be at least {{requiredLength}} characters long.",
|
||||
"UPPERCASEMISSING": "Must include an uppercase character.",
|
||||
"LOWERCASEMISSING": "Must include a lowercase character.",
|
||||
"MAXLENGTH": "Must be less than {{requiredLength}} characters.",
|
||||
"UPPERCASEMISSING": "Must include an uppercase letter.",
|
||||
"LOWERCASEMISSING": "Must include a lowercase letter.",
|
||||
"SYMBOLERROR": "Must include a symbol or punctuation mark.",
|
||||
"NUMBERERROR": "Must include a digit.",
|
||||
"PWNOTEQUAL": "The passwords provided do not match.",
|
||||
@ -880,7 +881,8 @@
|
||||
"SET": "Set New Password",
|
||||
"RESENDNOTIFICATION": "Send Password Reset Link",
|
||||
"REQUIRED": "Some required fields are missing.",
|
||||
"MINLENGTHERROR": "Has to be at least {{value}} characters long."
|
||||
"MINLENGTHERROR": "Must be at least {{value}} characters long.",
|
||||
"MAXLENGTHERROR": "Must be less than {{value}} characters."
|
||||
},
|
||||
"ID": "ID",
|
||||
"EMAIL": "E-mail",
|
||||
@ -1335,7 +1337,7 @@
|
||||
"DOMAIN": "Domain settings",
|
||||
"LOGINTEXTS": "Login Interface Texts",
|
||||
"BRANDING": "Branding",
|
||||
"PRIVACYPOLICY": "Privacy Policy",
|
||||
"PRIVACYPOLICY": "External links",
|
||||
"OIDC": "OIDC Token lifetime and expiration",
|
||||
"SECRETS": "Secret Generator",
|
||||
"SECURITY": "Security settings",
|
||||
@ -1571,6 +1573,9 @@
|
||||
"POLICYLINK": "Link to Privacy Policy",
|
||||
"HELPLINK": "Link to Help",
|
||||
"SUPPORTEMAIL": "Support Email",
|
||||
"DOCSLINK": "Docs Link (Console)",
|
||||
"CUSTOMLINK": "Custom Link (Console)",
|
||||
"CUSTOMLINKTEXT": "Custom Link Text (Console)",
|
||||
"SAVED": "Saved successfully!",
|
||||
"RESET_TITLE": "Restore Default Values",
|
||||
"RESET_DESCRIPTION": "You are about to restore the default Links for TOS and Privacy Policy. Do you really want to continue?"
|
||||
@ -2041,7 +2046,7 @@
|
||||
"DESCRIPTION": "Enter the credentials for your Apple Provider"
|
||||
},
|
||||
"SAML": {
|
||||
"TITLE": "Sign in with Saml SP",
|
||||
"TITLE": "Sign in with SAML SP",
|
||||
"DESCRIPTION": "Enter the credentials for your SAML Provider"
|
||||
}
|
||||
},
|
||||
@ -2174,7 +2179,10 @@
|
||||
"METADATAXML": "Metadata Xml",
|
||||
"METADATAURL": "Metadata URL",
|
||||
"BINDING": "Binding",
|
||||
"SIGNEDREQUEST": "Signed Request"
|
||||
"SIGNEDREQUEST": "Signed Request",
|
||||
"NAMEIDFORMAT": "NameID Format",
|
||||
"TRANSIENTMAPPINGATTRIBUTENAME": "Custom Mapping Attribute Name",
|
||||
"TRANSIENTMAPPINGATTRIBUTENAME_DESC": "Alternative attribute name to map the user in case the `nameid-format` returned is `transient`, e.g. `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress`"
|
||||
},
|
||||
"TOAST": {
|
||||
"SAVED": "Successfully saved.",
|
||||
@ -2243,7 +2251,7 @@
|
||||
"SMTP": {
|
||||
"LIST": {
|
||||
"TITLE": "SMTP Provider",
|
||||
"DESCRIPTION": "These are the SMTP providers for your Zitadel instance. Activate the one you want to use to send notifications to your users.",
|
||||
"DESCRIPTION": "These are the SMTP providers for your ZITADEL instance. Activate the one you want to use to send notifications to your users.",
|
||||
"EMPTY": "No SMTP Provider available",
|
||||
"ACTIVATED": "Activated",
|
||||
"ACTIVATE": "Activate provider",
|
||||
@ -2271,7 +2279,16 @@
|
||||
"CURRENT_DESC_TITLE": "These are your SMTP settings",
|
||||
"PROVIDER_SETTINGS": "SMTP Provider Settings",
|
||||
"SENDER_SETTINGS": "Sender Settings",
|
||||
"TEST_SETTINGS": "Test SMTP Settings"
|
||||
"TEST_SETTINGS": "Test SMTP Settings",
|
||||
"NEXT_STEPS": "Next Steps",
|
||||
"ACTIVATE": {
|
||||
"TITLE": "Activate your SMTP Provider",
|
||||
"DESCRIPTION": "ZITADEL cannot use this SMTP Provider to send notifications until you activate it. If you activate this provider any other provider that was active will now be deactivated."
|
||||
},
|
||||
"DEACTIVATE": {
|
||||
"TITLE": "Deactivate your SMTP Provider",
|
||||
"DESCRIPTION": "If you deactivate this SMTP Provider, ZITADEL cannot use it to send notifications until you activate it again."
|
||||
}
|
||||
}
|
||||
},
|
||||
"DETAIL": {
|
||||
|
@ -129,7 +129,7 @@
|
||||
},
|
||||
"PRIVACY_POLICY": {
|
||||
"TITLE": "Enlaces Externos",
|
||||
"DESCRIPTION": "Guía a tus usuarios hacia recursos externos personalizados mostrados en la página de inicio de sesión. Los usuarios necesitan aceptar los Términos de Servicio y la Política de Privacidad antes de que puedan registrarse."
|
||||
"DESCRIPTION": "Guía a tus usuarios a recursos externos personalizados que se muestran en la página de inicio de sesión. Los usuarios deben aceptar los Términos de servicio y la Política de privacidad antes de poder registrarse. Cambia el enlace a tu documentación o introduce una cadena de texto vacía para ocultar el botón de documentación de la consola. Agrega un enlace externo personalizado y un texto personalizado para dicho enlace en la consola, o déjalos vacíos para ocultar ese botón."
|
||||
},
|
||||
"SMTP_PROVIDER": {
|
||||
"TITLE": "Configuración de SMTP",
|
||||
@ -595,6 +595,7 @@
|
||||
"INVALID_FORMAT": "El formato no es valido.",
|
||||
"NOTANEMAIL": "El valor proporcionado no es una dirección de email.",
|
||||
"MINLENGTH": "Debe tener al menos {{requiredLength}} caracteres de longitud.",
|
||||
"MAXLENGTH": "Debe tener menos de {{requiredLength}} caracteres.",
|
||||
"UPPERCASEMISSING": "Debe incluir un carácter en mayúscula.",
|
||||
"LOWERCASEMISSING": "Debe incluir un carácter en minúscula.",
|
||||
"SYMBOLERROR": "Debe incluir un símbolo o un signo de puntuación.",
|
||||
@ -880,7 +881,8 @@
|
||||
"SET": "Establecer nueva contraseña",
|
||||
"RESENDNOTIFICATION": "Enviar enlace para restablecer la contraseña",
|
||||
"REQUIRED": "Faltan algunos campos requeridos.",
|
||||
"MINLENGTHERROR": "Debe tener al menos {{value}} caracteres de longitud."
|
||||
"MINLENGTHERROR": "Debe tener al menos {{value}} caracteres de longitud.",
|
||||
"MAXLENGTHERROR": "Debe tener menos de {{value}} caracteres"
|
||||
},
|
||||
"ID": "ID",
|
||||
"EMAIL": "Email",
|
||||
@ -1572,6 +1574,9 @@
|
||||
"POLICYLINK": "Enlace a Política de privacidad",
|
||||
"HELPLINK": "Enlace de ayuda",
|
||||
"SUPPORTEMAIL": "Email de soporte",
|
||||
"DOCSLINK": "Enlace de documentos (Console)",
|
||||
"CUSTOMLINK": "Enlace personalizado (Console)",
|
||||
"CUSTOMLINKTEXT": "Texto de enlace personalizado (Console)",
|
||||
"SAVED": "¡Se guardó con éxito!",
|
||||
"RESET_TITLE": "Restaurar valores por defecto",
|
||||
"RESET_DESCRIPTION": "Estás a punto de restaurar los enlaces por defecto para los TDS y la política de privacida. ¿Quieres continuar?"
|
||||
@ -2222,7 +2227,7 @@
|
||||
"SMTP": {
|
||||
"LIST": {
|
||||
"TITLE": "Proveedor SMTP",
|
||||
"DESCRIPTION": "Estos son los proveedores SMTP para tu instancia de Zitadel. Activa el que quieras utilizar para enviar notificaciones a tus usuarios.",
|
||||
"DESCRIPTION": "Estos son los proveedores SMTP para tu instancia de ZITADEL. Activa el que quieras utilizar para enviar notificaciones a tus usuarios.",
|
||||
"EMPTY": "No hay ningún proveedor SMTP disponible",
|
||||
"ACTIVATED": "Activado",
|
||||
"ACTIVATE": "Activar proveedor",
|
||||
@ -2250,7 +2255,16 @@
|
||||
"CURRENT_DESC_TITLE": "Estas son tus configuraciones SMTP",
|
||||
"PROVIDER_SETTINGS": "Configuración del proveedor SMTP",
|
||||
"SENDER_SETTINGS": "Configuración del remitente",
|
||||
"TEST_SETTINGS": "Probar la configuración SMTP"
|
||||
"TEST_SETTINGS": "Probar la configuración SMTP",
|
||||
"NEXT_STEPS": "Pŕoximos pasos",
|
||||
"ACTIVATE": {
|
||||
"TITLE": "Activa tu proveedor SMTP",
|
||||
"DESCRIPTION": "ZITADEL no puede usar este proveedor SMTP para enviar notificaciones hasta que lo actives. Si activas este proveedor cualquier otro proveedor que estuviera activado será desactivado ahora."
|
||||
},
|
||||
"DEACTIVATE": {
|
||||
"TITLE": "Desactiva tu proveedor SMTP",
|
||||
"DESCRIPTION": "Si desactivas este proveedor SMTP, ZITADEL no puede utilizarlo para enviar notificationes hasta que lo actives otra vez."
|
||||
}
|
||||
}
|
||||
},
|
||||
"DETAIL": {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -129,7 +129,7 @@
|
||||
},
|
||||
"PRIVACY_POLICY": {
|
||||
"TITLE": "Link Esterni",
|
||||
"DESCRIPTION": "Guida i tuoi utenti verso risorse esterne personalizzate mostrate nella pagina di login. Gli utenti devono accettare i Termini di Servizio e la Politica sulla Privacy prima che possano iscriversi."
|
||||
"DESCRIPTION": "Guida i tuoi utenti alle risorse esterne personalizzate mostrate nella pagina di accesso. Gli utenti devono accettare i Termini di servizio e l'Informativa sulla privacy prima di potersi registrare. Cambia il collegamento alla tua documentazione o imposta una stringa vuota per nascondere il pulsante della documentazione dalla console. Aggiungi un collegamento esterno personalizzato e un testo personalizzato per quel collegamento nella console oppure impostali vuoti per nascondere quel pulsante."
|
||||
},
|
||||
"SMTP_PROVIDER": {
|
||||
"TITLE": "Impostazioni SMTP",
|
||||
@ -593,6 +593,7 @@
|
||||
"INVALID_FORMAT": "Il formato non è valido.",
|
||||
"NOTANEMAIL": "Il valore dato non è un indirizzo e-mail.",
|
||||
"MINLENGTH": "Deve essere lunga almeno {{requiredLength}} caratteri.",
|
||||
"MAXLENGTH": "Deve contenere meno di {{requiredLength}} caratteri.",
|
||||
"UPPERCASEMISSING": "Deve includere un carattere maiuscolo.",
|
||||
"LOWERCASEMISSING": "Deve includere un carattere minuscolo.",
|
||||
"SYMBOLERROR": "Deve includere un simbolo o un segno di punteggiatura.",
|
||||
@ -878,7 +879,8 @@
|
||||
"SET": "Imposta nuova password",
|
||||
"RESENDNOTIFICATION": "Invia email per la reimpostazione",
|
||||
"REQUIRED": "Mancano alcuni campi obbligatori.",
|
||||
"MINLENGTHERROR": "Deve essere lunga almeno {{valore}} caratteri."
|
||||
"MINLENGTHERROR": "Deve essere lunga almeno {{valore}} caratteri.",
|
||||
"MAXLENGTHERROR": "Deve contenere meno di {{value}} caratteri"
|
||||
},
|
||||
"ID": "ID",
|
||||
"EMAIL": "E-mail",
|
||||
@ -1570,6 +1572,9 @@
|
||||
"POLICYLINK": "Link all'informativa sulla privacy",
|
||||
"HELPLINK": "link per l'aiuto",
|
||||
"SUPPORTEMAIL": "e-mail di supporto",
|
||||
"DOCSLINK": "Collegamento a Documenti (Console)",
|
||||
"CUSTOMLINK": "Collegamento personalizzato (Console)",
|
||||
"CUSTOMLINKTEXT": "Testo del collegamento personalizzato (Console)",
|
||||
"SAVED": "Salvato con successo!",
|
||||
"RESET_TITLE": "Ripristina i valori predefiniti",
|
||||
"RESET_DESCRIPTION": "Stai per ripristinare i link predefiniti per i TOS e l'informativa sulla privacy. Vuoi davvero continuare?"
|
||||
@ -2225,7 +2230,7 @@
|
||||
"SMTP": {
|
||||
"LIST": {
|
||||
"TITLE": "Fornitore SMTP",
|
||||
"DESCRIPTION": "Questi sono i provider SMTP per la tua istanza Zitadel. Attiva quello che desideri utilizzare per inviare notifiche ai tuoi utenti.",
|
||||
"DESCRIPTION": "Questi sono i provider SMTP per la tua istanza ZITADEL. Attiva quello che desideri utilizzare per inviare notifiche ai tuoi utenti.",
|
||||
"EMPTY": "Nessun provider SMTP disponibile",
|
||||
"ACTIVATED": "Attivato",
|
||||
"ACTIVATE": "Attiva fornitore",
|
||||
@ -2253,7 +2258,16 @@
|
||||
"CURRENT_DESC_TITLE": "Queste sono le tue impostazioni SMTP",
|
||||
"PROVIDER_SETTINGS": "Impostazioni del provider SMTP",
|
||||
"SENDER_SETTINGS": "Impostazioni mittente",
|
||||
"TEST_SETTINGS": "Testare le impostazioni SMTP"
|
||||
"TEST_SETTINGS": "Testare le impostazioni SMTP",
|
||||
"NEXT_STEPS": "Prossimi passi",
|
||||
"ACTIVATE": {
|
||||
"TITLE": "Attiva il tuo provider SMTP",
|
||||
"DESCRIPTION": "ZITADEL non può utilizzare questo provider SMTP per inviare notifiche finché non lo attivi. Se attivi questo fornitore, qualsiasi altro fornitore che era attivo verrà ora disattivato."
|
||||
},
|
||||
"DEACTIVATE": {
|
||||
"TITLE": "Disattiva il tuo provider SMTP",
|
||||
"DESCRIPTION": "Dopo aver disattivato l'archivio SMTP, la schermata non è disponibile per l'utente, il documento è nuovo e non è attivo."
|
||||
}
|
||||
}
|
||||
},
|
||||
"DETAIL": {
|
||||
|
@ -129,7 +129,7 @@
|
||||
},
|
||||
"PRIVACY_POLICY": {
|
||||
"TITLE": "外部リンク",
|
||||
"DESCRIPTION": "ログインページに表示されるカスタム外部リソースへのユーザーガイドです。ユーザーは、サインアップする前に利用規約とプライバシーポリシーを受け入れる必要があります。"
|
||||
"DESCRIPTION": "ログイン ページに表示されるカスタム外部リソースにユーザーを誘導します。ユーザーはサインアップする前に、サービス利用規約とプライバシー ポリシーに同意する必要があります。ドキュメントへのリンクを変更するか、空の文字列を設定してコンソールからドキュメント ボタンを非表示にします。カスタム外部リンクとそのリンクのカスタム テキストをコンソールに追加するか、それらを空に設定してそのボタンを非表示にします。"
|
||||
},
|
||||
"SMTP_PROVIDER": {
|
||||
"TITLE": "SMTP設定",
|
||||
@ -595,6 +595,7 @@
|
||||
"INVALID_FORMAT": "不正なフォーマットです",
|
||||
"NOTANEMAIL": "入力された値がメールアドレスではありません。",
|
||||
"MINLENGTH": "{{requiredLength}} 文字以上の文字列が必要です。",
|
||||
"MAXLENGTH": "{{requiredLength}}文字以下でなければなりません.",
|
||||
"UPPERCASEMISSING": "大文字を含める必要があります。",
|
||||
"LOWERCASEMISSING": "小文字を含める必要があります。",
|
||||
"SYMBOLERROR": "記号を含める必要があります。",
|
||||
@ -880,7 +881,8 @@
|
||||
"SET": "新しいパスワードを設定する",
|
||||
"RESENDNOTIFICATION": "パスワードリセットのリンクを送信する",
|
||||
"REQUIRED": "一部の必須項目が不足しています。",
|
||||
"MINLENGTHERROR": "最小で{{value}}文字の長さが必要です。"
|
||||
"MINLENGTHERROR": "最小で{{value}}文字の長さが必要です。",
|
||||
"MAXLENGTHERROR": "{{value}}文字以下でなければなりません"
|
||||
},
|
||||
"ID": "id",
|
||||
"EMAIL": "Eメール",
|
||||
@ -1566,6 +1568,10 @@
|
||||
"TOSLINK": "利用規約へのリンク",
|
||||
"POLICYLINK": "プライバシーポリシーへのリンク",
|
||||
"HELPLINK": "ヘルプへのリンク",
|
||||
"SUPPORTEMAIL": "サポートメール",
|
||||
"DOCSLINK": "ドキュメントリンク (Console)",
|
||||
"CUSTOMLINK": "カスタムリンク(Console)",
|
||||
"CUSTOMLINKTEXT": "カスタム リンク テキスト (Console)",
|
||||
"SAVED": "正常に保存されました!",
|
||||
"RESET_TITLE": "デフォルト値を復元する",
|
||||
"RESET_DESCRIPTION": "TOSおよびプライバシーポリシーのデフォルトリンクを復元しようとしています。本当によろしいですか?"
|
||||
@ -2216,7 +2222,7 @@
|
||||
"SMTP": {
|
||||
"LIST": {
|
||||
"TITLE": "SMTPプロバイダー",
|
||||
"DESCRIPTION": "これらは、Zitadel インスタンスの SMTP プロバイダーです。ユーザーに通知を送信するために使用するものをアクティブにします。",
|
||||
"DESCRIPTION": "これらは、ZITADEL インスタンスの SMTP プロバイダーです。ユーザーに通知を送信するために使用するものをアクティブにします。",
|
||||
"EMPTY": "使用可能な SMTP プロバイダーがありません",
|
||||
"ACTIVATED": "アクティブ化された",
|
||||
"ACTIVATE": "プロバイダーをアクティブ化する",
|
||||
@ -2244,7 +2250,16 @@
|
||||
"CURRENT_DESC_TITLE": "これらは SMTP 設定です",
|
||||
"PROVIDER_SETTINGS": "SMTPプロバイダーの設定",
|
||||
"SENDER_SETTINGS": "送信者の設定",
|
||||
"TEST_SETTINGS": "SMTP設定をテストする"
|
||||
"TEST_SETTINGS": "SMTP設定をテストする",
|
||||
"NEXT_STEPS": "次のステップ",
|
||||
"ACTIVATE": {
|
||||
"TITLE": "SMTP プロバイダーをアクティブ化する",
|
||||
"DESCRIPTION": "ZITADEL は、アクティブ化するまで、この SMTP プロバイダーを使用して通知を送信できません。このプロバイダーをアクティブ化すると、アクティブだった他のプロバイダーは非アクティブ化されます。"
|
||||
},
|
||||
"DEACTIVATE": {
|
||||
"TITLE": "SMTPプロバイダーを非アクティブ化します",
|
||||
"DESCRIPTION": "この SMTP プロバイダーを非アクティブ化すると、再度アクティブ化するまで、Zitadel はそれを使用して通知を送信できなくなります。"
|
||||
}
|
||||
}
|
||||
},
|
||||
"DETAIL": {
|
||||
|
@ -129,7 +129,7 @@
|
||||
},
|
||||
"PRIVACY_POLICY": {
|
||||
"TITLE": "Надворешни врски",
|
||||
"DESCRIPTION": "Упатете ги вашите корисници кон прилагодени надворешни ресурси прикажани на страницата за најава. Корисниците треба да ги прифатат условите за користење и политиката за приватност пред да се регистрираат."
|
||||
"DESCRIPTION": "Водете ги вашите корисници до сопствени надворешни ресурси прикажани на страницата за најавување. Корисниците треба да ги прифатат Условите за користење и Политиката за приватност пред да можат да се регистрираат. Променете ја врската до вашата документација или поставете празна низа за да го скриете копчето за документација од конзолата. Додајте приспособена надворешна врска и прилагоден текст за таа врска во конзолата или поставете ги празни за да го скриете тоа копче."
|
||||
},
|
||||
"SMTP_PROVIDER": {
|
||||
"TITLE": "SMTP поставки",
|
||||
@ -595,6 +595,7 @@
|
||||
"INVALID_FORMAT": "Невалиден формат.",
|
||||
"NOTANEMAIL": "Внесената вредност не е е-пошта.",
|
||||
"MINLENGTH": "Мора да биде најмалку {{requiredLength}} карактери долга.",
|
||||
"MAXLENGTH": "Мора да биде помалку од {{requiredLength}} карактери.",
|
||||
"UPPERCASEMISSING": "Мора да содржи голема буква.",
|
||||
"LOWERCASEMISSING": "Мора да содржи мала буква.",
|
||||
"SYMBOLERROR": "Мора да содржи симбол или знак за интерпункција.",
|
||||
@ -880,7 +881,8 @@
|
||||
"SET": "Постави нова лозинка",
|
||||
"RESENDNOTIFICATION": "Испрати линк за ресетирање на лозинката",
|
||||
"REQUIRED": "Некои задолжителни полиња не се пополнети.",
|
||||
"MINLENGTHERROR": "Мора да биде најмалку {{value}} карактери долга."
|
||||
"MINLENGTHERROR": "Мора да биде најмалку {{value}} карактери долга.",
|
||||
"MAXLENGTHERROR": "Мора да биде помалку од {{value}} карактери"
|
||||
},
|
||||
"ID": "ID",
|
||||
"EMAIL": "E-пошта",
|
||||
@ -1572,6 +1574,9 @@
|
||||
"POLICYLINK": "Линк кон Политиката за приватност",
|
||||
"HELPLINK": "Линк кон Помош",
|
||||
"SUPPORTEMAIL": "Е-пошта за поддршка",
|
||||
"DOCSLINK": "Врска за документи (Console)",
|
||||
"CUSTOMLINK": "Прилагодена врска (Console)",
|
||||
"CUSTOMLINKTEXT": "Текст за приспособена врска (Console)",
|
||||
"SAVED": "Успешно зачувано!",
|
||||
"RESET_TITLE": "Врати на стандардни вредности",
|
||||
"RESET_DESCRIPTION": "Се подготвувате да ги вратите стандардните линкови за Условите за користење и Политиката за приватност. Дали сте сигурни дека сакате да продолжите?"
|
||||
@ -2222,7 +2227,7 @@
|
||||
"SMTP": {
|
||||
"LIST": {
|
||||
"TITLE": "SMTP провајдер",
|
||||
"DESCRIPTION": "Ова се давателите на SMTP за вашиот пример Zitadel. Активирајте го оној што сакате да го користите за испраќање известувања до вашите корисници.",
|
||||
"DESCRIPTION": "Ова се давателите на SMTP за вашиот пример ZITADEL. Активирајте го оној што сакате да го користите за испраќање известувања до вашите корисници.",
|
||||
"EMPTY": "Нема достапен SMTP провајдер",
|
||||
"ACTIVATED": "Активиран",
|
||||
"ACTIVATE": "Активирајте го провајдерот",
|
||||
@ -2250,7 +2255,16 @@
|
||||
"CURRENT_DESC_TITLE": "Ова се вашите поставки за SMTP",
|
||||
"PROVIDER_SETTINGS": "Поставки на провајдерот SMTP",
|
||||
"SENDER_SETTINGS": "Поставки на испраќачот",
|
||||
"TEST_SETTINGS": "Тестирајте ги поставките за SMTP"
|
||||
"TEST_SETTINGS": "Тестирајте ги поставките за SMTP",
|
||||
"NEXT_STEPS": "Следните чекори",
|
||||
"ACTIVATE": {
|
||||
"TITLE": "Активирајте го вашиот SMTP провајдер",
|
||||
"DESCRIPTION": "ZITADEL не може да го користи овој SMTP провајдер за да испраќа известувања додека не го активирате. Ако го активирате овој добавувач, секој друг провајдер што бил активен сега ќе се деактивира."
|
||||
},
|
||||
"DEACTIVATE": {
|
||||
"TITLE": "Деактивирајте го вашиот SMTP провајдер",
|
||||
"DESCRIPTION": "Ако го деактивирате овој SMTP провајдер, ZITADEL не може да го користи за испраќање известувања додека не го активирате повторно."
|
||||
}
|
||||
}
|
||||
},
|
||||
"DETAIL": {
|
||||
|
@ -129,7 +129,7 @@
|
||||
},
|
||||
"PRIVACY_POLICY": {
|
||||
"TITLE": "Externe links",
|
||||
"DESCRIPTION": "Leid je gebruikers naar aangepaste externe bronnen die worden getoond op de inlogpagina. Gebruikers moeten de Algemene Voorwaarden en het Privacybeleid accepteren voordat ze zich kunnen aanmelden."
|
||||
"DESCRIPTION": "Leid uw gebruikers naar aangepaste externe bronnen die op de inlogpagina worden weergegeven. Gebruikers moeten de Servicevoorwaarden en het Privacybeleid accepteren voordat ze zich kunnen aanmelden. Wijzig de link naar uw documentatie of stel een lege string in om de documentatieknop voor de console te verbergen. Voeg een aangepaste externe link en een aangepaste tekst voor die link toe in de console, of stel ze leeg om die knop te verbergen."
|
||||
},
|
||||
"SMTP_PROVIDER": {
|
||||
"TITLE": "SMTP-instellingen",
|
||||
@ -595,6 +595,7 @@
|
||||
"INVALID_FORMAT": "De opmaak is ongeldig.",
|
||||
"NOTANEMAIL": "De opgegeven waarde is geen e-mailadres.",
|
||||
"MINLENGTH": "Moet minimaal {{requiredLength}} tekens lang zijn.",
|
||||
"MAXLENGTH": "Moet minder dan {{requiredLength}} tekens bevatten.",
|
||||
"UPPERCASEMISSING": "Moet een hoofdletter bevatten.",
|
||||
"LOWERCASEMISSING": "Moet een kleine letter bevatten.",
|
||||
"SYMBOLERROR": "Moet een symbool of leesteken bevatten.",
|
||||
@ -880,7 +881,8 @@
|
||||
"SET": "Stel nieuw wachtwoord in",
|
||||
"RESENDNOTIFICATION": "Stuur wachtwoord reset link",
|
||||
"REQUIRED": "Sommige verplichte velden ontbreken.",
|
||||
"MINLENGTHERROR": "Moet minstens {{value}} tekens lang zijn."
|
||||
"MINLENGTHERROR": "Moet minstens {{value}} tekens lang zijn.",
|
||||
"MAXLENGTHERROR": "Moet minder dan {{value}} tekens bevatten"
|
||||
},
|
||||
"ID": "ID",
|
||||
"EMAIL": "E-mail",
|
||||
@ -1571,6 +1573,9 @@
|
||||
"POLICYLINK": "Link naar Privacybeleid",
|
||||
"HELPLINK": "Link naar Help",
|
||||
"SUPPORTEMAIL": "Ondersteuning Email",
|
||||
"DOCSLINK": "Documentenlink (Console)",
|
||||
"CUSTOMLINK": "Aangepaste link (Console)",
|
||||
"CUSTOMLINKTEXT": "Aangepaste linktekst (Console)",
|
||||
"SAVED": "Succesvol opgeslagen!",
|
||||
"RESET_TITLE": "Herstel Standaard Waarden",
|
||||
"RESET_DESCRIPTION": "U staat op het punt de standaard Links voor TOS en Privacybeleid te herstellen. Weet u zeker dat u wilt doorgaan?"
|
||||
@ -2041,7 +2046,7 @@
|
||||
"DESCRIPTION": "Voer de inloggegevens in voor uw Apple Provider"
|
||||
},
|
||||
"SAML": {
|
||||
"TITLE": "Log in met Saml SP",
|
||||
"TITLE": "Log in met SAML SP",
|
||||
"DESCRIPTION": "Voer de inloggegevens in voor uw SAML Provider"
|
||||
}
|
||||
},
|
||||
@ -2243,7 +2248,7 @@
|
||||
"SMTP": {
|
||||
"LIST": {
|
||||
"TITLE": "SMTP-provider",
|
||||
"DESCRIPTION": "Dit zijn de SMTP-providers voor uw Zitadel-instantie. Activeer degene die u wilt gebruiken om meldingen naar uw gebruikers te sturen.",
|
||||
"DESCRIPTION": "Dit zijn de SMTP-providers voor uw ZITADEL-instantie. Activeer degene die u wilt gebruiken om meldingen naar uw gebruikers te sturen.",
|
||||
"EMPTY": "Geen SMTP-provider beschikbaar",
|
||||
"ACTIVATED": "Geactiveerd",
|
||||
"ACTIVATE": "Aanbieder activeren",
|
||||
@ -2271,7 +2276,16 @@
|
||||
"CURRENT_DESC_TITLE": "Dit zijn uw SMTP-instellingen",
|
||||
"PROVIDER_SETTINGS": "SMTP-providerinstellingen",
|
||||
"SENDER_SETTINGS": "Afzenderinstellingen",
|
||||
"TEST_SETTINGS": "SMTP-instellingen testen"
|
||||
"TEST_SETTINGS": "SMTP-instellingen testen",
|
||||
"NEXT_STEPS": "Volgende stappen",
|
||||
"ACTIVATE": {
|
||||
"TITLE": "Activeer uw SMTP-provider",
|
||||
"DESCRIPTION": "ZITADEL kan deze SMTP-provider niet gebruiken om meldingen te verzenden totdat u deze activeert. Als u deze provider activeert, worden alle andere actieve providers nu gedeactiveerd."
|
||||
},
|
||||
"DEACTIVATE": {
|
||||
"TITLE": "Deactiveer uw SMTP-provider",
|
||||
"DESCRIPTION": "Als u deze SMTP-provider deactiveert, kan ZITADEL deze niet gebruiken om meldingen te verzenden totdat u deze opnieuw activeert."
|
||||
}
|
||||
}
|
||||
},
|
||||
"DETAIL": {
|
||||
|
@ -129,7 +129,7 @@
|
||||
},
|
||||
"PRIVACY_POLICY": {
|
||||
"TITLE": "Linki zewnętrzne",
|
||||
"DESCRIPTION": "Przekieruj użytkowników do niestandardowych zasobów zewnętrznych pokazanych na stronie logowania. Użytkownicy muszą zaakceptować Warunki korzystania z usługi i Politykę prywatności, zanim będą mogli się zarejestrować."
|
||||
"DESCRIPTION": "Poprowadź użytkowników do niestandardowych zasobów zewnętrznych wyświetlanych na stronie logowania. Użytkownicy muszą zaakceptować Warunki świadczenia usług i Politykę prywatności, zanim będą mogli się zarejestrować. Zmień łącze do dokumentacji lub ustaw pusty ciąg, aby ukryć przycisk dokumentacji w konsoli. Dodaj niestandardowy link zewnętrzny i niestandardowy tekst dla tego łącza w konsoli lub ustaw je puste, aby ukryć ten przycisk."
|
||||
},
|
||||
"SMTP_PROVIDER": {
|
||||
"TITLE": "Ustawienia SMTP",
|
||||
@ -594,6 +594,7 @@
|
||||
"INVALID_FORMAT": "Format jest nieprawidłowy.",
|
||||
"NOTANEMAIL": "Podana wartość nie jest adresem e-mail.",
|
||||
"MINLENGTH": "Musi mieć co najmniej {{requiredLength}} znaków.",
|
||||
"MAXLENGTH": "Musi zawierać mniej niż {{requiredLength}} znaków.",
|
||||
"UPPERCASEMISSING": "Musi zawierać wielką literę.",
|
||||
"LOWERCASEMISSING": "Musi zawierać małą literę.",
|
||||
"SYMBOLERROR": "Musi zawierać symbol lub znak interpunkcyjny.",
|
||||
@ -879,7 +880,8 @@
|
||||
"SET": "Ustaw nowe hasło",
|
||||
"RESENDNOTIFICATION": "Wyślij link resetowania hasła",
|
||||
"REQUIRED": "Brakuje niektórych wymaganych pól.",
|
||||
"MINLENGTHERROR": "Musi mieć co najmniej {{value}} znaków."
|
||||
"MINLENGTHERROR": "Musi mieć co najmniej {{value}} znaków.",
|
||||
"MAXLENGTHERROR": "Musi zawierać mniej niż {{value}} znaków"
|
||||
},
|
||||
"ID": "ID",
|
||||
"EMAIL": "E-mail",
|
||||
@ -1570,6 +1572,9 @@
|
||||
"POLICYLINK": "Link do polityki prywatności",
|
||||
"HELPLINK": "Link do pomocy",
|
||||
"SUPPORTEMAIL": "E-mail wsparcia",
|
||||
"DOCSLINK": "Link do Dokumentów (Console)",
|
||||
"CUSTOMLINK": "Link niestandardowy (Console)",
|
||||
"CUSTOMLINKTEXT": "Niestandardowy tekst łącza (Console)",
|
||||
"SAVED": "Pomyślnie zapisano!",
|
||||
"RESET_TITLE": "Przywróć wartości domyślne",
|
||||
"RESET_DESCRIPTION": "Masz zamiar przywrócić domyślne linki dla TOS i polityki prywatności. Czy na pewno chcesz kontynuować?"
|
||||
@ -2225,7 +2230,7 @@
|
||||
"SMTP": {
|
||||
"LIST": {
|
||||
"TITLE": "Dostawca SMTP",
|
||||
"DESCRIPTION": "To są dostawcy SMTP dla Twojej instancji Zitadel. Aktywuj ten, którego chcesz używać do wysyłania powiadomień do użytkowników.",
|
||||
"DESCRIPTION": "To są dostawcy SMTP dla Twojej instancji ZITADEL. Aktywuj ten, którego chcesz używać do wysyłania powiadomień do użytkowników.",
|
||||
"EMPTY": "Brak dostępnego dostawcy SMTP",
|
||||
"ACTIVATED": "Aktywowany",
|
||||
"ACTIVATE": "Aktywuj dostawcę",
|
||||
@ -2253,7 +2258,16 @@
|
||||
"CURRENT_DESC_TITLE": "To są Twoje ustawienia SMTP",
|
||||
"PROVIDER_SETTINGS": "Ustawienia dostawcy SMTP",
|
||||
"SENDER_SETTINGS": "Ustawienia nadawcy",
|
||||
"TEST_SETTINGS": "Przetestuj ustawienia SMTP"
|
||||
"TEST_SETTINGS": "Przetestuj ustawienia SMTP",
|
||||
"NEXT_STEPS": "Następne kroki",
|
||||
"ACTIVATE": {
|
||||
"TITLE": "Aktywuj swojego dostawcę SMTP",
|
||||
"DESCRIPTION": "ZITADEL nie może używać tego dostawcy SMTP do wysyłania powiadomień, dopóki go nie aktywujesz. Jeśli aktywujesz tego dostawcę, każdy inny aktywny dostawca zostanie teraz dezaktywowany."
|
||||
},
|
||||
"DEACTIVATE": {
|
||||
"TITLE": "Dezaktywuj swojego dostawcę SMTP",
|
||||
"DESCRIPTION": "Jeśli dezaktywujesz tego dostawcę SMTP, ZITADEL nie będzie mógł go używać do wysyłania powiadomień, dopóki nie aktywujesz go ponownie."
|
||||
}
|
||||
}
|
||||
},
|
||||
"DETAIL": {
|
||||
|
@ -129,7 +129,7 @@
|
||||
},
|
||||
"PRIVACY_POLICY": {
|
||||
"TITLE": "Links Externos",
|
||||
"DESCRIPTION": "Guie seus usuários para recursos externos personalizados mostrados na página de login. Os usuários precisam aceitar os Termos de Serviço e a Política de Privacidade antes de poderem se inscrever."
|
||||
"DESCRIPTION": "Oriente seus usuários sobre recursos externos personalizados mostrados na página de login. Os usuários precisam aceitar os Termos de Serviço e a Política de Privacidade antes de se inscreverem. Altere o link para sua documentação ou defina uma string vazia para ocultar o botão de documentação do console. Adicione um link externo personalizado e um texto personalizado para esse link no console ou deixe-os vazios para ocultar esse botão."
|
||||
},
|
||||
"SMTP_PROVIDER": {
|
||||
"TITLE": "Configurações de SMTP",
|
||||
@ -595,6 +595,7 @@
|
||||
"INVALID_FORMAT": "O formato é inválido.",
|
||||
"NOTANEMAIL": "O valor fornecido não é um endereço de e-mail.",
|
||||
"MINLENGTH": "Deve ter pelo menos {{requiredLength}} caracteres.",
|
||||
"MAXLENGTH": "Deve ter menos de {{requiredLength}} caracteres.",
|
||||
"UPPERCASEMISSING": "Deve incluir uma letra maiúscula.",
|
||||
"LOWERCASEMISSING": "Deve incluir uma letra minúscula.",
|
||||
"SYMBOLERROR": "Deve incluir um símbolo ou caractere de pontuação.",
|
||||
@ -880,7 +881,8 @@
|
||||
"SET": "Definir Nova Senha",
|
||||
"RESENDNOTIFICATION": "Enviar Link de Redefinição de Senha",
|
||||
"REQUIRED": "Algumas informações obrigatórias estão faltando.",
|
||||
"MINLENGTHERROR": "Deve ter pelo menos {{value}} caracteres."
|
||||
"MINLENGTHERROR": "Deve ter pelo menos {{value}} caracteres.",
|
||||
"MAXLENGTHERROR": "Deve ter menos de {{value}} caracteres"
|
||||
},
|
||||
"ID": "ID",
|
||||
"EMAIL": "E-mail",
|
||||
@ -1572,6 +1574,9 @@
|
||||
"POLICYLINK": "Link para a Política de Privacidade",
|
||||
"HELPLINK": "Link para Ajuda",
|
||||
"SUPPORTEMAIL": "E-mail de suporte",
|
||||
"DOCSLINK": "Link do Documentos (Console)",
|
||||
"CUSTOMLINK": "Link personalizado (Console)",
|
||||
"CUSTOMLINKTEXT": "Texto do link personalizado (Console)",
|
||||
"SAVED": "Salvo com sucesso!",
|
||||
"RESET_TITLE": "Restaurar valores padrão",
|
||||
"RESET_DESCRIPTION": "Você está prestes a restaurar os Links padrão para TOS e Política de Privacidade. Deseja realmente continuar?"
|
||||
@ -2220,7 +2225,7 @@
|
||||
"SMTP": {
|
||||
"LIST": {
|
||||
"TITLE": "Provedor SMTP",
|
||||
"DESCRIPTION": "Estes são os provedores SMTP para sua instância Zitadel. Ative aquele que deseja usar para enviar notificações aos seus usuários.",
|
||||
"DESCRIPTION": "Estes são os provedores SMTP para sua instância ZITADEL. Ative aquele que deseja usar para enviar notificações aos seus usuários.",
|
||||
"EMPTY": "Nenhum provedor SMTP disponível",
|
||||
"ACTIVATED": "Ativado",
|
||||
"ACTIVATE": "Ativar provedor",
|
||||
@ -2248,7 +2253,16 @@
|
||||
"CURRENT_DESC_TITLE": "Estas são suas configurações de SMTP",
|
||||
"PROVIDER_SETTINGS": "Configurações do provedor SMTP",
|
||||
"SENDER_SETTINGS": "Configurações do remetente",
|
||||
"TEST_SETTINGS": "Testar configurações de SMTP"
|
||||
"TEST_SETTINGS": "Testar configurações de SMTP",
|
||||
"NEXT_STEPS": "Próximos passos",
|
||||
"ACTIVATE": {
|
||||
"TITLE": "Ative seu provedor SMTP",
|
||||
"DESCRIPTION": "ZITADEL não pode usar este provedor SMTP para enviar notificações até que você o ative. Se você ativar este provedor, qualquer outro provedor que estava ativo será desativado."
|
||||
},
|
||||
"DEACTIVATE": {
|
||||
"TITLE": "Desative seu provedor SMTP",
|
||||
"DESCRIPTION": "Se você desativar este provedor SMTP, a ZITADEL não poderá usá-lo para enviar notificações até que você o ative novamente."
|
||||
}
|
||||
}
|
||||
},
|
||||
"DETAIL": {
|
||||
|
@ -129,7 +129,7 @@
|
||||
},
|
||||
"PRIVACY_POLICY": {
|
||||
"TITLE": "Внешние ссылки",
|
||||
"DESCRIPTION": "Направьте ваших пользователей к пользовательским внешним ресурсам, показанным на странице входа. Пользователи должны принять Условия обслуживания и Политику конфиденциальности, прежде чем они смогут зарегистрироваться."
|
||||
"DESCRIPTION": "Guide your users to custom external resources shown on the login page. Users need to accept the Terms of Service and Privacy Policy before they can sign up. Change the link to your documentation or set an empty string to hide the documentation button from the console. Add a custom external link and a custom text for that link in the console, or set them empty to hide that button."
|
||||
},
|
||||
"SMTP_PROVIDER": {
|
||||
"TITLE": "Настройки SMTP",
|
||||
@ -594,6 +594,7 @@
|
||||
"INVALID_FORMAT": "Форматирование неверно.",
|
||||
"NOTANEMAIL": "Данное значение не является адресом электронной почты.",
|
||||
"MINLENGTH": "Должно быть не менее {{requiredLength}} символов.",
|
||||
"MAXLENGTH": "Должно быть меньше {{requiredLength}} символов.",
|
||||
"UPPERCASEMISSING": "Должен содержать символ верхнего регистра.",
|
||||
"LOWERCASEMISSING": "Должен включать строчные буквы.",
|
||||
"SYMBOLERROR": "Должен содержать символ или знак препинания.",
|
||||
@ -887,7 +888,8 @@
|
||||
"RESENDNOTIFICATION": "Отправить ссылку для сброса пароля",
|
||||
"REQUIRED": "Отсутствуют некоторые обязательные поля.",
|
||||
"MINLENGTHERROR": "Должно быть не менее {{value}} символов.",
|
||||
"NOTEQUAL": "Указанные пароли не совпадают."
|
||||
"NOTEQUAL": "Указанные пароли не совпадают.",
|
||||
"MAXLENGTHERROR": "Должно быть меньше {{value}} символов"
|
||||
},
|
||||
"ID": "Идентификатор",
|
||||
"EMAIL": "Электронная почта",
|
||||
@ -1626,6 +1628,9 @@
|
||||
"POLICYLINK": "Ссылка на Политику конфиденциальности",
|
||||
"HELPLINK": "Ссылка на Помощь",
|
||||
"SUPPORTEMAIL": "Электронная почта поддержки",
|
||||
"DOCSLINK": "Ссылка на Документы (Console)",
|
||||
"CUSTOMLINK": "Пользовательская ссылка (Console)",
|
||||
"CUSTOMLINKTEXT": "Пользовательский текст ссылки (Console)",
|
||||
"SAVED": "Успешно сохранено!",
|
||||
"RESET_TITLE": "Восстановить значения по умолчанию",
|
||||
"RESET_DESCRIPTION": "Вы собираетесь восстановить ссылки по умолчанию для Пользовательского соглашения и Политики конфиденциальности. Вы действительно хотите продолжить?"
|
||||
@ -2337,7 +2342,7 @@
|
||||
"SMTP": {
|
||||
"LIST": {
|
||||
"TITLE": "SMTP-провайдер",
|
||||
"DESCRIPTION": "Это поставщики SMTP для вашего экземпляра Zitadel. Активируйте тот, который вы хотите использовать для отправки уведомлений вашим пользователям.",
|
||||
"DESCRIPTION": "Это поставщики SMTP для вашего экземпляра ZITADEL. Активируйте тот, который вы хотите использовать для отправки уведомлений вашим пользователям.",
|
||||
"EMPTY": "SMTP-провайдер не доступен",
|
||||
"ACTIVATED": "Активировано",
|
||||
"ACTIVATE": "Активировать провайдера",
|
||||
@ -2365,7 +2370,16 @@
|
||||
"CURRENT_DESC_TITLE": "Это ваши настройки SMTP",
|
||||
"PROVIDER_SETTINGS": "Настройки SMTP-провайдера",
|
||||
"SENDER_SETTINGS": "Настройки отправителя",
|
||||
"TEST_SETTINGS": "Проверка настроек SMTP"
|
||||
"TEST_SETTINGS": "Проверка настроек SMTP",
|
||||
"NEXT_STEPS": "Следующие шаги",
|
||||
"ACTIVATE": {
|
||||
"TITLE": "Активируйте своего SMTP-провайдера",
|
||||
"DESCRIPTION": "ZITADEL не может использовать этого поставщика SMTP для отправки уведомлений, пока вы его не активируете. Если вы активируете этого провайдера, любой другой провайдер, который был активен, теперь будет деактивирован."
|
||||
},
|
||||
"DEACTIVATE": {
|
||||
"TITLE": "Деактивируйте своего SMTP-провайдера",
|
||||
"DESCRIPTION": "Если вы деактивируете этого поставщика SMTP, ZITADEL не сможет использовать его для отправки уведомлений, пока вы не активируете его снова."
|
||||
}
|
||||
}
|
||||
},
|
||||
"DETAIL": {
|
||||
|
@ -129,7 +129,7 @@
|
||||
},
|
||||
"PRIVACY_POLICY": {
|
||||
"TITLE": "外部链接",
|
||||
"DESCRIPTION": "引导您的用户到登录页面上显示的自定义外部资源。用户需要在注册前接受服务条款和隐私政策。"
|
||||
"DESCRIPTION": "引导您的用户访问登录页面上显示的自定义外部资源。用户需要先接受服务条款和隐私政策,然后才能注册。更改文档的链接或设置空字符串以在控制台中隐藏文档按钮。在控制台中添加自定义外部链接和该链接的自定义文本,或将它们设置为空以隐藏该按钮。"
|
||||
},
|
||||
"SMTP_PROVIDER": {
|
||||
"TITLE": "SMTP设置",
|
||||
@ -594,6 +594,7 @@
|
||||
"INVALID_FORMAT": "格式是无效的。",
|
||||
"NOTANEMAIL": "给定的值不是合法电子邮件地址。",
|
||||
"MINLENGTH": "长度必须至少是{{requiredLength}}字符。",
|
||||
"MAXLENGTH": "必须少于{{requiredLength}}个字符.",
|
||||
"UPPERCASEMISSING": "密码必须包含大写字符。",
|
||||
"LOWERCASEMISSING": "密码必须包含小写字符。",
|
||||
"SYMBOLERROR": "密码必须包含符号或标点符号。",
|
||||
@ -879,7 +880,8 @@
|
||||
"SET": "设置新密码",
|
||||
"RESENDNOTIFICATION": "发送重置密码链接",
|
||||
"REQUIRED": "缺少必填字段。",
|
||||
"MINLENGTHERROR": "密码长度必须至少为 {{value}} 个字符。"
|
||||
"MINLENGTHERROR": "密码长度必须至少为 {{value}} 个字符。",
|
||||
"MAXLENGTHERROR": "必须少于{{value}}个字符"
|
||||
},
|
||||
"ID": "ID",
|
||||
"EMAIL": "电子邮件",
|
||||
@ -1569,6 +1571,9 @@
|
||||
"POLICYLINK": "链接到隐私政策",
|
||||
"HELPLINK": "链接到帮助",
|
||||
"SUPPORTEMAIL": "支持邮箱",
|
||||
"DOCSLINK": "文档链接(Console)",
|
||||
"CUSTOMLINK": "自定义链接(Console)",
|
||||
"CUSTOMLINKTEXT": "自定义链接文本(Console)",
|
||||
"SAVED": "保存成功!",
|
||||
"RESET_TITLE": "恢复默认值",
|
||||
"RESET_DESCRIPTION": "您即将恢复 TOS 和隐私政策的默认链接。你真的要继续吗?"
|
||||
@ -2224,7 +2229,7 @@
|
||||
"SMTP": {
|
||||
"LIST": {
|
||||
"TITLE": "SMTP 提供商",
|
||||
"DESCRIPTION": "这些是您的 Zitadel 实例的 SMTP 提供商。激活您想要用来向用户发送通知的通知。",
|
||||
"DESCRIPTION": "这些是您的 ZITADEL 实例的 SMTP 提供商。激活您想要用来向用户发送通知的通知。",
|
||||
"EMPTY": "没有可用的 SMTP 提供商",
|
||||
"ACTIVATED": "活性",
|
||||
"ACTIVATE": "激活提供商",
|
||||
@ -2252,7 +2257,16 @@
|
||||
"CURRENT_DESC_TITLE": "这些是您的 SMTP 设置",
|
||||
"PROVIDER_SETTINGS": "SMTP 提供商设置",
|
||||
"SENDER_SETTINGS": "发件人设置",
|
||||
"TEST_SETTINGS": "测试 SMTP 设置"
|
||||
"TEST_SETTINGS": "测试 SMTP 设置",
|
||||
"NEXT_STEPS": "下一步",
|
||||
"ACTIVATE": {
|
||||
"TITLE": "激活您的 SMTP 提供商",
|
||||
"DESCRIPTION": "在您激活此 SMTP 提供程序之前,Zitadel 无法使用它来发送通知。如果您激活此提供程序,任何其他处于活动状态的提供程序现在都将被停用。"
|
||||
},
|
||||
"DEACTIVATE": {
|
||||
"TITLE": "停用您的 SMTP 提供商",
|
||||
"DESCRIPTION": "如果您停用此 SMTP 提供程序,Zitadel 将无法使用它发送通知,直到您再次激活它。"
|
||||
}
|
||||
}
|
||||
},
|
||||
"DETAIL": {
|
||||
|
@ -86,6 +86,11 @@ And if you use a different service, for example `zitadel.session.v2.SessionServi
|
||||
|
||||
### Targets and Includes
|
||||
|
||||
:::info
|
||||
Includes are limited to 3 levels, which mean that include1->include2->include3 is the maximum for now.
|
||||
If you have feedback to the include logic, or a reason why 3 levels are not enough, please open [an issue on github](https://github.com/zitadel/zitadel/issues) or [start a discussion on github](https://github.com/zitadel/zitadel/discussions)/[start a topic on discord](https://zitadel.com/chat)
|
||||
:::
|
||||
|
||||
An execution can not only contain a list of Targets, but also Includes.
|
||||
The Includes can be defined in the Execution directly, which means you include all defined Targets by a before set Execution.
|
||||
|
||||
|
36
docs/docs/concepts/features/account-linking.md
Normal file
36
docs/docs/concepts/features/account-linking.md
Normal file
@ -0,0 +1,36 @@
|
||||
---
|
||||
title: Account linking
|
||||
---
|
||||
|
||||
ZITADEL supports linking of user accounts from different external identity providers such as social logins or enterprise IdPs.
|
||||
A user can authenticate from any of their accounts and still be recognized by your app and associated with the same user profile.
|
||||
|
||||
In ZITADEL, users have one user account to simplify access management and provide a consistent audit trail.
|
||||
A user account can have a link to multiple external identities.
|
||||
|
||||
### Advantages
|
||||
|
||||
- Users can login with multiple identity providers without managing separate profiles
|
||||
- Already registered users can link existing profiles
|
||||
- Provide backup authentication methods in case an IdP is unavailable
|
||||
- Unified audit trail across multiple identities
|
||||
|
||||
### How it works
|
||||
|
||||
ZITADEL gives you great flexibility to configure account linking for an organization and based on the external identity provider.
|
||||
|
||||
When using external identity providers (ie. social login, enterprise SSO), a user account will be created in ZITADEL.
|
||||
The [external identity](../structure/users#federated-users) will be linked to the ZITADEL account.
|
||||
|
||||
If login with "Username / Password" (ie. local account) is enabled and you have configured external IDPs, the user can decide if they want to login with an external IDP or the local account.
|
||||
|
||||
When only one external identity provider is configured and login with "Username / Password" is disabled, then the user is immediately redirected to the external identity provider.
|
||||
|
||||
In cases when a local account already exists and a user logs in with an external identity provider, you can instruct ZITADEL to link the external identity to the local account based on the username or email address.
|
||||
|
||||
### Automatic account linking
|
||||
|
||||
You can link accounts with the same email or username and prompt users to link them.
|
||||
On an [identity provider template settings](/docs/guides/integrate/identity-providers/introduction#key-settings-on-the-templates), you must enable "Account linking allowed".
|
||||
|
||||
Automatic account linking is beneficial for users who wish to associate multiple login methods with their ZITADEL account, providing flexibility and convenience in how they access your application.
|
@ -14,6 +14,15 @@ This form of audit log has several benefits over storing classic audit logs.
|
||||
You can view past data in-context of the whole system at a single point in time.
|
||||
Reviewing a past state of the application can be important when tracing an incident that happened months back. Moreover the eventstore provides a truly complete and clean audit log.
|
||||
|
||||
:::info Future Plans
|
||||
There will be three major areas for future development on the audit data
|
||||
|
||||
- [Metrics](https://github.com/zitadel/zitadel/issues/4458) and [standard reports](https://github.com/zitadel/zitadel/discussions/2162#discussioncomment-1153259)
|
||||
- [Feedback loop](https://github.com/zitadel/zitadel/issues/5102) and threat detection
|
||||
- Forensics and replay of events
|
||||
|
||||
:::
|
||||
|
||||
## Accessing the Audit Log
|
||||
|
||||
### Last changes of an object
|
||||
@ -42,24 +51,6 @@ Access to the API is possible with a [Service User](/docs/guides/integrate/servi
|
||||
|
||||
## Using logs in external systems
|
||||
|
||||
You can use the [Event API](#event-api) to pull data and ingest it in an external system.
|
||||
You can use the events from the audit log in external systems such as a SOC/SIEM solution.
|
||||
|
||||
[Actions](actions.md) can be used to write events to the stdout and [process the events as logs](../../self-hosting/manage/production#logging).
|
||||
Please refer to the zitadel/actions repository for a [code sample](https://github.com/zitadel/actions/blob/main/examples/post_auth_log.js).
|
||||
You can use your log processing pipeline to parse and ingest the events in your favorite analytics tool.
|
||||
|
||||
It is possible to send events directly with an http request to an external tool.
|
||||
We don't recommend this approach since this would create back-pressure and increase the overall processing time for requests.
|
||||
|
||||
:::info Scope of Actions
|
||||
At this moment Actions can be invoked on certain events, but not generally on every event.
|
||||
This is not a technical limitation, but a [feature on our backlog](https://github.com/zitadel/zitadel/issues/5101).
|
||||
:::
|
||||
|
||||
## Future plans
|
||||
|
||||
There will be three major areas for future development on the audit data
|
||||
|
||||
- [Metrics](https://github.com/zitadel/zitadel/issues/4458) and [standard reports](https://github.com/zitadel/zitadel/discussions/2162#discussioncomment-1153259)
|
||||
- [Feedback loop](https://github.com/zitadel/zitadel/issues/5102) and threat detection
|
||||
- Forensics and replay of events
|
||||
Follow our guide on how to [integrate ZITADEL with external systems for streaming events and audit logs](/docs/guides/integrate/external-audit-log).
|
||||
|
@ -1,10 +1,28 @@
|
||||
---
|
||||
title: ZITADEL Applications
|
||||
title: Configure applications for your frontend and backend services and clients
|
||||
sidebar_label: Applications
|
||||
sidebar_position: 5
|
||||
---
|
||||
import AppType from "../../guides/manage/console/_application-types.mdx";
|
||||
|
||||
# Applications
|
||||
Applications are the entry point to your project.
|
||||
[Users](users.md) either login into one of your clients and interact with them directly or use one of your APIs.
|
||||
All applications share the roles and authorizations of their [project](projects.md).
|
||||
|
||||
Applications are the entry point to your project. Users either login into one of your clients and interact with them directly or use one of your APIs. All applications share the roles and authorizations of their project.
|
||||
## Supported application types
|
||||
|
||||
To read more about available authentication types and how to setup applications, read this guide [here](../../guides/manage/console/applications)
|
||||
ZITADEL supports the following client types:
|
||||
|
||||
<AppType />
|
||||
|
||||
## Security considerations
|
||||
|
||||
Ensure the configuration of application settings is limited to authorized users only.
|
||||
|
||||
- Use [Manager roles](managers.mdx) to limit permissions for your users to make changes to your applications
|
||||
- When [granting projects](granted_projects.md) to other organizations, the receiving organization can't see or change application configuration
|
||||
|
||||
## References
|
||||
|
||||
- [Configure Applications in the Console](../../guides/manage/console/applications)
|
||||
- [ZITADEL API: Applications](/docs/category/apis/resources/mgmt/applications)
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
title: ZITADEL Instances
|
||||
sidebar_label: Instances
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
## Instance Structure
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
title: ZITADEL Organizations
|
||||
sidebar_label: Organizations
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
import OrgDescription from './_org_description.mdx';
|
||||
|
@ -1,10 +1,9 @@
|
||||
---
|
||||
title: ZITADEL Projects
|
||||
title: Organize applications, services, and roles with projects
|
||||
sidebar_label: Projects
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
# Project
|
||||
|
||||
import ProjectDescription from './\_project_description.mdx';
|
||||
|
||||
<ProjectDescription name="ProjectDescription" />
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
title: ZITADEL Users
|
||||
sidebar_label: Users
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
## Types of users
|
||||
@ -15,18 +16,36 @@ Human users typically logon with an interactive login.
|
||||
This means that an application redirects a user to a website ("login page") where the user can provide the credentials.
|
||||
ZITADEL handles the authentication and provides the application with a token that verifies the authentication process.
|
||||
|
||||
Read more on how to [login users with ZITADEL](/docs/guides/integrate/login/login-users).
|
||||
|
||||
### Service users
|
||||
|
||||
Service users are for machine-to-machine communication and you would use those typically to access secure backend services.
|
||||
For example in ZITADEL you would require an authenticated Service User to access the Management API.
|
||||
The main difference between human and machine users is the type of credentials that can be used for authentication: Human users typically logon via an login prompt, but Machine users require a non-interactive logon process.
|
||||
|
||||
Learn how to [use service users](/docs/guides/integrate/service-users/authenticate-service-users) with ZITADEL.
|
||||
|
||||
### Managers
|
||||
|
||||
Any user, human or service user, can be given a [Manager](/concepts/structure/managers) role.
|
||||
Given a manager role, a user is not only an end-user of ZITADEL but can also manage certain aspects of ZITADEL itself.
|
||||
|
||||
## Constraints
|
||||
### Federated users
|
||||
|
||||
Federated users are identities that are managed by a third-party identity provider.
|
||||
Users can login via an external identity provider, using [identity brokering](../features/identity-brokering) ("Single-sign-on").
|
||||
Federated user [accounts are linked](../features/account-linking) to internal users to be able to assign roles and keep an audit trail.
|
||||
|
||||
### External users
|
||||
|
||||
In a multi-tenancy architecture, you might use [organizations](organizations) to separate user groups.
|
||||
By using [external user grants](../features/external-user-grant) an organization is able to invite users from another organization.
|
||||
These invited users are called external users.
|
||||
|
||||
## Considerations
|
||||
|
||||
### Uniqueness of users
|
||||
|
||||
Users can only exist within one [organization](/concepts/structure/organizations).
|
||||
It is currently not possible to move users between organizations.
|
||||
@ -34,20 +53,30 @@ It is currently not possible to move users between organizations.
|
||||
User accounts are uniquely identified by their `id` or `loginname` in combination of the `organization domain` (eg, `road.runner@acme.zitadel.local`).
|
||||
You can use the same email address for different user accounts.
|
||||
|
||||
## Where to store users
|
||||
### How to structure user pools
|
||||
|
||||
Depending on your [scenario](/guides/solution-scenarios/introduction), you might want to store all users in one organization (CIAM / B2C) or create a new organization for each logical group of users, e.g. each business customer (B2B).
|
||||
With a project grant, you can delegate the access management of an organization's project to another organization.
|
||||
You can also create a user grant to allow single users to access projects from another organization.
|
||||
This is also an alternative to cases where you might want to move users between organizations.
|
||||
Consider this general recommendation as a starting point:
|
||||
|
||||
## Identity linking
|
||||
- Create one organization ("default organization") for your own company
|
||||
- Configure projects and applications in the default organization
|
||||
- Structure users in organizations based on common domains that are self-managed (eg, company)
|
||||
- Grant your projects to the organizations, allow Managers to give granted roles to their users
|
||||
|
||||
When using external identity providers (ie. social login, enterprise SSO), a user account will be created in ZITADEL.
|
||||
The external identity will be linked to the ZITADEL account.
|
||||
You might want to adjust this general setup based on your [scenario](/guides/solution-scenarios/introduction).
|
||||
|
||||
You can link multiple external accounts to a ZITADEl account.
|
||||
If login with "Username / Password" (ie. local account) is enabled and you have configured external IDPs, the user can decide if she wants to login with an external IDP or the local account.
|
||||
When only one external identity provider is configured and login with "Username / Password" is disabled, then the user is immediately redirected to the external identity provider.
|
||||
One important consideration in the setup is that you can only have a domain once for an organization. If you have multiple teams working with the same email address, you might need to add them to one single organization that has the domain verified for the teams' domain.
|
||||
|
||||
More about how to manage your users read our [users guide](../../guides/manage/console/users).
|
||||
For a CIAM / B2C setup, you might want to store all users in one organization and allow that organization to use a specific set of social logins.
|
||||
In a multitenancy / B2B scenario, you might have thousands of smaller teams.
|
||||
|
||||
#### Hierarchy
|
||||
|
||||
There is no concept of hierarchies and inheritance based on users or organizations.
|
||||
This is why we recommend to structure users along the smallest unit of groups.
|
||||
You can use organization metadata or your own business logic to describe a hierarchy of organizations or user groups.
|
||||
|
||||
## References
|
||||
|
||||
- [Manage users in the Console](../../guides/manage/console/users)
|
||||
- [ZITADEL APIs: Users](/docs/category/apis/resources/mgmt/users)
|
||||
- [User onboarding and registration](/docs/guides/integrate/onboarding)
|
||||
|
@ -8,7 +8,7 @@ OAuth 2 Token Introspection.
|
||||
|
||||
At the end of the guide you should have an API with a protected endpoint.
|
||||
|
||||
> This documentation references our HTTP example. There's also one for GRPC. Check them out on [GitHub](https://github.com/zitadel/zitadel-go/tree/authorization/example/api).
|
||||
> This documentation references our HTTP example. There's also one for GRPC. Check them out on [GitHub](https://github.com/zitadel/zitadel-go/blob/next/example/api/http/main.go).
|
||||
|
||||
## Set up application and obtain keys
|
||||
|
||||
|
@ -13,7 +13,6 @@ curl --request PATCH \
|
||||
--header 'Authorization: Bearer '"$TOKEN"''\
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"sessionToken": "yMDi6uVPJAcphbbz0LaxC07ihWkNTe7m0Xqch8SzfM5Cz3HSIQIDZ65x1f5Qal0jxz0MEyo-_zYcUg",
|
||||
"checks": {
|
||||
"webAuthN": {
|
||||
"credentialAssertionData": {}
|
||||
|
@ -140,7 +140,6 @@ curl --request PATCH \
|
||||
--header 'Accept: application/json' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"sessionToken": "W3mEoesTiYOsiR1LYUCRw3vaEwXKLGDTsqOV_bkOhlah_-ZbuiLgvnzADwe_iYMusbwkMhp7VfMn8j",
|
||||
"checks": {
|
||||
"totp": {
|
||||
"code": "323764"
|
||||
@ -270,7 +269,6 @@ curl --request PATCH \
|
||||
--header 'Authorization: Bearer '"$TOKEN"'' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"sessionToken": "W3mEoesTiYOsiR1LYUCRw3WaFwXKLGDRsqOV_bkOhlah_-ZpuiLgvnzADwe_iYMusbwkMhp7VfMn8g",
|
||||
"checks": {
|
||||
"otpSms": {
|
||||
"code": "3237642"
|
||||
@ -359,7 +357,6 @@ curl --request PATCH \
|
||||
--header 'Authorization: Bearer '"$TOKEN"'' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"sessionToken": "W3mEoesTiYOsiR1LYUCRw3WaFwXKLGDRsqOV_bkOhlah_-ZpuiLgvnzADwe_iYMusbwkMhp7VfMn8g",
|
||||
"checks": {
|
||||
"otpEmail": {
|
||||
"code": "3237642"
|
||||
|
@ -76,12 +76,14 @@ The application can then request a token calling the /token endpoint of the logi
|
||||
- [ ] AuthRequest UI locales
|
||||
- Multifactor
|
||||
- [x] Passkeys
|
||||
- [ ] TOTP
|
||||
- [x] TOTP
|
||||
- [x] OTP via email
|
||||
- [x] OTP via SMS
|
||||
- Passwordless
|
||||
- [x] Passkeys
|
||||
- Security Prompts
|
||||
- [x] Setup Passkey as Passwordless method
|
||||
- [ ] Setup TOTP as Multifactor
|
||||
- [x] Setup TOTP as Multifactor
|
||||
- [ ] Password Change
|
||||
- Login
|
||||
- [x] Email Password
|
||||
@ -89,7 +91,7 @@ The application can then request a token calling the /token endpoint of the logi
|
||||
- [x] IDPs
|
||||
- [x] Google
|
||||
- [ ] GitHub
|
||||
- [ ] GitLab
|
||||
- [x] GitLab
|
||||
- [ ] Azure
|
||||
- [ ] Apple
|
||||
- Register
|
||||
@ -104,8 +106,12 @@ Authenticated users are directly able to self service their account.
|
||||
- [ ] Change user information
|
||||
- [ ] Password Change
|
||||
- [x] Setup Passkey
|
||||
- [ ] Setup Multifactor TOTP
|
||||
- [ ] Setup Multifactor Passkey (U2F)
|
||||
- [x] Setup Multifactor
|
||||
- [x] Passkeys
|
||||
- [x] TOTP
|
||||
- [x] OTP via email
|
||||
- [x] OTP via SMS
|
||||
- [x] Setup Multifactor Passkey (U2F)
|
||||
- [ ] Validate Account (email verification)
|
||||
|
||||
### Setup
|
||||
|
@ -163,7 +163,7 @@ Checkout how to handle [session validation](./session-validation).
|
||||
|
||||
Your session already has a username check.
|
||||
The next step is to check the password.
|
||||
To update an existing session, add the session ID to the URL and the session token you got in the previous step to the request body.
|
||||
To update an existing session, add the session ID you got in the previous step to the URL.
|
||||
|
||||
### Request
|
||||
|
||||
@ -174,7 +174,6 @@ curl --request PATCH \
|
||||
--header 'Authorization: Bearer '"$TOKEN"''\
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"sessionToken": "yMDi6uVPJAcphbbz0LaxC07ihWkNTe7m0Xqch8SzfM5Cz3HSIQIDZ65x1f5Qal0jxz0MEyo-_zYcUg",
|
||||
"checks": {
|
||||
"password": {
|
||||
"password": "Secr3tP4ssw0rd!"
|
||||
|
5
docs/docs/guides/manage/console/_application-types.mdx
Normal file
5
docs/docs/guides/manage/console/_application-types.mdx
Normal file
@ -0,0 +1,5 @@
|
||||
- [**Web**](#web) (Server-side web applications such as java, .net, ...)
|
||||
- [**Native**](#native) (native, mobile or desktop applications)
|
||||
- [**User Agent**](#user-agent) (single page applications / SPA, generally JavaScript executed in the browser)
|
||||
- [**API**](#api) (OAuth Resource Server)
|
||||
- [**SAML**](#saml)
|
@ -7,6 +7,7 @@ import ThemedImage from "@theme/ThemedImage";
|
||||
|
||||
import AuthType from "../../integrate/application/_auth-type.mdx";
|
||||
import ReviewConfig from "../../integrate/application/_review-config.mdx";
|
||||
import AppType from "./_application-types.mdx";
|
||||
|
||||
## What is an application?
|
||||
|
||||
@ -36,13 +37,9 @@ To add an application to your project, click on the add button and select your a
|
||||
|
||||
## Application Types
|
||||
|
||||
At the moment ZITADEL offers four client types:
|
||||
At the moment ZITADEL offers five client types:
|
||||
|
||||
- [**Web**](#web) (Server-side web applications such as java, .net, ...)
|
||||
- [**Native**](#native) (native, mobile or desktop applications)
|
||||
- [**User Agent**](#user-agent) (single page applications / SPA, generally JavaScript executed in the browser)
|
||||
- [**API**](#api) (OAuth Resource Server)
|
||||
- [**SAML**](#saml)
|
||||
<AppType />
|
||||
|
||||
The first three options (Web, Native and User Agent) require user interaction, the fourth option (API) has no direct user-interaction.
|
||||
Depending on the app type, there are small differences in the possible settings.
|
||||
|
@ -26,8 +26,7 @@ When you configure your default settings, you can set the following:
|
||||
- [**Branding**](#branding): Appearance of the login interface.
|
||||
- [**Message Texts**](#message-texts): Text and internationalization for emails
|
||||
- [**Login Interface Texts**](#login-interface-texts): Text and internationalization for the login interface
|
||||
- [**Languages**](#languages): Select which supported langauges are shown to your users. Set the default language if no context is provided.
|
||||
- [**Privacy Policy**](#privacy-policy-and-tos): Links to your own Terms of Service and Privacy Policy regulations. Link to Help Page.
|
||||
- [**External Links**](#external-links): Links to your own Terms of Service and Privacy Policy regulations, Help Page, Support email, documentation link...
|
||||
- [**OIDC Token Lifetimes and Expiration**](#oidc-token-lifetimes-and-expiration): Token lifetime and expiration settings.
|
||||
- [**Secret Generator**](#secret-generator): Appearance and expiration of the generated codes and secrets used in mails for verification etc.
|
||||
|
||||
@ -256,9 +255,10 @@ You can either set this attribute on your whole ZITADEL instance or just on some
|
||||
|
||||
Please refer to the [configuration guide](/docs/guides/solution-scenarios/configurations#use-email-to-login) for more information.
|
||||
|
||||
## Privacy Policy and TOS
|
||||
## External links
|
||||
|
||||
With this setting you are able to configure your privacy policy, terms of service, help links and help/support email address.
|
||||
|
||||
On register each user has to accept these policies.
|
||||
|
||||
This policy can be also be overriden by your organizations.
|
||||
@ -269,8 +269,16 @@ Example:
|
||||
`https://demo.com/tos-{{.Lang}}`
|
||||
|
||||
<img
|
||||
src="/docs/img/guides/console/privacypolicy.png"
|
||||
alt="Privacy Policy"
|
||||
src="/docs/img/guides/console/external_links_1.png"
|
||||
alt="External Links"
|
||||
width="600px"
|
||||
/>
|
||||
|
||||
Also you can set the link associated to the Documentation button in the console. Set an empty text if you don't want to show a Documentation button in your console. If you need a custom button to be shown in the console you can set the button text and the link associated to the button (if the button text is button no text will be shown).
|
||||
|
||||
<img
|
||||
src="/docs/img/guides/console/external_links_2.png"
|
||||
alt="Custom button"
|
||||
width="600px"
|
||||
/>
|
||||
|
||||
|
@ -114,7 +114,7 @@ Those settings are the same as on your instance.
|
||||
- [**Branding**](./default-settings#branding): Appearance of the login interface.
|
||||
- [**Message Texts**](./default-settings#message-texts): Text and internationalization for emails
|
||||
- [**Login Interface Texts**](./default-settings#login-interface-texts): Text and internationalization for the login interface
|
||||
- [**Privacy Policy**](./default-settings#privacy-policy-and-tos): Links to your own Terms of Service and Privacy Policy regulations. Link to Help Page.
|
||||
- [**External Links**](./default-settings#external-links): Links to your own Terms of Service and Privacy Policy regulations, Help Page, Support email, documentation link...
|
||||
|
||||
If you need custom branding on a organization (for example in a B2B scenario, where organizations are allowed to use their custom design), navigate back to the home page, choose your organization in the header above, navigate to the organization settings and set the custom design here.
|
||||
|
||||
|
@ -181,7 +181,7 @@ As a user of the ZITADEL Cloud Customer Portal, you now can create multiple inst
|
||||
|
||||
![Add Role](/img/guides/quickstart/25.png)
|
||||
|
||||
### 6. Add authorizations to your project
|
||||
### 6. Add authorizations to your project (optional)
|
||||
|
||||
1. Click on “Authorizations” on the top menu.
|
||||
|
||||
|
@ -3,7 +3,7 @@ title: Rate Limit Policy
|
||||
custom_edit_url: null
|
||||
---
|
||||
|
||||
Last updated on April 20, 2023
|
||||
Last updated on April 24, 2024
|
||||
|
||||
This policy is an annex to the [Terms of Service](../terms-of-service) and clarifies your obligations while using our Services, specifically how we will use rate limiting to enforce certain aspects of our [Acceptable Use Policy](acceptable-use-policy).
|
||||
|
||||
@ -36,8 +36,10 @@ For ZITADEL Cloud, we have a rate limiting rule for login paths (login, register
|
||||
Rate limits are implemented with the following rules:
|
||||
|
||||
| Path | Description | Rate Limiting | One Minute Banning |
|
||||
|--------------------------|----------------------------------------|--------------------------------------|----------------------------------------|
|
||||
| /ui/login* | Global Login, Register and Reset Limit | 10 requests per second over a minute | 15 requests per second over 3 minutes |
|
||||
| -------------------- | -------------------------------------------------------------- | ------------------------------------ | ------------------------------------- |
|
||||
| /ui/login\* | Global Login, Register and Reset Limit | 10 requests per second over a minute | 15 requests per second over 3 minutes |
|
||||
| /oauth/v2/keys | OAuth/OpenID Public Keys Endpoint | 20 requests per second over a minute | 15 requests per second over 3 minutes |
|
||||
| /oauth/v2/introspect | OAuth Introspection Endpoint | 20 requests per second over a minute | 15 requests per second over 3 minutes |
|
||||
| All other paths | All gRPC- and REST APIs as well as the ZITADEL Customer Portal | 10 requests per second over a minute | 10 requests per second over 3 minutes |
|
||||
|
||||
## Load Testing
|
||||
|
@ -6,7 +6,7 @@ sidebar_label: Introduction
|
||||
You can integrate ZITADEL quickly into your application and be up and running within minutes.
|
||||
To achieve your goals as fast as possible, we provide you with SDKs, Example Repositories and Guides.
|
||||
|
||||
The SDKs and Integration depend on the framework and language you are using.
|
||||
The SDKs and integration depend on the framework and language you are using.
|
||||
|
||||
import { Frameworks } from "../../src/components/frameworks";
|
||||
|
||||
@ -14,6 +14,12 @@ import { Frameworks } from "../../src/components/frameworks";
|
||||
|
||||
<Frameworks />
|
||||
|
||||
To further streamline your setup, simply visit the console in ZITADEL where you can select one of the languages or frameworks. This will allow you to instantly set up the configuration for that specific sample in ZITADEL, ensuring you have everything you need to get started right away.
|
||||
|
||||
![Console](/img/sdk-examples/console.png)
|
||||
|
||||
To begin configuring login for any of these samples, start [here](https://zitadel.com/signin).
|
||||
|
||||
### OIDC Libraries
|
||||
|
||||
OIDC is a standard for authentication and most languages and frameworks do provide a OIDC library which can be easily integrated to your application.
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
The default database of ZITADEL is [CockroachDB](https://www.cockroachlabs.com). The SQL database provides a bunch of features like horizontal scalability, data regionality and many more.
|
||||
|
||||
Currently versions >= 23.2 are supported.
|
||||
|
||||
The default configuration of the database looks like this:
|
||||
|
||||
```yaml
|
||||
|
27
docs/docs/support/advisory/a10009.md
Normal file
27
docs/docs/support/advisory/a10009.md
Normal file
@ -0,0 +1,27 @@
|
||||
---
|
||||
title: Technical Advisory 10009
|
||||
---
|
||||
|
||||
## Date and Version
|
||||
|
||||
Version: 2.53.0
|
||||
|
||||
Date: Calendar week 23/24 2024
|
||||
|
||||
## Description
|
||||
|
||||
There were rare cases where Cockroachdb got blocked during runtime of ZITADEL and returned `WRITE_TOO_OLD`-errors to ZITADEL. The root cause of the problem is described in [this github issue of the database](https://github.com/cockroachdb/cockroach/issues/77119). The workaround provided by the database is enabling the `enable_durable_locking_for_serializable`-flag as described [here](https://github.com/cockroachdb/cockroach/issues/75456#issuecomment-1936277716).
|
||||
|
||||
Because enabling flags requires admin privileges the statement must be executed manually or by executing `zitadel init` command.
|
||||
|
||||
## Statement
|
||||
|
||||
Ensure lock distribution for `FOR UPDATE`-statements on Cockroachdb.
|
||||
|
||||
## Mitigation
|
||||
|
||||
Cockroachdb version >= 23.2.
|
||||
|
||||
## Impact
|
||||
|
||||
Adding additional raft queries to `FOR UPDATE`-statements can impact performance slightly but ensures availability of the system.
|
@ -149,11 +149,23 @@ We understand that these advisories may include breaking changes, and we aim to
|
||||
<td>New flag to prefill projections during setup instead of after start</td>
|
||||
<td>Feature description</td>
|
||||
<td>
|
||||
new flag `--init-projections` introduced to `zitadel setup` commands (`setup`, `start-from-setup`, `start-from-init`)
|
||||
New flag `--init-projections` introduced to `zitadel setup` commands (`setup`, `start-from-setup`, `start-from-init`)
|
||||
</td>
|
||||
<td>2.44.0, 2.43.6, 2.42.12</td>
|
||||
<td>2024-01-25</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="./advisory/a10009">A-10009</a>
|
||||
</td>
|
||||
<td>Ensure lock distribution for `FOR UPDATE`-statements on Cockroachdb</td>
|
||||
<td>Feature description</td>
|
||||
<td>
|
||||
Fixes rare cases where updating projections was blocked by a `WRITE_TOO_OLD`-error when using cockroachdb.
|
||||
</td>
|
||||
<td>2.53.0</td>
|
||||
<td>2024-05-27</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## Subscribe to our Mailing List
|
||||
|
@ -474,17 +474,29 @@ module.exports = {
|
||||
"This part of our documentation contains ZITADEL specific or general concepts required to understand the system or our guides.",
|
||||
},
|
||||
items: [
|
||||
"concepts/structure/instance",
|
||||
"concepts/structure/organizations",
|
||||
"concepts/structure/projects",
|
||||
"concepts/structure/applications",
|
||||
"concepts/structure/granted_projects",
|
||||
"concepts/structure/users",
|
||||
"concepts/structure/managers",
|
||||
"concepts/structure/policies",
|
||||
{
|
||||
type: "category",
|
||||
label: "Resources",
|
||||
collapsed: false,
|
||||
items: [
|
||||
{
|
||||
type: "autogenerated",
|
||||
dirName: "concepts/structure",
|
||||
}
|
||||
]
|
||||
|
||||
},
|
||||
{
|
||||
type: "category",
|
||||
label: "Features",
|
||||
collapsed: false,
|
||||
items: [
|
||||
{
|
||||
type: "autogenerated",
|
||||
dirName: "concepts/features",
|
||||
}
|
||||
]
|
||||
|
||||
},
|
||||
{
|
||||
type: "autogenerated",
|
||||
|
BIN
docs/static/img/guides/console/external_links_1.png
vendored
Normal file
BIN
docs/static/img/guides/console/external_links_1.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 51 KiB |
BIN
docs/static/img/guides/console/external_links_2.png
vendored
Normal file
BIN
docs/static/img/guides/console/external_links_2.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.4 KiB |
BIN
docs/static/img/guides/console/privacypolicy.png
vendored
BIN
docs/static/img/guides/console/privacypolicy.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 28 KiB |
BIN
docs/static/img/sdk-examples/console.png
vendored
Normal file
BIN
docs/static/img/sdk-examples/console.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 200 KiB |
@ -32,6 +32,7 @@ describe('instance notifications', () => {
|
||||
cy.get('[formcontrolname="replyToAddress"]').clear().type('replyto1@example.com');
|
||||
cy.get('[data-e2e="create-button"]').click();
|
||||
cy.shouldConfirmSuccess();
|
||||
cy.get('[data-e2e="close-button"]').click();
|
||||
cy.get('tr').contains('mailgun');
|
||||
cy.get('tr').contains('smtp.mailgun.org:587');
|
||||
cy.get('tr').contains('sender1@example.com');
|
||||
@ -51,6 +52,7 @@ describe('instance notifications', () => {
|
||||
cy.get('[formcontrolname="senderName"]').clear().type('Change1');
|
||||
cy.get('[data-e2e="create-button"]').click();
|
||||
cy.shouldConfirmSuccess();
|
||||
cy.get('[data-e2e="close-button"]').click();
|
||||
rowSelector = `tr:contains('mailgun')`;
|
||||
cy.get(rowSelector).contains('mailgun');
|
||||
cy.get(rowSelector).contains('smtp.mailgun.org:587');
|
||||
@ -81,6 +83,7 @@ describe('instance notifications', () => {
|
||||
cy.get('[formcontrolname="replyToAddress"]').clear().type('replyto2@example.com');
|
||||
cy.get('[data-e2e="create-button"]').click();
|
||||
cy.shouldConfirmSuccess();
|
||||
cy.get('[data-e2e="close-button"]').click();
|
||||
rowSelector = `tr:contains('mailjet')`;
|
||||
cy.get(rowSelector).contains('mailjet');
|
||||
cy.get(rowSelector).contains('in-v3.mailjet.com:587');
|
||||
@ -130,6 +133,51 @@ describe('instance notifications', () => {
|
||||
rowSelector = `tr:contains('mailgun')`;
|
||||
cy.get(rowSelector).should('not.exist');
|
||||
});
|
||||
it(`should add Mailgun SMTP provider settings and activate it using wizard`, () => {
|
||||
let rowSelector = `a:contains('Mailgun')`;
|
||||
cy.visit(smtpPath);
|
||||
cy.get(rowSelector).click();
|
||||
cy.get('[formcontrolname="hostAndPort"]').should('have.value', 'smtp.mailgun.org:587');
|
||||
cy.get('[formcontrolname="user"]').clear().type('user@example.com');
|
||||
cy.get('[formcontrolname="password"]').clear().type('password');
|
||||
cy.get('[data-e2e="continue-button"]').click();
|
||||
cy.get('[formcontrolname="senderAddress"]').clear().type('sender1@example.com');
|
||||
cy.get('[formcontrolname="senderName"]').clear().type('Test1');
|
||||
cy.get('[formcontrolname="replyToAddress"]').clear().type('replyto1@example.com');
|
||||
cy.get('[data-e2e="create-button"]').click();
|
||||
cy.shouldConfirmSuccess();
|
||||
cy.get('[data-e2e="activate-button"]').click();
|
||||
cy.shouldConfirmSuccess();
|
||||
cy.get('[data-e2e="close-button"]').click();
|
||||
rowSelector = `tr:contains('smtp.mailgun.org:587')`;
|
||||
cy.get(rowSelector).find('[data-e2e="active-provider"]');
|
||||
cy.get(rowSelector).contains('mailgun');
|
||||
cy.get(rowSelector).contains('smtp.mailgun.org:587');
|
||||
cy.get(rowSelector).contains('sender1@example.com');
|
||||
});
|
||||
it(`should add Mailgun SMTP provider settings and deactivate it using wizard`, () => {
|
||||
let rowSelector = `tr:contains('mailgun')`;
|
||||
cy.visit(smtpPath);
|
||||
cy.get(rowSelector).click();
|
||||
cy.get('[data-e2e="continue-button"]').click();
|
||||
cy.get('[data-e2e="create-button"]').click();
|
||||
cy.shouldConfirmSuccess();
|
||||
cy.get('[data-e2e="deactivate-button"]').click();
|
||||
cy.shouldConfirmSuccess();
|
||||
cy.get('[data-e2e="close-button"]').click();
|
||||
rowSelector = `tr:contains('mailgun')`;
|
||||
cy.get(rowSelector).find('[data-e2e="active-provider"]').should('not.exist');
|
||||
});
|
||||
it(`should delete Mailgun SMTP provider`, () => {
|
||||
let rowSelector = `tr:contains('mailgun')`;
|
||||
cy.visit(smtpPath);
|
||||
cy.get(rowSelector).find('[data-e2e="delete-provider-button"]').click({ force: true });
|
||||
cy.get('[data-e2e="confirm-dialog-input"]').focus().type('Test1');
|
||||
cy.get('[data-e2e="confirm-dialog-button"]').click();
|
||||
cy.shouldConfirmSuccess();
|
||||
rowSelector = `tr:contains('mailgun')`;
|
||||
cy.get(rowSelector).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
describe('sms settings', () => {
|
||||
|
@ -26,8 +26,9 @@ describe('organizations', () => {
|
||||
it('should delete an org', () => {
|
||||
cy.visit(orgsPath);
|
||||
cy.contains('tr', newOrg).click();
|
||||
cy.wait(3000);
|
||||
cy.get('[data-e2e="actions"]').click();
|
||||
cy.get('[data-e2e="delete"]', { timeout: 3000 }).should('be.visible').click();
|
||||
cy.get('[data-e2e="delete"]', { timeout: 1000 }).should('be.visible').click();
|
||||
cy.get('[data-e2e="confirm-dialog-input"]').focus().clear().type(newOrg);
|
||||
cy.get('[data-e2e="confirm-dialog-button"]').click();
|
||||
cy.shouldConfirmSuccess();
|
||||
|
104
e2e/cypress/e2e/settings/external-links-settings.cy.ts
Normal file
104
e2e/cypress/e2e/settings/external-links-settings.cy.ts
Normal file
@ -0,0 +1,104 @@
|
||||
import { ensureExternalLinksSettingsSet } from 'support/api/external-links-settings';
|
||||
import { apiAuth } from '../../support/api/apiauth';
|
||||
|
||||
describe('instance external link settings', () => {
|
||||
const externalLinkSettingsPath = `/instance?id=privacypolicy`;
|
||||
|
||||
const tosLink = 'https://zitadel.com/docs/legal/terms-of-service';
|
||||
const privacyPolicyLink = 'https://zitadel.com/docs/legal/privacy-policy';
|
||||
const helpLink = '';
|
||||
const supportEmail = '';
|
||||
const customLink = '';
|
||||
const customLinkText = '';
|
||||
const docsLink = 'https://zitadel.com/docs';
|
||||
|
||||
beforeEach(`ensure they are set`, () => {
|
||||
apiAuth().then((apiCallProperties) => {
|
||||
ensureExternalLinksSettingsSet(apiCallProperties, tosLink, privacyPolicyLink, docsLink);
|
||||
cy.visit(externalLinkSettingsPath);
|
||||
});
|
||||
});
|
||||
|
||||
it(`should have default settings`, () => {
|
||||
cy.get('[formcontrolname="tosLink"]').should('value', tosLink);
|
||||
cy.get('[formcontrolname="privacyLink"]').should('value', privacyPolicyLink);
|
||||
cy.get('[formcontrolname="helpLink"]').should('value', helpLink);
|
||||
cy.get('[formcontrolname="supportEmail"]').should('value', supportEmail);
|
||||
cy.get('[formcontrolname="customLink"]').should('value', customLink);
|
||||
cy.get('[formcontrolname="customLinkText"]').should('value', customLinkText);
|
||||
cy.get('[formcontrolname="docsLink"]').should('value', docsLink);
|
||||
});
|
||||
|
||||
it(`should update external links`, () => {
|
||||
cy.get('[formcontrolname="tosLink"]').clear().type('tosLink2');
|
||||
cy.get('[formcontrolname="privacyLink"]').clear().type('privacyLink2');
|
||||
cy.get('[formcontrolname="helpLink"]').clear().type('helpLink');
|
||||
cy.get('[formcontrolname="supportEmail"]').clear().type('support@example.com');
|
||||
cy.get('[formcontrolname="customLink"]').clear().type('customLink');
|
||||
cy.get('[formcontrolname="customLinkText"]').clear().type('customLinkText');
|
||||
cy.get('[formcontrolname="docsLink"]').clear().type('docsLink');
|
||||
cy.get('[data-e2e="save-button"]').click();
|
||||
cy.shouldConfirmSuccess();
|
||||
});
|
||||
|
||||
it(`should return to default values`, () => {
|
||||
cy.get('[formcontrolname="tosLink"]').should('value', tosLink);
|
||||
cy.get('[formcontrolname="privacyLink"]').should('value', privacyPolicyLink);
|
||||
cy.get('[formcontrolname="helpLink"]').should('value', helpLink);
|
||||
cy.get('[formcontrolname="supportEmail"]').should('value', supportEmail);
|
||||
cy.get('[formcontrolname="customLink"]').should('value', customLink);
|
||||
cy.get('[formcontrolname="customLinkText"]').should('value', customLinkText);
|
||||
cy.get('[formcontrolname="docsLink"]').should('value', docsLink);
|
||||
});
|
||||
});
|
||||
|
||||
describe('instance external link settings', () => {
|
||||
const externalLinkSettingsPath = `/org-settings?id=privacypolicy`;
|
||||
|
||||
const tosLink = 'https://zitadel.com/docs/legal/terms-of-service';
|
||||
const privacyPolicyLink = 'https://zitadel.com/docs/legal/privacy-policy';
|
||||
const helpLink = '';
|
||||
const supportEmail = '';
|
||||
const customLink = '';
|
||||
const customLinkText = '';
|
||||
const docsLink = 'https://zitadel.com/docs';
|
||||
|
||||
beforeEach(() => {
|
||||
cy.context().as('ctx');
|
||||
cy.visit(externalLinkSettingsPath);
|
||||
});
|
||||
|
||||
it(`should have default settings`, () => {
|
||||
cy.get('[formcontrolname="tosLink"]').should('value', tosLink);
|
||||
cy.get('[formcontrolname="privacyLink"]').should('value', privacyPolicyLink);
|
||||
cy.get('[formcontrolname="helpLink"]').should('value', helpLink);
|
||||
cy.get('[formcontrolname="supportEmail"]').should('value', supportEmail);
|
||||
cy.get('[formcontrolname="customLink"]').should('value', customLink);
|
||||
cy.get('[formcontrolname="customLinkText"]').should('value', customLinkText);
|
||||
cy.get('[formcontrolname="docsLink"]').should('value', docsLink);
|
||||
});
|
||||
|
||||
it(`should update external links`, () => {
|
||||
cy.get('[formcontrolname="tosLink"]').clear().type('tosLink2');
|
||||
cy.get('[formcontrolname="privacyLink"]').clear().type('privacyLink2');
|
||||
cy.get('[formcontrolname="helpLink"]').clear().type('helpLink');
|
||||
cy.get('[formcontrolname="supportEmail"]').clear().type('support@example.com');
|
||||
cy.get('[formcontrolname="customLink"]').clear().type('customLink');
|
||||
cy.get('[formcontrolname="customLinkText"]').clear().type('customLinkText');
|
||||
cy.get('[formcontrolname="docsLink"]').clear().type('docsLink');
|
||||
cy.get('[data-e2e="save-button"]').click();
|
||||
cy.shouldConfirmSuccess();
|
||||
});
|
||||
|
||||
it(`should return to default values`, () => {
|
||||
cy.get('[data-e2e="reset-button"]').click();
|
||||
cy.get('[data-e2e="confirm-dialog-button"]').click();
|
||||
cy.get('[formcontrolname="tosLink"]').should('value', tosLink);
|
||||
cy.get('[formcontrolname="privacyLink"]').should('value', privacyPolicyLink);
|
||||
cy.get('[formcontrolname="helpLink"]').should('value', helpLink);
|
||||
cy.get('[formcontrolname="supportEmail"]').should('value', supportEmail);
|
||||
cy.get('[formcontrolname="customLink"]').should('value', customLink);
|
||||
cy.get('[formcontrolname="customLinkText"]').should('value', customLinkText);
|
||||
cy.get('[formcontrolname="docsLink"]').should('value', docsLink);
|
||||
});
|
||||
});
|
32
e2e/cypress/support/api/external-links-settings.ts
Normal file
32
e2e/cypress/support/api/external-links-settings.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { ensureSetting } from './ensure';
|
||||
import { API } from './types';
|
||||
|
||||
export function ensureExternalLinksSettingsSet(api: API, tosLink: string, privacyPolicyLink: string, docsLink: string) {
|
||||
return ensureSetting(
|
||||
api,
|
||||
`${api.adminBaseURL}/policies/privacy`,
|
||||
(body: any) => {
|
||||
const result = {
|
||||
sequence: body.policy?.details?.sequence,
|
||||
id: body.policy.id,
|
||||
entity: null,
|
||||
};
|
||||
|
||||
if (
|
||||
body.policy &&
|
||||
body.policy.tosLink === tosLink &&
|
||||
body.policy.privacyLink === privacyPolicyLink &&
|
||||
body.policy.docsLink === docsLink
|
||||
) {
|
||||
return { ...result, entity: body.policy };
|
||||
}
|
||||
return result;
|
||||
},
|
||||
`${api.adminBaseURL}/policies/privacy`,
|
||||
{
|
||||
tosLink,
|
||||
privacyLink: privacyPolicyLink,
|
||||
docsLink,
|
||||
},
|
||||
);
|
||||
}
|
36
go.mod
36
go.mod
@ -49,7 +49,7 @@ require (
|
||||
github.com/nicksnyder/go-i18n/v2 v2.4.0
|
||||
github.com/pquerna/otp v1.4.0
|
||||
github.com/rakyll/statik v0.1.7
|
||||
github.com/rs/cors v1.10.1
|
||||
github.com/rs/cors v1.11.0
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
|
||||
github.com/sony/sonyflake v1.2.0
|
||||
github.com/spf13/cobra v1.8.0
|
||||
@ -58,20 +58,20 @@ require (
|
||||
github.com/superseriousbusiness/exifremove v0.0.0-20210330092427-6acd27eac203
|
||||
github.com/ttacon/libphonenumber v1.2.1
|
||||
github.com/zitadel/logging v0.6.0
|
||||
github.com/zitadel/oidc/v3 v3.21.0
|
||||
github.com/zitadel/oidc/v3 v3.23.2
|
||||
github.com/zitadel/passwap v0.5.0
|
||||
github.com/zitadel/saml v0.1.3
|
||||
github.com/zitadel/schema v1.3.0
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.50.0
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0
|
||||
go.opentelemetry.io/otel v1.25.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.47.0
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.25.0
|
||||
go.opentelemetry.io/otel/metric v1.25.0
|
||||
go.opentelemetry.io/otel/sdk v1.25.0
|
||||
go.opentelemetry.io/otel/sdk/metric v1.25.0
|
||||
go.opentelemetry.io/otel/trace v1.25.0
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0
|
||||
go.opentelemetry.io/otel v1.26.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.48.0
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0
|
||||
go.opentelemetry.io/otel/metric v1.26.0
|
||||
go.opentelemetry.io/otel/sdk v1.26.0
|
||||
go.opentelemetry.io/otel/sdk/metric v1.26.0
|
||||
go.opentelemetry.io/otel/trace v1.26.0
|
||||
go.uber.org/mock v0.4.0
|
||||
golang.org/x/crypto v0.22.0
|
||||
golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8
|
||||
@ -80,9 +80,9 @@ require (
|
||||
golang.org/x/sync v0.7.0
|
||||
golang.org/x/text v0.14.0
|
||||
google.golang.org/api v0.172.0
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240412170617-26222e5d3d56
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240429193739-8cf5692501f6
|
||||
google.golang.org/grpc v1.63.2
|
||||
google.golang.org/protobuf v1.33.0
|
||||
google.golang.org/protobuf v1.34.0
|
||||
sigs.k8s.io/yaml v1.4.0
|
||||
)
|
||||
|
||||
@ -116,7 +116,7 @@ require (
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240412170617-26222e5d3d56 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240412170617-26222e5d3d56 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
@ -183,8 +183,8 @@ require (
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_golang v1.19.0
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.52.3 // indirect
|
||||
github.com/prometheus/procfs v0.13.0 // indirect
|
||||
github.com/prometheus/common v0.53.0 // indirect
|
||||
github.com/prometheus/procfs v0.14.0 // indirect
|
||||
github.com/rs/xid v1.5.0 // indirect
|
||||
github.com/russellhaering/goxmldsig v1.4.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
@ -196,7 +196,7 @@ require (
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.2.0 // indirect
|
||||
golang.org/x/sys v0.19.0
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
|
72
go.sum
72
go.sum
@ -618,16 +618,16 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
|
||||
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
github.com/prometheus/common v0.52.3 h1:5f8uj6ZwHSscOGNdIQg6OiZv/ybiK2CO2q2drVZAQSA=
|
||||
github.com/prometheus/common v0.52.3/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U=
|
||||
github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE=
|
||||
github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o=
|
||||
github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g=
|
||||
github.com/prometheus/procfs v0.14.0 h1:Lw4VdGGoKEZilJsayHf0B+9YgLGREba2C6xr+Fdfq6s=
|
||||
github.com/prometheus/procfs v0.14.0/go.mod h1:XL+Iwz8k8ZabyZfMFHPiilCniixqQarAy5Mu67pHlNQ=
|
||||
github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ=
|
||||
github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
@ -639,8 +639,8 @@ github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6po
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo=
|
||||
github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po=
|
||||
github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/russellhaering/goxmldsig v1.4.0 h1:8UcDh/xGyQiyrW+Fq5t8f+l2DLB1+zlhYzkPUJ7Qhys=
|
||||
@ -731,8 +731,8 @@ github.com/zenazn/goji v1.0.1 h1:4lbD8Mx2h7IvloP7r2C0D6ltZP6Ufip8Hn0wmSK5LR8=
|
||||
github.com/zenazn/goji v1.0.1/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
github.com/zitadel/logging v0.6.0 h1:t5Nnt//r+m2ZhhoTmoPX+c96pbMarqJvW1Vq6xFTank=
|
||||
github.com/zitadel/logging v0.6.0/go.mod h1:Y4CyAXHpl3Mig6JOszcV5Rqqsojj+3n7y2F591Mp/ow=
|
||||
github.com/zitadel/oidc/v3 v3.21.0 h1:dvhPLAOCJQHxZq+1vqd2+TYu1EzwrHhnPSSh4nVamgo=
|
||||
github.com/zitadel/oidc/v3 v3.21.0/go.mod h1:3uCwJc680oWoTBdzIppMZQS+VNxq+sVcwgodbreuatM=
|
||||
github.com/zitadel/oidc/v3 v3.23.2 h1:vRUM6SKudr6WR/lqxue4cvCbgR+IdEJGVBklucKKXgk=
|
||||
github.com/zitadel/oidc/v3 v3.23.2/go.mod h1:9snlhm3W/GNURqxtchjL1AAuClWRZ2NTkn9sLs1WYfM=
|
||||
github.com/zitadel/passwap v0.5.0 h1:kFMoRyo0GnxtOz7j9+r/CsRwSCjHGRaAKoUe69NwPvs=
|
||||
github.com/zitadel/passwap v0.5.0/go.mod h1:uqY7D3jqdTFcKsW0Q3Pcv5qDMmSHpVTzUZewUKC1KZA=
|
||||
github.com/zitadel/saml v0.1.3 h1:LI4DOCVyyU1qKPkzs3vrGcA5J3H4pH3+CL9zr9ShkpM=
|
||||
@ -746,28 +746,28 @@ go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.50.0 h1:zvpPXY7RfYAGSdYQLjp6zxdJNSYD/+FFoCTQN9IPxBs=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.50.0/go.mod h1:BMn8NB1vsxTljvuorms2hyOs8IBuuBEq0pl7ltOfy30=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 h1:cEPbyTSEHlQR89XVlyo78gqluF8Y3oMeBkXGWzQsfXY=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0/go.mod h1:DKdbWcT4GH1D0Y3Sqt/PFXt2naRKDWtU+eE6oLdFNA8=
|
||||
go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k=
|
||||
go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0 h1:dT33yIHtmsqpixFsSQPwNeY5drM9wTcoL8h0FWF4oGM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0/go.mod h1:h95q0LBGh7hlAC08X2DhSeyIG02YQ0UyioTCVAqRPmc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0 h1:vOL89uRfOCCNIjkisd0r7SEdJF3ZJFyCNY34fdZs8eU=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0/go.mod h1:8GlBGcDk8KKi7n+2S4BT/CPZQYH3erLu0/k64r1MYgo=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.47.0 h1:OL6yk1Z/pEGdDnrBbxSsH+t4FY1zXfBRGd7bjwhlMLU=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.47.0/go.mod h1:xF3N4OSICZDVbbYZydz9MHFro1RjmkPUKEvar2utG+Q=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.25.0 h1:0vZZdECYzhTt9MKQZ5qQ0V+J3MFu4MQaQ3COfugF+FQ=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.25.0/go.mod h1:e7iXx3HjaSSBXfy9ykVUlupS2Vp7LBIBuT21ousM2Hk=
|
||||
go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA=
|
||||
go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s=
|
||||
go.opentelemetry.io/otel/sdk v1.25.0 h1:PDryEJPC8YJZQSyLY5eqLeafHtG+X7FWnf3aXMtxbqo=
|
||||
go.opentelemetry.io/otel/sdk v1.25.0/go.mod h1:oFgzCM2zdsxKzz6zwpTZYLLQsFwc+K0daArPdIhuxkw=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.25.0 h1:7CiHOy08LbrxMAp4vWpbiPcklunUshVpAvGBrdDRlGw=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.25.0/go.mod h1:LzwoKptdbBBdYfvtGCzGwk6GWMA3aUzBOwtQpR6Nz7o=
|
||||
go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM=
|
||||
go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 h1:A3SayB3rNyt+1S6qpI9mHPkeHTZbD7XILEqWnYZb2l0=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0/go.mod h1:27iA5uvhuRNmalO+iEUdVn5ZMj2qy10Mm+XRIpRmyuU=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 h1:Xs2Ncz0gNihqu9iosIZ5SkBbWo5T8JhhLJFMQL1qmLI=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0/go.mod h1:vy+2G/6NvVMpwGX/NyLqcC41fxepnuKHk16E6IZUcJc=
|
||||
go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs=
|
||||
go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 h1:1u/AyyOqAWzy+SkPxDpahCNZParHV8Vid1RnI2clyDE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0/go.mod h1:z46paqbJ9l7c9fIPCXTqTGwhQZ5XoTIsfeFYWboizjs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 h1:Waw9Wfpo/IXzOI8bCB7DIk+0JZcqqsyn1JFnAc+iam8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0/go.mod h1:wnJIG4fOqyynOnnQF/eQb4/16VlX2EJAHhHgqIqWfAo=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.48.0 h1:sBQe3VNGUjY9IKWQC6z2lNqa5iGbDSxhs60ABwK4y0s=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.48.0/go.mod h1:DtrbMzoZWwQHyrQmCfLam5DZbnmorsGbOtTbYHycU5o=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0 h1:0W5o9SzoR15ocYHEQfvfipzcNog1lBxOLfnex91Hk6s=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0/go.mod h1:zVZ8nz+VSggWmnh6tTsJqXQ7rU4xLwRtna1M4x5jq58=
|
||||
go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30=
|
||||
go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4=
|
||||
go.opentelemetry.io/otel/sdk v1.26.0 h1:Y7bumHf5tAiDlRYFmGqetNcLaVUZmh4iYfmGxtmz7F8=
|
||||
go.opentelemetry.io/otel/sdk v1.26.0/go.mod h1:0p8MXpqLeJ0pzcszQQN4F0S5FVjBLgypeGSngLsmirs=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.26.0 h1:cWSks5tfriHPdWFnl+qpX3P681aAYqlZHcAyHw5aU9Y=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.26.0/go.mod h1:ClMFFknnThJCksebJwz7KIyEDHO+nTB6gK8obLy8RyE=
|
||||
go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA=
|
||||
go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0=
|
||||
go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94=
|
||||
go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
@ -991,10 +991,10 @@ google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEY
|
||||
google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20240412170617-26222e5d3d56 h1:LlcUFJ4BLmJVS4Kly+WCK7LQqcevmycHj88EPgyhNx8=
|
||||
google.golang.org/genproto v0.0.0-20240412170617-26222e5d3d56/go.mod h1:n1CaIKYMIlxFt1zJE/1kU40YpSL0drGMbl0Idum1VSs=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240412170617-26222e5d3d56 h1:KuFzeG+qPmpT8KpJXcrKAyeHhn64dgEICWlccP9qp0U=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240412170617-26222e5d3d56/go.mod h1:wTHjrkbcS8AoQbb/0v9bFIPItZQPAsyVfgG9YPUhjAM=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240412170617-26222e5d3d56 h1:zviK8GX4VlMstrK3JkexM5UHjH1VOkRebH9y3jhSBGk=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240412170617-26222e5d3d56/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240429193739-8cf5692501f6 h1:DTJM0R8LECCgFeUwApvcEJHz85HLagW8uRENYxHh1ww=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240429193739-8cf5692501f6/go.mod h1:10yRODfgim2/T8csjQsMPgZOMvtytXKTDRzH6HRGzRw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 h1:DujSIu+2tC9Ht0aPNA7jgj23Iq8Ewi5sgkQ++wdvonE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
||||
@ -1022,8 +1022,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.34.0 h1:Qo/qEd2RZPCf2nKuorzksSknv0d3ERwp1vFG38gSmH4=
|
||||
google.golang.org/protobuf v1.34.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
@ -196,6 +196,33 @@ func TestServer_SetExecution_Request_Include(t *testing.T) {
|
||||
executionTargetsSingleTarget(targetResp.GetId()),
|
||||
)
|
||||
|
||||
circularExecutionService := &action.Condition{
|
||||
ConditionType: &action.Condition_Request{
|
||||
Request: &action.RequestExecution{
|
||||
Condition: &action.RequestExecution_Service{
|
||||
Service: "zitadel.session.v2beta.SessionService",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
Tester.SetExecution(CTX, t,
|
||||
circularExecutionService,
|
||||
executionTargetsSingleInclude(executionCond),
|
||||
)
|
||||
circularExecutionMethod := &action.Condition{
|
||||
ConditionType: &action.Condition_Request{
|
||||
Request: &action.RequestExecution{
|
||||
Condition: &action.RequestExecution_Method{
|
||||
Method: "/zitadel.session.v2beta.SessionService/ListSessions",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
Tester.SetExecution(CTX, t,
|
||||
circularExecutionMethod,
|
||||
executionTargetsSingleInclude(circularExecutionService),
|
||||
)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
ctx context.Context
|
||||
@ -203,6 +230,15 @@ func TestServer_SetExecution_Request_Include(t *testing.T) {
|
||||
want *action.SetExecutionResponse
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "method, circular error",
|
||||
ctx: CTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: circularExecutionService,
|
||||
Targets: executionTargetsSingleInclude(circularExecutionMethod),
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "method, ok",
|
||||
ctx: CTX,
|
||||
@ -247,30 +283,6 @@ func TestServer_SetExecution_Request_Include(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
/* circular
|
||||
{
|
||||
name: "all, ok",
|
||||
ctx: CTX,
|
||||
req: &action.SetExecutionRequest{
|
||||
Condition: &action.Condition{
|
||||
ConditionType: &action.Condition_Request{
|
||||
Request: &action.RequestExecution{
|
||||
Condition: &action.RequestExecution_All{
|
||||
All: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Targets: executionTargetsSingleInclude(executionCond),
|
||||
},
|
||||
want: &action.SetExecutionResponse{
|
||||
Details: &object.Details{
|
||||
ChangeDate: timestamppb.Now(),
|
||||
ResourceOwner: Tester.Instance.InstanceID(),
|
||||
},
|
||||
},
|
||||
},
|
||||
*/
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
@ -538,6 +538,9 @@ func (s *Server) getPrivacyPolicy(ctx context.Context, orgID string) (_ *managem
|
||||
PrivacyLink: queriedPrivacy.PrivacyLink,
|
||||
HelpLink: queriedPrivacy.HelpLink,
|
||||
SupportEmail: string(queriedPrivacy.SupportEmail),
|
||||
DocsLink: queriedPrivacy.DocsLink,
|
||||
CustomLink: queriedPrivacy.CustomLink,
|
||||
CustomLinkText: queriedPrivacy.CustomLinkText,
|
||||
}, nil
|
||||
}
|
||||
return nil, nil
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/muhlemmer/gu"
|
||||
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
object_pb "github.com/zitadel/zitadel/internal/api/grpc/object"
|
||||
|
@ -172,6 +172,7 @@ func SMTPConfigToPb(smtp *query.SMTPConfig) *settings_pb.SMTPConfig {
|
||||
User: smtp.User,
|
||||
Details: obj_grpc.ToViewDetailsPb(smtp.Sequence, smtp.CreationDate, smtp.ChangeDate, smtp.ResourceOwner),
|
||||
Id: smtp.ID,
|
||||
State: settings_pb.SMTPConfigState(smtp.State),
|
||||
}
|
||||
return mapped
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package admin
|
||||
|
||||
import (
|
||||
"github.com/crewjam/saml"
|
||||
"github.com/muhlemmer/gu"
|
||||
|
||||
idp_grpc "github.com/zitadel/zitadel/internal/api/grpc/idp"
|
||||
"github.com/zitadel/zitadel/internal/api/grpc/object"
|
||||
@ -469,23 +470,35 @@ func updateAppleProviderToCommand(req *admin_pb.UpdateAppleProviderRequest) comm
|
||||
}
|
||||
|
||||
func addSAMLProviderToCommand(req *admin_pb.AddSAMLProviderRequest) command.SAMLProvider {
|
||||
var nameIDFormat *domain.SAMLNameIDFormat
|
||||
if req.NameIdFormat != nil {
|
||||
nameIDFormat = gu.Ptr(idp_grpc.SAMLNameIDFormatToDomain(req.GetNameIdFormat()))
|
||||
}
|
||||
return command.SAMLProvider{
|
||||
Name: req.Name,
|
||||
Metadata: req.GetMetadataXml(),
|
||||
MetadataURL: req.GetMetadataUrl(),
|
||||
Binding: bindingToCommand(req.Binding),
|
||||
WithSignedRequest: req.WithSignedRequest,
|
||||
NameIDFormat: nameIDFormat,
|
||||
TransientMappingAttributeName: req.GetTransientMappingAttributeName(),
|
||||
IDPOptions: idp_grpc.OptionsToCommand(req.ProviderOptions),
|
||||
}
|
||||
}
|
||||
|
||||
func updateSAMLProviderToCommand(req *admin_pb.UpdateSAMLProviderRequest) command.SAMLProvider {
|
||||
var nameIDFormat *domain.SAMLNameIDFormat
|
||||
if req.NameIdFormat != nil {
|
||||
nameIDFormat = gu.Ptr(idp_grpc.SAMLNameIDFormatToDomain(req.GetNameIdFormat()))
|
||||
}
|
||||
return command.SAMLProvider{
|
||||
Name: req.Name,
|
||||
Metadata: req.GetMetadataXml(),
|
||||
MetadataURL: req.GetMetadataUrl(),
|
||||
Binding: bindingToCommand(req.Binding),
|
||||
WithSignedRequest: req.WithSignedRequest,
|
||||
NameIDFormat: nameIDFormat,
|
||||
TransientMappingAttributeName: req.GetTransientMappingAttributeName(),
|
||||
IDPOptions: idp_grpc.OptionsToCommand(req.ProviderOptions),
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
org_grpc "github.com/zitadel/zitadel/internal/api/grpc/org"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/admin"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/org"
|
||||
)
|
||||
|
||||
func listOrgRequestToModel(req *admin.ListOrgsRequest) (*query.OrgSearchQueries, error) {
|
||||
@ -18,18 +17,9 @@ func listOrgRequestToModel(req *admin.ListOrgsRequest) (*query.OrgSearchQueries,
|
||||
SearchRequest: query.SearchRequest{
|
||||
Offset: offset,
|
||||
Limit: limit,
|
||||
SortingColumn: fieldNameToOrgColumn(req.SortingColumn),
|
||||
SortingColumn: org_grpc.FieldNameToOrgColumn(req.SortingColumn),
|
||||
Asc: asc,
|
||||
},
|
||||
Queries: queries,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func fieldNameToOrgColumn(fieldName org.OrgFieldName) query.Column {
|
||||
switch fieldName {
|
||||
case org.OrgFieldName_ORG_FIELD_NAME_NAME:
|
||||
return query.OrgColumnName
|
||||
default:
|
||||
return query.Column{}
|
||||
}
|
||||
}
|
||||
|
@ -11,5 +11,8 @@ func UpdatePrivacyPolicyToDomain(req *admin_pb.UpdatePrivacyPolicyRequest) *doma
|
||||
PrivacyLink: req.PrivacyLink,
|
||||
HelpLink: req.HelpLink,
|
||||
SupportEmail: domain.EmailAddress(req.SupportEmail),
|
||||
DocsLink: req.DocsLink,
|
||||
CustomLink: req.CustomLink,
|
||||
CustomLinkText: req.CustomLinkText,
|
||||
}
|
||||
}
|
||||
|
@ -269,6 +269,7 @@ func ListMyProjectOrgsRequestToQuery(req *auth_pb.ListMyProjectOrgsRequest) (*qu
|
||||
Offset: offset,
|
||||
Limit: limit,
|
||||
Asc: asc,
|
||||
SortingColumn: org.FieldNameToOrgColumn(req.SortingColumn),
|
||||
},
|
||||
Queries: queries,
|
||||
}, nil
|
||||
|
@ -16,6 +16,7 @@ func systemFeaturesToCommand(req *feature_pb.SetSystemFeaturesRequest) *command.
|
||||
UserSchema: req.UserSchema,
|
||||
Actions: req.Actions,
|
||||
TokenExchange: req.OidcTokenExchange,
|
||||
ImprovedPerformance: improvedPerformanceListToDomain(req.ImprovedPerformance),
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,6 +29,7 @@ func systemFeaturesToPb(f *query.SystemFeatures) *feature_pb.GetSystemFeaturesRe
|
||||
UserSchema: featureSourceToFlagPb(&f.UserSchema),
|
||||
OidcTokenExchange: featureSourceToFlagPb(&f.TokenExchange),
|
||||
Actions: featureSourceToFlagPb(&f.Actions),
|
||||
ImprovedPerformance: featureSourceToImprovedPerformanceFlagPb(&f.ImprovedPerformance),
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,6 +41,7 @@ func instanceFeaturesToCommand(req *feature_pb.SetInstanceFeaturesRequest) *comm
|
||||
UserSchema: req.UserSchema,
|
||||
TokenExchange: req.OidcTokenExchange,
|
||||
Actions: req.Actions,
|
||||
ImprovedPerformance: improvedPerformanceListToDomain(req.ImprovedPerformance),
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,6 +54,14 @@ func instanceFeaturesToPb(f *query.InstanceFeatures) *feature_pb.GetInstanceFeat
|
||||
UserSchema: featureSourceToFlagPb(&f.UserSchema),
|
||||
OidcTokenExchange: featureSourceToFlagPb(&f.TokenExchange),
|
||||
Actions: featureSourceToFlagPb(&f.Actions),
|
||||
ImprovedPerformance: featureSourceToImprovedPerformanceFlagPb(&f.ImprovedPerformance),
|
||||
}
|
||||
}
|
||||
|
||||
func featureSourceToImprovedPerformanceFlagPb(fs *query.FeatureSource[[]feature.ImprovedPerformanceType]) *feature_pb.ImprovedPerformanceFeatureFlag {
|
||||
return &feature_pb.ImprovedPerformanceFeatureFlag{
|
||||
ExecutionPaths: improvedPerformanceTypesToPb(fs.Value),
|
||||
Source: featureLevelToSourcePb(fs.Level),
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,3 +92,48 @@ func featureLevelToSourcePb(level feature.Level) feature_pb.Source {
|
||||
return feature_pb.Source(level)
|
||||
}
|
||||
}
|
||||
|
||||
func improvedPerformanceTypesToPb(types []feature.ImprovedPerformanceType) []feature_pb.ImprovedPerformance {
|
||||
res := make([]feature_pb.ImprovedPerformance, len(types))
|
||||
|
||||
for i, typ := range types {
|
||||
res[i] = improvedPerformanceTypeToPb(typ)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func improvedPerformanceTypeToPb(typ feature.ImprovedPerformanceType) feature_pb.ImprovedPerformance {
|
||||
switch typ {
|
||||
case feature.ImprovedPerformanceTypeUnknown:
|
||||
return feature_pb.ImprovedPerformance_IMPROVED_PERFORMANCE_UNSPECIFIED
|
||||
case feature.ImprovedPerformanceTypeOrgByID:
|
||||
return feature_pb.ImprovedPerformance_IMPROVED_PERFORMANCE_ORG_BY_ID
|
||||
default:
|
||||
return feature_pb.ImprovedPerformance(typ)
|
||||
}
|
||||
}
|
||||
|
||||
func improvedPerformanceListToDomain(list []feature_pb.ImprovedPerformance) []feature.ImprovedPerformanceType {
|
||||
if list == nil {
|
||||
return nil
|
||||
}
|
||||
res := make([]feature.ImprovedPerformanceType, len(list))
|
||||
|
||||
for i, typ := range list {
|
||||
res[i] = improvedPerformanceToDomain(typ)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func improvedPerformanceToDomain(typ feature_pb.ImprovedPerformance) feature.ImprovedPerformanceType {
|
||||
switch typ {
|
||||
case feature_pb.ImprovedPerformance_IMPROVED_PERFORMANCE_UNSPECIFIED:
|
||||
return feature.ImprovedPerformanceTypeUnknown
|
||||
case feature_pb.ImprovedPerformance_IMPROVED_PERFORMANCE_ORG_BY_ID:
|
||||
return feature.ImprovedPerformanceTypeOrgByID
|
||||
default:
|
||||
return feature.ImprovedPerformanceTypeUnknown
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user